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"
2005-08-14 02:01:23 +00:00
#include "ScreenSaveSync.h"
2002-05-20 08:59:37 +00:00
#include "GameConstantsAndTypes.h"
#include "GameManager.h"
2006-06-15 06:07:45 +00:00
#include "RageInput.h"
2002-05-20 08:59:37 +00:00
#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-19 06:27:20 +00:00
#include "NoteSkinManager.h"
2003-08-03 00:13:55 +00:00
#include "Steps.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-07-21 05:58:34 +00:00
#include "ScreenMiniMenu.h"
#include "ScreenPrompt.h"
2005-01-15 02:01:26 +00:00
#include "Style.h"
2005-02-09 05:27:51 +00:00
#include "ActorUtil.h"
2005-03-08 07:57:14 +00:00
#include "CommonMetrics.h"
2005-05-31 01:17:37 +00:00
#include "BackgroundUtil.h"
2005-07-21 05:58:34 +00:00
#include <utility>
#include <float.h>
2005-09-05 02:26:50 +00:00
#include "InputEventPlus.h"
2005-12-03 20:34:49 +00:00
#include "NotesWriterSM.h"
2005-12-22 03:10:04 +00:00
#include "LocalizedString.h"
2006-02-06 01:23:25 +00:00
#include "AdjustSync.h"
2002-05-20 08:59:37 +00:00
2005-07-21 21:23:18 +00:00
static Preference < float > g_iDefaultRecordLength ( "DefaultRecordLength" , 4 );
2005-12-19 00:26:43 +00:00
static Preference < bool > g_bEditorShowBGChangesPlay ( "EditorShowBGChangesPlay" , false );
2005-07-21 21:23:18 +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
//
2005-03-20 09:52:48 +00:00
const float RECORD_HOLD_SECONDS = 0.3f ;
2002-05-20 08:59:37 +00:00
2006-03-07 20:43:40 +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
2006-03-07 20:43:40 +00:00
#define EDIT_X (SCREEN_CENTER_X)
#define EDIT_Y (PLAYER_Y)
2005-04-07 19:27:53 +00:00
2006-03-07 20:43:40 +00:00
#define RECORD_X (SCREEN_CENTER_X)
#define RECORD_Y (SCREEN_CENTER_Y)
2005-04-07 19:27:53 +00:00
2006-01-08 18:40:20 +00:00
#define PLAY_RECORD_HELP_TEXT THEME->GetString(m_sName,"PlayRecordHelpText")
2006-03-07 20:43:40 +00:00
#define EDIT_HELP_TEXT THEME->GetString(m_sName,"EditHelpText")
2003-02-18 23:15:38 +00:00
2005-04-01 08:34:23 +00:00
AutoScreenMessage ( SM_UpdateTextInfo )
2005-03-28 08:01:36 +00:00
AutoScreenMessage ( SM_BackFromMainMenu )
AutoScreenMessage ( SM_BackFromAreaMenu )
AutoScreenMessage ( SM_BackFromStepsInformation )
2005-07-20 00:30:19 +00:00
AutoScreenMessage ( SM_BackFromOptions )
2005-03-28 08:01:36 +00:00
AutoScreenMessage ( SM_BackFromSongInformation )
AutoScreenMessage ( SM_BackFromBGChange )
2005-08-30 18:09:00 +00:00
AutoScreenMessage ( SM_BackFromInsertTapAttack )
AutoScreenMessage ( SM_BackFromInsertTapAttackPlayerOptions )
AutoScreenMessage ( SM_BackFromInsertCourseAttack )
AutoScreenMessage ( SM_BackFromInsertCourseAttackPlayerOptions )
2005-03-28 08:01:36 +00:00
AutoScreenMessage ( SM_BackFromCourseModeMenu )
AutoScreenMessage ( SM_DoRevertToLastSave )
2005-05-18 03:31:36 +00:00
AutoScreenMessage ( SM_DoRevertFromDisk )
2005-03-28 08:01:36 +00:00
AutoScreenMessage ( SM_BackFromBPMChange )
AutoScreenMessage ( SM_BackFromStopChange )
AutoScreenMessage ( SM_DoSaveAndExit )
AutoScreenMessage ( SM_DoExit )
2005-12-29 03:27:21 +00:00
AutoScreenMessage ( SM_SaveSuccessful );
AutoScreenMessage ( SM_SaveFailed );
2003-02-07 23:58:21 +00:00
2006-01-04 22:30:51 +00:00
static const char * EditStateNames [] = {
2005-07-22 05:02:04 +00:00
"Edit" ,
"Record" ,
"RecordPaused" ,
"Playing"
};
XToString ( EditState , NUM_EDIT_STATES );
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
{
2006-03-07 02:43:09 +00:00
m_EditMappingsDeviceInput . Clear ();
2005-01-14 23:17:04 +00:00
2006-03-14 22:07:56 +00:00
//
// Common mappings:
//
2006-03-07 20:43:40 +00:00
switch ( EDIT_MODE . GetValue () )
{
case EditMode_Practice :
m_EditMappingsDeviceInput . button [ EDIT_BUTTON_SCROLL_PREV_MEASURE ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_UP );
m_EditMappingsMenuButton . button [ EDIT_BUTTON_SCROLL_PREV_MEASURE ][ 0 ] = MENU_BUTTON_UP ;
m_EditMappingsDeviceInput . button [ EDIT_BUTTON_SCROLL_NEXT_MEASURE ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_DOWN );
m_EditMappingsMenuButton . button [ EDIT_BUTTON_SCROLL_NEXT_MEASURE ][ 0 ] = MENU_BUTTON_DOWN ;
break ;
default :
m_EditMappingsDeviceInput . button [ EDIT_BUTTON_SCROLL_UP_LINE ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_UP );
m_EditMappingsMenuButton . button [ EDIT_BUTTON_SCROLL_UP_LINE ][ 0 ] = MENU_BUTTON_UP ;
m_EditMappingsDeviceInput . button [ EDIT_BUTTON_SCROLL_DOWN_LINE ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_DOWN );
m_EditMappingsMenuButton . button [ EDIT_BUTTON_SCROLL_DOWN_LINE ][ 0 ] = MENU_BUTTON_DOWN ;
break ;
}
2006-03-07 02:43:09 +00:00
m_EditMappingsDeviceInput . button [ EDIT_BUTTON_SCROLL_UP_PAGE ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_PGUP );
m_EditMappingsDeviceInput . button [ EDIT_BUTTON_SCROLL_DOWN_PAGE ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_PGDN );
m_EditMappingsDeviceInput . button [ EDIT_BUTTON_SCROLL_HOME ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_HOME );
m_EditMappingsDeviceInput . button [ EDIT_BUTTON_SCROLL_END ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_END );
m_EditMappingsDeviceInput . button [ EDIT_BUTTON_SCROLL_NEXT ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_PERIOD );
m_EditMappingsDeviceInput . button [ EDIT_BUTTON_SCROLL_PREV ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_COMMA );
2005-11-01 00:17:26 +00:00
2006-03-07 02:43:09 +00:00
m_EditMappingsDeviceInput . button [ EDIT_BUTTON_SCROLL_SELECT ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_LSHIFT );
m_EditMappingsDeviceInput . button [ EDIT_BUTTON_SCROLL_SELECT ][ 1 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_RSHIFT );
m_EditMappingsDeviceInput . button [ EDIT_BUTTON_LAY_SELECT ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_SPACE );
2005-11-01 00:17:26 +00:00
2006-03-14 22:07:56 +00:00
m_EditMappingsDeviceInput . button [ EDIT_BUTTON_PLAY_FROM_START ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_Cp );
m_EditMappingsDeviceInput . hold [ EDIT_BUTTON_PLAY_FROM_START ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_LCTRL );
m_EditMappingsDeviceInput . hold [ EDIT_BUTTON_PLAY_FROM_START ][ 1 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_RCTRL );
m_EditMappingsDeviceInput . button [ EDIT_BUTTON_PLAY_FROM_CURSOR ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_Cp );
m_EditMappingsDeviceInput . hold [ EDIT_BUTTON_PLAY_FROM_CURSOR ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_LSHIFT );
m_EditMappingsDeviceInput . hold [ EDIT_BUTTON_PLAY_FROM_CURSOR ][ 1 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_RSHIFT );
m_EditMappingsDeviceInput . button [ EDIT_BUTTON_PLAY_SELECTION ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_Cp );
//
// EditMode-specific mappings
//
2005-11-01 00:17:26 +00:00
switch ( EDIT_MODE . GetValue () )
{
2005-12-06 23:44:01 +00:00
case EditMode_Practice :
2005-11-01 00:17:26 +00:00
// Left = Zoom out (1x, 2x, 4x)
// Right = Zoom in
2006-03-07 02:43:09 +00:00
m_EditMappingsDeviceInput . button [ EDIT_BUTTON_SCROLL_SPEED_DOWN ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_LEFT );
m_EditMappingsDeviceInput . button [ EDIT_BUTTON_SCROLL_SPEED_UP ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_RIGHT );
2005-11-01 00:17:26 +00:00
// F1 = Show help popup
2006-03-07 02:43:09 +00:00
m_EditMappingsDeviceInput . button [ EDIT_BUTTON_OPEN_INPUT_HELP ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_F1 );
2005-11-01 00:17:26 +00:00
// Esc = Show Edit Menu
2006-03-07 02:43:09 +00:00
m_EditMappingsDeviceInput . button [ EDIT_BUTTON_OPEN_EDIT_MENU ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_ESC );
m_EditMappingsMenuButton . button [ EDIT_BUTTON_OPEN_EDIT_MENU ][ 0 ] = MENU_BUTTON_START ;
2006-03-07 20:43:40 +00:00
m_EditMappingsMenuButton . button [ EDIT_BUTTON_OPEN_EDIT_MENU ][ 1 ] = MENU_BUTTON_BACK ;
2005-11-01 00:17:26 +00:00
// Escape, Enter = exit play/record
2006-03-07 02:43:09 +00:00
m_PlayMappingsDeviceInput . button [ EDIT_BUTTON_RETURN_TO_EDIT ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_ENTER );
m_PlayMappingsDeviceInput . button [ EDIT_BUTTON_RETURN_TO_EDIT ][ 1 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_ESC );
m_PlayMappingsMenuButton . button [ EDIT_BUTTON_RETURN_TO_EDIT ][ 0 ] = MENU_BUTTON_START ;
2006-03-07 20:43:40 +00:00
m_PlayMappingsMenuButton . button [ EDIT_BUTTON_RETURN_TO_EDIT ][ 1 ] = MENU_BUTTON_BACK ;
2005-11-01 00:17:26 +00:00
return ;
2006-03-12 00:45:18 +00:00
case EditMode_CourseMods :
// Left/Right = Snap to Next/Prev
m_EditMappingsDeviceInput . button [ EDIT_BUTTON_SNAP_NEXT ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_LEFT );
m_EditMappingsDeviceInput . button [ EDIT_BUTTON_SNAP_PREV ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_RIGHT );
// v = course attack menu
m_EditMappingsDeviceInput . button [ EDIT_BUTTON_OPEN_COURSE_ATTACK_MENU ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_Cv );
2006-03-14 08:41:16 +00:00
m_EditMappingsDeviceInput . button [ EDIT_BUTTON_ADD_COURSE_MODS ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_Cm );
2006-03-12 00:45:18 +00:00
// F1 = Show help popup
m_EditMappingsDeviceInput . button [ EDIT_BUTTON_OPEN_INPUT_HELP ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_F1 );
// Esc = Show Edit Menu
m_EditMappingsDeviceInput . button [ EDIT_BUTTON_OPEN_EDIT_MENU ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_ESC );
m_EditMappingsMenuButton . button [ EDIT_BUTTON_OPEN_EDIT_MENU ][ 0 ] = MENU_BUTTON_START ;
m_EditMappingsMenuButton . button [ EDIT_BUTTON_OPEN_EDIT_MENU ][ 1 ] = MENU_BUTTON_BACK ;
// Escape, Enter = exit play/record
m_PlayMappingsDeviceInput . button [ EDIT_BUTTON_RETURN_TO_EDIT ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_ENTER );
m_PlayMappingsDeviceInput . button [ EDIT_BUTTON_RETURN_TO_EDIT ][ 1 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_ESC );
m_PlayMappingsMenuButton . button [ EDIT_BUTTON_RETURN_TO_EDIT ][ 0 ] = MENU_BUTTON_START ;
m_PlayMappingsMenuButton . button [ EDIT_BUTTON_RETURN_TO_EDIT ][ 1 ] = MENU_BUTTON_BACK ;
return ;
2006-01-30 04:00:14 +00:00
case EditMode_Full :
/* Don't allow F5/F6 in home mode. It breaks the "delay creation until first save" logic. */
2006-03-07 02:43:09 +00:00
m_EditMappingsDeviceInput . button [ EDIT_BUTTON_OPEN_PREV_STEPS ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_F5 );
m_EditMappingsDeviceInput . button [ EDIT_BUTTON_OPEN_NEXT_STEPS ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_F6 );
m_EditMappingsDeviceInput . button [ EDIT_BUTTON_BPM_DOWN ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_F7 );
m_EditMappingsDeviceInput . button [ EDIT_BUTTON_BPM_UP ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_F8 );
m_EditMappingsDeviceInput . button [ EDIT_BUTTON_STOP_DOWN ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_F9 );
m_EditMappingsDeviceInput . button [ EDIT_BUTTON_STOP_UP ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_F10 );
m_EditMappingsDeviceInput . button [ EDIT_BUTTON_OFFSET_DOWN ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_F11 );
m_EditMappingsDeviceInput . button [ EDIT_BUTTON_OFFSET_UP ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_F12 );
2006-01-30 04:00:14 +00:00
2006-03-07 02:43:09 +00:00
m_EditMappingsDeviceInput . button [ EDIT_BUTTON_SAMPLE_START_UP ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_RBRACKET );
m_EditMappingsDeviceInput . button [ EDIT_BUTTON_SAMPLE_START_DOWN ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_LBRACKET );
m_EditMappingsDeviceInput . button [ EDIT_BUTTON_SAMPLE_LENGTH_UP ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_RBRACKET );
m_EditMappingsDeviceInput . hold [ EDIT_BUTTON_SAMPLE_LENGTH_UP ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_LSHIFT );
m_EditMappingsDeviceInput . hold [ EDIT_BUTTON_SAMPLE_LENGTH_UP ][ 1 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_RSHIFT );
m_EditMappingsDeviceInput . button [ EDIT_BUTTON_SAMPLE_LENGTH_DOWN ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_LBRACKET );
m_EditMappingsDeviceInput . hold [ EDIT_BUTTON_SAMPLE_LENGTH_DOWN ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_LSHIFT );
m_EditMappingsDeviceInput . hold [ EDIT_BUTTON_SAMPLE_LENGTH_DOWN ][ 1 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_RSHIFT );
2006-01-30 04:00:14 +00:00
2006-03-07 02:43:09 +00:00
m_EditMappingsDeviceInput . button [ EDIT_BUTTON_PLAY_SAMPLE_MUSIC ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_Cm );
2006-01-30 04:00:14 +00:00
2006-03-07 02:43:09 +00:00
m_EditMappingsDeviceInput . button [ EDIT_BUTTON_OPEN_BGCHANGE_LAYER1_MENU ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_Cb );
m_EditMappingsDeviceInput . button [ EDIT_BUTTON_OPEN_BGCHANGE_LAYER2_MENU ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_Cb );
m_EditMappingsDeviceInput . hold [ EDIT_BUTTON_OPEN_BGCHANGE_LAYER2_MENU ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_LSHIFT );
m_EditMappingsDeviceInput . hold [ EDIT_BUTTON_OPEN_BGCHANGE_LAYER2_MENU ][ 1 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_RSHIFT );
m_EditMappingsDeviceInput . button [ EDIT_BUTTON_OPEN_COURSE_MENU ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_Cc );
m_EditMappingsDeviceInput . button [ EDIT_BUTTON_OPEN_COURSE_ATTACK_MENU ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_Cv );
2006-01-30 04:00:14 +00:00
2006-03-07 02:43:09 +00:00
m_EditMappingsDeviceInput . button [ EDIT_BUTTON_INSERT_SHIFT_PAUSES ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_INSERT );
m_EditMappingsDeviceInput . hold [ EDIT_BUTTON_INSERT_SHIFT_PAUSES ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_LCTRL );
m_EditMappingsDeviceInput . hold [ EDIT_BUTTON_INSERT_SHIFT_PAUSES ][ 1 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_RCTRL );
m_EditMappingsDeviceInput . button [ EDIT_BUTTON_DELETE_SHIFT_PAUSES ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_DEL );
m_EditMappingsDeviceInput . hold [ EDIT_BUTTON_DELETE_SHIFT_PAUSES ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_LCTRL );
m_EditMappingsDeviceInput . hold [ EDIT_BUTTON_DELETE_SHIFT_PAUSES ][ 1 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_RCTRL );
2006-01-30 04:00:14 +00:00
break ;
}
2006-03-07 02:43:09 +00:00
m_EditMappingsDeviceInput . button [ EDIT_BUTTON_COLUMN_0 ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_C1 );
m_EditMappingsDeviceInput . button [ EDIT_BUTTON_COLUMN_1 ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_C2 );
m_EditMappingsDeviceInput . button [ EDIT_BUTTON_COLUMN_2 ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_C3 );
m_EditMappingsDeviceInput . button [ EDIT_BUTTON_COLUMN_3 ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_C4 );
m_EditMappingsDeviceInput . button [ EDIT_BUTTON_COLUMN_4 ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_C5 );
m_EditMappingsDeviceInput . button [ EDIT_BUTTON_COLUMN_5 ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_C6 );
m_EditMappingsDeviceInput . button [ EDIT_BUTTON_COLUMN_6 ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_C7 );
m_EditMappingsDeviceInput . button [ EDIT_BUTTON_COLUMN_7 ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_C8 );
m_EditMappingsDeviceInput . button [ EDIT_BUTTON_COLUMN_8 ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_C9 );
m_EditMappingsDeviceInput . button [ EDIT_BUTTON_COLUMN_9 ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_C0 );
2005-01-14 23:17:04 +00:00
2006-03-07 02:43:09 +00:00
m_EditMappingsDeviceInput . button [ EDIT_BUTTON_RIGHT_SIDE ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_LALT );
m_EditMappingsDeviceInput . button [ EDIT_BUTTON_RIGHT_SIDE ][ 1 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_RALT );
m_EditMappingsDeviceInput . button [ EDIT_BUTTON_LAY_MINE_OR_ROLL ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_LSHIFT );
// m_EditMappingsDeviceInput.button[EDIT_BUTTON_LAY_TAP_ATTACK][0] = DeviceInput(DEVICE_KEYBOARD, KEY_RSHIFT);
2005-01-14 23:17:04 +00:00
2006-03-07 02:43:09 +00:00
m_EditMappingsDeviceInput . button [ EDIT_BUTTON_SCROLL_SPEED_UP ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_UP );
m_EditMappingsDeviceInput . hold [ EDIT_BUTTON_SCROLL_SPEED_UP ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_LCTRL );
m_EditMappingsDeviceInput . hold [ EDIT_BUTTON_SCROLL_SPEED_UP ][ 1 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_RCTRL );
2005-01-14 23:17:04 +00:00
2006-03-07 02:43:09 +00:00
m_EditMappingsDeviceInput . button [ EDIT_BUTTON_SCROLL_SPEED_DOWN ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_DOWN );
m_EditMappingsDeviceInput . hold [ EDIT_BUTTON_SCROLL_SPEED_DOWN ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_LCTRL );
m_EditMappingsDeviceInput . hold [ EDIT_BUTTON_SCROLL_SPEED_DOWN ][ 1 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_RCTRL );
2005-01-14 23:17:04 +00:00
2006-03-07 02:43:09 +00:00
m_EditMappingsDeviceInput . button [ EDIT_BUTTON_SCROLL_SELECT ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_LSHIFT );
m_EditMappingsDeviceInput . button [ EDIT_BUTTON_SCROLL_SELECT ][ 1 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_RSHIFT );
2005-01-14 23:17:04 +00:00
2006-03-07 02:43:09 +00:00
m_EditMappingsDeviceInput . button [ EDIT_BUTTON_SNAP_NEXT ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_LEFT );
m_EditMappingsDeviceInput . button [ EDIT_BUTTON_SNAP_PREV ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_RIGHT );
2005-01-14 23:17:04 +00:00
2006-03-07 02:43:09 +00:00
m_EditMappingsDeviceInput . button [ EDIT_BUTTON_OPEN_EDIT_MENU ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_ESC );
m_EditMappingsMenuButton . button [ EDIT_BUTTON_OPEN_EDIT_MENU ][ 0 ] = MENU_BUTTON_START ;
2006-03-07 20:43:40 +00:00
m_EditMappingsMenuButton . button [ EDIT_BUTTON_OPEN_EDIT_MENU ][ 1 ] = MENU_BUTTON_BACK ;
2006-03-07 02:43:09 +00:00
m_EditMappingsDeviceInput . button [ EDIT_BUTTON_OPEN_AREA_MENU ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_ENTER );
m_EditMappingsDeviceInput . button [ EDIT_BUTTON_OPEN_INPUT_HELP ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_F1 );
2005-06-05 01:27:15 +00:00
2006-03-07 02:43:09 +00:00
m_EditMappingsDeviceInput . button [ EDIT_BUTTON_BAKE_RANDOM_FROM_SONG_GROUP ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_Cb );
m_EditMappingsDeviceInput . hold [ EDIT_BUTTON_BAKE_RANDOM_FROM_SONG_GROUP ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_LALT );
m_EditMappingsDeviceInput . hold [ EDIT_BUTTON_BAKE_RANDOM_FROM_SONG_GROUP ][ 1 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_RALT );
m_EditMappingsDeviceInput . button [ EDIT_BUTTON_BAKE_RANDOM_FROM_SONG_GROUP_AND_GENRE ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_Cb );
m_EditMappingsDeviceInput . hold [ EDIT_BUTTON_BAKE_RANDOM_FROM_SONG_GROUP_AND_GENRE ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_LCTRL );
m_EditMappingsDeviceInput . hold [ EDIT_BUTTON_BAKE_RANDOM_FROM_SONG_GROUP_AND_GENRE ][ 1 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_RCTRL );
2005-01-14 23:17:04 +00:00
2006-03-07 02:43:09 +00:00
m_EditMappingsDeviceInput . button [ EDIT_BUTTON_RECORD_SELECTION ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_Cr );
m_EditMappingsDeviceInput . hold [ EDIT_BUTTON_RECORD_SELECTION ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_LCTRL );
m_EditMappingsDeviceInput . hold [ EDIT_BUTTON_RECORD_SELECTION ][ 1 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_RCTRL );
2005-01-14 23:17:04 +00:00
2006-03-07 02:43:09 +00:00
m_EditMappingsDeviceInput . button [ EDIT_BUTTON_INSERT ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_INSERT );
m_EditMappingsDeviceInput . button [ EDIT_BUTTON_INSERT ][ 1 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_BACKSLASH );
m_EditMappingsDeviceInput . button [ EDIT_BUTTON_DELETE ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_DEL );
2005-01-14 23:17:04 +00:00
2006-03-07 02:43:09 +00:00
m_EditMappingsDeviceInput . button [ EDIT_BUTTON_ADJUST_FINE ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_RALT );
m_EditMappingsDeviceInput . button [ EDIT_BUTTON_ADJUST_FINE ][ 1 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_LALT );
2005-01-14 23:17:04 +00:00
2006-03-07 02:43:09 +00:00
m_EditMappingsDeviceInput . button [ EDIT_BUTTON_UNDO ][ 1 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_Cu );
2005-05-17 07:24:25 +00:00
2006-03-07 02:43:09 +00:00
m_PlayMappingsDeviceInput . button [ EDIT_BUTTON_RETURN_TO_EDIT ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_ESC );
m_PlayMappingsMenuButton . button [ EDIT_BUTTON_RETURN_TO_EDIT ][ 0 ] = MENU_BUTTON_START ;
2006-03-07 20:43:40 +00:00
m_PlayMappingsMenuButton . button [ EDIT_BUTTON_RETURN_TO_EDIT ][ 1 ] = MENU_BUTTON_BACK ;
2006-03-07 02:43:09 +00:00
m_PlayMappingsDeviceInput . button [ EDIT_BUTTON_TOGGLE_ASSIST_TICK ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_F4 );
m_PlayMappingsDeviceInput . button [ EDIT_BUTTON_TOGGLE_AUTOPLAY ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_F8 );
2005-01-14 23:17:04 +00:00
2006-03-07 02:43:09 +00:00
m_RecordMappingsDeviceInput . button [ EDIT_BUTTON_LAY_MINE_OR_ROLL ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_LSHIFT );
m_RecordMappingsDeviceInput . button [ EDIT_BUTTON_LAY_MINE_OR_ROLL ][ 1 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_RSHIFT );
m_RecordMappingsDeviceInput . button [ EDIT_BUTTON_REMOVE_NOTE ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_LALT );
m_RecordMappingsDeviceInput . button [ EDIT_BUTTON_REMOVE_NOTE ][ 1 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_RALT );
m_RecordMappingsDeviceInput . button [ EDIT_BUTTON_RETURN_TO_EDIT ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_ESC );
m_RecordMappingsMenuButton . button [ EDIT_BUTTON_RETURN_TO_EDIT ][ 0 ] = MENU_BUTTON_START ;
2006-03-07 20:43:40 +00:00
m_RecordMappingsMenuButton . button [ EDIT_BUTTON_RETURN_TO_EDIT ][ 1 ] = MENU_BUTTON_BACK ;
2005-07-21 21:23:18 +00:00
2006-03-07 02:43:09 +00:00
m_RecordPausedMappingsDeviceInput . button [ EDIT_BUTTON_PLAY_SELECTION ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_Cp );
m_RecordPausedMappingsDeviceInput . button [ EDIT_BUTTON_RECORD_SELECTION ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_Cr );
m_RecordPausedMappingsDeviceInput . hold [ EDIT_BUTTON_RECORD_SELECTION ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_LCTRL );
m_RecordPausedMappingsDeviceInput . hold [ EDIT_BUTTON_RECORD_SELECTION ][ 1 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_RCTRL );
m_RecordPausedMappingsDeviceInput . button [ EDIT_BUTTON_RECORD_FROM_CURSOR ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_Cr );
m_RecordPausedMappingsDeviceInput . button [ EDIT_BUTTON_RETURN_TO_EDIT ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_ESC );
m_RecordPausedMappingsMenuButton . button [ EDIT_BUTTON_RETURN_TO_EDIT ][ 0 ] = MENU_BUTTON_START ;
2006-03-07 20:43:40 +00:00
m_RecordPausedMappingsMenuButton . button [ EDIT_BUTTON_RETURN_TO_EDIT ][ 1 ] = MENU_BUTTON_BACK ;
2006-03-07 02:43:09 +00:00
m_RecordPausedMappingsDeviceInput . button [ EDIT_BUTTON_UNDO ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_Cu );
2005-01-14 23:17:04 +00:00
}
#endif
/* Given a DeviceInput that was just depressed, return an active edit function. */
2006-03-07 02:43:09 +00:00
bool ScreenEdit :: DeviceToEdit ( const DeviceInput & DeviceI , EditButton & button ) const
2005-01-14 23:17:04 +00:00
{
ASSERT ( DeviceI . IsValid () );
2006-03-07 02:43:09 +00:00
const MapEditToDI * pCurrentMap = GetCurrentDeviceInputMap ();
2005-01-15 13:14:36 +00:00
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-03-27 00:33:31 +00:00
if ( hDI . IsValid () && INPUTFILTER -> IsBeingPressed ( hDI ) )
2005-01-14 23:17:04 +00:00
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 ;
}
2006-03-07 02:43:09 +00:00
/* Given a DeviceInput that was just depressed, return an active edit function. */
bool ScreenEdit :: MenuInputToEditButton ( const MenuInput & MenuI , EditButton & button ) const
{
ASSERT ( MenuI . IsValid () );
const MapEditButtonToMenuButton * pCurrentMap = GetCurrentMenuButtonMap ();
FOREACH_EditButton ( e )
{
for ( int slot = 0 ; slot < NUM_EDIT_TO_MENU_SLOTS ; ++ slot )
{
if ( pCurrentMap -> button [ e ][ slot ] == MenuI . button )
{
/* The button maps to this function. */
button = e ;
return true ;
}
}
}
button = EDIT_BUTTON_INVALID ;
return false ;
}
2005-01-23 23:49:19 +00:00
/* If DeviceI was just pressed, return true if button is triggered. (More than one
* function may be mapped to a key.) */
bool ScreenEdit :: EditPressed ( EditButton button , const DeviceInput & DeviceI )
{
ASSERT ( DeviceI . IsValid () );
2006-03-07 02:43:09 +00:00
const MapEditToDI * pCurrentMap = GetCurrentDeviceInputMap ();
2005-01-23 23:49:19 +00:00
/* First, search to see if a key that requires a modifier is pressed. */
bool bPrimaryButtonPressed = false ;
for ( int slot = 0 ; slot < NUM_EDIT_TO_DEVICE_SLOTS ; ++ slot )
{
if ( pCurrentMap -> button [ button ][ slot ] == DeviceI )
bPrimaryButtonPressed = true ;
}
if ( ! bPrimaryButtonPressed )
return false ;
/* The button maps to this function. Does the function has one or more shift modifiers attached? */
if ( ! pCurrentMap -> hold [ button ][ 0 ]. IsValid () )
return true ;
for ( int holdslot = 0 ; holdslot < NUM_EDIT_TO_DEVICE_SLOTS ; ++ holdslot )
{
DeviceInput hDI = pCurrentMap -> hold [ button ][ holdslot ];
if ( INPUTFILTER -> IsBeingPressed ( hDI ) )
return true ;
}
/* No shifted keys matched. */
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 );
2006-03-07 02:43:09 +00:00
const MapEditToDI * pCurrentMap = GetCurrentDeviceInputMap ();
2005-03-12 00:51:09 +00:00
if ( pCurrentMap -> button [ button ][ iSlotNum ]. IsValid () )
DeviceI = pCurrentMap -> button [ button ][ iSlotNum ];
else if ( pCurrentMap -> hold [ button ][ iSlotNum ]. IsValid () )
DeviceI = pCurrentMap -> hold [ 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 ;
}
2006-03-07 02:43:09 +00:00
const MapEditToDI * ScreenEdit :: GetCurrentDeviceInputMap () const
2005-01-15 13:14:36 +00:00
{
2005-04-14 06:34:17 +00:00
switch ( m_EditState )
2005-01-15 13:14:36 +00:00
{
2006-06-14 09:56:57 +00:00
DEFAULT_FAIL ( m_EditState );
2006-03-07 02:43:09 +00:00
case STATE_EDITING : return & m_EditMappingsDeviceInput ;
case STATE_PLAYING : return & m_PlayMappingsDeviceInput ;
case STATE_RECORDING : return & m_RecordMappingsDeviceInput ;
case STATE_RECORDING_PAUSED : return & m_RecordPausedMappingsDeviceInput ;
}
}
const MapEditButtonToMenuButton * ScreenEdit :: GetCurrentMenuButtonMap () const
{
switch ( m_EditState )
{
2006-06-14 09:56:57 +00:00
DEFAULT_FAIL ( m_EditState );
2006-03-07 02:43:09 +00:00
case STATE_EDITING : return & m_EditMappingsMenuButton ;
case STATE_PLAYING : return & m_PlayMappingsMenuButton ;
case STATE_RECORDING : return & m_RecordMappingsMenuButton ;
case STATE_RECORDING_PAUSED : return & m_RecordPausedMappingsMenuButton ;
2005-01-15 13:14:36 +00:00
}
}
2002-06-29 11:59:09 +00:00
2005-05-31 01:17:37 +00:00
2005-07-05 11:23:31 +00:00
static MenuDef g_EditHelp (
2006-03-16 20:59:15 +00:00
"ScreenMiniMenuEditHelp"
// fill this in dynamically
2005-11-01 22:17:07 +00:00
);
2005-07-05 11:23:31 +00:00
static MenuDef g_MainMenu (
2005-03-20 06:41:56 +00:00
"ScreenMiniMenuMainMenu" ,
2006-03-07 20:43:40 +00:00
MenuRowDef ( ScreenEdit :: play_selection , "Play selection" , true , EditMode_Practice , true , true , 0 , NULL ),
2006-03-15 22:18:25 +00:00
MenuRowDef ( ScreenEdit :: set_selection_start , "Set selection start" , true , EditMode_Practice , true , true , 0 , NULL ),
MenuRowDef ( ScreenEdit :: set_selection_end , "Set selection end" , true , EditMode_Practice , true , true , 0 , NULL ),
MenuRowDef ( ScreenEdit :: edit_steps_information , "Edit steps information" , true , EditMode_Practice , true , true , 0 , NULL ),
MenuRowDef ( ScreenEdit :: play_whole_song , "Play whole song" , true , EditMode_Practice , true , true , 0 , NULL ),
MenuRowDef ( ScreenEdit :: play_current_beat_to_end , "Play current beat to end" , true , EditMode_Practice , true , true , 0 , NULL ),
2006-02-13 22:45:17 +00:00
MenuRowDef ( ScreenEdit :: save , "Save" , true , EditMode_Home , true , true , 0 , NULL ),
2006-03-15 22:18:25 +00:00
MenuRowDef ( ScreenEdit :: revert_to_last_save , "Revert to last save" , true , EditMode_Home , true , true , 0 , NULL ),
MenuRowDef ( ScreenEdit :: revert_from_disk , "Revert from disk" , true , EditMode_Full , true , true , 0 , NULL ),
MenuRowDef ( ScreenEdit :: options , "Editor options" , true , EditMode_Practice , true , true , 0 , NULL ),
MenuRowDef ( ScreenEdit :: edit_song_info , "Edit song info" , true , EditMode_Full , true , true , 0 , NULL ),
MenuRowDef ( ScreenEdit :: edit_bpm , "Edit BPM change" , true , EditMode_Full , true , true , 0 , NULL ),
MenuRowDef ( ScreenEdit :: edit_stop , "Edit stop" , true , EditMode_Full , true , true , 0 , NULL ),
MenuRowDef ( ScreenEdit :: play_preview_music , "Play preview music" , true , EditMode_Full , true , true , 0 , NULL ),
MenuRowDef ( ScreenEdit :: exit , "Exit editor" , true , EditMode_Practice , true , true , 0 , NULL )
2005-03-20 06:41:56 +00:00
);
2002-06-29 11:59:09 +00:00
2005-07-05 11:23:31 +00:00
static MenuDef g_AreaMenu (
2005-03-20 06:41:56 +00:00
"ScreenMiniMenuAreaMenu" ,
2006-02-13 22:45:17 +00:00
MenuRowDef ( ScreenEdit :: cut , "Cut" , true , EditMode_Practice , true , true , 0 , NULL ),
MenuRowDef ( ScreenEdit :: copy , "Copy" , true , EditMode_Practice , true , true , 0 , NULL ),
MenuRowDef ( ScreenEdit :: paste_at_current_beat , "Paste at current beat" , true , EditMode_Practice , true , true , 0 , NULL ),
MenuRowDef ( ScreenEdit :: paste_at_begin_marker , "Paste at begin marker" , true , EditMode_Practice , true , true , 0 , NULL ),
MenuRowDef ( ScreenEdit :: clear , "Clear area" , true , EditMode_Practice , true , true , 0 , NULL ),
MenuRowDef ( ScreenEdit :: quantize , "Quantize" , true , EditMode_Practice , true , true , 0 , "4th" , "8th" , "12th" , "16th" , "24th" , "32nd" , "48th" , "64th" , "192nd" ),
MenuRowDef ( ScreenEdit :: turn , "Turn" , true , EditMode_Practice , true , true , 0 , "Left" , "Right" , "Mirror" , "Shuffle" , "SuperShuffle" ),
MenuRowDef ( ScreenEdit :: transform , "Transform" , true , EditMode_Practice , true , true , 0 , "NoHolds" , "NoMines" , "Little" , "Wide" , "Big" , "Quick" , "Skippy" , "Mines" , "Echo" , "Stomp" , "Planted" , "Floored" , "Twister" , "NoJumps" , "NoHands" , "NoQuads" , "NoStretch" ),
MenuRowDef ( ScreenEdit :: alter , "Alter" , true , EditMode_Practice , true , true , 0 , "Autogen To Fill Width" , "Backwards" , "Swap Sides" , "Copy Left To Right" , "Copy Right To Left" , "Clear Left" , "Clear Right" , "Collapse To One" , "Collapse Left" , "Shift Left" , "Shift Right" ),
MenuRowDef ( ScreenEdit :: tempo , "Tempo" , true , EditMode_Full , true , true , 0 , "Compress 2x" , "Compress 3->2" , "Compress 4->3" , "Expand 3->4" , "Expand 2->3" , "Expand 2x" ),
MenuRowDef ( ScreenEdit :: play , "Play selection" , true , EditMode_Practice , true , true , 0 , NULL ),
MenuRowDef ( ScreenEdit :: record , "Record in selection" , true , EditMode_Practice , true , true , 0 , NULL ),
MenuRowDef ( ScreenEdit :: insert_and_shift , "Insert beat and shift down" , true , EditMode_Practice , true , true , 0 , NULL ),
MenuRowDef ( ScreenEdit :: delete_and_shift , "Delete beat and shift up" , true , EditMode_Practice , true , true , 0 , NULL ),
MenuRowDef ( ScreenEdit :: shift_pauses_forward , "Shift pauses and BPM changes down" , true , EditMode_Full , true , true , 0 , NULL ),
MenuRowDef ( ScreenEdit :: shift_pauses_backward , "Shift pauses and BPM changes up" , true , EditMode_Full , true , true , 0 , NULL ),
MenuRowDef ( ScreenEdit :: convert_to_pause , "Convert selection to pause" , true , EditMode_Full , true , true , 0 , NULL ),
MenuRowDef ( ScreenEdit :: convert_pause_to_beat , "Convert pause to beats" , true , EditMode_Full , true , true , 0 , NULL ),
MenuRowDef ( ScreenEdit :: undo , "Undo" , true , EditMode_Practice , true , true , 0 , NULL )
2005-03-20 06:41:56 +00:00
);
2002-09-26 06:05:32 +00:00
2005-07-05 11:23:31 +00:00
static MenuDef g_StepsInformation (
2005-03-20 20:13:27 +00:00
"ScreenMiniMenuStepsInformation" ,
2006-02-13 22:45:17 +00:00
MenuRowDef ( ScreenEdit :: difficulty , "Difficulty" , true , EditMode_Practice , true , true , 0 , NULL ),
MenuRowDef ( ScreenEdit :: meter , "Meter" , true , EditMode_Practice , true , false , 0 , "1" , "2" , "3" , "4" , "5" , "6" , "7" , "8" , "9" , "10" , "11" , "12" , "13" ),
MenuRowDef ( ScreenEdit :: description , "Description" , true , EditMode_Practice , true , true , 0 , NULL ),
MenuRowDef ( ScreenEdit :: predict_meter , "Predicted Meter" , false , EditMode_Full , true , true , 0 , NULL ),
2006-03-18 19:49:33 +00:00
MenuRowDef ( ScreenEdit :: tap_notes , "Tap Steps" , false , EditMode_Full , true , true , 0 , NULL ),
MenuRowDef ( ScreenEdit :: jumps , "Jumps" , false , EditMode_Full , true , true , 0 , NULL ),
MenuRowDef ( ScreenEdit :: hands , "Hands" , false , EditMode_Full , true , true , 0 , NULL ),
MenuRowDef ( ScreenEdit :: quads , "Quads" , false , EditMode_Full , true , true , 0 , NULL ),
MenuRowDef ( ScreenEdit :: holds , "Holds" , false , EditMode_Full , true , true , 0 , NULL ),
MenuRowDef ( ScreenEdit :: mines , "Mines" , false , EditMode_Full , true , true , 0 , NULL ),
2006-02-13 22:45:17 +00:00
MenuRowDef ( ScreenEdit :: stream , "Stream" , false , EditMode_Full , true , true , 0 , NULL ),
MenuRowDef ( ScreenEdit :: voltage , "Voltage" , false , EditMode_Full , true , true , 0 , NULL ),
MenuRowDef ( ScreenEdit :: air , "Air" , false , EditMode_Full , true , true , 0 , NULL ),
MenuRowDef ( ScreenEdit :: freeze , "Freeze" , false , EditMode_Full , true , true , 0 , NULL ),
MenuRowDef ( ScreenEdit :: chaos , "Chaos" , false , EditMode_Full , true , true , 0 , NULL )
2005-03-20 06:41:56 +00:00
);
2002-05-20 08:59:37 +00:00
2005-07-05 11:23:31 +00:00
static MenuDef g_SongInformation (
2005-07-19 18:58:12 +00:00
"ScreenMiniMenuSongInformation" ,
2006-02-13 22:45:17 +00:00
MenuRowDef ( ScreenEdit :: main_title , "Main title" , true , EditMode_Practice , true , true , 0 , NULL ),
MenuRowDef ( ScreenEdit :: sub_title , "Sub title" , true , EditMode_Practice , true , true , 0 , NULL ),
MenuRowDef ( ScreenEdit :: artist , "Artist" , true , EditMode_Practice , true , true , 0 , NULL ),
MenuRowDef ( ScreenEdit :: credit , "Credit" , true , EditMode_Practice , true , true , 0 , NULL ),
MenuRowDef ( ScreenEdit :: main_title_transliteration , "Main title transliteration" , true , EditMode_Practice , true , true , 0 , NULL ),
MenuRowDef ( ScreenEdit :: sub_title_transliteration , "Sub title transliteration" , true , EditMode_Practice , true , true , 0 , NULL ),
MenuRowDef ( ScreenEdit :: artist_transliteration , "Artist transliteration" , true , EditMode_Practice , true , true , 0 , NULL )
2005-03-20 06:41:56 +00:00
);
2003-02-18 23:15:38 +00:00
2005-06-05 01:27:15 +00:00
enum { song_bganimation , song_movie , song_bitmap , global_bganimation , global_movie , global_movie_song_group , global_movie_song_group_and_genre , dynamic_random , baked_random , none };
static bool EnabledIfSet1SongBGAnimation ();
static bool EnabledIfSet1SongMovie ();
static bool EnabledIfSet1SongBitmap ();
static bool EnabledIfSet1GlobalBGAnimation ();
static bool EnabledIfSet1GlobalMovie ();
static bool EnabledIfSet1GlobalMovieSongGroup ();
static bool EnabledIfSet1GlobalMovieSongGroupAndGenre ();
static bool EnabledIfSet2SongBGAnimation ();
static bool EnabledIfSet2SongMovie ();
static bool EnabledIfSet2SongBitmap ();
static bool EnabledIfSet2GlobalBGAnimation ();
static bool EnabledIfSet2GlobalMovie ();
static bool EnabledIfSet2GlobalMovieSongGroup ();
static bool EnabledIfSet2GlobalMovieSongGroupAndGenre ();
2005-07-05 11:23:31 +00:00
static MenuDef g_BackgroundChange (
2005-03-20 06:41:56 +00:00
"ScreenMiniMenuBackgroundChange" ,
2006-02-13 22:45:17 +00:00
MenuRowDef ( ScreenEdit :: layer , "Layer" , false , EditMode_Full , true , true , 0 , "" ),
MenuRowDef ( ScreenEdit :: rate , "Rate" , true , EditMode_Full , true , false , 10 , "0%" , "10%" , "20%" , "30%" , "40%" , "50%" , "60%" , "70%" , "80%" , "90%" , "100%" , "120%" , "140%" , "160%" , "180%" , "200%" ),
MenuRowDef ( ScreenEdit :: transition , "Force Transition" , true , EditMode_Full , true , true , 0 , NULL ),
MenuRowDef ( ScreenEdit :: effect , "Force Effect" , true , EditMode_Full , true , true , 0 , NULL ),
MenuRowDef ( ScreenEdit :: color1 , "Force Color 1" , true , EditMode_Full , true , false , 0 , "" , "1,1,1,1" , "0.5,0.5,0.5,1" , "1,1,1,0.5" , "0,0,0,1" , "1,0,0,1" , "0,1,0,1" , "0,0,1,1" , "1,1,0,1" , "0,1,1,1" , "1,0,1,1" ),
MenuRowDef ( ScreenEdit :: color2 , "Force Color 2" , true , EditMode_Full , true , false , 0 , "" , "1,1,1,1" , "0.5,0.5,0.5,1" , "1,1,1,0.5" , "0,0,0,1" , "1,0,0,1" , "0,1,0,1" , "0,0,1,1" , "1,1,0,1" , "0,1,1,1" , "1,0,1,1" ),
MenuRowDef ( ScreenEdit :: file1_type , "File1 Type" , true , EditMode_Full , true , true , 0 , "Song BGAnimation" , "Song Movie" , "Song Bitmap" , "Global BGAnimation" , "Global Movie" , "Global Movie from Song Group" , "Global Movie from Song Group and Genre" , "Dynamic Random" , "Baked Random" , "None" ),
2006-07-14 21:33:08 +00:00
MenuRowDef ( ScreenEdit :: file1_song_bganimation , "File1 Song BGAnimation" , EnabledIfSet1SongBGAnimation , EditMode_Full , true , false , 0 , NULL ),
MenuRowDef ( ScreenEdit :: file1_song_movie , "File1 Song Movie" , EnabledIfSet1SongMovie , EditMode_Full , true , false , 0 , NULL ),
MenuRowDef ( ScreenEdit :: file1_song_still , "File1 Song Still" , EnabledIfSet1SongBitmap , EditMode_Full , true , false , 0 , NULL ),
MenuRowDef ( ScreenEdit :: file1_global_bganimation , "File1 Global BGAnimation" , EnabledIfSet1GlobalBGAnimation , EditMode_Full , true , false , 0 , NULL ),
MenuRowDef ( ScreenEdit :: file1_global_movie , "File1 Global Movie" , EnabledIfSet1GlobalMovie , EditMode_Full , true , false , 0 , NULL ),
MenuRowDef ( ScreenEdit :: file1_global_movie_song_group , "File1 Global Movie (Group)" , EnabledIfSet1GlobalMovieSongGroup , EditMode_Full , true , false , 0 , NULL ),
MenuRowDef ( ScreenEdit :: file1_global_movie_song_group_and_genre , "File1 Global Movie (Group + Genre)" , EnabledIfSet1GlobalMovieSongGroupAndGenre , EditMode_Full , true , false , 0 , NULL ),
2006-02-13 22:45:17 +00:00
MenuRowDef ( ScreenEdit :: file2_type , "File2 Type" , true , EditMode_Full , true , true , 0 , "Song BGAnimation" , "Song Movie" , "Song Bitmap" , "Global BGAnimation" , "Global Movie" , "Global Movie from Song Group" , "Global Movie from Song Group and Genre" , "Dynamic Random" , "Baked Random" , "None" ),
2006-07-14 21:33:08 +00:00
MenuRowDef ( ScreenEdit :: file2_song_bganimation , "File2 Song BGAnimation" , EnabledIfSet2SongBGAnimation , EditMode_Full , true , false , 0 , NULL ),
MenuRowDef ( ScreenEdit :: file2_song_movie , "File2 Song Movie" , EnabledIfSet2SongMovie , EditMode_Full , true , false , 0 , NULL ),
MenuRowDef ( ScreenEdit :: file2_song_still , "File2 Song Still" , EnabledIfSet2SongBitmap , EditMode_Full , true , false , 0 , NULL ),
MenuRowDef ( ScreenEdit :: file2_global_bganimation , "File2 Global BGAnimation" , EnabledIfSet2GlobalBGAnimation , EditMode_Full , true , false , 0 , NULL ),
MenuRowDef ( ScreenEdit :: file2_global_movie , "File2 Global Movie" , EnabledIfSet2GlobalMovie , EditMode_Full , true , false , 0 , NULL ),
MenuRowDef ( ScreenEdit :: file2_global_movie_song_group , "File2 Global Movie (Group)" , EnabledIfSet2GlobalMovieSongGroup , EditMode_Full , true , false , 0 , NULL ),
MenuRowDef ( ScreenEdit :: file2_global_movie_song_group_and_genre , "File2 Global Movie (Group + Genre)" , EnabledIfSet2GlobalMovieSongGroupAndGenre , EditMode_Full , true , false , 0 , NULL ),
2006-07-14 21:34:17 +00:00
MenuRowDef ( ScreenEdit :: delete_change , "Remove Change" , true , EditMode_Full , true , true , 0 , NULL )
2005-03-20 06:41:56 +00:00
);
2006-01-19 02:40:44 +00:00
static bool EnabledIfSet1SongBGAnimation () { return ScreenMiniMenu :: s_viLastAnswers [ ScreenEdit :: file1_type ] == song_bganimation && ! g_BackgroundChange . rows [ ScreenEdit :: file1_song_bganimation ]. choices . empty (); }
static bool EnabledIfSet1SongMovie () { return ScreenMiniMenu :: s_viLastAnswers [ ScreenEdit :: file1_type ] == song_movie && ! g_BackgroundChange . rows [ ScreenEdit :: file1_song_movie ]. choices . empty (); }
static bool EnabledIfSet1SongBitmap () { return ScreenMiniMenu :: s_viLastAnswers [ ScreenEdit :: file1_type ] == song_bitmap && ! g_BackgroundChange . rows [ ScreenEdit :: file1_song_still ]. choices . empty (); }
static bool EnabledIfSet1GlobalBGAnimation () { return ScreenMiniMenu :: s_viLastAnswers [ ScreenEdit :: file1_type ] == global_bganimation && ! g_BackgroundChange . rows [ ScreenEdit :: file1_global_bganimation ]. choices . empty (); }
static bool EnabledIfSet1GlobalMovie () { return ScreenMiniMenu :: s_viLastAnswers [ ScreenEdit :: file1_type ] == global_movie && ! g_BackgroundChange . rows [ ScreenEdit :: file1_global_movie ]. choices . empty (); }
static bool EnabledIfSet1GlobalMovieSongGroup () { return ScreenMiniMenu :: s_viLastAnswers [ ScreenEdit :: file1_type ] == global_movie_song_group && ! g_BackgroundChange . rows [ ScreenEdit :: file1_global_movie_song_group ]. choices . empty (); }
2005-06-05 01:27:15 +00:00
static bool EnabledIfSet1GlobalMovieSongGroupAndGenre () { return ScreenMiniMenu :: s_viLastAnswers [ ScreenEdit :: file1_type ] == global_movie_song_group_and_genre && ! g_BackgroundChange . rows [ ScreenEdit :: file1_global_movie_song_group_and_genre ]. choices . empty (); }
2006-01-19 02:40:44 +00:00
static bool EnabledIfSet2SongBGAnimation () { return ScreenMiniMenu :: s_viLastAnswers [ ScreenEdit :: file2_type ] == song_bganimation && ! g_BackgroundChange . rows [ ScreenEdit :: file2_song_bganimation ]. choices . empty (); }
static bool EnabledIfSet2SongMovie () { return ScreenMiniMenu :: s_viLastAnswers [ ScreenEdit :: file2_type ] == song_movie && ! g_BackgroundChange . rows [ ScreenEdit :: file2_song_movie ]. choices . empty (); }
static bool EnabledIfSet2SongBitmap () { return ScreenMiniMenu :: s_viLastAnswers [ ScreenEdit :: file2_type ] == song_bitmap && ! g_BackgroundChange . rows [ ScreenEdit :: file2_song_still ]. choices . empty (); }
static bool EnabledIfSet2GlobalBGAnimation () { return ScreenMiniMenu :: s_viLastAnswers [ ScreenEdit :: file2_type ] == global_bganimation && ! g_BackgroundChange . rows [ ScreenEdit :: file2_global_bganimation ]. choices . empty (); }
static bool EnabledIfSet2GlobalMovie () { return ScreenMiniMenu :: s_viLastAnswers [ ScreenEdit :: file2_type ] == global_movie && ! g_BackgroundChange . rows [ ScreenEdit :: file2_global_movie ]. choices . empty (); }
static bool EnabledIfSet2GlobalMovieSongGroup () { return ScreenMiniMenu :: s_viLastAnswers [ ScreenEdit :: file2_type ] == global_movie_song_group && ! g_BackgroundChange . rows [ ScreenEdit :: file2_global_movie_song_group ]. choices . empty (); }
2005-06-05 01:27:15 +00:00
static bool EnabledIfSet2GlobalMovieSongGroupAndGenre () { return ScreenMiniMenu :: s_viLastAnswers [ ScreenEdit :: file2_type ] == global_movie_song_group_and_genre && ! g_BackgroundChange . rows [ ScreenEdit :: file2_global_movie_song_group_and_genre ]. choices . empty (); }
2005-05-31 01:17:37 +00:00
2006-01-22 01:00:06 +00:00
static RString GetOneBakedRandomFile ( Song * pSong , bool bTryGenre = true )
2005-06-05 01:27:15 +00:00
{
2006-01-22 01:00:06 +00:00
vector < RString > vsPathsOut ;
vector < RString > vsNamesOut ;
2005-06-05 01:27:15 +00:00
BackgroundUtil :: GetGlobalRandomMovies (
pSong ,
"" ,
vsPathsOut ,
2005-06-07 09:42:57 +00:00
vsNamesOut ,
bTryGenre );
2005-06-05 01:27:15 +00:00
if ( ! vsNamesOut . empty () )
2006-06-26 12:14:30 +00:00
return vsNamesOut [ RandomInt ( vsNamesOut . size ())];
2005-06-05 01:27:15 +00:00
else
2006-01-22 01:00:06 +00:00
return RString ();
2005-06-05 01:27:15 +00:00
}
2002-05-20 08:59:37 +00:00
2005-08-30 18:09:00 +00:00
static MenuDef g_InsertTapAttack (
"ScreenMiniMenuInsertTapAttack" ,
2006-02-13 22:45:17 +00:00
MenuRowDef ( - 1 , "Duration seconds" , true , EditMode_Practice , true , false , 3 , "5" , "10" , "15" , "20" , "25" , "30" , "35" , "40" , "45" ),
MenuRowDef ( - 1 , "Set modifiers" , true , EditMode_Practice , true , true , 0 , "Press Start" )
2005-08-30 18:09:00 +00:00
);
static MenuDef g_InsertCourseAttack (
"ScreenMiniMenuInsertCourseAttack" ,
2006-02-13 22:45:17 +00:00
MenuRowDef ( ScreenEdit :: duration , "Duration seconds" , true , EditMode_Practice , true , false , 3 , "5" , "10" , "15" , "20" , "25" , "30" , "35" , "40" , "45" ),
MenuRowDef ( ScreenEdit :: set_mods , "Set modifiers" , true , EditMode_Practice , true , true , 0 , "Press Start" ),
MenuRowDef ( ScreenEdit :: remove , "Remove" , true , EditMode_Practice , true , true , 0 , "Press Start" )
2005-03-20 06:41:56 +00:00
);
2003-11-12 08:13:02 +00:00
2005-07-05 11:23:31 +00:00
static MenuDef g_CourseMode (
2005-03-20 06:41:56 +00:00
"ScreenMiniMenuCourseDisplay" ,
2006-02-13 22:45:17 +00:00
MenuRowDef ( - 1 , "Play mods from course" , true , EditMode_Practice , true , true , 0 , NULL )
2005-03-20 06:41:56 +00:00
);
2004-01-26 20:56:58 +00:00
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.
2005-08-30 18:09:00 +00:00
static int g_iLastInsertTapAttackTrack = - 1 ;
2005-07-20 19:19:14 +00:00
static float g_fLastInsertAttackDurationSeconds = - 1 ;
2006-03-14 08:41:16 +00:00
static float g_fLastInsertAttackPositionSeconds = - 1 ;
2005-07-20 19:19:14 +00:00
static BackgroundLayer g_CurrentBGChangeLayer = BACKGROUND_LAYER_INVALID ;
2003-11-12 08:13:02 +00:00
2006-01-15 20:46:15 +00:00
REGISTER_SCREEN_CLASS ( ScreenEdit );
2005-02-23 06:29:05 +00:00
void ScreenEdit :: Init ()
{
2006-01-15 18:54:03 +00:00
ASSERT ( GAMESTATE -> m_pCurSong );
ASSERT ( GAMESTATE -> m_pCurSteps [ 0 ] );
2006-03-12 00:45:18 +00:00
EDIT_MODE . Load ( m_sName , "EditMode" );
2005-03-18 18:58:22 +00:00
ScreenWithMenuElements :: Init ();
2002-05-20 08:59:37 +00:00
2005-01-14 23:17:04 +00:00
InitEditMappings ();
2005-03-08 21:19:17 +00:00
// save the originals for reverting later
CopyToLastSave ();
2005-03-14 04:43:25 +00:00
m_CurrentAction = MAIN_MENU_CHOICE_INVALID ;
2005-03-08 21:19:17 +00:00
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 ];
2005-07-21 21:23:18 +00:00
m_bReturnToRecordMenuAfterPlay = false ;
2005-07-21 02:44:53 +00:00
m_fBeatToReturnTo = 0 ;
2002-05-20 08:59:37 +00:00
2005-10-10 04:36:04 +00:00
GAMESTATE -> m_bGameplayLeadIn . Set ( true );
2006-03-19 01:20:42 +00:00
GAMESTATE -> m_EditMode = EDIT_MODE . GetValue ();
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-03-01 05:41:40 +00:00
GAMESTATE -> StoreSelectedOptions ();
2002-05-20 08:59:37 +00:00
2005-07-20 04:50:06 +00:00
m_iShiftAnchor = - 1 ;
2005-07-20 05:26:27 +00:00
m_iStartPlayingAt = - 1 ;
m_iStopPlayingAt = - 1 ;
2003-09-21 23:16:44 +00:00
2005-03-18 19:44:01 +00:00
this -> AddChild ( & m_Background );
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 );
2005-03-18 19:44:01 +00:00
this -> AddChild ( & m_SnapDisplay );
2005-07-21 01:06:53 +00:00
if ( NOTESKIN -> DoesNoteSkinExist ( "note" ) )
m_PlayerStateEdit . m_PlayerOptions . m_sNoteSkin = "note" ; // change noteskin before loading all of the edit Actors
m_PlayerStateEdit . m_PlayerNumber = PLAYER_1 ;
m_PlayerStateEdit . m_PlayerOptions . m_sNoteSkin = GAMESTATE -> m_pPlayerState [ PLAYER_1 ] -> m_PlayerOptions . m_sNoteSkin ;
2005-07-20 03:10:15 +00:00
m_pSteps -> GetNoteData ( m_NoteDataEdit );
2005-04-07 19:27:53 +00:00
m_NoteFieldEdit . SetXY ( EDIT_X , EDIT_Y );
2002-05-20 08:59:37 +00:00
m_NoteFieldEdit . SetZoom ( 0.5f );
2005-04-07 18:32:19 +00:00
m_NoteFieldEdit . Init ( & m_PlayerStateEdit , PLAYER_HEIGHT * 2 );
2005-06-04 23:29:50 +00:00
m_NoteFieldEdit . Load ( & m_NoteDataEdit , - 240 , 850 );
2005-03-18 19:44:01 +00:00
this -> AddChild ( & m_NoteFieldEdit );
2005-07-20 04:48:26 +00:00
m_NoteDataRecord . SetNumTracks ( m_NoteDataEdit . GetNumTracks () );
2005-04-07 19:27:53 +00:00
m_NoteFieldRecord . SetXY ( RECORD_X , RECORD_Y );
2006-02-01 04:59:38 +00:00
m_NoteFieldRecord . Init ( GAMESTATE -> m_pPlayerState [ PLAYER_1 ], PLAYER_HEIGHT );
2005-07-20 04:48:26 +00:00
m_NoteFieldRecord . Load ( & m_NoteDataRecord , - ( int ) SCREEN_HEIGHT / 2 , ( int ) SCREEN_HEIGHT / 2 );
2005-03-18 19:44:01 +00:00
this -> AddChild ( & m_NoteFieldRecord );
2002-05-20 08:59:37 +00:00
2006-02-01 04:59:38 +00:00
m_EditState = STATE_INVALID ;
TransitionEditState ( STATE_EDITING );
2005-07-30 07:07:11 +00:00
m_bRemoveNoteButtonDown = false ;
2005-01-22 02:50:45 +00:00
m_Clipboard . SetNumTracks ( m_NoteDataEdit . GetNumTracks () );
2002-07-02 00:27:58 +00:00
2005-03-29 20:25:14 +00:00
m_bHasUndo = false ;
2005-03-23 10:43:57 +00:00
m_Undo . SetNumTracks ( m_NoteDataEdit . GetNumTracks () );
2003-02-19 06:27:20 +00:00
2005-02-26 05:59:12 +00:00
m_Player . Init ( "Player" , GAMESTATE -> m_pPlayerState [ PLAYER_1 ], NULL , NULL , NULL , NULL , NULL , NULL , NULL , NULL );
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 );
2005-03-18 19:44:01 +00:00
this -> AddChild ( & m_Player );
this -> AddChild ( & m_Foreground );
2002-05-20 08:59:37 +00:00
2006-03-07 20:43:40 +00:00
m_textInputTips . SetName ( "EditHelp" );
m_textInputTips . LoadFromFont ( THEME -> GetPathF ( "ScreenEdit" , "EditHelp" ) );
m_textInputTips . SetText ( EDIT_HELP_TEXT );
2005-03-20 07:11:23 +00:00
SET_XY_AND_ON_COMMAND ( m_textInputTips );
this -> AddChild ( & m_textInputTips );
2002-05-20 08:59:37 +00:00
2005-03-20 07:11:23 +00:00
m_textInfo . SetName ( "Info" );
2005-03-20 07:22:55 +00:00
m_textInfo . LoadFromFont ( THEME -> GetPathF ( "ScreenEdit" , "Info" ) );
2005-03-20 07:11:23 +00:00
SET_XY_AND_ON_COMMAND ( m_textInfo );
2005-03-18 19:44:01 +00:00
this -> AddChild ( & m_textInfo );
2002-06-29 11:59:09 +00:00
2005-03-21 14:13:11 +00:00
m_textPlayRecordHelp . SetName ( "PlayRecordHelp" );
m_textPlayRecordHelp . LoadFromFont ( THEME -> GetPathF ( "ScreenEdit" , "PlayRecordHelp" ) );
m_textPlayRecordHelp . SetText ( PLAY_RECORD_HELP_TEXT );
SET_XY_AND_ON_COMMAND ( m_textPlayRecordHelp );
this -> AddChild ( & m_textPlayRecordHelp );
2005-03-18 19:44:01 +00:00
this -> SortByDrawOrder ();
2006-02-04 18:35:29 +00:00
m_soundAddNote . Load ( THEME -> GetPathS ( "ScreenEdit" , "AddNote" ), true );
m_soundRemoveNote . Load ( THEME -> GetPathS ( "ScreenEdit" , "RemoveNote" ), true );
m_soundChangeLine . Load ( THEME -> GetPathS ( "ScreenEdit" , "line" ), true );
m_soundChangeSnap . Load ( THEME -> GetPathS ( "ScreenEdit" , "snap" ), true );
m_soundMarker . Load ( THEME -> GetPathS ( "ScreenEdit" , "marker" ), true );
m_soundValueIncrease . Load ( THEME -> GetPathS ( "ScreenEdit" , "value increase" ), true );
m_soundValueDecrease . Load ( THEME -> GetPathS ( "ScreenEdit" , "value decrease" ), true );
2006-02-03 19:24:39 +00:00
m_soundSwitchSteps . Load ( THEME -> GetPathS ( "ScreenEdit" , "switch steps" ) );
2006-02-04 18:35:29 +00:00
m_soundSave . Load ( THEME -> GetPathS ( "ScreenEdit" , "save" ) );
2006-03-16 07:36:27 +00:00
m_soundAssistTick . Load ( THEME -> GetPathS ( "ScreenEdit" , "assist tick" ), true );
2002-05-20 08:59:37 +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-04-01 08:34:23 +00:00
this -> HandleScreenMessage ( SM_UpdateTextInfo );
m_bTextInfoNeedsUpdate = true ;
2002-05-20 08:59:37 +00:00
}
ScreenEdit ::~ ScreenEdit ()
{
2005-03-08 21:39:01 +00:00
// UGLY: Don't delete the Song's steps.
m_songLastSave . DetachSteps ();
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
}
2006-03-16 07:35:47 +00:00
void ScreenEdit :: BeginScreen ()
{
/* We do this ourself. */
SOUND -> HandleSongTimer ( false );
}
void ScreenEdit :: EndScreen ()
{
SOUND -> HandleSongTimer ( true );
}
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
{
2005-04-14 06:34:17 +00:00
if ( ! GAMESTATE -> m_SongOptions . m_bAssistTick || m_EditState != STATE_PLAYING )
2004-01-12 09:36:01 +00:00
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. */
2006-03-29 11:12:20 +00:00
float fPositionSeconds = GAMESTATE -> m_fMusicSeconds ;
2005-10-27 05:16:19 +00:00
fPositionSeconds += SOUND -> GetPlayLatency () + ( float ) CommonMetrics :: TICK_EARLY_SECONDS + 0.250f ;
2006-03-29 11:12:20 +00:00
const float fSongBeat = GAMESTATE -> m_pCurSong -> m_Timing . GetBeatFromElapsedTimeNoOffset ( 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:
2005-01-31 19:12:30 +00:00
FOREACH_NONEMPTY_ROW_ALL_TRACKS_RANGE ( m_Player . m_NoteData , r , iRowLastCrossed + 1 , iSongRow + 1 )
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 );
2006-03-29 11:12:20 +00:00
const float fTickSecond = GAMESTATE -> m_pCurSong -> m_Timing . GetElapsedTimeFromBeatNoOffset ( fTickBeat );
float fSecondsUntil = fTickSecond - GAMESTATE -> m_fMusicSeconds ;
2004-01-12 09:36:01 +00:00
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 ;
2006-03-28 09:28:55 +00:00
p . m_StartTime = GAMESTATE -> m_LastBeatUpdate + ( fSecondsUntil - ( float ) CommonMetrics :: 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 ()
{
2006-06-23 17:54:48 +00:00
SOUND -> StopMusic ();
2005-07-22 22:17:34 +00:00
SOUND -> PlayMusic (
m_pSong -> GetMusicPath (),
NULL ,
false ,
2003-03-05 02:38:17 +00:00
m_pSong -> m_fMusicSampleStartSeconds ,
m_pSong -> m_fMusicSampleLengthSeconds ,
1.5f );
}
2005-07-19 21:43:12 +00:00
void ScreenEdit :: MakeFilteredMenuDef ( const MenuDef * pDef , MenuDef & menu )
2005-07-14 04:59:06 +00:00
{
2005-07-19 21:43:12 +00:00
menu = * pDef ;
2005-07-14 04:59:06 +00:00
menu . rows . clear ();
vector < MenuRowDef > aRows ;
FOREACH_CONST ( MenuRowDef , pDef -> rows , r )
{
// Don't add rows that aren't applicable to this edit mode.
if ( EDIT_MODE >= r -> emShowIn )
menu . rows . push_back ( * r );
}
2005-07-19 21:43:12 +00:00
}
2005-07-14 04:59:06 +00:00
2006-01-30 06:59:15 +00:00
void ScreenEdit :: EditMiniMenu ( const MenuDef * pDef , ScreenMessage SM_SendOnOK , ScreenMessage SM_SendOnCancel )
2005-07-19 21:43:12 +00:00
{
2006-01-30 06:59:15 +00:00
/* Reload options. */
MenuDef menu ( "" );
MakeFilteredMenuDef ( pDef , menu );
ScreenMiniMenu :: MiniMenu ( & menu , SM_SendOnOK , SM_SendOnCancel );
2005-07-14 04:59:06 +00:00
}
2002-05-20 08:59:37 +00:00
void ScreenEdit :: Update ( float fDeltaTime )
{
2005-04-07 18:32:19 +00:00
m_PlayerStateEdit . Update ( 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
2005-04-14 06:34:17 +00:00
if ( m_EditState == STATE_RECORDING )
2002-10-18 19:01:32 +00:00
{
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 );
2005-07-30 07:07:11 +00:00
fSecsHeld = min ( fSecsHeld , m_RemoveNoteButtonLastChanged . Ago () );
if ( fSecsHeld == 0 )
continue ;
2002-10-18 19:01:32 +00:00
2005-07-20 05:35:10 +00:00
float fStartPlayingAtBeat = NoteRowToBeat ( m_iStartPlayingAt );
2005-07-30 07:07:11 +00:00
if ( GAMESTATE -> m_fSongBeat <= fStartPlayingAtBeat )
continue ;
float fStartedHoldingSeconds = m_soundMusic . GetPositionSeconds () - fSecsHeld ;
float fStartBeat = max ( fStartPlayingAtBeat , m_pSong -> GetBeatFromElapsedTime ( fStartedHoldingSeconds ) );
float fEndBeat = max ( fStartBeat , GAMESTATE -> m_fSongBeat );
fEndBeat = min ( fEndBeat , NoteRowToBeat ( m_iStopPlayingAt ) );
// Round start and end to the nearest snap interval
fStartBeat = Quantize ( fStartBeat , NoteTypeToBeat ( m_SnapDisplay . GetNoteType ()) );
fEndBeat = Quantize ( fEndBeat , NoteTypeToBeat ( m_SnapDisplay . GetNoteType ()) );
if ( m_bRemoveNoteButtonDown )
2002-10-18 19:01:32 +00:00
{
2005-07-30 07:07:11 +00:00
m_NoteDataRecord . ClearRangeForTrack ( BeatToNoteRow ( fStartBeat ), BeatToNoteRow ( fEndBeat ), t );
}
else if ( fSecsHeld > RECORD_HOLD_SECONDS )
{
// create or extend a hold or roll note
2005-07-20 05:45:16 +00:00
TapNote tn = TAP_ORIGINAL_HOLD_HEAD ;
if ( EditIsBeingPressed ( EDIT_BUTTON_LAY_MINE_OR_ROLL ) )
tn = TAP_ORIGINAL_ROLL_HEAD ;
m_NoteDataRecord . AddHoldNote ( t , BeatToNoteRow ( fStartBeat ), BeatToNoteRow ( fEndBeat ), tn );
2002-10-18 19:01:32 +00:00
}
}
}
2005-07-21 01:17:51 +00:00
//
// check for end of playback/record
//
2005-04-14 06:34:17 +00:00
if ( m_EditState == STATE_RECORDING || m_EditState == STATE_PLAYING )
2002-05-20 08:59:37 +00:00
{
2005-07-21 01:17:51 +00:00
/*
* If any arrow is being held, continue for up to half a second after
* the end marker. This makes it possible to start a hold note near
* the end of the range. We won't allow placing anything outside of the
* range.
*/
bool bButtonIsBeingPressed = false ;
for ( int t = 0 ; t < GAMESTATE -> GetCurrentStyle () -> m_iColsPerPlayer ; t ++ ) // for each track
{
StyleInput StyleI ( PLAYER_1 , t );
if ( INPUTMAPPER -> IsButtonDown ( StyleI ) )
bButtonIsBeingPressed = true ;
}
2002-05-20 08:59:37 +00:00
2005-07-21 01:17:51 +00:00
float fLastBeat = NoteRowToBeat ( m_iStopPlayingAt );
if ( bButtonIsBeingPressed && m_EditState == STATE_RECORDING )
{
float fSeconds = m_pSong -> m_Timing . GetElapsedTimeFromBeat ( fLastBeat );
fLastBeat = m_pSong -> m_Timing . GetBeatFromElapsedTime ( fSeconds + 0.5f );
}
2006-04-04 21:58:20 +00:00
float fStopAtSeconds = m_pSong -> m_Timing . GetElapsedTimeFromBeat ( NoteRowToBeat ( m_iStopPlayingAt ) ) + 1 ;
if ( GAMESTATE -> m_fMusicSeconds > fStopAtSeconds )
{
// loop
TransitionEditState ( STATE_PLAYING );
}
2002-05-20 08:59:37 +00:00
}
2002-07-31 19:40:40 +00:00
//LOG->Trace( "ScreenEdit::Update(%f)", fDeltaTime );
2005-03-18 18:58:22 +00:00
ScreenWithMenuElements :: Update ( fDeltaTime );
2002-05-20 08:59:37 +00:00
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 ;
2005-02-03 03:39:15 +00:00
if ( fabsf ( fDelta ) < 10 )
fapproach ( m_fTrailingBeat , GAMESTATE -> m_fSongBeat ,
2005-07-21 01:04:54 +00:00
fDeltaTime * 40 / m_NoteFieldEdit . GetPlayerState () -> m_CurrentPlayerOptions . m_fScrollSpeed );
2002-06-29 11:59:09 +00:00
else
2005-02-03 03:39:15 +00:00
fapproach ( m_fTrailingBeat , GAMESTATE -> m_fSongBeat ,
fabsf ( fDelta ) * fDeltaTime * 5 );
2002-06-29 11:59:09 +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
2006-02-02 08:33:09 +00:00
static LocalizedString CURRENT_BEAT ( "ScreenEdit" , "Current beat" );
static LocalizedString CURRENT_SECOND ( "ScreenEdit" , "Current second" );
static LocalizedString SNAP_TO ( "ScreenEdit" , "Snap to" );
2006-06-14 21:03:43 +00:00
static LocalizedString NOTES ( "ScreenEdit" , "%s notes" );
2006-02-02 08:33:09 +00:00
static LocalizedString SELECTION_BEAT ( "ScreenEdit" , "Selection beat" );
static LocalizedString DIFFICULTY ( "ScreenEdit" , "Difficulty" );
static LocalizedString DESCRIPTION ( "ScreenEdit" , "Description" );
static LocalizedString MAIN_TITLE ( "ScreenEdit" , "Main title" );
static LocalizedString SUBTITLE ( "ScreenEdit" , "Subtitle" );
static LocalizedString TAP_STEPS ( "ScreenEdit" , "Tap Steps" );
static LocalizedString JUMPS ( "ScreenEdit" , "Jumps" );
static LocalizedString HANDS ( "ScreenEdit" , "Hands" );
static LocalizedString HOLDS ( "ScreenEdit" , "Holds" );
static LocalizedString MINES ( "ScreenEdit" , "Mines" );
static LocalizedString ROLLS ( "ScreenEdit" , "Rolls" );
static LocalizedString BEAT_0_OFFSET ( "ScreenEdit" , "Beat 0 offset" );
static LocalizedString PREVIEW_START ( "ScreenEdit" , "Preview Start" );
static LocalizedString PREVIEW_LENGTH ( "ScreenEdit" , "Preview Length" );
2003-03-30 20:43:30 +00:00
void ScreenEdit :: UpdateTextInfo ()
{
2005-03-08 22:21:18 +00:00
if ( m_pSteps == NULL )
return ;
2005-04-01 08:34:23 +00:00
// Don't update the text during playback or record. It causes skips.
2005-04-14 06:34:17 +00:00
if ( m_EditState != STATE_EDITING )
2005-04-01 08:34:23 +00:00
return ;
if ( ! m_bTextInfoNeedsUpdate )
return ;
m_bTextInfoNeedsUpdate = false ;
2006-06-14 21:03:43 +00:00
RString sNoteType = ssprintf ( NOTES . GetValue (), NoteTypeToLocalizedString ( m_SnapDisplay . GetNoteType ()). c_str () );
2002-05-20 08:59:37 +00:00
2006-01-22 01:00:06 +00:00
RString sText ;
2006-02-02 08:33:09 +00:00
sText += ssprintf ( "%s: \n %.3f \n " , CURRENT_BEAT . GetValue (). c_str (), GAMESTATE -> m_fSongBeat );
sText += ssprintf ( "%s: \n %.3f \n " , CURRENT_SECOND . GetValue (). c_str (), m_pSong -> GetElapsedTimeFromBeat ( GAMESTATE -> m_fSongBeat ) );
2005-04-19 04:11:33 +00:00
switch ( EDIT_MODE . GetValue () )
2005-03-20 09:52:48 +00:00
{
2006-06-14 09:56:57 +00:00
DEFAULT_FAIL ( EDIT_MODE . GetValue () );
2005-12-06 23:44:01 +00:00
case EditMode_Practice :
2005-04-19 01:44:22 +00:00
break ;
2006-03-12 00:45:18 +00:00
case EditMode_CourseMods :
2005-12-06 23:44:01 +00:00
case EditMode_Home :
case EditMode_Full :
2006-02-02 08:33:09 +00:00
sText += ssprintf ( "%s: \n %s \n " , SNAP_TO . GetValue (). c_str (), sNoteType . c_str () );
2005-04-19 01:44:22 +00:00
break ;
}
2006-02-02 08:33:09 +00:00
if ( m_NoteFieldEdit . m_iBeginMarker != - 1 )
{
sText += ssprintf ( "%s: \n %.3f" , SELECTION_BEAT . GetValue (). c_str (), NoteRowToBeat ( m_NoteFieldEdit . m_iBeginMarker ) );
if ( m_NoteFieldEdit . m_iEndMarker != - 1 )
sText += ssprintf ( "-%.3f \n " , NoteRowToBeat ( m_NoteFieldEdit . m_iEndMarker ) );
else
sText += " ... \n " ;
}
2005-04-19 04:11:33 +00:00
switch ( EDIT_MODE . GetValue () )
2005-04-19 01:44:22 +00:00
{
2006-06-14 09:56:57 +00:00
DEFAULT_FAIL ( EDIT_MODE . GetValue () );
2005-12-06 23:44:01 +00:00
case EditMode_Practice :
2006-03-12 00:45:18 +00:00
case EditMode_CourseMods :
2005-12-06 23:44:01 +00:00
case EditMode_Home :
2005-04-19 01:44:22 +00:00
break ;
2005-12-06 23:44:01 +00:00
case EditMode_Full :
2006-02-02 08:33:09 +00:00
sText += ssprintf ( "%s: \n %s \n " , DIFFICULTY . GetValue (). c_str (), DifficultyToString ( m_pSteps -> GetDifficulty () ). c_str () );
sText += ssprintf ( "%s: \n %s \n " , DESCRIPTION . GetValue (). c_str (), m_pSteps -> GetDescription (). c_str () );
sText += ssprintf ( "%s: \n %s \n " , MAIN_TITLE . GetValue (). c_str (), m_pSong -> m_sMainTitle . c_str () );
if ( m_pSong -> m_sSubTitle . size () )
sText += ssprintf ( "%s: \n %s \n " , SUBTITLE . GetValue (). c_str (), m_pSong -> m_sSubTitle . c_str () );
2005-04-19 01:44:22 +00:00
break ;
2005-03-20 09:52:48 +00:00
}
2006-02-02 08:33:09 +00:00
sText += ssprintf ( "%s: \n %d \n " , TAP_STEPS . GetValue (). c_str (), m_NoteDataEdit . GetNumTapNotes () );
2006-03-07 02:43:09 +00:00
sText += ssprintf ( "%s: \n %d \n " , JUMPS . GetValue (). c_str (), m_NoteDataEdit . GetNumJumps () );
sText += ssprintf ( "%s: \n %d \n " , HANDS . GetValue (). c_str (), m_NoteDataEdit . GetNumHands () );
sText += ssprintf ( "%s: \n %d \n " , HOLDS . GetValue (). c_str (), m_NoteDataEdit . GetNumHoldNotes () );
sText += ssprintf ( "%s: \n %d \n " , MINES . GetValue (). c_str (), m_NoteDataEdit . GetNumMines () );
sText += ssprintf ( "%s: \n %d \n " , ROLLS . GetValue (). c_str (), m_NoteDataEdit . GetNumRolls () );
2005-04-19 04:11:33 +00:00
switch ( EDIT_MODE . GetValue () )
2005-04-14 06:34:17 +00:00
{
2006-06-14 09:56:57 +00:00
DEFAULT_FAIL ( EDIT_MODE . GetValue () );
2005-12-06 23:44:01 +00:00
case EditMode_Practice :
2006-03-12 00:45:18 +00:00
case EditMode_CourseMods :
2005-12-06 23:44:01 +00:00
case EditMode_Home :
2005-04-19 01:44:22 +00:00
break ;
2005-12-06 23:44:01 +00:00
case EditMode_Full :
2006-02-02 08:33:09 +00:00
sText += ssprintf ( "%s: \n %.3f secs \n " , BEAT_0_OFFSET . GetValue (). c_str (), m_pSong -> m_Timing . m_fBeat0OffsetInSeconds );
sText += ssprintf ( "%s: \n %.3f secs \n " , PREVIEW_START . GetValue (). c_str (), m_pSong -> m_fMusicSampleStartSeconds );
sText += ssprintf ( "%s: \n %.3f secs \n " , PREVIEW_LENGTH . GetValue (). c_str (), m_pSong -> m_fMusicSampleLengthSeconds );
2005-04-19 01:44:22 +00:00
break ;
2005-04-14 06:34:17 +00:00
}
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 ()
{
2005-03-18 19:44:01 +00:00
// HACK: Draw using the trailing beat
float fSongBeat = GAMESTATE -> m_fSongBeat ; // save song beat
GAMESTATE -> m_fSongBeat = m_fTrailingBeat ; // put trailing beat in effect
2002-05-20 08:59:37 +00:00
2005-03-18 18:58:22 +00:00
ScreenWithMenuElements :: DrawPrimitives ();
2005-03-18 19:44:01 +00:00
GAMESTATE -> m_fSongBeat = fSongBeat ; // restore real song beat
2002-05-20 08:59:37 +00:00
}
2005-09-05 02:26:50 +00:00
void ScreenEdit :: Input ( const InputEventPlus & input )
2002-05-20 08:59:37 +00:00
{
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
EditButton EditB ;
2006-03-07 02:43:09 +00:00
if ( ! DeviceToEdit ( input . DeviceI , EditB ) )
if ( input . MenuI . IsValid () )
MenuInputToEditButton ( input . MenuI , EditB );
2005-07-30 07:07:11 +00:00
if ( EditB == EDIT_BUTTON_REMOVE_NOTE )
{
// Ugly: we need to know when the button was pressed or released, so we
// can clamp operations to that time. Should InputFilter keep track of
// last release, too?
2005-09-05 02:26:50 +00:00
m_bRemoveNoteButtonDown = ( input . type != IET_RELEASE );
2005-07-30 07:07:11 +00:00
m_RemoveNoteButtonLastChanged . Touch ();
}
2005-04-14 06:34:17 +00:00
switch ( m_EditState )
2002-05-20 08:59:37 +00:00
{
2006-06-14 09:56:57 +00:00
DEFAULT_FAIL ( m_EditState );
2005-04-14 06:34:17 +00:00
case STATE_EDITING :
2005-09-05 02:26:50 +00:00
InputEdit ( input , EditB );
2005-04-01 08:34:23 +00:00
m_bTextInfoNeedsUpdate = true ;
2005-03-30 01:06:13 +00:00
break ;
2005-04-14 06:34:17 +00:00
case STATE_RECORDING :
2005-09-05 02:26:50 +00:00
InputRecord ( input , EditB );
2005-03-30 01:06:13 +00:00
break ;
2005-07-21 21:23:18 +00:00
case STATE_RECORDING_PAUSED :
2005-09-05 02:26:50 +00:00
InputRecordPaused ( input , EditB );
2005-07-21 21:23:18 +00:00
break ;
2005-04-14 06:34:17 +00:00
case STATE_PLAYING :
2005-09-05 02:26:50 +00:00
InputPlay ( input , EditB );
2005-03-30 01:06:13 +00:00
break ;
2002-05-20 08:59:37 +00:00
}
}
2005-03-24 23:03:12 +00:00
static void ShiftToRightSide ( int & iCol , int iNumTracks )
{
switch ( GAMESTATE -> GetCurrentStyle () -> m_StyleType )
{
2006-06-14 09:56:57 +00:00
DEFAULT_FAIL ( GAMESTATE -> GetCurrentStyle () -> m_StyleType );
2005-03-24 23:03:12 +00:00
case ONE_PLAYER_ONE_SIDE :
break ;
case TWO_PLAYERS_TWO_SIDES :
case ONE_PLAYER_TWO_SIDES :
2006-06-24 05:25:39 +00:00
case TWO_PLAYERS_SHARED_SIDES :
2005-03-24 23:03:12 +00:00
iCol += iNumTracks / 2 ;
break ;
}
}
2003-09-07 22:28:46 +00:00
2006-03-14 08:41:16 +00:00
static int FindAttackAtTime ( const AttackArray & attacks , float fStartTime )
{
for ( unsigned i = 0 ; i < attacks . size (); ++ i )
{
2006-03-14 08:51:12 +00:00
if ( fabs ( attacks [ i ]. fStartSecond - fStartTime ) < 0.001f )
2006-03-14 08:41:16 +00:00
return i ;
}
return - 1 ;
}
2006-03-12 00:45:18 +00:00
static LocalizedString SWITCHED_TO ( "ScreenEdit" , "Switched to" );
2005-12-20 08:35:47 +00:00
static LocalizedString NO_BACKGROUNDS_AVAILABLE ( "ScreenEdit" , "No backgrounds available" );
2005-09-05 02:26:50 +00:00
void ScreenEdit :: InputEdit ( const InputEventPlus & input , EditButton EditB )
2002-05-20 08:59:37 +00:00
{
2005-09-05 02:26:50 +00:00
if ( input . type == IET_LEVEL_CHANGED )
2004-09-09 22:21:50 +00:00
return ; // don't care
2005-09-05 02:26:50 +00:00
if ( input . type == IET_RELEASE )
2002-08-21 22:48:33 +00:00
{
2005-09-05 02:26:50 +00:00
if ( EditPressed ( EDIT_BUTTON_SCROLL_SELECT , input . DeviceI ) )
2005-07-20 04:50:06 +00:00
m_iShiftAnchor = - 1 ;
2002-08-21 22:48:33 +00:00
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_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
{
2005-09-05 02:26:50 +00:00
if ( input . type != IET_FIRST_PRESS )
2002-08-17 06:44:04 +00:00
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-03-24 23:03:12 +00:00
ShiftToRightSide ( iCol , m_NoteDataEdit . GetNumTracks () );
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-03-22 13:38:18 +00:00
int iHeadRow ;
2005-07-22 00:14:24 +00:00
if ( m_NoteDataEdit . IsHoldNoteAtRow ( iCol , iSongIndex , & iHeadRow ) )
2002-08-17 06:44:04 +00:00
{
2005-03-22 13:38:18 +00:00
m_soundRemoveNote . Play ();
2005-03-23 10:43:57 +00:00
SaveUndo ();
m_NoteDataEdit . SetTapNote ( iCol , iHeadRow , TAP_EMPTY );
// Don't CheckNumberOfNotesAndUndo. We don't want to revert any change that removes notes.
2002-08-17 06:44:04 +00:00
}
2005-03-22 13:38:18 +00:00
else if ( m_NoteDataEdit . GetTapNote ( iCol , iSongIndex ). type != TapNote :: empty )
2003-11-15 08:51:47 +00:00
{
2005-03-22 13:38:18 +00:00
m_soundRemoveNote . Play ();
2005-03-23 10:43:57 +00:00
SaveUndo ();
m_NoteDataEdit . SetTapNote ( iCol , iSongIndex , TAP_EMPTY );
// Don't CheckNumberOfNotesAndUndo. We don't want to revert any change that removes notes.
2003-11-15 08:51:47 +00:00
}
2005-04-18 01:23:57 +00:00
else if ( EditIsBeingPressed ( EDIT_BUTTON_LAY_MINE_OR_ROLL ) )
2003-11-15 08:51:47 +00:00
{
2005-03-22 13:38:18 +00:00
m_soundAddNote . Play ();
2005-03-23 10:43:57 +00:00
SaveUndo ();
m_NoteDataEdit . SetTapNote ( iCol , iSongIndex , TAP_ORIGINAL_MINE );
CheckNumberOfNotesAndUndo ();
2003-11-15 08:51:47 +00:00
}
2005-08-30 18:09:00 +00:00
else if ( EditIsBeingPressed ( EDIT_BUTTON_LAY_TAP_ATTACK ) )
2003-11-15 08:51:47 +00:00
{
2005-08-30 18:09:00 +00:00
g_iLastInsertTapAttackTrack = iCol ;
2006-01-30 06:59:15 +00:00
EditMiniMenu ( & g_InsertTapAttack , SM_BackFromInsertTapAttack );
2003-11-15 08:51:47 +00:00
}
else
{
2005-03-22 13:38:18 +00:00
m_soundAddNote . Play ();
2005-03-23 10:43:57 +00:00
SaveUndo ();
m_NoteDataEdit . SetTapNote ( iCol , iSongIndex , TAP_ORIGINAL_TAP );
CheckNumberOfNotesAndUndo ();
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-07-21 01:04:54 +00:00
PlayerState * pPlayerState = const_cast < PlayerState *> ( m_NoteFieldEdit . GetPlayerState ());
float & fScrollSpeed = pPlayerState -> m_PlayerOptions . m_fScrollSpeed ;
2006-03-13 07:46:02 +00:00
const float fSpeeds [] = { 1.0f , 1.5f , 2.0f , 3.0f , 4.0f , 6.0f , 8.0f };
int iSpeed = 0 ;
for ( unsigned i = 0 ; i < ARRAYSIZE ( fSpeeds ); ++ i )
{
if ( fSpeeds [ i ] == fScrollSpeed )
{
iSpeed = i ;
break ;
}
}
2005-01-14 23:17:04 +00:00
2005-03-27 00:32:20 +00:00
if ( EditB == EDIT_BUTTON_SCROLL_SPEED_DOWN )
2006-03-13 07:46:02 +00:00
-- iSpeed ;
2005-03-27 00:32:20 +00:00
else if ( EditB == EDIT_BUTTON_SCROLL_SPEED_UP )
2006-03-13 07:46:02 +00:00
++ iSpeed ;
iSpeed = clamp ( iSpeed , 0 , ( int ) ARRAYSIZE ( fSpeeds ) - 1 );
if ( fSpeeds [ iSpeed ] != fScrollSpeed )
2005-01-14 23:17:04 +00:00
{
2006-03-13 07:46:02 +00:00
m_soundMarker . Play ();
fScrollSpeed = fSpeeds [ iSpeed ];
2003-02-18 23:15:38 +00:00
}
2002-08-17 06:44:04 +00:00
break ;
2005-01-14 23:17:04 +00:00
}
2005-07-22 04:12:56 +00:00
break ;
case EDIT_BUTTON_SCROLL_HOME :
ScrollTo ( 0 );
break ;
case EDIT_BUTTON_SCROLL_END :
ScrollTo ( m_NoteDataEdit . GetLastBeat () );
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 :
{
float fBeatsToMove = 0.f ;
switch ( EditB )
{
2006-06-14 09:56:57 +00:00
DEFAULT_FAIL ( EditB );
2005-01-14 23:17:04 +00:00
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 ;
2002-08-17 06:44:04 +00:00
}
2005-03-26 19:11:22 +00:00
float fDestinationBeat = GAMESTATE -> m_fSongBeat + fBeatsToMove ;
fDestinationBeat = Quantize ( fDestinationBeat , NoteTypeToBeat ( m_SnapDisplay . GetNoteType ()) );
2005-07-21 22:31:09 +00:00
ScrollTo ( fDestinationBeat );
2002-08-17 06:44:04 +00:00
}
break ;
2005-07-22 01:28:20 +00:00
case EDIT_BUTTON_SCROLL_NEXT_MEASURE :
{
float fDestinationBeat = GAMESTATE -> m_fSongBeat + BEATS_PER_MEASURE ;
fDestinationBeat = ftruncf ( fDestinationBeat , ( float ) BEATS_PER_MEASURE );
ScrollTo ( fDestinationBeat );
break ;
}
case EDIT_BUTTON_SCROLL_PREV_MEASURE :
{
float fDestinationBeat = QuantizeUp ( GAMESTATE -> m_fSongBeat , ( float ) BEATS_PER_MEASURE );
fDestinationBeat -= ( float ) BEATS_PER_MEASURE ;
ScrollTo ( fDestinationBeat );
break ;
}
2005-07-22 00:55:36 +00:00
case EDIT_BUTTON_SCROLL_NEXT :
{
int iRow = BeatToNoteRow ( GAMESTATE -> m_fSongBeat );
NoteDataUtil :: GetNextEditorPosition ( m_NoteDataEdit , iRow );
ScrollTo ( NoteRowToBeat ( iRow ) );
}
break ;
case EDIT_BUTTON_SCROLL_PREV :
{
int iRow = BeatToNoteRow ( GAMESTATE -> m_fSongBeat );
NoteDataUtil :: GetPrevEditorPosition ( m_NoteDataEdit , iRow );
ScrollTo ( NoteRowToBeat ( iRow ) );
}
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 :
2002-08-17 06:44:04 +00:00
{
2006-03-07 20:43:40 +00:00
const int iCurrentRow = BeatToNoteRow ( GAMESTATE -> m_fSongBeat );
if ( m_NoteFieldEdit . m_iBeginMarker ==- 1 && m_NoteFieldEdit . m_iEndMarker ==- 1 )
2002-08-17 06:44:04 +00:00
{
2006-03-07 20:43:40 +00:00
// lay begin marker
m_NoteFieldEdit . m_iBeginMarker = BeatToNoteRow ( GAMESTATE -> m_fSongBeat );
2002-08-17 06:44:04 +00:00
}
2006-03-07 20:43:40 +00:00
else if ( m_NoteFieldEdit . m_iEndMarker ==- 1 ) // only begin marker is laid
2002-08-17 06:44:04 +00:00
{
2006-03-07 20:43:40 +00:00
if ( iCurrentRow == m_NoteFieldEdit . m_iBeginMarker )
{
m_NoteFieldEdit . m_iBeginMarker = - 1 ;
}
else
{
m_NoteFieldEdit . m_iEndMarker = max ( m_NoteFieldEdit . m_iBeginMarker , iCurrentRow );
m_NoteFieldEdit . m_iBeginMarker = min ( m_NoteFieldEdit . m_iBeginMarker , iCurrentRow );
}
2002-08-17 06:44:04 +00:00
}
2006-03-07 20:43:40 +00:00
else // both markers are laid
{
m_NoteFieldEdit . m_iBeginMarker = iCurrentRow ;
m_NoteFieldEdit . m_iEndMarker = - 1 ;
}
m_soundMarker . Play ();
2002-08-17 06:44:04 +00:00
}
2003-02-18 23:15:38 +00:00
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 ;
2005-03-20 06:41:56 +00:00
g_AreaMenu . rows [ cut ]. bEnabled = bAreaSelected ;
g_AreaMenu . rows [ copy ]. bEnabled = bAreaSelected ;
2005-03-29 20:25:14 +00:00
g_AreaMenu . rows [ paste_at_current_beat ]. bEnabled = ! m_Clipboard . IsEmpty ();
g_AreaMenu . rows [ paste_at_begin_marker ]. bEnabled = ! m_Clipboard . IsEmpty () != 0 && m_NoteFieldEdit . m_iBeginMarker !=- 1 ;
2005-03-20 06:41:56 +00:00
g_AreaMenu . rows [ clear ]. bEnabled = bAreaSelected ;
g_AreaMenu . rows [ quantize ]. bEnabled = bAreaSelected ;
g_AreaMenu . rows [ turn ]. bEnabled = bAreaSelected ;
g_AreaMenu . rows [ transform ]. bEnabled = bAreaSelected ;
g_AreaMenu . rows [ alter ]. bEnabled = bAreaSelected ;
g_AreaMenu . rows [ tempo ]. bEnabled = bAreaSelected ;
g_AreaMenu . rows [ play ]. bEnabled = bAreaSelected ;
g_AreaMenu . rows [ record ]. bEnabled = bAreaSelected ;
2005-12-18 23:56:14 +00:00
g_AreaMenu . rows [ convert_to_pause ]. bEnabled = bAreaSelected ;
2005-03-29 20:25:14 +00:00
g_AreaMenu . rows [ undo ]. bEnabled = m_bHasUndo ;
2006-01-30 06:59:15 +00:00
EditMiniMenu ( & g_AreaMenu , SM_BackFromAreaMenu );
2003-02-18 23:15:38 +00:00
}
2002-08-17 06:44:04 +00:00
break ;
2005-01-14 23:17:04 +00:00
case EDIT_BUTTON_OPEN_EDIT_MENU :
2006-01-30 06:59:15 +00:00
EditMiniMenu ( & 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 :
2006-03-16 20:59:15 +00:00
DoHelp ();
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
{
2005-03-23 10:43:57 +00:00
// don't keep undo when changing Steps
2005-12-29 03:29:20 +00:00
ClearUndo ();
2005-03-23 10:43:57 +00:00
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 ;
2006-06-13 01:10:37 +00:00
SongUtil :: GetSteps ( GAMESTATE -> m_pCurSong , vSteps , st );
2003-08-24 05:12:08 +00:00
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
{
2006-06-14 09:56:57 +00:00
DEFAULT_FAIL ( EditB );
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 ;
}
2004-05-24 03:41:39 +00:00
pSteps = * it ;
2005-02-25 18:17:26 +00:00
GAMESTATE -> m_pCurSteps [ PLAYER_1 ]. Set ( pSteps );
2005-02-25 05:27:28 +00:00
m_pSteps = pSteps ;
2005-01-22 02:50:45 +00:00
pSteps -> GetNoteData ( m_NoteDataEdit );
2005-12-20 21:32:26 +00:00
2006-01-22 01:00:06 +00:00
RString s = ssprintf (
2005-12-20 08:35:47 +00:00
SWITCHED_TO . GetValue () + " %s %s '%s' (%d of %d)" ,
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 (),
2005-12-06 12:41:06 +00:00
pSteps -> GetDescription (). c_str (),
2006-01-28 03:19:21 +00:00
it - vSteps . begin () + 1 ,
2005-12-12 09:48:58 +00:00
int ( vSteps . size ()) );
2005-12-06 12:41:06 +00:00
SCREENMAN -> SystemMessage ( s );
2006-02-03 19:24:39 +00:00
m_soundSwitchSteps . Play ();
2003-08-24 05:12:08 +00:00
}
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 );
2006-02-04 18:35:29 +00:00
float fDelta ;
2005-01-14 23:17:04 +00:00
switch ( EditB )
2002-08-17 06:44:04 +00:00
{
2006-06-14 09:56:57 +00:00
DEFAULT_FAIL ( EditB );
2006-02-04 18:35:29 +00:00
case EDIT_BUTTON_BPM_UP : fDelta = + 0.020f ; break ;
case EDIT_BUTTON_BPM_DOWN : fDelta = - 0.020f ; break ;
2002-08-17 06:44:04 +00:00
}
2005-01-14 23:17:04 +00:00
if ( EditIsBeingPressed ( EDIT_BUTTON_ADJUST_FINE ) )
2002-08-17 06:44:04 +00:00
{
2006-02-04 18:35:29 +00:00
fDelta /= 20 ; // .001 bpm
2005-09-05 02:26:50 +00:00
}
else
{
switch ( input . type )
{
2006-02-04 18:35:29 +00:00
case IET_SLOW_REPEAT : fDelta *= 10 ; break ;
case IET_FAST_REPEAT : fDelta *= 40 ; break ;
2005-09-05 02:26:50 +00:00
}
2002-08-17 06:44:04 +00:00
}
2003-09-07 22:28:46 +00:00
2006-02-04 18:35:29 +00:00
float fNewBPM = fBPM + fDelta ;
2003-09-07 22:28:46 +00:00
m_pSong -> SetBPMAtBeat ( GAMESTATE -> m_fSongBeat , fNewBPM );
2006-02-04 18:35:29 +00:00
( fDelta > 0 ? m_soundValueIncrease : m_soundValueDecrease ). Play ();
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
{
2006-02-04 18:35:29 +00:00
float fDelta ;
2005-01-14 23:17:04 +00:00
switch ( EditB )
2002-08-17 06:44:04 +00:00
{
2006-06-14 09:56:57 +00:00
DEFAULT_FAIL ( EditB );
2006-02-04 18:35:29 +00:00
case EDIT_BUTTON_STOP_UP : fDelta = + 0.020f ; break ;
case EDIT_BUTTON_STOP_DOWN : fDelta = - 0.020f ; break ;
2002-08-17 06:44:04 +00:00
}
2005-01-14 23:17:04 +00:00
if ( EditIsBeingPressed ( EDIT_BUTTON_ADJUST_FINE ) )
2002-08-17 06:44:04 +00:00
{
2006-02-04 18:35:29 +00:00
fDelta /= 20 ; /* 1ms */
2005-09-05 02:26:50 +00:00
}
else
{
switch ( input . type )
{
2006-02-04 18:35:29 +00:00
case IET_SLOW_REPEAT : fDelta *= 10 ; break ;
case IET_FAST_REPEAT : fDelta *= 40 ; break ;
2005-09-05 02:26:50 +00:00
}
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 ;
}
2006-05-30 17:20:42 +00:00
if ( i == m_pSong -> m_Timing . m_StopSegments . size () ) // there is no StopSegment at the current beat
2002-08-17 06:44:04 +00:00
{
// create a new StopSegment
2006-02-04 18:35:29 +00:00
if ( fDelta > 0 )
m_pSong -> AddStopSegment ( StopSegment ( BeatToNoteRow ( GAMESTATE -> m_fSongBeat ), fDelta ) );
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
{
2006-02-04 18:35:29 +00:00
m_pSong -> m_Timing . m_StopSegments [ i ]. m_fStopSeconds += fDelta ;
2003-12-18 04:48:26 +00:00
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
}
2006-02-04 18:35:29 +00:00
( fDelta > 0 ? m_soundValueIncrease : m_soundValueDecrease ). Play ();
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
{
2006-02-04 18:35:29 +00:00
float fDelta ;
2005-01-14 23:17:04 +00:00
switch ( EditB )
2002-08-17 06:44:04 +00:00
{
2006-06-14 09:56:57 +00:00
DEFAULT_FAIL ( EditB );
2006-02-04 18:35:29 +00:00
case EDIT_BUTTON_OFFSET_DOWN : fDelta = - 0.02f ; break ;
case EDIT_BUTTON_OFFSET_UP : fDelta = + 0.02f ; break ;
2002-08-17 06:44:04 +00:00
}
2005-01-14 23:17:04 +00:00
if ( EditIsBeingPressed ( EDIT_BUTTON_ADJUST_FINE ) )
2002-08-17 06:44:04 +00:00
{
2006-02-04 18:35:29 +00:00
fDelta /= 20 ; /* 1ms */
2005-09-05 02:26:50 +00:00
}
else
{
switch ( input . type )
{
2006-02-04 18:35:29 +00:00
case IET_SLOW_REPEAT : fDelta *= 10 ; break ;
case IET_FAST_REPEAT : fDelta *= 40 ; break ;
2005-09-05 02:26:50 +00:00
}
2002-08-17 06:44:04 +00:00
}
2006-02-04 18:35:29 +00:00
m_pSong -> m_Timing . m_fBeat0OffsetInSeconds += fDelta ;
( fDelta > 0 ? m_soundValueIncrease : m_soundValueDecrease ). Play ();
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 :
2006-02-02 08:38:50 +00:00
case EDIT_BUTTON_SAMPLE_LENGTH_DOWN :
case EDIT_BUTTON_SAMPLE_LENGTH_UP :
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
{
2006-06-14 09:56:57 +00:00
DEFAULT_FAIL ( EditB );
2005-01-14 23:17:04 +00:00
case EDIT_BUTTON_SAMPLE_START_DOWN : fDelta = - 0.02f ; break ;
2006-02-02 08:38:15 +00:00
case EDIT_BUTTON_SAMPLE_START_UP : fDelta = + 0.02f ; break ;
2005-01-14 23:17:04 +00:00
case EDIT_BUTTON_SAMPLE_LENGTH_DOWN : fDelta = - 0.02f ; break ;
2006-02-02 08:38:15 +00:00
case EDIT_BUTTON_SAMPLE_LENGTH_UP : fDelta = + 0.02f ; break ;
2002-08-17 06:44:04 +00:00
}
2005-09-05 02:26:50 +00:00
switch ( input . type )
2002-08-17 06:44:04 +00:00
{
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 );
2006-03-12 00:45:18 +00:00
}
else
{
2002-08-21 22:48:33 +00:00
m_pSong -> m_fMusicSampleStartSeconds += fDelta ;
m_pSong -> m_fMusicSampleStartSeconds = max ( m_pSong -> m_fMusicSampleStartSeconds , 0 );
}
2006-02-04 18:35:29 +00:00
( fDelta > 0 ? m_soundValueIncrease : m_soundValueDecrease ). Play ();
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-06-05 09:46:29 +00:00
case EDIT_BUTTON_OPEN_BGCHANGE_LAYER1_MENU :
case EDIT_BUTTON_OPEN_BGCHANGE_LAYER2_MENU :
2005-07-20 01:57:53 +00:00
switch ( EditB )
{
2006-06-14 09:56:57 +00:00
DEFAULT_FAIL ( EditB );
2005-07-20 01:57:53 +00:00
case EDIT_BUTTON_OPEN_BGCHANGE_LAYER1_MENU : g_CurrentBGChangeLayer = BACKGROUND_LAYER_1 ; break ;
case EDIT_BUTTON_OPEN_BGCHANGE_LAYER2_MENU : g_CurrentBGChangeLayer = BACKGROUND_LAYER_2 ; break ;
}
{
//
// Fill in option names
//
2006-01-22 01:00:06 +00:00
vector < RString > vThrowAway ;
2005-07-20 01:57:53 +00:00
2006-01-30 04:16:48 +00:00
MenuDef & menu = g_BackgroundChange ;
menu . rows [ layer ]. choices [ 0 ] = ssprintf ( "%d" , g_CurrentBGChangeLayer );
BackgroundUtil :: GetBackgroundTransitions ( "" , vThrowAway , menu . rows [ transition ]. choices );
2005-07-20 01:57:53 +00:00
g_BackgroundChange . rows [ transition ]. choices . insert ( g_BackgroundChange . rows [ transition ]. choices . begin (), "" ); // add "no transition"
2006-01-30 04:16:48 +00:00
BackgroundUtil :: GetBackgroundEffects ( "" , vThrowAway , menu . rows [ effect ]. choices );
menu . rows [ effect ]. choices . insert ( menu . rows [ effect ]. choices . begin (), "" ); // add "default effect"
2005-07-20 01:57:53 +00:00
2006-01-30 04:16:48 +00:00
BackgroundUtil :: GetSongBGAnimations ( m_pSong , "" , vThrowAway , menu . rows [ file1_song_bganimation ]. choices );
BackgroundUtil :: GetSongMovies ( m_pSong , "" , vThrowAway , menu . rows [ file1_song_movie ]. choices );
BackgroundUtil :: GetSongBitmaps ( m_pSong , "" , vThrowAway , menu . rows [ file1_song_still ]. choices );
BackgroundUtil :: GetGlobalBGAnimations ( m_pSong , "" , vThrowAway , menu . rows [ file1_global_bganimation ]. choices ); // NULL to get all background files
BackgroundUtil :: GetGlobalRandomMovies ( m_pSong , "" , vThrowAway , menu . rows [ file1_global_movie ]. choices , false , false ); // all backgrounds
BackgroundUtil :: GetGlobalRandomMovies ( m_pSong , "" , vThrowAway , menu . rows [ file1_global_movie_song_group ]. choices , false , true ); // song group's backgrounds
BackgroundUtil :: GetGlobalRandomMovies ( m_pSong , "" , vThrowAway , menu . rows [ file1_global_movie_song_group_and_genre ]. choices , true , true ); // song group and genre's backgrounds
2005-07-20 01:57:53 +00:00
2006-01-30 04:16:48 +00:00
menu . rows [ file2_type ]. choices = menu . rows [ file1_type ]. choices ;
menu . rows [ file2_song_bganimation ]. choices = menu . rows [ file1_song_bganimation ]. choices ;
menu . rows [ file2_song_movie ]. choices = menu . rows [ file1_song_movie ]. choices ;
menu . rows [ file2_song_still ]. choices = menu . rows [ file1_song_still ]. choices ;
menu . rows [ file2_global_bganimation ]. choices = menu . rows [ file1_global_bganimation ]. choices ;
menu . rows [ file2_global_movie ]. choices = menu . rows [ file1_global_movie ]. choices ;
menu . rows [ file2_global_movie_song_group ]. choices = menu . rows [ file1_global_movie_song_group ]. choices ;
menu . rows [ file2_global_movie_song_group_and_genre ]. choices = menu . rows [ file1_global_movie_song_group_and_genre ]. choices ;
2005-07-20 01:57:53 +00:00
//
// Fill in line's enabled/disabled
//
bool bAlreadyBGChangeHere = false ;
BackgroundChange bgChange ;
FOREACH ( BackgroundChange , m_pSong -> GetBackgroundChanges ( g_CurrentBGChangeLayer ), bgc )
{
if ( bgc -> m_fStartBeat == GAMESTATE -> m_fSongBeat )
{
bAlreadyBGChangeHere = true ;
bgChange = * bgc ;
}
}
2006-01-30 04:16:48 +00:00
#define FILL_ENABLED( x ) menu.rows[x].bEnabled = menu.rows[x].choices.size() > 0;
2005-07-20 01:57:53 +00:00
FILL_ENABLED ( transition );
FILL_ENABLED ( effect );
FILL_ENABLED ( file1_song_bganimation );
FILL_ENABLED ( file1_song_movie );
FILL_ENABLED ( file1_song_still );
FILL_ENABLED ( file1_global_bganimation );
FILL_ENABLED ( file1_global_movie );
FILL_ENABLED ( file1_global_movie_song_group );
FILL_ENABLED ( file1_global_movie_song_group_and_genre );
FILL_ENABLED ( file2_song_bganimation );
FILL_ENABLED ( file2_song_movie );
FILL_ENABLED ( file2_song_still );
FILL_ENABLED ( file2_global_bganimation );
FILL_ENABLED ( file2_global_movie );
FILL_ENABLED ( file2_global_movie_song_group );
FILL_ENABLED ( file2_global_movie_song_group_and_genre );
#undef FILL_ENABLED
2006-01-30 04:16:48 +00:00
menu . rows [ delete_change ]. bEnabled = bAlreadyBGChangeHere ;
2005-07-20 01:57:53 +00:00
// set default choices
2006-01-30 04:16:48 +00:00
menu . rows [ rate ]. SetDefaultChoiceIfPresent ( ssprintf ( "%2.0f%%" , bgChange . m_fRate * 100 ) );
menu . rows [ transition ]. SetDefaultChoiceIfPresent ( bgChange . m_sTransition );
menu . rows [ effect ]. SetDefaultChoiceIfPresent ( bgChange . m_def . m_sEffect );
menu . rows [ file1_type ]. iDefaultChoice = none ;
if ( bgChange . m_def . m_sFile1 == RANDOM_BACKGROUND_FILE ) menu . rows [ file1_type ]. iDefaultChoice = dynamic_random ;
if ( menu . rows [ file1_song_bganimation ]. SetDefaultChoiceIfPresent ( bgChange . m_def . m_sFile1 ) ) menu . rows [ file1_type ]. iDefaultChoice = song_bganimation ;
if ( menu . rows [ file1_song_movie ]. SetDefaultChoiceIfPresent ( bgChange . m_def . m_sFile1 ) ) menu . rows [ file1_type ]. iDefaultChoice = song_movie ;
if ( menu . rows [ file1_song_still ]. SetDefaultChoiceIfPresent ( bgChange . m_def . m_sFile1 ) ) menu . rows [ file1_type ]. iDefaultChoice = song_bitmap ;
if ( menu . rows [ file1_global_bganimation ]. SetDefaultChoiceIfPresent ( bgChange . m_def . m_sFile1 ) ) menu . rows [ file1_type ]. iDefaultChoice = global_bganimation ;
if ( menu . rows [ file1_global_movie ]. SetDefaultChoiceIfPresent ( bgChange . m_def . m_sFile1 ) ) menu . rows [ file1_type ]. iDefaultChoice = global_movie ;
if ( menu . rows [ file1_global_movie_song_group ]. SetDefaultChoiceIfPresent ( bgChange . m_def . m_sFile1 ) ) menu . rows [ file1_type ]. iDefaultChoice = global_movie_song_group ;
if ( menu . rows [ file1_global_movie_song_group_and_genre ]. SetDefaultChoiceIfPresent ( bgChange . m_def . m_sFile1 ) ) menu . rows [ file1_type ]. iDefaultChoice = global_movie_song_group_and_genre ;
menu . rows [ file2_type ]. iDefaultChoice = none ;
if ( bgChange . m_def . m_sFile2 == RANDOM_BACKGROUND_FILE ) menu . rows [ file2_type ]. iDefaultChoice = dynamic_random ;
if ( menu . rows [ file2_song_bganimation ]. SetDefaultChoiceIfPresent ( bgChange . m_def . m_sFile2 ) ) menu . rows [ file2_type ]. iDefaultChoice = song_bganimation ;
if ( menu . rows [ file2_song_movie ]. SetDefaultChoiceIfPresent ( bgChange . m_def . m_sFile2 ) ) menu . rows [ file2_type ]. iDefaultChoice = song_movie ;
if ( menu . rows [ file2_song_still ]. SetDefaultChoiceIfPresent ( bgChange . m_def . m_sFile2 ) ) menu . rows [ file2_type ]. iDefaultChoice = song_bitmap ;
if ( menu . rows [ file2_global_bganimation ]. SetDefaultChoiceIfPresent ( bgChange . m_def . m_sFile2 ) ) menu . rows [ file2_type ]. iDefaultChoice = global_bganimation ;
if ( menu . rows [ file2_global_movie ]. SetDefaultChoiceIfPresent ( bgChange . m_def . m_sFile2 ) ) menu . rows [ file2_type ]. iDefaultChoice = global_movie ;
if ( menu . rows [ file2_global_movie_song_group ]. SetDefaultChoiceIfPresent ( bgChange . m_def . m_sFile2 ) ) menu . rows [ file2_type ]. iDefaultChoice = global_movie_song_group ;
if ( menu . rows [ file2_global_movie_song_group_and_genre ]. SetDefaultChoiceIfPresent ( bgChange . m_def . m_sFile2 ) ) menu . rows [ file2_type ]. iDefaultChoice = global_movie_song_group_and_genre ;
menu . rows [ color1 ]. SetDefaultChoiceIfPresent ( bgChange . m_def . m_sColor1 );
menu . rows [ color2 ]. SetDefaultChoiceIfPresent ( bgChange . m_def . m_sColor2 );
2005-07-20 01:57:53 +00:00
2006-01-30 06:59:15 +00:00
EditMiniMenu ( & g_BackgroundChange , SM_BackFromBGChange );
2005-07-20 01:57:53 +00:00
}
2003-03-16 00:05:23 +00:00
break ;
2005-07-20 01:57:53 +00:00
2005-01-14 23:17:04 +00:00
case EDIT_BUTTON_OPEN_COURSE_MENU :
2004-01-26 20:56:58 +00:00
{
2005-06-07 09:42:57 +00:00
g_CourseMode . rows [ 0 ]. choices . clear ();
g_CourseMode . rows [ 0 ]. choices . push_back ( "OFF" );
g_CourseMode . rows [ 0 ]. iDefaultChoice = 0 ;
2004-01-26 20:56:58 +00:00
2005-06-07 09:42:57 +00:00
vector < Course *> courses ;
SONGMAN -> GetAllCourses ( courses , false );
for ( unsigned i = 0 ; i < courses . size (); ++ i )
2004-01-26 20:56:58 +00:00
{
2005-06-07 09:42:57 +00:00
const Course * crs = courses [ i ];
bool bUsesThisSong = false ;
2005-06-28 08:11:30 +00:00
for ( unsigned e = 0 ; e < crs -> m_vEntries . size (); ++ e )
2005-06-07 09:42:57 +00:00
{
2005-06-28 08:11:30 +00:00
if ( crs -> m_vEntries [ e ]. pSong != m_pSong )
2005-06-07 09:42:57 +00:00
continue ;
bUsesThisSong = true ;
}
if ( bUsesThisSong )
{
g_CourseMode . rows [ 0 ]. choices . push_back ( crs -> GetDisplayFullTitle () );
2005-07-30 19:34:23 +00:00
if ( crs == GAMESTATE -> m_pCurCourse )
2005-06-07 09:42:57 +00:00
g_CourseMode . rows [ 0 ]. iDefaultChoice = g_CourseMode . rows [ 0 ]. choices . size () - 1 ;
}
2004-01-26 20:56:58 +00:00
}
2006-01-30 06:59:15 +00:00
EditMiniMenu ( & g_CourseMode , SM_BackFromCourseModeMenu );
2004-01-26 20:56:58 +00:00
}
2005-08-30 18:09:00 +00:00
break ;
case EDIT_BUTTON_OPEN_COURSE_ATTACK_MENU :
{
Course * pCourse = GAMESTATE -> m_pCurCourse ;
2006-06-24 07:46:17 +00:00
if ( pCourse == NULL )
break ;
2005-08-30 18:09:00 +00:00
CourseEntry & ce = pCourse -> m_vEntries [ GAMESTATE -> m_iEditCourseEntryIndex ];
2006-03-14 08:41:16 +00:00
float fStartTime = m_pSong -> GetElapsedTimeFromBeat ( GAMESTATE -> m_fSongBeat );
int iAttack = FindAttackAtTime ( ce . attacks , fStartTime );
2005-08-30 18:09:00 +00:00
2006-03-14 08:41:16 +00:00
if ( iAttack >= 0 )
{
2006-03-14 08:51:12 +00:00
const RString sDuration = ssprintf ( "%.3f" , ce . attacks [ iAttack ]. fSecsRemaining );
2006-03-14 08:41:16 +00:00
g_InsertCourseAttack . rows [ remove ]. bEnabled = true ;
if ( g_InsertCourseAttack . rows [ duration ]. choices . size () == 9 )
g_InsertCourseAttack . rows [ duration ]. choices . push_back ( sDuration );
else
g_InsertCourseAttack . rows [ duration ]. choices . back () = sDuration ;
g_InsertCourseAttack . rows [ duration ]. iDefaultChoice = 9 ;
}
else
{
if ( g_InsertCourseAttack . rows [ duration ]. choices . size () == 10 )
g_InsertCourseAttack . rows [ duration ]. choices . pop_back ();
g_InsertCourseAttack . rows [ duration ]. iDefaultChoice = 3 ;
}
2005-08-30 18:09:00 +00:00
2006-01-30 06:59:15 +00:00
EditMiniMenu ( & g_InsertCourseAttack , SM_BackFromInsertCourseAttack );
2005-08-30 18:09:00 +00:00
}
break ;
2006-03-14 08:41:16 +00:00
case EDIT_BUTTON_ADD_COURSE_MODS :
{
float fStart , fEnd ;
PlayerOptions po ;
const Course * pCourse = GAMESTATE -> m_pCurCourse ;
2006-06-24 07:46:17 +00:00
if ( pCourse == NULL )
break ;
2006-03-14 08:41:16 +00:00
const CourseEntry & ce = pCourse -> m_vEntries [ GAMESTATE -> m_iEditCourseEntryIndex ];
if ( m_NoteFieldEdit . m_iBeginMarker == - 1 )
{
fStart = - 1 ;
fEnd = - 1 ;
po . FromString ( ce . sModifiers );
}
else
{
fStart = m_pSong -> GetElapsedTimeFromBeat ( NoteRowToBeat ( m_NoteFieldEdit . m_iBeginMarker ) );
int iAttack = FindAttackAtTime ( ce . attacks , fStart );
if ( iAttack >= 0 )
po . FromString ( ce . attacks [ iAttack ]. sModifiers );
if ( m_NoteFieldEdit . m_iEndMarker == - 1 )
fEnd = m_pSong -> m_fMusicLengthSeconds ;
else
fEnd = m_pSong -> GetElapsedTimeFromBeat ( NoteRowToBeat ( m_NoteFieldEdit . m_iEndMarker ) );
}
g_fLastInsertAttackPositionSeconds = fStart ;
g_fLastInsertAttackDurationSeconds = fEnd - fStart ;
GAMESTATE -> m_pPlayerState [ PLAYER_1 ] -> m_PlayerOptions = po ;
SCREENMAN -> AddNewScreenToTop ( "ScreenPlayerOptions" , SM_BackFromInsertCourseAttackPlayerOptions );
}
break ;
2005-06-07 09:42:57 +00:00
case EDIT_BUTTON_BAKE_RANDOM_FROM_SONG_GROUP :
case EDIT_BUTTON_BAKE_RANDOM_FROM_SONG_GROUP_AND_GENRE :
2005-06-05 01:27:15 +00:00
{
2005-06-07 09:42:57 +00:00
bool bTryGenre = EditB == EDIT_BUTTON_BAKE_RANDOM_FROM_SONG_GROUP_AND_GENRE ;
2006-01-22 01:00:06 +00:00
RString sName = GetOneBakedRandomFile ( m_pSong , bTryGenre );
2005-06-07 09:42:57 +00:00
if ( sName . empty () )
2005-06-05 01:27:15 +00:00
{
SCREENMAN -> PlayInvalidSound ();
2005-12-20 08:35:47 +00:00
SCREENMAN -> SystemMessage ( NO_BACKGROUNDS_AVAILABLE );
2005-06-05 01:27:15 +00:00
}
else
{
bool bAlreadyBGChangeHere = false ;
BackgroundLayer iLayer = BACKGROUND_LAYER_1 ;
BackgroundChange bgChange ;
bgChange . m_fStartBeat = GAMESTATE -> m_fSongBeat ;
2005-06-05 09:46:29 +00:00
FOREACH ( BackgroundChange , m_pSong -> GetBackgroundChanges ( iLayer ), bgc )
2005-06-05 01:27:15 +00:00
{
2005-06-05 09:46:29 +00:00
if ( bgc -> m_fStartBeat == GAMESTATE -> m_fSongBeat )
2005-06-05 01:27:15 +00:00
{
2005-06-05 09:46:29 +00:00
bAlreadyBGChangeHere = true ;
bgChange = * bgc ;
m_pSong -> GetBackgroundChanges ( iLayer ). erase ( bgc );
2005-06-07 09:42:57 +00:00
break ;
2005-06-05 01:27:15 +00:00
}
}
2005-06-07 09:42:57 +00:00
bgChange . m_def . m_sFile1 = sName ;
2005-06-05 01:27:15 +00:00
m_pSong -> AddBackgroundChange ( iLayer , bgChange );
m_soundMarker . Play ();
}
}
break ;
2005-01-14 23:17:04 +00:00
case EDIT_BUTTON_PLAY_FROM_START :
2005-03-20 06:41:56 +00:00
HandleMainMenuChoice ( play_whole_song );
2003-02-22 01:58:56 +00:00
break ;
2005-01-14 23:17:04 +00:00
case EDIT_BUTTON_PLAY_FROM_CURSOR :
2005-03-20 06:41:56 +00:00
HandleMainMenuChoice ( play_current_beat_to_end );
2003-04-21 03:09:48 +00:00
break ;
2005-01-14 23:17:04 +00:00
case EDIT_BUTTON_PLAY_SELECTION :
2006-03-14 22:07:56 +00:00
HandleMainMenuChoice ( play_selection );
2003-03-16 00:31:23 +00:00
break ;
2005-07-21 20:37:04 +00:00
case EDIT_BUTTON_RECORD_SELECTION :
2005-01-23 23:17:12 +00:00
if ( m_NoteFieldEdit . m_iBeginMarker !=- 1 && m_NoteFieldEdit . m_iEndMarker !=- 1 )
2006-03-14 22:07:56 +00:00
{
2005-03-20 06:41:56 +00:00
HandleAreaMenuChoice ( record );
2006-03-14 22:07:56 +00:00
}
2005-07-21 21:23:18 +00:00
else
{
if ( g_iDefaultRecordLength . Get () == - 1 )
2005-07-22 02:30:15 +00:00
{
m_iStartPlayingAt = BeatToNoteRow ( GAMESTATE -> m_fSongBeat );
2006-04-24 22:03:59 +00:00
m_iStopPlayingAt = max ( m_iStartPlayingAt , m_NoteDataEdit . GetLastRow () + 1 );
2005-07-22 02:30:15 +00:00
}
2005-07-21 21:23:18 +00:00
else
2005-07-22 02:30:15 +00:00
{
m_iStartPlayingAt = BeatToNoteRow ( ftruncf ( GAMESTATE -> m_fSongBeat , g_iDefaultRecordLength . Get ()) );
2005-07-21 21:23:18 +00:00
m_iStopPlayingAt = m_iStartPlayingAt + BeatToNoteRow ( g_iDefaultRecordLength . Get () );
2005-07-22 02:30:15 +00:00
}
2005-07-22 04:11:15 +00:00
2005-07-21 21:23:18 +00:00
if ( GAMESTATE -> m_pCurSteps [ 0 ] -> IsAnEdit () )
m_iStopPlayingAt = min ( m_iStopPlayingAt , BeatToNoteRow ( GetMaximumBeatForNewNote ()) );
2005-07-22 04:11:15 +00:00
if ( m_iStartPlayingAt >= m_iStopPlayingAt )
{
SCREENMAN -> PlayInvalidSound ();
return ;
}
2005-07-21 21:23:18 +00:00
TransitionEditState ( STATE_RECORDING );
}
2005-01-14 23:17:04 +00:00
break ;
2005-07-21 21:23:18 +00:00
case EDIT_BUTTON_RECORD_FROM_CURSOR :
m_iStartPlayingAt = BeatToNoteRow ( GAMESTATE -> m_fSongBeat );
2006-04-24 22:03:59 +00:00
m_iStopPlayingAt = max ( m_iStartPlayingAt , m_NoteDataEdit . GetLastRow () );
2005-07-21 21:23:18 +00:00
TransitionEditState ( STATE_RECORDING );
break ;
2005-01-14 23:17:04 +00:00
case EDIT_BUTTON_INSERT :
2005-03-20 06:41:56 +00:00
HandleAreaMenuChoice ( insert_and_shift );
2005-01-14 23:17:04 +00:00
SCREENMAN -> PlayInvalidSound ();
break ;
case EDIT_BUTTON_INSERT_SHIFT_PAUSES :
2005-03-20 06:41:56 +00:00
HandleAreaMenuChoice ( shift_pauses_forward );
2005-01-14 23:17:04 +00:00
SCREENMAN -> PlayInvalidSound ();
break ;
case EDIT_BUTTON_DELETE :
2005-03-20 06:41:56 +00:00
HandleAreaMenuChoice ( delete_and_shift );
2005-01-14 23:17:04 +00:00
SCREENMAN -> PlayInvalidSound ();
break ;
case EDIT_BUTTON_DELETE_SHIFT_PAUSES :
2005-03-20 06:41:56 +00:00
HandleAreaMenuChoice ( shift_pauses_backward );
2005-01-14 23:17:04 +00:00
SCREENMAN -> PlayInvalidSound ();
2003-03-16 00:31:23 +00:00
break ;
2005-05-17 07:24:25 +00:00
case EDIT_BUTTON_UNDO :
Undo ();
break ;
2002-05-20 08:59:37 +00:00
}
}
2005-09-05 02:26:50 +00:00
void ScreenEdit :: InputRecord ( const InputEventPlus & input , EditButton EditB )
2002-05-20 08:59:37 +00:00
{
2006-03-30 04:46:01 +00:00
if ( input . type == IET_FIRST_PRESS && EditB == EDIT_BUTTON_RETURN_TO_EDIT )
2002-05-20 08:59:37 +00:00
{
2005-04-14 06:34:17 +00:00
TransitionEditState ( STATE_EDITING );
2002-10-18 19:01:32 +00:00
return ;
}
2005-09-05 02:26:50 +00:00
if ( input . StyleI . player != PLAYER_1 )
2002-10-18 19:01:32 +00:00
return ; // ignore
2005-09-05 02:26:50 +00:00
const int iCol = input . StyleI . col ;
2002-10-18 19:01:32 +00:00
2005-09-05 02:26:50 +00:00
switch ( input . type )
2002-10-18 19:01:32 +00:00
{
2006-06-14 09:56:57 +00:00
DEFAULT_FAIL ( input . type );
2002-10-18 19:01:32 +00:00
case IET_FIRST_PRESS :
2002-05-20 08:59:37 +00:00
{
2005-07-30 07:07:11 +00:00
if ( EditIsBeingPressed ( EDIT_BUTTON_REMOVE_NOTE ) )
{
// Remove notes in Update.
break ;
}
2005-07-20 05:35:10 +00:00
// Add a tap
2002-10-18 19:01:32 +00:00
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-07-21 02:22:07 +00:00
// Don't add outside of the range.
if ( iRow < m_iStartPlayingAt || iRow >= m_iStopPlayingAt )
return ;
2005-04-07 19:38:01 +00:00
// Remove hold if any so that we don't have taps inside of a hold.
int iHeadRow ;
2005-07-22 00:14:24 +00:00
if ( m_NoteDataRecord . IsHoldNoteAtRow ( iCol , iRow , & iHeadRow ) )
2005-04-07 19:38:01 +00:00
m_NoteDataRecord . SetTapNote ( iCol , iHeadRow , TAP_EMPTY );
2005-07-20 05:45:16 +00:00
TapNote tn = TAP_ORIGINAL_TAP ;
if ( EditIsBeingPressed ( EDIT_BUTTON_LAY_MINE_OR_ROLL ) )
tn = TAP_ORIGINAL_MINE ;
m_NoteDataRecord . SetTapNote ( iCol , iRow , tn );
2005-10-09 04:30:59 +00:00
m_NoteFieldRecord . Step ( iCol , TNS_W1 );
2002-10-18 19:01:32 +00:00
}
break ;
case IET_SLOW_REPEAT :
case IET_FAST_REPEAT :
case IET_RELEASE :
2006-06-14 09:56:57 +00:00
case IET_LEVEL_CHANGED :
2005-07-20 05:35:10 +00:00
// don't add or extend holds here; we do it in Update()
2002-10-18 19:01:32 +00:00
break ;
2002-05-20 08:59:37 +00:00
}
}
2005-09-05 02:26:50 +00:00
void ScreenEdit :: InputRecordPaused ( const InputEventPlus & input , EditButton EditB )
2005-07-21 21:23:18 +00:00
{
2005-09-05 02:26:50 +00:00
if ( input . type != IET_FIRST_PRESS )
2005-07-21 21:23:18 +00:00
return ; // don't care
switch ( EditB )
{
case EDIT_BUTTON_UNDO :
/* We've already actually committed changes to m_NoteDataEdit, so all we have
* to do to undo is Undo() as usual, and copy the note data back in. */
Undo ();
m_NoteDataRecord . CopyAll ( m_NoteDataEdit );
break ;
case EDIT_BUTTON_PLAY_SELECTION :
TransitionEditState ( STATE_PLAYING );
break ;
case EDIT_BUTTON_RECORD_SELECTION :
TransitionEditState ( STATE_RECORDING );
break ;
case EDIT_BUTTON_RECORD_FROM_CURSOR :
if ( GAMESTATE -> m_pCurSteps [ 0 ] -> IsAnEdit () )
{
float fMaximumBeat = GetMaximumBeatForNewNote ();
if ( NoteRowToBeat ( m_iStopPlayingAt ) >= fMaximumBeat )
{
// We're already at the end.
SCREENMAN -> PlayInvalidSound ();
return ;
}
}
/* Pick up where we left off. */
{
int iSize = m_iStopPlayingAt - m_iStartPlayingAt ;
m_iStartPlayingAt = m_iStopPlayingAt ;
m_iStopPlayingAt += iSize ;
if ( GAMESTATE -> m_pCurSteps [ 0 ] -> IsAnEdit () )
m_iStopPlayingAt = min ( m_iStopPlayingAt , BeatToNoteRow ( GetMaximumBeatForNewNote ()) );
}
TransitionEditState ( STATE_RECORDING );
break ;
case EDIT_BUTTON_RETURN_TO_EDIT :
TransitionEditState ( STATE_EDITING );
break ;
}
}
2005-09-05 02:26:50 +00:00
void ScreenEdit :: InputPlay ( const InputEventPlus & input , EditButton EditB )
2002-05-20 08:59:37 +00:00
{
2005-09-05 02:26:50 +00:00
if ( input . type != IET_FIRST_PRESS )
2002-05-20 08:59:37 +00:00
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 :
2005-07-21 02:44:53 +00:00
/* When exiting play mode manually, leave the cursor where it is. */
m_fBeatToReturnTo = GAMESTATE -> m_fSongBeat ;
2005-04-14 06:34:17 +00:00
TransitionEditState ( STATE_EDITING );
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 :
{
2005-05-18 07:15:56 +00:00
PREFSMAN -> m_AutoPlay . Set ( PREFSMAN -> m_AutoPlay != PC_HUMAN ? PC_HUMAN : PC_AUTOPLAY );
2005-01-14 23:17:04 +00:00
FOREACH_HumanPlayer ( p )
2005-05-18 07:15:56 +00:00
GAMESTATE -> m_pPlayerState [ p ] -> m_PlayerController = PREFSMAN -> m_AutoPlay ;
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 )
{
2006-06-14 09:56:57 +00:00
DEFAULT_FAIL ( EditB );
2005-01-14 23:17:04 +00:00
case EDIT_BUTTON_OFFSET_DOWN : fOffsetDelta = - 0.020f ; break ;
case EDIT_BUTTON_OFFSET_UP : fOffsetDelta = + 0.020f ; break ;
}
if ( EditIsBeingPressed ( EDIT_BUTTON_ADJUST_FINE ) )
{
2005-09-05 02:26:50 +00:00
fOffsetDelta /= 20 ; /* 1ms */
}
else
{
switch ( input . type )
{
case IET_SLOW_REPEAT : fOffsetDelta *= 10 ; break ;
case IET_FAST_REPEAT : fOffsetDelta *= 40 ; break ;
}
2005-01-14 23:17:04 +00:00
}
m_pSong -> m_Timing . m_fBeat0OffsetInSeconds += fOffsetDelta ;
}
break ;
2002-05-20 08:59:37 +00:00
}
2005-09-05 02:26:50 +00:00
switch ( input . StyleI . player )
2002-05-20 08:59:37 +00:00
{
2003-07-13 00:34:30 +00:00
case PLAYER_1 :
2005-05-18 07:15:56 +00:00
if ( PREFSMAN -> m_AutoPlay == PC_HUMAN )
2005-09-05 02:26:50 +00:00
m_Player . Step ( input . StyleI . col , input . DeviceI . ts );
2003-07-13 00:34:30 +00:00
break ;
2002-05-20 08:59:37 +00:00
}
}
2005-04-14 06:34:17 +00:00
void ScreenEdit :: TransitionEditState ( EditState em )
2002-05-20 08:59:37 +00:00
{
2005-04-14 06:34:17 +00:00
EditState old = m_EditState ;
2005-03-18 18:58:22 +00:00
2005-07-21 21:23:18 +00:00
// If we're going from recording to paused, come back when we're done.
if ( old == STATE_RECORDING_PAUSED && em == STATE_PLAYING )
m_bReturnToRecordMenuAfterPlay = true ;
2006-04-04 21:58:20 +00:00
const bool bStateChanging = em != old ;
2006-02-02 01:24:17 +00:00
#if 0
2005-07-21 21:23:18 +00:00
//
// If switching out of record, open the menu.
//
{
bool bGoToRecordMenu = (old == STATE_RECORDING);
if( m_bReturnToRecordMenuAfterPlay && old == STATE_PLAYING )
{
bGoToRecordMenu = true;
m_bReturnToRecordMenuAfterPlay = false;
}
if( bGoToRecordMenu )
em = STATE_RECORDING_PAUSED;
}
2006-02-02 01:24:17 +00:00
#endif
2005-07-21 21:23:18 +00:00
2005-07-21 06:25:29 +00:00
/* If we're playing music, sample music or assist ticks when changing modes, stop. */
2005-07-22 23:07:49 +00:00
SOUND -> StopMusic ();
2005-07-21 06:25:29 +00:00
m_soundMusic . StopPlaying ();
m_soundAssistTick . StopPlaying ();
2005-10-10 04:36:04 +00:00
GAMESTATE -> m_bGameplayLeadIn . Set ( true );
2005-07-20 05:02:56 +00:00
2006-04-04 21:58:20 +00:00
if ( bStateChanging )
2005-05-19 23:29:39 +00:00
{
2006-04-04 21:58:20 +00:00
switch ( old )
{
case STATE_EDITING :
// If exiting EDIT mode, save the cursor position.
m_fBeatToReturnTo = GAMESTATE -> m_fSongBeat ;
break ;
2005-07-21 06:48:56 +00:00
2006-04-04 21:58:20 +00:00
case STATE_PLAYING :
if ( AdjustSync :: IsSyncDataChanged () )
ScreenSaveSync :: PromptSaveSync ();
break ;
2005-07-21 06:50:39 +00:00
2006-04-04 21:58:20 +00:00
case STATE_RECORDING :
SaveUndo ();
2005-07-21 06:50:39 +00:00
2006-04-04 21:58:20 +00:00
// delete old TapNotes in the range
m_NoteDataEdit . ClearRange ( m_iStartPlayingAt , m_iStopPlayingAt );
m_NoteDataEdit . CopyRange ( m_NoteDataRecord , m_iStartPlayingAt , m_iStopPlayingAt , m_iStartPlayingAt );
m_NoteDataRecord . ClearAll ();
2005-07-21 06:50:39 +00:00
2006-04-04 21:58:20 +00:00
CheckNumberOfNotesAndUndo ();
break ;
}
2005-05-19 23:29:39 +00:00
}
2006-02-01 05:49:55 +00:00
//
2006-02-01 05:47:50 +00:00
// Set up player options for this mode. (EDITING uses m_PlayerStateEdit, which we
// don't need to change.)
2006-02-01 05:49:55 +00:00
//
2006-02-01 05:47:50 +00:00
if ( em != STATE_EDITING )
{
// Stop displaying course attacks, if any.
GAMESTATE -> m_pPlayerState [ PLAYER_1 ] -> RemoveActiveAttacks ();
// Load the player's default PlayerOptions.
GAMESTATE -> m_pPlayerState [ PLAYER_1 ] -> RebuildPlayerOptionsFromActiveAttacks ();
switch ( em )
{
case STATE_RECORDING :
case STATE_RECORDING_PAUSED :
GAMESTATE -> m_pPlayerState [ PLAYER_1 ] -> m_PlayerOptions . m_fScrolls [ PlayerOptions :: SCROLL_CENTERED ] = 1.0f ;
break ;
}
/* Snap to current options. */
GAMESTATE -> m_pPlayerState [ PLAYER_1 ] -> m_CurrentPlayerOptions = GAMESTATE -> m_pPlayerState [ PLAYER_1 ] -> m_PlayerOptions ;
}
2005-03-18 19:44:01 +00:00
switch ( em )
{
2006-06-14 09:56:57 +00:00
DEFAULT_FAIL ( em );
2005-04-14 06:34:17 +00:00
case STATE_EDITING :
2005-03-18 19:44:01 +00:00
/* Important: people will stop playing, change the BG and start again; make sure we reload */
m_Background . Unload ();
m_Foreground . Unload ();
2004-01-26 20:56:58 +00:00
2005-07-21 02:44:53 +00:00
/* Restore the cursor position. */
GAMESTATE -> m_fSongBeat = m_fBeatToReturnTo ;
2005-03-18 19:44:01 +00:00
/* Make sure we're snapped. */
GAMESTATE -> m_fSongBeat = Quantize ( GAMESTATE -> m_fSongBeat , NoteTypeToBeat ( m_SnapDisplay . GetNoteType ()) );
2002-05-20 08:59:37 +00:00
2005-03-18 19:44:01 +00:00
/* Playing and recording have lead-ins, which may start before beat 0;
2005-07-21 06:50:39 +00:00
* make sure we don't stay there if we escaped out early. */
2005-03-18 19:44:01 +00:00
GAMESTATE -> m_fSongBeat = max ( GAMESTATE -> m_fSongBeat , 0 );
2002-05-20 08:59:37 +00:00
2005-03-18 19:44:01 +00:00
break ;
2005-07-21 20:41:26 +00:00
2005-04-14 06:34:17 +00:00
case STATE_PLAYING :
2005-07-21 20:41:26 +00:00
case STATE_RECORDING :
2005-07-21 20:42:56 +00:00
{
2006-04-04 21:58:20 +00:00
if ( bStateChanging )
AdjustSync :: ResetOriginalSyncData ();
2005-03-18 19:44:01 +00:00
2006-02-01 05:00:51 +00:00
/* Give a 1 second lead-in. If we're loading Player, this must be done first. */
2005-07-20 05:26:27 +00:00
float fSeconds = m_pSong -> m_Timing . GetElapsedTimeFromBeat ( NoteRowToBeat ( m_iStartPlayingAt ) ) - 1 ;
GAMESTATE -> UpdateSongPosition ( fSeconds , m_pSong -> m_Timing );
2005-07-20 22:19:14 +00:00
2005-10-10 04:36:04 +00:00
GAMESTATE -> m_bGameplayLeadIn . Set ( false );
2005-07-20 22:19:14 +00:00
/* Reset the note skin, in case preferences have changed. */
2006-01-13 05:55:45 +00:00
// XXX
// GAMESTATE->ResetNoteSkins();
2006-01-30 06:59:15 +00:00
//GAMESTATE->res
2005-07-20 22:19:14 +00:00
2005-07-20 05:26:27 +00:00
break ;
2005-07-21 20:42:56 +00:00
}
2005-07-21 21:23:18 +00:00
case STATE_RECORDING_PAUSED :
break ;
2005-07-20 05:26:27 +00:00
}
2005-07-20 05:07:07 +00:00
switch ( em )
{
case STATE_PLAYING :
2006-03-28 21:28:56 +00:00
GAMESTATE -> RestoreSelectedOptions ();
GAMESTATE -> StoreStageOptions ();
2005-07-20 05:07:07 +00:00
/* If we're in course display mode, set that up. */
SetupCourseAttacks ();
m_Player . Load ( m_NoteDataEdit );
GAMESTATE -> m_pPlayerState [ PLAYER_1 ] -> m_PlayerController = PREFSMAN -> m_AutoPlay ;
2005-12-19 00:26:43 +00:00
if ( g_bEditorShowBGChangesPlay )
2005-07-20 05:07:07 +00:00
{
/* FirstBeat affects backgrounds, so commit changes to memory (not to disk)
* and recalc it. */
Steps * pSteps = GAMESTATE -> m_pCurSteps [ PLAYER_1 ];
ASSERT ( pSteps );
pSteps -> SetNoteData ( m_NoteDataEdit );
m_pSong -> ReCalculateRadarValuesAndLastBeat ();
m_Background . Unload ();
m_Background . LoadFromSong ( m_pSong );
m_Foreground . Unload ();
m_Foreground . LoadFromSong ( m_pSong );
}
break ;
case STATE_RECORDING :
2005-07-21 21:23:18 +00:00
case STATE_RECORDING_PAUSED :
2005-07-20 05:07:07 +00:00
// initialize m_NoteFieldRecord
m_NoteDataRecord . CopyAll ( m_NoteDataEdit );
2005-07-21 01:22:10 +00:00
// highlight the section being recorded
m_NoteFieldRecord . m_iBeginMarker = m_iStartPlayingAt ;
m_NoteFieldRecord . m_iEndMarker = m_iStopPlayingAt ;
2005-07-20 05:07:07 +00:00
break ;
}
2005-07-20 22:22:43 +00:00
//
// Show/hide depending on em
//
2005-07-22 05:02:04 +00:00
m_sprOverlay -> PlayCommand ( EditStateToString ( em ) );
m_sprUnderlay -> PlayCommand ( EditStateToString ( em ) );
2005-12-19 00:26:43 +00:00
m_Background . SetHidden ( ! g_bEditorShowBGChangesPlay || em == STATE_EDITING );
2005-07-20 22:22:43 +00:00
m_autoHeader -> SetHidden ( em != STATE_EDITING );
m_textInputTips . SetHidden ( em != STATE_EDITING );
m_textInfo . SetHidden ( em != STATE_EDITING );
// Play the OnCommands again so that these will be re-hidden if the OnCommand hides them.
if ( em == STATE_EDITING )
{
m_textInputTips . PlayCommand ( "On" );
m_textInfo . PlayCommand ( "On" );
}
m_textPlayRecordHelp . SetHidden ( em == STATE_EDITING );
m_SnapDisplay . SetHidden ( em != STATE_EDITING );
m_NoteFieldEdit . SetHidden ( em != STATE_EDITING );
2005-07-21 21:23:18 +00:00
m_NoteFieldRecord . SetHidden ( em != STATE_RECORDING && em != STATE_RECORDING_PAUSED );
2005-07-20 22:22:43 +00:00
m_Player . SetHidden ( em != STATE_PLAYING );
2005-12-19 00:26:43 +00:00
m_Foreground . SetHidden ( ! g_bEditorShowBGChangesPlay || em == STATE_EDITING );
2005-07-20 22:22:43 +00:00
2005-07-20 05:07:07 +00:00
switch ( em )
{
case STATE_PLAYING :
case STATE_RECORDING :
const float fStartSeconds = m_pSong -> GetElapsedTimeFromBeat ( GAMESTATE -> m_fSongBeat );
LOG -> Trace ( "Starting playback at %f" , fStartSeconds );
RageSoundParams p ;
p . SetPlaybackRate ( GAMESTATE -> m_SongOptions . m_fMusicRate );
p . m_StartSecond = fStartSeconds ;
2005-09-23 00:12:32 +00:00
p . m_bAccurateSync = true ;
2005-07-20 05:07:07 +00:00
p . StopMode = RageSoundParams :: M_CONTINUE ;
m_soundMusic . Play ( & p );
break ;
}
2005-03-18 19:44:01 +00:00
2005-04-14 06:34:17 +00:00
m_EditState = em ;
2002-05-20 08:59:37 +00:00
}
2005-07-21 22:31:09 +00:00
void ScreenEdit :: ScrollTo ( float fDestinationBeat )
{
2005-07-22 01:28:20 +00:00
CLAMP ( fDestinationBeat , 0 , GetMaximumBeatForMoving () );
2005-07-21 22:31:09 +00:00
// Don't play the sound and do the hold note logic below if our position didn't change.
const float fOriginalBeat = GAMESTATE -> m_fSongBeat ;
if ( fOriginalBeat == fDestinationBeat )
return ;
GAMESTATE -> m_fSongBeat = fDestinationBeat ;
// check to see if they're holding a button
for ( int n = 0 ; n < NUM_EDIT_BUTTON_COLUMNS ; n ++ )
{
int iCol = n ;
// Ctrl + number = input to right half
if ( EditIsBeingPressed ( EDIT_BUTTON_RIGHT_SIDE ) )
ShiftToRightSide ( iCol , m_NoteDataEdit . GetNumTracks () );
if ( iCol >= m_NoteDataEdit . GetNumTracks () )
continue ; // skip
EditButton b = EditButton ( EDIT_BUTTON_COLUMN_0 + n );
if ( ! EditIsBeingPressed ( b ) )
continue ;
// create a new hold note
int iStartRow = BeatToNoteRow ( min ( fOriginalBeat , fDestinationBeat ) );
int iEndRow = BeatToNoteRow ( max ( fOriginalBeat , fDestinationBeat ) );
// Don't SaveUndo. We want to undo the whole hold, not just the last segment
// that the user made. Dragging the hold bigger can only absorb and remove
// other taps, so dragging won't cause us to exceed the note limit.
if ( EditIsBeingPressed ( EDIT_BUTTON_LAY_MINE_OR_ROLL ) )
m_NoteDataEdit . AddHoldNote ( iCol , iStartRow , iEndRow , TAP_ORIGINAL_ROLL_HEAD );
else
m_NoteDataEdit . AddHoldNote ( iCol , iStartRow , iEndRow , TAP_ORIGINAL_HOLD_HEAD );
}
if ( EditIsBeingPressed ( EDIT_BUTTON_SCROLL_SELECT ) )
{
/* Shift is being held.
2006-03-07 02:43:09 +00:00
*
* If this is the first time we've moved since shift was depressed,
* the old position (before this move) becomes the start pos: */
2005-07-21 22:31:09 +00:00
int iDestinationRow = BeatToNoteRow ( fDestinationBeat );
if ( m_iShiftAnchor == - 1 )
m_iShiftAnchor = BeatToNoteRow ( fOriginalBeat );
if ( iDestinationRow == m_iShiftAnchor )
{
/* We're back at the anchor, so we have nothing selected. */
m_NoteFieldEdit . m_iBeginMarker = m_NoteFieldEdit . m_iEndMarker = - 1 ;
}
else
{
m_NoteFieldEdit . m_iBeginMarker = m_iShiftAnchor ;
m_NoteFieldEdit . m_iEndMarker = iDestinationRow ;
if ( m_NoteFieldEdit . m_iBeginMarker > m_NoteFieldEdit . m_iEndMarker )
swap ( m_NoteFieldEdit . m_iBeginMarker , m_NoteFieldEdit . m_iEndMarker );
}
}
m_soundChangeLine . Play ();
}
2005-12-29 03:27:21 +00:00
static LocalizedString SAVE_SUCCESSFUL ( "ScreenEdit" , "Save successful." );
2002-05-20 08:59:37 +00:00
void ScreenEdit :: HandleScreenMessage ( const ScreenMessage SM )
{
2005-04-01 08:34:23 +00:00
if ( SM != SM_UpdateTextInfo )
m_bTextInfoNeedsUpdate = true ;
2005-03-30 01:06:13 +00:00
2005-04-01 08:34:23 +00:00
if ( SM == SM_UpdateTextInfo )
{
UpdateTextInfo ();
2005-04-02 01:44:04 +00:00
this -> PostScreenMessage ( SM_UpdateTextInfo , 0.1f );
2005-04-01 08:34:23 +00:00
}
else if ( SM == SM_GoToNextScreen )
2002-05-20 08:59:37 +00:00
{
2005-12-06 23:44:01 +00:00
GAMESTATE -> m_EditMode = EditMode_INVALID ;
2005-03-23 08:48:38 +00:00
}
else if ( SM == SM_BackFromMainMenu )
{
2005-03-20 06:41:56 +00:00
HandleMainMenuChoice ( ( MainMenuChoice ) ScreenMiniMenu :: s_iLastRowCode , ScreenMiniMenu :: s_viLastAnswers );
2005-03-23 08:48:38 +00:00
}
else if ( SM == SM_BackFromAreaMenu )
{
2005-03-20 06:41:56 +00:00
HandleAreaMenuChoice ( ( AreaMenuChoice ) ScreenMiniMenu :: s_iLastRowCode , ScreenMiniMenu :: s_viLastAnswers );
2005-03-23 08:48:38 +00:00
}
else if ( SM == SM_BackFromStepsInformation )
{
2005-03-20 20:13:27 +00:00
HandleStepsInformationChoice ( ( StepsInformationChoice ) ScreenMiniMenu :: s_iLastRowCode , ScreenMiniMenu :: s_viLastAnswers );
2005-03-23 08:48:38 +00:00
}
else if ( SM == SM_BackFromSongInformation )
{
2005-03-20 20:13:27 +00:00
HandleSongInformationChoice ( ( SongInformationChoice ) ScreenMiniMenu :: s_iLastRowCode , ScreenMiniMenu :: s_viLastAnswers );
2005-03-23 08:48:38 +00:00
}
else if ( SM == SM_BackFromBPMChange )
{
2006-06-12 06:42:25 +00:00
float fBPM = StringToFloat ( ScreenTextEntry :: s_sLastAnswer );
2005-03-23 08:48:38 +00:00
if ( fBPM > 0 )
m_pSong -> SetBPMAtBeat ( GAMESTATE -> m_fSongBeat , fBPM );
}
else if ( SM == SM_BackFromStopChange )
{
2006-06-12 06:42:25 +00:00
float fStop = StringToFloat ( ScreenTextEntry :: s_sLastAnswer );
2005-03-23 08:48:38 +00:00
if ( fStop >= 0 )
m_pSong -> m_Timing . SetStopAtBeat ( GAMESTATE -> m_fSongBeat , fStop );
}
else if ( SM == SM_BackFromBGChange )
{
2005-03-20 06:41:56 +00:00
HandleBGChangeChoice ( ( BGChangeChoice ) ScreenMiniMenu :: s_iLastRowCode , ScreenMiniMenu :: s_viLastAnswers );
2005-03-23 08:48:38 +00:00
}
else if ( SM == SM_BackFromCourseModeMenu )
2004-01-26 20:56:58 +00:00
{
2005-03-20 06:41:56 +00:00
const int num = ScreenMiniMenu :: s_viLastAnswers [ 0 ];
2005-07-30 19:34:23 +00:00
GAMESTATE -> m_pCurCourse . Set ( NULL );
2004-01-26 20:56:58 +00:00
if ( num != 0 )
{
2006-01-22 01:00:06 +00:00
const RString name = g_CourseMode . rows [ 0 ]. choices [ num ];
2005-07-30 19:34:23 +00:00
Course * pCourse = SONGMAN -> FindCourse ( name );
GAMESTATE -> m_pCurCourse . Set ( pCourse );
ASSERT ( GAMESTATE -> m_pCurCourse );
2004-01-26 20:56:58 +00:00
}
}
2005-07-20 00:30:19 +00:00
else if ( SM == SM_BackFromOptions )
2005-03-23 08:48:38 +00:00
{
2006-02-01 05:49:55 +00:00
// Store the new options, so they stick when we RebuildPlayerOptionsFromActiveAttacks.
GAMESTATE -> StoreSelectedOptions ();
2004-08-18 22:39:56 +00:00
2006-02-01 06:22:35 +00:00
// The options may have changed the note skin.
m_NoteFieldRecord . CacheAllUsedNoteSkins ();
m_Player . CacheAllUsedNoteSkins ();
2004-08-18 22:39:56 +00:00
// stop any music that screen may have been playing
SOUND -> StopMusic ();
2005-03-23 08:48:38 +00:00
}
2005-08-30 18:09:00 +00:00
else if ( SM == SM_BackFromInsertTapAttack )
2005-03-23 08:48:38 +00:00
{
int iDurationChoice = ScreenMiniMenu :: s_viLastAnswers [ 0 ];
2006-06-12 06:42:25 +00:00
g_fLastInsertAttackDurationSeconds = StringToFloat ( g_InsertTapAttack . rows [ 0 ]. choices [ iDurationChoice ] );
2004-08-18 22:39:56 +00:00
2005-08-30 18:09:00 +00:00
SCREENMAN -> AddNewScreenToTop ( "ScreenPlayerOptions" , SM_BackFromInsertTapAttackPlayerOptions );
2005-03-23 08:48:38 +00:00
}
2005-08-30 18:09:00 +00:00
else if ( SM == SM_BackFromInsertTapAttackPlayerOptions )
2005-03-23 08:48:38 +00:00
{
PlayerOptions poChosen = GAMESTATE -> m_pPlayerState [ PLAYER_1 ] -> m_PlayerOptions ;
2006-01-22 01:00:06 +00:00
RString sMods = poChosen . GetString ();
2005-03-23 08:48:38 +00:00
const int row = BeatToNoteRow ( GAMESTATE -> m_fSongBeat );
TapNote tn (
2005-04-18 01:23:57 +00:00
TapNote :: attack ,
2005-04-20 01:53:41 +00:00
TapNote :: SubType_invalid ,
2005-04-18 01:23:57 +00:00
TapNote :: original ,
2005-03-23 08:48:38 +00:00
sMods ,
g_fLastInsertAttackDurationSeconds ,
false ,
0 );
2005-03-23 10:43:57 +00:00
SaveUndo ();
2005-08-30 18:09:00 +00:00
m_NoteDataEdit . SetTapNote ( g_iLastInsertTapAttackTrack , row , tn );
2005-03-23 10:43:57 +00:00
CheckNumberOfNotesAndUndo ();
2005-03-23 08:48:38 +00:00
}
2005-08-30 18:09:00 +00:00
else if ( SM == SM_BackFromInsertCourseAttack )
{
int iDurationChoice = ScreenMiniMenu :: s_viLastAnswers [ 0 ];
2006-03-14 08:41:16 +00:00
Course * pCourse = GAMESTATE -> m_pCurCourse ;
CourseEntry & ce = pCourse -> m_vEntries [ GAMESTATE -> m_iEditCourseEntryIndex ];
int iAttack ;
g_fLastInsertAttackPositionSeconds = m_pSong -> GetElapsedTimeFromBeat ( GAMESTATE -> m_fSongBeat );
2006-06-12 06:42:25 +00:00
g_fLastInsertAttackDurationSeconds = StringToFloat ( g_InsertCourseAttack . rows [ 0 ]. choices [ iDurationChoice ] );
2006-03-14 08:41:16 +00:00
iAttack = FindAttackAtTime ( ce . attacks , g_fLastInsertAttackPositionSeconds );
2005-08-30 18:09:00 +00:00
if ( ScreenMiniMenu :: s_iLastRowCode == ScreenEdit :: remove )
{
2006-03-14 08:41:16 +00:00
ASSERT ( iAttack >= 0 );
ce . attacks . erase ( ce . attacks . begin () + iAttack );
2005-08-30 18:09:00 +00:00
}
else
{
2006-03-14 08:41:16 +00:00
PlayerOptions po ;
if ( iAttack >= 0 )
po . FromString ( ce . attacks [ iAttack ]. sModifiers );
GAMESTATE -> m_pPlayerState [ PLAYER_1 ] -> m_PlayerOptions = po ;
2005-08-30 18:09:00 +00:00
SCREENMAN -> AddNewScreenToTop ( "ScreenPlayerOptions" , SM_BackFromInsertCourseAttackPlayerOptions );
}
}
else if ( SM == SM_BackFromInsertCourseAttackPlayerOptions )
{
PlayerOptions poChosen = GAMESTATE -> m_pPlayerState [ PLAYER_1 ] -> m_PlayerOptions ;
2006-01-22 01:00:06 +00:00
RString sMods = poChosen . GetString ();
2005-08-30 18:09:00 +00:00
Course * pCourse = GAMESTATE -> m_pCurCourse ;
CourseEntry & ce = pCourse -> m_vEntries [ GAMESTATE -> m_iEditCourseEntryIndex ];
2006-03-14 08:41:16 +00:00
if ( g_fLastInsertAttackPositionSeconds < 0 )
{
ce . sModifiers = sMods ;
}
else
{
Attack a (
ATTACK_LEVEL_1 ,
g_fLastInsertAttackPositionSeconds ,
g_fLastInsertAttackDurationSeconds ,
sMods ,
false ,
false );
int iAttack = FindAttackAtTime ( ce . attacks , g_fLastInsertAttackPositionSeconds );
if ( iAttack >= 0 )
ce . attacks [ iAttack ] = a ;
else
ce . attacks . push_back ( a );
}
2005-08-30 18:09:00 +00:00
}
2005-03-23 08:48:38 +00:00
else if ( SM == SM_DoRevertToLastSave )
{
2005-03-08 21:19:17 +00:00
if ( ScreenPrompt :: s_LastAnswer == ANSWER_YES )
2004-01-24 20:36:09 +00:00
{
2005-07-20 06:47:30 +00:00
SaveUndo ();
2005-03-08 21:19:17 +00:00
CopyFromLastSave ();
m_pSteps -> GetNoteData ( m_NoteDataEdit );
2004-01-24 20:36:09 +00:00
}
2005-03-23 08:48:38 +00:00
}
2005-05-18 03:31:36 +00:00
else if ( SM == SM_DoRevertFromDisk )
{
if ( ScreenPrompt :: s_LastAnswer == ANSWER_YES )
{
2005-07-20 06:47:30 +00:00
SaveUndo ();
2005-05-18 03:31:36 +00:00
RevertFromDisk ();
m_pSteps -> GetNoteData ( m_NoteDataEdit );
}
}
2005-03-23 08:48:38 +00:00
else if ( SM == SM_DoSaveAndExit ) // just asked "save before exiting? yes, no, cancel"
{
2005-03-14 04:43:25 +00:00
switch ( ScreenPrompt :: s_LastAnswer )
{
2006-06-14 09:56:57 +00:00
DEFAULT_FAIL ( ScreenPrompt :: s_LastAnswer );
2005-03-14 04:43:25 +00:00
case ANSWER_YES :
2005-12-29 03:27:21 +00:00
// This will send SM_SaveSuccessful or SM_SaveFailed.
2005-03-20 06:41:56 +00:00
HandleMainMenuChoice ( ScreenEdit :: save_on_exit );
2005-03-14 04:43:25 +00:00
return ;
case ANSWER_NO :
/* Don't save; just exit. */
SCREENMAN -> SendMessageToTopScreen ( SM_DoExit );
return ;
case ANSWER_CANCEL :
break ; // do nothing
}
2005-03-23 08:48:38 +00:00
}
2005-12-29 03:27:21 +00:00
else if ( SM == SM_SaveSuccessful )
2005-03-23 08:48:38 +00:00
{
2005-03-14 04:43:25 +00:00
LOG -> Trace ( "Save successful." );
m_pSteps -> SetSavedToDisk ( true );
CopyToLastSave ();
if ( m_CurrentAction == save_on_exit )
2005-12-29 03:27:21 +00:00
ScreenPrompt :: Prompt ( SM_DoExit , SAVE_SUCCESSFUL );
else
SCREENMAN -> SystemMessage ( SAVE_SUCCESSFUL );
2005-03-23 08:48:38 +00:00
}
2005-12-29 03:27:21 +00:00
else if ( SM == SM_SaveFailed ) // save failed ; stay in the editor
2005-03-23 08:48:38 +00:00
{
2005-03-14 04:43:25 +00:00
/* We committed the steps to SongManager. Revert to the last save, and
* recommit the reversion to SongManager. */
LOG -> Trace ( "Save failed. Changes uncommitted from memory." );
CopyFromLastSave ();
m_pSteps -> SetNoteData ( m_NoteDataEdit );
2005-03-23 08:48:38 +00:00
}
else if ( SM == SM_DoExit )
{
2005-07-20 02:40:20 +00:00
// IMPORTANT: CopyFromLastSave before deleting the Steps below
2005-03-23 08:48:38 +00:00
CopyFromLastSave ();
2005-03-14 04:43:25 +00:00
2005-03-23 08:48:38 +00:00
// If these steps have never been saved, then we should delete them.
// If the user created them in the edit menu and never bothered
// to save them, then they aren't wanted.
Steps * pSteps = GAMESTATE -> m_pCurSteps [ PLAYER_1 ];
if ( ! pSteps -> GetSavedToDisk () )
2005-03-08 07:57:14 +00:00
{
2005-03-23 08:48:38 +00:00
Song * pSong = GAMESTATE -> m_pCurSong ;
2005-07-29 02:23:02 +00:00
pSong -> DeleteSteps ( pSteps );
2005-03-23 08:48:38 +00:00
m_pSteps = NULL ;
GAMESTATE -> m_pCurSteps [ PLAYER_1 ]. Set ( NULL );
2005-03-08 07:57:14 +00:00
}
2005-03-14 04:43:25 +00:00
m_Out . StartTransitioning ( SM_GoToNextScreen );
2005-03-23 08:48:38 +00:00
}
else if ( SM == SM_GainFocus )
{
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 ;
2005-03-23 08:48:38 +00:00
}
else if ( SM == SM_LoseFocus )
{
2004-01-26 23:08:46 +00:00
/* Snap the trailing beat, in case we lose focus while tweening. */
m_fTrailingBeat = GAMESTATE -> m_fSongBeat ;
2002-05-20 08:59:37 +00:00
}
2005-07-12 05:38:13 +00:00
ScreenWithMenuElements :: HandleScreenMessage ( SM );
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
2006-01-22 01:00:06 +00:00
static void ChangeDescription ( const RString & sNew )
2003-02-19 05:46:09 +00:00
{
2004-05-24 06:12:17 +00:00
Steps * pSteps = GAMESTATE -> m_pCurSteps [ PLAYER_1 ];
2005-12-22 03:08:29 +00:00
/* Don't erase edit descriptions. */
if ( sNew . empty () && pSteps -> GetDifficulty () == DIFFICULTY_EDIT )
return ;
2004-05-24 03:41:39 +00:00
pSteps -> SetDescription ( sNew );
2003-02-19 05:46:09 +00:00
}
2006-01-22 01:00:06 +00:00
static void ChangeMainTitle ( const RString & sNew )
2003-02-19 05:46:09 +00:00
{
Song * pSong = GAMESTATE -> m_pCurSong ;
pSong -> m_sMainTitle = sNew ;
}
2006-01-22 01:00:06 +00:00
static void ChangeSubTitle ( const RString & sNew )
2003-02-19 05:46:09 +00:00
{
Song * pSong = GAMESTATE -> m_pCurSong ;
pSong -> m_sSubTitle = sNew ;
}
2006-01-22 01:00:06 +00:00
static void ChangeArtist ( const RString & sNew )
2003-02-19 05:46:09 +00:00
{
Song * pSong = GAMESTATE -> m_pCurSong ;
pSong -> m_sArtist = sNew ;
}
2006-01-22 01:00:06 +00:00
static void ChangeCredit ( const RString & sNew )
2003-06-23 02:24:13 +00:00
{
Song * pSong = GAMESTATE -> m_pCurSong ;
pSong -> m_sCredit = sNew ;
}
2006-01-22 01:00:06 +00:00
static void ChangeMainTitleTranslit ( const RString & sNew )
2003-02-19 05:46:09 +00:00
{
Song * pSong = GAMESTATE -> m_pCurSong ;
pSong -> m_sMainTitleTranslit = sNew ;
}
2006-01-22 01:00:06 +00:00
static void ChangeSubTitleTranslit ( const RString & sNew )
2003-02-19 05:46:09 +00:00
{
Song * pSong = GAMESTATE -> m_pCurSong ;
pSong -> m_sSubTitleTranslit = sNew ;
}
2006-01-22 01:00:06 +00:00
static void ChangeArtistTranslit ( const RString & sNew )
2003-02-19 05:46:09 +00:00
{
Song * pSong = GAMESTATE -> m_pCurSong ;
pSong -> m_sArtistTranslit = sNew ;
}
// End helper functions
2006-03-07 20:43:40 +00:00
static LocalizedString REVERT_LAST_SAVE ( "ScreenEdit" , "Do you want to revert to your last save?" );
2005-12-20 21:32:26 +00:00
static LocalizedString DESTROY_ALL_UNSAVED_CHANGES ( "ScreenEdit" , "This will destroy all unsaved changes." );
2006-03-07 20:43:40 +00:00
static LocalizedString REVERT_FROM_DISK ( "ScreenEdit" , "Do you want to revert from disk?" );
2005-12-20 21:32:26 +00:00
static LocalizedString SAVE_CHANGES_BEFORE_EXITING ( "ScreenEdit" , "Do you want to save changes before exiting?" );
2006-03-07 20:43:40 +00:00
static LocalizedString ENTER_BPM_VALUE ( "ScreenEdit" , "Enter a new BPM value." );
static LocalizedString ENTER_STOP_VALUE ( "ScreenEdit" , "Enter a new Stop value." );
2005-03-20 06:41:56 +00:00
void ScreenEdit :: HandleMainMenuChoice ( MainMenuChoice c , const vector < int > & iAnswers )
2002-08-17 06:44:04 +00:00
{
2003-02-18 23:15:38 +00:00
switch ( c )
{
2006-06-14 09:56:57 +00:00
DEFAULT_FAIL ( c );
2006-03-07 20:43:40 +00:00
case play_selection :
2006-03-13 08:59:32 +00:00
if ( m_NoteFieldEdit . m_iBeginMarker !=- 1 && m_NoteFieldEdit . m_iEndMarker !=- 1 )
HandleAreaMenuChoice ( play );
2006-03-14 22:07:56 +00:00
else if ( m_NoteFieldEdit . m_iBeginMarker !=- 1 )
HandleMainMenuChoice ( play_selection_start_to_end );
2006-03-13 08:59:32 +00:00
else
HandleMainMenuChoice ( play_current_beat_to_end );
2006-03-13 09:03:02 +00:00
break ;
case play_whole_song :
{
m_iStartPlayingAt = 0 ;
m_iStopPlayingAt = m_NoteDataEdit . GetLastRow ();
2006-03-14 22:07:56 +00:00
TransitionEditState ( STATE_PLAYING );
}
break ;
case play_selection_start_to_end :
{
m_iStartPlayingAt = m_NoteFieldEdit . m_iBeginMarker ;
2006-04-24 22:03:59 +00:00
m_iStopPlayingAt = max ( m_iStartPlayingAt , m_NoteDataEdit . GetLastRow () );
2006-03-13 09:03:02 +00:00
TransitionEditState ( STATE_PLAYING );
}
break ;
case play_current_beat_to_end :
{
m_iStartPlayingAt = BeatToNoteRow ( GAMESTATE -> m_fSongBeat );
2006-04-24 22:03:59 +00:00
m_iStopPlayingAt = max ( m_iStartPlayingAt , m_NoteDataEdit . GetLastRow () );
2006-03-13 09:03:02 +00:00
TransitionEditState ( STATE_PLAYING );
}
2006-03-07 20:43:40 +00:00
break ;
case set_selection_start :
{
const int iCurrentRow = BeatToNoteRow ( GAMESTATE -> m_fSongBeat );
if ( m_NoteFieldEdit . m_iEndMarker !=- 1 && iCurrentRow >= m_NoteFieldEdit . m_iEndMarker )
{
SCREENMAN -> PlayInvalidSound ();
}
else
{
m_NoteFieldEdit . m_iBeginMarker = iCurrentRow ;
m_soundMarker . Play ();
}
}
break ;
case set_selection_end :
{
const int iCurrentRow = BeatToNoteRow ( GAMESTATE -> m_fSongBeat );
if ( m_NoteFieldEdit . m_iBeginMarker !=- 1 && iCurrentRow <= m_NoteFieldEdit . m_iBeginMarker )
{
SCREENMAN -> PlayInvalidSound ();
}
else
{
m_NoteFieldEdit . m_iEndMarker = iCurrentRow ;
m_soundMarker . Play ();
}
}
break ;
2005-03-20 20:13:27 +00:00
case edit_steps_information :
2003-02-18 23:15:38 +00:00
{
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 ();
2005-04-16 04:55:50 +00:00
g_StepsInformation . rows [ difficulty ]. choices . clear ();
FOREACH_Difficulty ( dc )
2006-01-07 04:11:29 +00:00
g_StepsInformation . rows [ difficulty ]. choices . push_back ( "|" + DifficultyToLocalizedString ( pSteps -> GetDifficulty ()) );
2005-03-20 20:13:27 +00:00
g_StepsInformation . rows [ difficulty ]. iDefaultChoice = pSteps -> GetDifficulty ();
2005-12-06 23:44:01 +00:00
g_StepsInformation . rows [ difficulty ]. bEnabled = ( EDIT_MODE . GetValue () >= EditMode_Full );
2005-03-20 20:13:27 +00:00
g_StepsInformation . rows [ meter ]. iDefaultChoice = clamp ( pSteps -> GetMeter () - 1 , 0 , MAX_METER + 1 );
2005-12-06 23:44:01 +00:00
g_StepsInformation . rows [ meter ]. bEnabled = ( EDIT_MODE . GetValue () >= EditMode_Home );
2005-12-29 04:19:22 +00:00
g_StepsInformation . rows [ predict_meter ]. SetOneUnthemedChoice ( ssprintf ( "%.2f" , pSteps -> PredictMeter ()) );
2005-12-06 23:44:01 +00:00
g_StepsInformation . rows [ description ]. bEnabled = ( EDIT_MODE . GetValue () >= EditMode_Full );
2005-12-29 04:19:22 +00:00
g_StepsInformation . rows [ description ]. SetOneUnthemedChoice ( pSteps -> GetDescription () );
g_StepsInformation . rows [ tap_notes ]. SetOneUnthemedChoice ( ssprintf ( "%d" , m_NoteDataEdit . GetNumTapNotes ()) );
g_StepsInformation . rows [ jumps ]. SetOneUnthemedChoice ( ssprintf ( "%d" , m_NoteDataEdit . GetNumJumps ()) );
g_StepsInformation . rows [ hands ]. SetOneUnthemedChoice ( ssprintf ( "%d" , m_NoteDataEdit . GetNumHands ()) );
g_StepsInformation . rows [ quads ]. SetOneUnthemedChoice ( ssprintf ( "%d" , m_NoteDataEdit . GetNumQuads ()) );
g_StepsInformation . rows [ holds ]. SetOneUnthemedChoice ( ssprintf ( "%d" , m_NoteDataEdit . GetNumHoldNotes ()) );
g_StepsInformation . rows [ mines ]. SetOneUnthemedChoice ( ssprintf ( "%d" , m_NoteDataEdit . GetNumMines ()) );
g_StepsInformation . rows [ stream ]. SetOneUnthemedChoice ( ssprintf ( "%.2f" , NoteDataUtil :: GetStreamRadarValue ( m_NoteDataEdit , fMusicSeconds )) );
g_StepsInformation . rows [ voltage ]. SetOneUnthemedChoice ( ssprintf ( "%.2f" , NoteDataUtil :: GetVoltageRadarValue ( m_NoteDataEdit , fMusicSeconds )) );
g_StepsInformation . rows [ air ]. SetOneUnthemedChoice ( ssprintf ( "%.2f" , NoteDataUtil :: GetAirRadarValue ( m_NoteDataEdit , fMusicSeconds )) );
g_StepsInformation . rows [ freeze ]. SetOneUnthemedChoice ( ssprintf ( "%.2f" , NoteDataUtil :: GetFreezeRadarValue ( m_NoteDataEdit , fMusicSeconds )) );
g_StepsInformation . rows [ chaos ]. SetOneUnthemedChoice ( ssprintf ( "%.2f" , NoteDataUtil :: GetChaosRadarValue ( m_NoteDataEdit , fMusicSeconds )) );
2006-01-30 06:59:15 +00:00
EditMiniMenu ( & g_StepsInformation , SM_BackFromStepsInformation , SM_None );
2003-02-18 23:15:38 +00:00
}
2003-03-16 00:05:23 +00:00
break ;
2003-02-18 23:15:38 +00:00
case save :
2005-03-08 09:03:12 +00:00
case save_on_exit :
2003-02-18 23:15:38 +00:00
{
2005-03-14 04:43:25 +00:00
m_CurrentAction = c ;
2003-08-03 00:13:55 +00:00
// copy edit into current Steps
2005-04-03 21:43:29 +00:00
Song * pSong = GAMESTATE -> m_pCurSong ;
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 );
2005-04-03 21:43:29 +00:00
pSteps -> CalculateRadarValues ( pSong -> m_fMusicLengthSeconds );
2005-03-08 21:19:17 +00:00
2005-04-19 04:11:33 +00:00
switch ( EDIT_MODE . GetValue () )
2005-03-08 07:57:14 +00:00
{
2006-06-14 09:56:57 +00:00
DEFAULT_FAIL ( EDIT_MODE . GetValue () );
2005-12-06 23:44:01 +00:00
case EditMode_Home :
2005-03-08 09:03:12 +00:00
{
2005-12-03 20:34:49 +00:00
ASSERT ( pSteps -> IsAnEdit () );
2005-12-06 20:40:09 +00:00
NotesWriterSM w ;
2006-03-08 22:05:23 +00:00
RString sError ;
if ( ! w . WriteEditFileToMachine ( pSong , pSteps , sError ) )
{
ScreenPrompt :: Prompt ( SM_None , sError );
2005-12-06 20:40:09 +00:00
break ;
2006-03-08 22:05:23 +00:00
}
2005-12-06 20:40:09 +00:00
2005-12-29 03:33:00 +00:00
// HACK: clear undo, so "exit" below knows we don't need to save.
// This only works because important non-steps data can't be changed in
// home mode (BPMs, stops).
2005-12-06 12:41:06 +00:00
ClearUndo ();
2005-12-03 20:34:49 +00:00
SCREENMAN -> ZeroNextUpdate ();
2005-12-29 03:27:21 +00:00
HandleScreenMessage ( SM_SaveSuccessful );
2005-12-29 02:59:23 +00:00
2005-12-06 12:41:06 +00:00
/* FIXME
2006-01-22 01:00:06 +00:00
RString s;
2005-04-14 06:34:17 +00:00
switch( c )
{
case save: s = "ScreenMemcardSaveEditsAfterSave"; break;
case save_on_exit: s = "ScreenMemcardSaveEditsAfterExit"; break;
default: ASSERT(0);
}
SCREENMAN->AddNewScreenToTop( s );
2005-12-03 20:34:49 +00:00
*/
2005-03-08 09:03:12 +00:00
}
2005-04-14 06:34:17 +00:00
break ;
2005-12-06 23:44:01 +00:00
case EditMode_Full :
2005-04-14 06:34:17 +00:00
{
2005-12-03 20:34:49 +00:00
pSong -> Save ();
2005-04-14 06:34:17 +00:00
SCREENMAN -> ZeroNextUpdate ();
2005-03-08 21:19:17 +00:00
2005-12-29 03:27:21 +00:00
HandleScreenMessage ( SM_SaveSuccessful );
2005-04-14 06:34:17 +00:00
}
break ;
2006-03-12 00:45:18 +00:00
case EditMode_CourseMods :
2005-12-06 23:44:01 +00:00
case EditMode_Practice :
2005-04-14 06:34:17 +00:00
break ;
2005-03-08 07:57:14 +00:00
}
2003-02-18 23:15:38 +00:00
2005-03-21 03:02:47 +00:00
m_soundSave . Play ();
2003-02-18 23:15:38 +00:00
}
break ;
2005-03-08 21:19:17 +00:00
case revert_to_last_save :
2005-12-20 21:32:26 +00:00
ScreenPrompt :: Prompt ( SM_DoRevertToLastSave , REVERT_LAST_SAVE . GetValue () + " \n\n " + DESTROY_ALL_UNSAVED_CHANGES . GetValue (), PROMPT_YES_NO , ANSWER_NO );
2004-01-24 20:36:09 +00:00
break ;
2005-05-18 03:31:36 +00:00
case revert_from_disk :
2005-12-20 21:32:26 +00:00
ScreenPrompt :: Prompt ( SM_DoRevertFromDisk , REVERT_FROM_DISK . GetValue () + " \n\n " + DESTROY_ALL_UNSAVED_CHANGES . GetValue (), PROMPT_YES_NO , ANSWER_NO );
2005-05-18 03:31:36 +00:00
break ;
2005-07-20 00:30:19 +00:00
case options :
2006-01-30 07:09:25 +00:00
SCREENMAN -> AddNewScreenToTop ( "ScreenEditOptions" , SM_BackFromOptions );
2003-02-18 23:15:38 +00:00
break ;
case edit_song_info :
2003-02-19 05:46:09 +00:00
{
2005-12-29 04:19:22 +00:00
const Song * pSong = GAMESTATE -> m_pCurSong ;
g_SongInformation . rows [ main_title ]. SetOneUnthemedChoice ( pSong -> m_sMainTitle );
g_SongInformation . rows [ sub_title ]. SetOneUnthemedChoice ( pSong -> m_sSubTitle );
g_SongInformation . rows [ artist ]. SetOneUnthemedChoice ( pSong -> m_sArtist );
g_SongInformation . rows [ credit ]. SetOneUnthemedChoice ( pSong -> m_sCredit );
g_SongInformation . rows [ main_title_transliteration ]. SetOneUnthemedChoice ( pSong -> m_sMainTitleTranslit );
g_SongInformation . rows [ sub_title_transliteration ]. SetOneUnthemedChoice ( pSong -> m_sSubTitleTranslit );
g_SongInformation . rows [ artist_transliteration ]. SetOneUnthemedChoice ( pSong -> m_sArtistTranslit );
2003-02-19 05:46:09 +00:00
2006-01-30 06:59:15 +00:00
EditMiniMenu ( & g_SongInformation , SM_BackFromSongInformation );
2003-02-19 05:46:09 +00:00
}
2003-02-18 23:15:38 +00:00
break ;
2005-01-08 07:41:26 +00:00
case edit_bpm :
2005-07-03 04:45:34 +00:00
ScreenTextEntry :: TextEntry (
2005-03-23 04:08:27 +00:00
SM_BackFromBPMChange ,
2005-12-21 12:55:20 +00:00
ENTER_BPM_VALUE ,
2005-03-23 04:08:27 +00:00
ssprintf ( "%.4f" , m_pSong -> GetBPMAtBeat ( GAMESTATE -> m_fSongBeat ) ),
10
);
2005-01-08 07:41:26 +00:00
break ;
case edit_stop :
2005-12-29 04:01:54 +00:00
ScreenTextEntry :: TextEntry (
SM_BackFromStopChange ,
ENTER_STOP_VALUE ,
ssprintf ( "%.4f" , m_pSong -> m_Timing . GetStopAtRow ( BeatToNoteRow ( GAMESTATE -> m_fSongBeat ) ) ),
10
);
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 :
2005-04-19 04:11:33 +00:00
switch ( EDIT_MODE . GetValue () )
2005-04-14 06:34:17 +00:00
{
2006-06-14 09:56:57 +00:00
DEFAULT_FAIL ( EDIT_MODE . GetValue () );
2005-12-06 23:44:01 +00:00
case EditMode_Full :
case EditMode_Home :
2005-12-06 12:41:06 +00:00
if ( m_bHasUndo )
2005-12-20 21:32:26 +00:00
ScreenPrompt :: Prompt ( SM_DoSaveAndExit , SAVE_CHANGES_BEFORE_EXITING , PROMPT_YES_NO_CANCEL , ANSWER_CANCEL );
2005-12-06 12:41:06 +00:00
else
SCREENMAN -> SendMessageToTopScreen ( SM_DoExit );
2005-04-14 06:34:17 +00:00
break ;
2005-12-06 23:44:01 +00:00
case EditMode_Practice :
2006-03-12 00:45:18 +00:00
case EditMode_CourseMods :
2005-04-14 06:34:17 +00:00
SCREENMAN -> SendMessageToTopScreen ( SM_DoExit );
break ;
}
2003-02-18 23:15:38 +00:00
break ;
};
2002-08-17 06:44:04 +00:00
}
2005-03-23 10:43:57 +00:00
void ScreenEdit :: HandleAreaMenuChoice ( AreaMenuChoice c , const vector < int > & iAnswers , bool bAllowUndo )
2002-08-17 06:44:04 +00:00
{
2005-03-23 10:43:57 +00:00
bool bSaveUndo = false ;
switch ( c )
{
2006-06-14 09:56:57 +00:00
DEFAULT_FAIL ( c );
2005-03-23 10:43:57 +00:00
case cut :
case copy :
case play :
case record :
case undo :
bSaveUndo = false ;
break ;
case paste_at_current_beat :
case paste_at_begin_marker :
case clear :
case quantize :
case turn :
case transform :
case alter :
case tempo :
case insert_and_shift :
case delete_and_shift :
case shift_pauses_forward :
case shift_pauses_backward :
2005-12-18 23:56:14 +00:00
case convert_to_pause :
2005-03-23 10:43:57 +00:00
case convert_pause_to_beat :
bSaveUndo = true ;
break ;
}
// We call HandleAreaMenuChoice recursively. Only the outermost HandleAreaMenuChoice
// should allow Undo so that the inner calls don't also save Undo and mess up the outermost
if ( ! bAllowUndo )
bSaveUndo = false ;
if ( bSaveUndo )
SaveUndo ();
2003-02-18 23:15:38 +00:00
switch ( c )
{
2006-06-14 09:56:57 +00:00
DEFAULT_FAIL ( c );
2003-02-18 23:15:38 +00:00
case cut :
{
2005-03-20 06:41:56 +00:00
HandleAreaMenuChoice ( copy );
HandleAreaMenuChoice ( clear );
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 :
case paste_at_begin_marker :
{
2005-03-29 20:25:14 +00:00
int iDestFirstRow = - 1 ;
switch ( c )
{
2006-06-14 09:56:57 +00:00
DEFAULT_FAIL ( c );
2005-03-29 20:25:14 +00:00
case paste_at_current_beat :
iDestFirstRow = BeatToNoteRow ( GAMESTATE -> m_fSongBeat );
break ;
case paste_at_begin_marker :
ASSERT ( m_NoteFieldEdit . m_iBeginMarker !=- 1 );
iDestFirstRow = m_NoteFieldEdit . m_iBeginMarker ;
break ;
}
2005-04-02 21:59:27 +00:00
int iRowsToCopy = m_Clipboard . GetLastRow () + 1 ;
2005-03-29 20:25:14 +00:00
m_NoteDataEdit . CopyRange ( m_Clipboard , 0 , iRowsToCopy , iDestFirstRow );
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 );
2005-03-20 06:41:56 +00:00
HandleAreaMenuChoice ( cut );
2003-02-22 00:48:38 +00:00
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 )
{
2006-06-14 09:56:57 +00:00
DEFAULT_FAIL ( tt );
2006-03-11 06:13:18 +00:00
case left : NoteDataUtil :: Turn ( m_Clipboard , st , NoteDataUtil :: left ); break ;
case right : NoteDataUtil :: Turn ( m_Clipboard , st , NoteDataUtil :: right ); break ;
2003-08-07 06:36:34 +00:00
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
}
2005-03-20 06:41:56 +00:00
HandleAreaMenuChoice ( paste_at_begin_marker );
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 )
{
2006-06-14 09:56:57 +00:00
DEFAULT_FAIL ( tt );
2006-03-11 06:13:18 +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 ;
2005-01-22 17:34:10 +00:00
case big : NoteDataUtil :: Big ( m_NoteDataEdit , iBeginRow , iEndRow ); break ;
2006-03-11 06:13:18 +00:00
case quick : NoteDataUtil :: Quick ( m_NoteDataEdit , iBeginRow , iEndRow ); break ;
case skippy : NoteDataUtil :: Skippy ( m_NoteDataEdit , iBeginRow , iEndRow ); break ;
case add_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 ;
case nostretch : NoteDataUtil :: RemoveStretch ( m_NoteDataEdit , st , iBeginRow , iBeginRow ); break ;
2003-03-13 09:20:21 +00:00
}
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 );
2005-03-20 06:41:56 +00:00
HandleAreaMenuChoice ( cut );
2003-03-13 21:44:14 +00:00
AlterType at = ( AlterType ) iAnswers [ c ];
switch ( at )
{
2006-06-14 09:56:57 +00:00
DEFAULT_FAIL ( at );
2005-03-25 09:36:08 +00:00
case autogen_to_fill_width :
{
NoteData temp ( m_Clipboard );
int iNumUsedTracks = NoteDataUtil :: GetNumUsedTracks ( temp );
2005-03-30 06:09:30 +00:00
if ( iNumUsedTracks == 0 )
break ;
2005-03-25 09:36:08 +00:00
temp . SetNumTracks ( iNumUsedTracks );
NoteDataUtil :: LoadTransformedSlidingWindow ( temp , m_Clipboard , m_Clipboard . GetNumTracks () );
2005-05-01 04:35:29 +00:00
NoteDataUtil :: RemoveStretch ( m_Clipboard , GAMESTATE -> m_pCurSteps [ 0 ] -> m_StepsType );
2005-03-25 09:36:08 +00:00
}
break ;
2006-03-11 06:13:18 +00:00
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 ;
2003-03-13 21:44:14 +00:00
case collapse_to_one : NoteDataUtil :: CollapseToOne ( m_Clipboard ); break ;
2006-03-11 06:13:18 +00:00
case collapse_left : NoteDataUtil :: CollapseLeft ( m_Clipboard ); break ;
case shift_left : NoteDataUtil :: ShiftLeft ( m_Clipboard ); break ;
case shift_right : NoteDataUtil :: ShiftRight ( m_Clipboard ); break ;
2003-03-13 21:44:14 +00:00
}
2005-03-20 06:41:56 +00:00
HandleAreaMenuChoice ( paste_at_begin_marker );
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 );
2005-03-20 06:41:56 +00:00
HandleAreaMenuChoice ( cut );
2003-09-07 22:28:46 +00:00
AlterType at = ( AlterType ) iAnswers [ c ];
float fScale = - 1 ;
switch ( at )
{
2006-06-14 09:56:57 +00:00
DEFAULT_FAIL ( 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 ;
2006-03-11 06:13:18 +00:00
case expand_2x : fScale = 2 ; break ;
2003-09-07 22:28:46 +00:00
}
switch ( at )
{
2006-06-14 09:56:57 +00:00
DEFAULT_FAIL ( at );
2003-09-07 22:28:46 +00:00
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 ;
}
2005-12-19 00:10:53 +00:00
int iOldClipboardRow = m_NoteFieldEdit . m_iEndMarker - m_NoteFieldEdit . m_iBeginMarker ;
int iNewClipboardRow = lrintf ( iOldClipboardRow * fScale );
int iDeltaRows = iNewClipboardRow - iOldClipboardRow ;
int iNewClipboardEndRow = m_NoteFieldEdit . m_iBeginMarker + iNewClipboardRow ;
if ( iDeltaRows > 0 )
NoteDataUtil :: InsertRows ( m_NoteDataEdit , m_NoteFieldEdit . m_iBeginMarker , iDeltaRows );
2005-12-18 07:09:56 +00:00
else
2005-12-19 00:10:53 +00:00
NoteDataUtil :: DeleteRows ( m_NoteDataEdit , m_NoteFieldEdit . m_iBeginMarker , - iDeltaRows );
2005-12-18 07:09:56 +00:00
2005-01-23 23:17:12 +00:00
m_pSong -> m_Timing . ScaleRegion ( fScale , m_NoteFieldEdit . m_iBeginMarker , m_NoteFieldEdit . m_iEndMarker );
2004-02-26 05:38:46 +00:00
2005-03-20 06:41:56 +00:00
HandleAreaMenuChoice ( paste_at_begin_marker );
2004-02-26 05:38:46 +00:00
const vector < Steps *> sIter = m_pSong -> GetAllSteps ();
2006-01-22 01:00:06 +00:00
RString 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 ;
2005-01-25 05:02:35 +00:00
NoteData ndTemp ;
2004-10-23 17:43:49 +00:00
sIter [ i ] -> GetNoteData ( ndTemp );
2005-01-23 23:17:12 +00:00
NoteDataUtil :: ScaleRegion ( ndTemp , fScale , m_NoteFieldEdit . m_iBeginMarker , m_NoteFieldEdit . m_iEndMarker );
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-12-19 00:10:53 +00:00
m_NoteFieldEdit . m_iEndMarker = iNewClipboardEndRow ;
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-12-18 07:34:19 +00:00
m_pSong -> m_Timing . SetBPMAtRow ( m_NoteFieldEdit . m_iBeginMarker , fNewBPM );
2005-12-19 00:10:53 +00:00
m_pSong -> m_Timing . SetBPMAtRow ( iNewClipboardEndRow , fOldBPM );
2003-09-07 22:28:46 +00:00
}
break ;
2003-02-18 23:15:38 +00:00
case play :
2005-07-20 05:07:07 +00:00
ASSERT ( m_NoteFieldEdit . m_iBeginMarker !=- 1 && m_NoteFieldEdit . m_iEndMarker !=- 1 );
2005-07-20 05:26:27 +00:00
m_iStartPlayingAt = m_NoteFieldEdit . m_iBeginMarker ;
m_iStopPlayingAt = m_NoteFieldEdit . m_iEndMarker ;
2005-07-20 05:07:07 +00:00
TransitionEditState ( STATE_PLAYING );
2003-02-18 23:15:38 +00:00
break ;
case record :
2005-07-20 05:07:07 +00:00
ASSERT ( m_NoteFieldEdit . m_iBeginMarker !=- 1 && m_NoteFieldEdit . m_iEndMarker !=- 1 );
2005-07-20 05:26:27 +00:00
m_iStartPlayingAt = m_NoteFieldEdit . m_iBeginMarker ;
m_iStopPlayingAt = m_NoteFieldEdit . m_iEndMarker ;
2005-07-20 05:07:07 +00:00
TransitionEditState ( STATE_RECORDING );
2003-02-18 23:15:38 +00:00
break ;
case insert_and_shift :
2005-12-18 07:09:56 +00:00
NoteDataUtil :: InsertRows ( m_NoteDataEdit , BeatToNoteRow ( GAMESTATE -> m_fSongBeat ), BeatToNoteRow ( 1 ) );
2003-02-18 23:15:38 +00:00
break ;
case delete_and_shift :
2005-12-18 07:09:56 +00:00
NoteDataUtil :: DeleteRows ( m_NoteDataEdit , BeatToNoteRow ( GAMESTATE -> m_fSongBeat ), BeatToNoteRow ( 1 ) );
2004-02-27 06:28:31 +00:00
break ;
case shift_pauses_forward :
2005-12-18 08:01:45 +00:00
m_pSong -> m_Timing . InsertRows ( BeatToNoteRow ( GAMESTATE -> m_fSongBeat ), BeatToNoteRow ( 1 ) );
2004-02-27 06:28:31 +00:00
break ;
case shift_pauses_backward :
2005-12-18 08:01:45 +00:00
m_pSong -> m_Timing . DeleteRows ( BeatToNoteRow ( GAMESTATE -> m_fSongBeat ), BeatToNoteRow ( 1 ) );
2003-02-18 23:15:38 +00:00
break ;
2005-12-18 23:56:14 +00:00
case convert_to_pause :
2003-11-03 08:44:49 +00:00
{
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 ) );
2005-12-18 07:16:47 +00:00
// The length of the stop segment we're going to create. This includes time spent in any
// stops in the selection, which will be deleted and subsumed into the new stop.
2004-02-23 17:18:02 +00:00
float fStopLength = fMarkerEnd - fMarkerStart ;
2005-12-18 07:16:47 +00:00
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-12-18 06:58:52 +00:00
NoteDataUtil :: DeleteRows ( m_NoteDataEdit ,
2006-03-11 06:13:18 +00:00
m_NoteFieldEdit . m_iBeginMarker + 1 ,
m_NoteFieldEdit . m_iEndMarker - m_NoteFieldEdit . m_iBeginMarker
);
2005-12-18 07:59:44 +00:00
m_pSong -> m_Timing . DeleteRows ( m_NoteFieldEdit . m_iBeginMarker ,
2006-03-11 06:13:18 +00:00
m_NoteFieldEdit . m_iEndMarker - m_NoteFieldEdit . m_iBeginMarker );
2005-12-18 07:34:19 +00:00
m_pSong -> m_Timing . SetStopAtRow ( m_NoteFieldEdit . m_iBeginMarker , fStopLength );
2005-12-18 06:58:52 +00:00
m_NoteFieldEdit . m_iBeginMarker = - 1 ;
2005-01-23 23:17:12 +00:00
m_NoteFieldEdit . m_iEndMarker = - 1 ;
2003-11-03 08:44:49 +00:00
break ;
}
case convert_pause_to_beat :
{
2005-12-19 00:08:07 +00:00
float fStopSeconds = m_pSong -> m_Timing . GetStopAtRow ( BeatToNoteRow ( GAMESTATE -> m_fSongBeat ) );
m_pSong -> m_Timing . SetStopAtBeat ( GAMESTATE -> m_fSongBeat , 0 );
2003-11-03 08:44:49 +00:00
2005-12-19 00:08:07 +00:00
float fStopBeats = fStopSeconds * m_pSong -> GetBPMAtBeat ( GAMESTATE -> m_fSongBeat ) / 60 ;
// don't move the step from where it is, just move everything later
NoteDataUtil :: InsertRows ( m_NoteDataEdit , BeatToNoteRow ( GAMESTATE -> m_fSongBeat ) + 1 , BeatToNoteRow ( fStopBeats ) );
m_pSong -> m_Timing . InsertRows ( BeatToNoteRow ( GAMESTATE -> m_fSongBeat ) + 1 , BeatToNoteRow ( fStopSeconds ) );
2003-11-03 08:44:49 +00:00
}
2005-03-23 10:43:57 +00:00
break ;
case undo :
Undo ();
break ;
2003-02-18 23:15:38 +00:00
};
2005-03-23 10:43:57 +00:00
if ( bSaveUndo )
CheckNumberOfNotesAndUndo ();
2002-08-17 06:44:04 +00:00
}
2003-02-18 23:15:38 +00:00
2005-12-21 12:55:20 +00:00
static LocalizedString ENTER_NEW_DESCRIPTION ( "ScreenEdit" , "Enter a new description." );
2005-03-20 20:13:27 +00:00
void ScreenEdit :: HandleStepsInformationChoice ( StepsInformationChoice c , const vector < int > & iAnswers )
2003-02-18 23:15:38 +00:00
{
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 :
2005-07-03 04:45:34 +00:00
ScreenTextEntry :: TextEntry (
2005-03-23 04:08:27 +00:00
SM_None ,
2005-12-21 12:55:20 +00:00
ENTER_NEW_DESCRIPTION ,
2005-03-23 04:08:27 +00:00
m_pSteps -> GetDescription (),
2005-07-29 02:23:02 +00:00
( dc == DIFFICULTY_EDIT ) ? MAX_EDIT_STEPS_DESCRIPTION_LENGTH : 255 ,
2006-03-08 04:03:39 +00:00
SongUtil :: ValidateCurrentStepsDescription ,
2005-03-23 04:08:27 +00:00
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
}
2006-03-08 04:03:39 +00:00
static LocalizedString ENTER_MAIN_TITLE ( "ScreenEdit" , "Enter a new main title." );
static LocalizedString ENTER_SUB_TITLE ( "ScreenEdit" , "Enter a new sub title." );
static LocalizedString ENTER_ARTIST ( "ScreenEdit" , "Enter a new artist." );
static LocalizedString ENTER_CREDIT ( "ScreenEdit" , "Enter a new credit." );
2005-12-21 12:55:20 +00:00
static LocalizedString ENTER_MAIN_TITLE_TRANSLIT ( "ScreenEdit" , "Enter a new main title transliteration." );
static LocalizedString ENTER_SUB_TITLE_TRANSLIT ( "ScreenEdit" , "Enter a new sub title transliteration." );
static LocalizedString ENTER_ARTIST_TRANSLIT ( "ScreenEdit" , "Enter a new artist transliteration." );
2005-03-20 20:13:27 +00:00
void ScreenEdit :: HandleSongInformationChoice ( SongInformationChoice c , const vector < int > & iAnswers )
2003-02-18 23:15:38 +00:00
{
2003-02-19 05:46:09 +00:00
Song * pSong = GAMESTATE -> m_pCurSong ;
2003-02-18 23:15:38 +00:00
switch ( c )
{
2006-06-14 09:56:57 +00:00
DEFAULT_FAIL ( c );
2003-02-18 23:15:38 +00:00
case main_title :
2005-12-21 12:55:20 +00:00
ScreenTextEntry :: TextEntry ( SM_None , ENTER_MAIN_TITLE , pSong -> m_sMainTitle , 100 , NULL , ChangeMainTitle , NULL );
2003-02-18 23:15:38 +00:00
break ;
case sub_title :
2005-12-21 12:55:20 +00:00
ScreenTextEntry :: TextEntry ( SM_None , ENTER_SUB_TITLE , pSong -> m_sSubTitle , 100 , NULL , ChangeSubTitle , NULL );
2003-02-18 23:15:38 +00:00
break ;
case artist :
2005-12-21 12:55:20 +00:00
ScreenTextEntry :: TextEntry ( SM_None , ENTER_ARTIST , pSong -> m_sArtist , 100 , NULL , ChangeArtist , NULL );
2003-02-18 23:15:38 +00:00
break ;
2003-06-23 02:24:13 +00:00
case credit :
2005-12-21 12:55:20 +00:00
ScreenTextEntry :: TextEntry ( SM_None , ENTER_CREDIT , pSong -> m_sCredit , 100 , NULL , ChangeCredit , NULL );
2003-06-23 02:24:13 +00:00
break ;
2003-02-18 23:15:38 +00:00
case main_title_transliteration :
2005-12-21 12:55:20 +00:00
ScreenTextEntry :: TextEntry ( SM_None , ENTER_MAIN_TITLE_TRANSLIT , pSong -> m_sMainTitleTranslit , 100 , NULL , ChangeMainTitleTranslit , NULL );
2003-02-18 23:15:38 +00:00
break ;
case sub_title_transliteration :
2005-12-21 12:55:20 +00:00
ScreenTextEntry :: TextEntry ( SM_None , ENTER_SUB_TITLE_TRANSLIT , pSong -> m_sSubTitleTranslit , 100 , NULL , ChangeSubTitleTranslit , NULL );
2003-02-18 23:15:38 +00:00
break ;
case artist_transliteration :
2005-12-21 12:55:20 +00:00
ScreenTextEntry :: TextEntry ( SM_None , ENTER_ARTIST_TRANSLIT , pSong -> m_sArtistTranslit , 100 , NULL , ChangeArtistTranslit , NULL );
2003-02-18 23:15:38 +00:00
break ;
};
2003-03-15 19:25:37 +00:00
}
2005-03-20 06:41:56 +00:00
void ScreenEdit :: HandleBGChangeChoice ( BGChangeChoice c , const vector < int > & iAnswers )
2003-03-15 19:25:37 +00:00
{
2004-08-20 08:36:17 +00:00
BackgroundChange newChange ;
2005-06-05 09:46:29 +00:00
FOREACH ( BackgroundChange , m_pSong -> GetBackgroundChanges ( g_CurrentBGChangeLayer ), iter )
2004-08-20 08:36:17 +00:00
{
if ( iter -> m_fStartBeat == GAMESTATE -> m_fSongBeat )
{
newChange = * iter ;
// delete the old change. We'll add a new one below.
2005-06-05 09:46:29 +00:00
m_pSong -> GetBackgroundChanges ( g_CurrentBGChangeLayer ). erase ( iter );
2004-08-20 08:36:17 +00:00
break ;
}
}
newChange . m_fStartBeat = GAMESTATE -> m_fSongBeat ;
2006-06-12 06:42:25 +00:00
newChange . m_fRate = StringToFloat ( g_BackgroundChange . rows [ rate ]. choices [ iAnswers [ rate ]] ) / 100.f ;
2005-05-29 01:11:49 +00:00
newChange . m_sTransition = g_BackgroundChange . rows [ transition ]. choices [ iAnswers [ transition ]];
2005-06-04 21:22:50 +00:00
newChange . m_def . m_sEffect = g_BackgroundChange . rows [ effect ]. choices [ iAnswers [ effect ]];
2005-06-05 22:21:55 +00:00
newChange . m_def . m_sColor1 = g_BackgroundChange . rows [ color1 ]. choices [ iAnswers [ color1 ]];
newChange . m_def . m_sColor2 = g_BackgroundChange . rows [ color2 ]. choices [ iAnswers [ color2 ]];
2005-05-31 01:17:37 +00:00
switch ( iAnswers [ file1_type ] )
{
2006-06-14 09:56:57 +00:00
DEFAULT_FAIL ( iAnswers [ file1_type ] );
2006-03-11 06:13:18 +00:00
case none : newChange . m_def . m_sFile1 = "" ; break ;
case dynamic_random : newChange . m_def . m_sFile1 = RANDOM_BACKGROUND_FILE ; break ;
2005-06-05 01:27:15 +00:00
case baked_random : newChange . m_def . m_sFile1 = GetOneBakedRandomFile ( m_pSong ); break ;
2005-05-31 01:17:37 +00:00
case song_bganimation :
case song_movie :
case song_bitmap :
case global_bganimation :
case global_movie :
2005-06-05 01:27:15 +00:00
case global_movie_song_group :
case global_movie_song_group_and_genre :
2005-05-31 01:17:37 +00:00
{
2005-06-05 01:27:15 +00:00
BGChangeChoice row1 = ( BGChangeChoice )( file1_song_bganimation + iAnswers [ file1_type ]);
2005-06-06 00:59:37 +00:00
newChange . m_def . m_sFile1 = g_BackgroundChange . rows [ row1 ]. choices . empty () ? "" : g_BackgroundChange . rows [ row1 ]. choices [ iAnswers [ row1 ]];
2005-05-31 01:17:37 +00:00
}
break ;
}
switch ( iAnswers [ file2_type ] )
{
2006-06-14 09:56:57 +00:00
DEFAULT_FAIL ( iAnswers [ file2_type ]);
2006-03-11 06:13:18 +00:00
case none : newChange . m_def . m_sFile2 = "" ; break ;
case dynamic_random : newChange . m_def . m_sFile2 = RANDOM_BACKGROUND_FILE ; break ;
2005-06-05 01:27:15 +00:00
case baked_random : newChange . m_def . m_sFile2 = GetOneBakedRandomFile ( m_pSong ); break ;
2005-05-31 01:17:37 +00:00
case song_bganimation :
case song_movie :
case song_bitmap :
case global_bganimation :
case global_movie :
2005-06-05 01:27:15 +00:00
case global_movie_song_group :
case global_movie_song_group_and_genre :
2005-05-31 01:17:37 +00:00
{
2005-06-05 01:27:15 +00:00
BGChangeChoice row2 = ( BGChangeChoice )( file2_song_bganimation + iAnswers [ file2_type ]);
2005-06-06 00:59:37 +00:00
newChange . m_def . m_sFile2 = g_BackgroundChange . rows [ row2 ]. choices . empty () ? "" : g_BackgroundChange . rows [ row2 ]. choices [ iAnswers [ row2 ]];
2005-05-31 01:17:37 +00:00
}
break ;
}
2003-04-14 04:10:01 +00:00
2005-06-07 09:42:57 +00:00
if ( c == delete_change || newChange . m_def . m_sFile1 . empty () )
{
// don't add
}
else
{
m_pSong -> AddBackgroundChange ( g_CurrentBGChangeLayer , newChange );
}
2005-06-05 09:46:29 +00:00
g_CurrentBGChangeLayer = BACKGROUND_LAYER_INVALID ;
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 ();
2006-01-13 05:51:37 +00:00
GAMESTATE -> m_pPlayerState [ PLAYER_1 ] -> RemoveActiveAttacks ();
2004-01-26 20:56:58 +00:00
2005-07-30 19:34:23 +00:00
if ( GAMESTATE -> m_pCurCourse )
2004-01-26 20:56:58 +00:00
{
2006-03-19 01:59:42 +00:00
AttackArray Attacks ;
if ( EDIT_MODE == EditMode_CourseMods )
{
Attacks = GAMESTATE -> m_pCurCourse -> m_vEntries [ GAMESTATE -> m_iEditCourseEntryIndex ]. attacks ;
}
else
{
2006-03-12 00:45:18 +00:00
GAMESTATE -> m_pCurCourse -> RevertFromDisk (); // Remove this and have a separate reload key?
2004-01-26 20:56:58 +00:00
2006-03-19 01:59:42 +00:00
for ( unsigned e = 0 ; e < GAMESTATE -> m_pCurCourse -> m_vEntries . size (); ++ e )
{
if ( GAMESTATE -> m_pCurCourse -> m_vEntries [ e ]. pSong != m_pSong )
continue ;
2004-01-26 20:56:58 +00:00
2006-03-19 01:59:42 +00:00
Attacks = GAMESTATE -> m_pCurCourse -> m_vEntries [ e ]. attacks ;
break ;
}
2004-01-26 20:56:58 +00:00
}
2006-03-19 01:59:42 +00:00
FOREACH ( Attack , Attacks , attack )
GAMESTATE -> m_pPlayerState [ PLAYER_1 ] -> LaunchAttack ( * attack );
2004-01-26 20:56:58 +00:00
}
2005-07-07 21:29:35 +00:00
GAMESTATE -> m_pPlayerState [ PLAYER_1 ] -> RebuildPlayerOptionsFromActiveAttacks ();
2004-01-26 20:56:58 +00:00
}
2004-06-08 05:22:33 +00:00
2005-03-08 21:19:17 +00:00
void ScreenEdit :: CopyToLastSave ()
{
m_songLastSave = * GAMESTATE -> m_pCurSong ;
2005-03-08 22:21:18 +00:00
if ( GAMESTATE -> m_pCurSteps [ PLAYER_1 ] )
m_stepsLastSave = * GAMESTATE -> m_pCurSteps [ PLAYER_1 ];
2005-03-08 21:19:17 +00:00
}
void ScreenEdit :: CopyFromLastSave ()
{
* GAMESTATE -> m_pCurSong = m_songLastSave ;
2005-03-08 22:21:18 +00:00
if ( GAMESTATE -> m_pCurSteps [ PLAYER_1 ] )
* GAMESTATE -> m_pCurSteps [ PLAYER_1 ] = m_stepsLastSave ;
2005-03-08 21:19:17 +00:00
}
2005-05-18 03:31:36 +00:00
void ScreenEdit :: RevertFromDisk ()
{
StepsID id ;
if ( GAMESTATE -> m_pCurSteps [ PLAYER_1 ] )
id . FromSteps ( GAMESTATE -> m_pCurSteps [ PLAYER_1 ] );
2006-01-22 01:00:06 +00:00
RString sSongDir = GAMESTATE -> m_pCurSong -> GetSongDir ();
2005-05-18 03:31:36 +00:00
GAMESTATE -> m_pCurSong -> LoadFromSongDir ( sSongDir );
if ( id . IsValid () )
GAMESTATE -> m_pCurSteps [ PLAYER_1 ]. Set ( id . ToSteps ( GAMESTATE -> m_pCurSong , false ) );
m_songLastSave = * GAMESTATE -> m_pCurSong ;
if ( GAMESTATE -> m_pCurSteps [ PLAYER_1 ] )
m_stepsLastSave = * GAMESTATE -> m_pCurSteps [ PLAYER_1 ];
}
2005-03-23 10:43:57 +00:00
void ScreenEdit :: SaveUndo ()
{
2005-03-29 20:25:14 +00:00
m_bHasUndo = true ;
2005-03-23 10:43:57 +00:00
m_Undo . CopyAll ( m_NoteDataEdit );
}
2005-12-20 08:35:47 +00:00
static LocalizedString UNDO ( "ScreenEdit" , "Undo" );
2006-03-11 06:13:18 +00:00
static LocalizedString CANT_UNDO ( "ScreenEdit" , "Can't undo - no undo data." );
2005-03-23 10:43:57 +00:00
void ScreenEdit :: Undo ()
{
2005-05-17 07:24:25 +00:00
if ( m_bHasUndo )
{
2005-12-06 12:41:06 +00:00
// swap
2005-07-20 06:47:30 +00:00
NoteData temp ( m_NoteDataEdit );
2005-05-17 07:24:25 +00:00
m_NoteDataEdit . CopyAll ( m_Undo );
2005-07-20 06:47:30 +00:00
m_Undo . CopyAll ( temp );
2005-12-06 12:41:06 +00:00
2005-12-20 08:35:47 +00:00
SCREENMAN -> SystemMessage ( UNDO );
2005-05-17 07:24:25 +00:00
}
else
{
2005-12-20 08:35:47 +00:00
SCREENMAN -> SystemMessage ( CANT_UNDO );
2005-05-17 07:24:25 +00:00
SCREENMAN -> PlayInvalidSound ();
}
2005-03-23 10:43:57 +00:00
}
2005-12-06 12:41:06 +00:00
void ScreenEdit :: ClearUndo ()
{
m_bHasUndo = false ;
2005-12-29 03:29:20 +00:00
m_Undo . ClearAll ();
2005-12-06 12:41:06 +00:00
}
2005-12-20 21:32:26 +00:00
static LocalizedString CREATES_MORE_THAN_NOTES ( "ScreenEdit" , "This change creates more than %d notes in a measure." );
2006-03-11 06:13:18 +00:00
static LocalizedString MORE_THAN_NOTES ( "ScreenEdit" , "More than %d notes per measure is not allowed. This change has been reverted." );
2005-12-20 21:32:26 +00:00
static LocalizedString CREATES_NOTES_PAST_END ( "ScreenEdit" , "This change creates notes past the end of the music and is not allowed." );
2006-03-11 06:13:18 +00:00
static LocalizedString CHANGE_REVERTED ( "ScreenEdit" , "The change has been reverted." );
2005-03-23 10:43:57 +00:00
void ScreenEdit :: CheckNumberOfNotesAndUndo ()
{
for ( int row = 0 ; row <= m_NoteDataEdit . GetLastRow (); row += ROWS_PER_MEASURE )
{
int iNumNotesThisMeasure = 0 ;
FOREACH_NONEMPTY_ROW_ALL_TRACKS_RANGE ( m_NoteDataEdit , r , row , row + ROWS_PER_MEASURE )
iNumNotesThisMeasure += m_NoteDataEdit . GetNumTapNonEmptyTracks ( r );
if ( iNumNotesThisMeasure > MAX_NOTES_PER_MEASURE )
{
Undo ();
2005-07-20 06:47:30 +00:00
m_bHasUndo = false ;
2006-01-22 01:00:06 +00:00
RString sError = ssprintf ( CREATES_MORE_THAN_NOTES . GetValue () + " \n\n " + MORE_THAN_NOTES . GetValue (), MAX_NOTES_PER_MEASURE , MAX_NOTES_PER_MEASURE );
2005-07-03 04:34:53 +00:00
ScreenPrompt :: Prompt ( SM_None , sError );
2005-03-23 10:43:57 +00:00
return ;
}
}
2005-04-02 21:59:27 +00:00
if ( GAMESTATE -> m_pCurSteps [ 0 ] -> IsAnEdit () )
{
// Check that the action didn't push notes any farther past the last measure.
// This blocks Insert Beat from pushing past the end, but allows Delete Beat
// to pull back the notes that are already past the end.
float fNewLastBeat = m_NoteDataEdit . GetLastBeat ();
bool bLastBeatIncreased = fNewLastBeat > m_Undo . GetLastBeat ();
bool bPassedTheEnd = fNewLastBeat > GetMaximumBeatForNewNote ();
if ( bLastBeatIncreased && bPassedTheEnd )
{
Undo ();
2005-07-20 06:47:30 +00:00
m_bHasUndo = false ;
2006-01-22 01:00:06 +00:00
RString sError = CREATES_NOTES_PAST_END . GetValue () + " \n\n " + CHANGE_REVERTED . GetValue ();
2005-07-03 04:34:53 +00:00
ScreenPrompt :: Prompt ( SM_None , sError );
2005-04-02 21:59:27 +00:00
return ;
}
}
2005-03-23 10:43:57 +00:00
}
2005-04-02 21:59:27 +00:00
float ScreenEdit :: GetMaximumBeatForNewNote () const
2005-03-26 19:11:22 +00:00
{
2005-04-19 04:11:33 +00:00
switch ( EDIT_MODE . GetValue () )
2005-03-26 19:11:22 +00:00
{
2006-06-14 09:56:57 +00:00
DEFAULT_FAIL ( EDIT_MODE . GetValue () );
2005-12-06 23:44:01 +00:00
case EditMode_Practice :
2006-03-12 00:45:18 +00:00
case EditMode_CourseMods :
2005-12-06 23:44:01 +00:00
case EditMode_Home :
2005-04-19 01:44:22 +00:00
{
float fEndBeat = GAMESTATE -> m_pCurSong -> m_fLastBeat ;
2005-03-26 19:11:22 +00:00
2005-04-19 01:44:22 +00:00
// Round up to the next measure end. Some songs end on weird beats
// mid-measure, and it's odd to have movement capped to these weird
// beats.
fEndBeat += BEATS_PER_MEASURE ;
fEndBeat = ftruncf ( fEndBeat , ( float ) BEATS_PER_MEASURE );
2005-04-02 10:36:44 +00:00
2005-04-19 01:44:22 +00:00
return fEndBeat ;
}
2005-12-06 23:44:01 +00:00
case EditMode_Full :
2006-05-30 17:41:26 +00:00
return NoteRowToBeat ( MAX_NOTE_ROW );
2005-03-26 19:11:22 +00:00
}
}
2005-04-02 21:59:27 +00:00
float ScreenEdit :: GetMaximumBeatForMoving () const
{
float fEndBeat = GetMaximumBeatForNewNote ();
// Jump to GetLastBeat even if it's past m_pCurSong->m_fLastBeat
// so that users can delete garbage steps past then end that they have
// have inserted in a text editor. Once they delete all steps on
// GetLastBeat() and move off of that beat, they won't be able to return.
fEndBeat = max ( fEndBeat , m_NoteDataEdit . GetLastBeat () );
return fEndBeat ;
}
2006-03-16 20:59:15 +00:00
struct EditHelpLine
{
const char * szEnglishDescription ;
vector < EditButton > veb ;
EditHelpLine (
const char * _szEnglishDescription ,
EditButton eb0 ,
EditButton eb1 = EDIT_BUTTON_INVALID ,
EditButton eb2 = EDIT_BUTTON_INVALID ,
EditButton eb3 = EDIT_BUTTON_INVALID ,
EditButton eb4 = EDIT_BUTTON_INVALID ,
EditButton eb5 = EDIT_BUTTON_INVALID ,
EditButton eb6 = EDIT_BUTTON_INVALID ,
EditButton eb7 = EDIT_BUTTON_INVALID ,
EditButton eb8 = EDIT_BUTTON_INVALID ,
EditButton eb9 = EDIT_BUTTON_INVALID )
{
szEnglishDescription = _szEnglishDescription ;
#define PUSH_IF_VALID( x ) if( x != EDIT_BUTTON_INVALID ) veb.push_back( x );
PUSH_IF_VALID ( eb0 );
PUSH_IF_VALID ( eb1 );
PUSH_IF_VALID ( eb2 );
PUSH_IF_VALID ( eb3 );
PUSH_IF_VALID ( eb4 );
PUSH_IF_VALID ( eb5 );
PUSH_IF_VALID ( eb6 );
PUSH_IF_VALID ( eb7 );
PUSH_IF_VALID ( eb8 );
PUSH_IF_VALID ( eb9 );
#undef PUSH_IF_VALID
}
};
static const EditHelpLine g_EditHelpLines [] =
{
2006-03-16 21:09:36 +00:00
EditHelpLine ( "Move cursor" , EDIT_BUTTON_SCROLL_UP_LINE , EDIT_BUTTON_SCROLL_DOWN_LINE ),
EditHelpLine ( "Jump measure" , EDIT_BUTTON_SCROLL_UP_PAGE , EDIT_BUTTON_SCROLL_DOWN_PAGE ),
2006-03-16 20:59:15 +00:00
EditHelpLine ( "Jump measure" , EDIT_BUTTON_SCROLL_PREV_MEASURE , EDIT_BUTTON_SCROLL_NEXT_MEASURE ),
EditHelpLine ( "Select region" , EDIT_BUTTON_SCROLL_SELECT ),
EditHelpLine ( "Jump to first/last beat" , EDIT_BUTTON_SCROLL_HOME , EDIT_BUTTON_SCROLL_END ),
2006-03-16 21:09:36 +00:00
EditHelpLine ( "Change zoom" , EDIT_BUTTON_SCROLL_SPEED_UP , EDIT_BUTTON_SCROLL_SPEED_DOWN ),
2006-03-16 20:59:15 +00:00
EditHelpLine ( "Play" , EDIT_BUTTON_PLAY_SELECTION ),
EditHelpLine ( "Play current beat to end" , EDIT_BUTTON_PLAY_FROM_CURSOR ),
EditHelpLine ( "Play whole song" , EDIT_BUTTON_PLAY_FROM_START ),
EditHelpLine ( "Record" , EDIT_BUTTON_RECORD_SELECTION ),
EditHelpLine ( "Set selection" , EDIT_BUTTON_LAY_SELECT ),
EditHelpLine ( "Drag area marker" , EDIT_BUTTON_SCROLL_SELECT ),
EditHelpLine ( "Toggle assist tick" , EDIT_BUTTON_TOGGLE_ASSIST_TICK ),
2006-03-16 21:09:36 +00:00
EditHelpLine ( "Next/prev steps of same StepsType" , EDIT_BUTTON_OPEN_NEXT_STEPS , EDIT_BUTTON_OPEN_PREV_STEPS ),
EditHelpLine ( "Decrease/increase BPM at cur beat" , EDIT_BUTTON_BPM_DOWN , EDIT_BUTTON_BPM_UP ),
EditHelpLine ( "Decrease/increase stop at cur beat" , EDIT_BUTTON_STOP_DOWN , EDIT_BUTTON_STOP_UP ),
2006-03-16 20:59:15 +00:00
EditHelpLine ( "Decrease/increase music offset" , EDIT_BUTTON_OFFSET_DOWN , EDIT_BUTTON_OFFSET_UP ),
2006-03-16 21:09:36 +00:00
EditHelpLine ( "Decrease/increase sample music start" , EDIT_BUTTON_SAMPLE_START_DOWN , EDIT_BUTTON_SAMPLE_START_UP ),
EditHelpLine ( "Decrease/increase sample music length" , EDIT_BUTTON_SAMPLE_LENGTH_DOWN , EDIT_BUTTON_SAMPLE_LENGTH_UP ),
2006-03-16 20:59:15 +00:00
EditHelpLine ( "Play sample music" , EDIT_BUTTON_PLAY_SAMPLE_MUSIC ),
EditHelpLine ( "Add/Edit Background Change" , EDIT_BUTTON_OPEN_BGCHANGE_LAYER1_MENU ),
EditHelpLine ( "Insert beat and shift down" , EDIT_BUTTON_INSERT ),
EditHelpLine ( "Shift BPM changes and stops down one beat" , EDIT_BUTTON_INSERT_SHIFT_PAUSES ),
EditHelpLine ( "Delete beat and shift up" , EDIT_BUTTON_DELETE ),
EditHelpLine ( "Shift BPM changes and stops up one beat" , EDIT_BUTTON_DELETE_SHIFT_PAUSES ),
EditHelpLine ( "Lay mine" , EDIT_BUTTON_LAY_MINE_OR_ROLL ),
EditHelpLine ( "Add to/remove from right half" , EDIT_BUTTON_RIGHT_SIDE ),
};
static bool IsMapped ( EditButton eb , const MapEditToDI & editmap )
{
for ( int s = 0 ; s < NUM_EDIT_TO_DEVICE_SLOTS ; s ++ )
{
DeviceInput diPress = editmap . button [ eb ][ s ];
DeviceInput diHold = editmap . hold [ eb ][ s ];
if ( diPress . IsValid () )
return true ;
}
return false ;
}
static void ProcessKeyName ( RString & s )
{
s . Replace ( "Key_" , "" );
}
static void ProcessKeyNames ( vector < RString > & vs )
{
FOREACH ( RString , vs , s )
ProcessKeyName ( * s );
sort ( vs . begin (), vs . end () );
vector < RString >:: iterator toDelete = unique ( vs . begin (), vs . end () );
vs . erase ( toDelete , vs . end ());
}
static RString GetDeviceButtonsLocalized ( const vector < EditButton > & veb , const MapEditToDI & editmap )
{
vector < RString > vsPress ;
vector < RString > vsHold ;
FOREACH_CONST ( EditButton , veb , eb )
{
if ( ! IsMapped ( * eb , editmap ) )
continue ;
for ( int s = 0 ; s < NUM_EDIT_TO_DEVICE_SLOTS ; s ++ )
{
DeviceInput diPress = editmap . button [ * eb ][ s ];
DeviceInput diHold = editmap . hold [ * eb ][ s ];
if ( diPress . IsValid () )
2006-06-15 06:07:45 +00:00
vsPress . push_back ( INPUTMAN -> GetLocalizedInputString ( diPress ) );
2006-03-16 20:59:15 +00:00
if ( diHold . IsValid () )
2006-06-15 06:07:45 +00:00
vsHold . push_back ( INPUTMAN -> GetLocalizedInputString ( diHold ) );
2006-03-16 20:59:15 +00:00
}
}
ProcessKeyNames ( vsPress );
ProcessKeyNames ( vsHold );
RString s = join ( "/" , vsPress );
if ( ! vsHold . empty () )
s = join ( "/" , vsHold ) + " + " + s ;
return s ;
}
void ScreenEdit :: DoHelp ()
{
g_EditHelp . rows . clear ();
2006-03-18 08:43:15 +00:00
for ( unsigned i = 0 ; i < ARRAYSIZE ( g_EditHelpLines ); ++ i )
2006-03-16 20:59:15 +00:00
{
const EditHelpLine & hl = g_EditHelpLines [ i ];
if ( ! IsMapped ( hl . veb [ 0 ], m_EditMappingsDeviceInput ) )
continue ;
RString sButtons = GetDeviceButtonsLocalized ( hl . veb , m_EditMappingsDeviceInput );
RString sDescription = THEME -> GetString ( "EditHelpDescription" , hl . szEnglishDescription );
g_EditHelp . rows . push_back ( MenuRowDef ( - 1 , sDescription , false , EditMode_Practice , false , false , 0 , sButtons ) );
}
EditMiniMenu ( & g_EditHelp );
}
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.
*/