DeviceButton StringToDeviceButton( const RString& s )
{
	InitNames();

	if( s.size() == 1 )
		return (DeviceButton) s[0];

	int i;
	if( sscanf(s, "unk %i", &i) == 1 )
		return enum_add2( KEY_OTHER_0, i );

	if( sscanf(s, "B%i", &i) == 1 )
		return enum_add2( JOY_BUTTON_1, i-1 );

	if( sscanf(s, "Midi %i", &i) == 1 )
		return enum_add2( MIDI_FIRST, i );

	if( sscanf(s, "Mouse %i", &i) == 1 )
		return enum_add2( MOUSE_LEFT, i );

	map<RString,DeviceButton>::const_iterator it = g_mapStringToNames.find( s );
	if( it != g_mapStringToNames.end() )
		return it->second;

	return DeviceButton_Invalid;
}
void ScoreKeeperNormal::HandleTapScoreNone()
{
	if( PENALIZE_TAP_SCORE_NONE )
	{
		m_pPlayerStageStats->m_iCurCombo = 0;

		if( m_pPlayerState->m_PlayerNumber != PLAYER_INVALID )
			MESSAGEMAN->Broadcast( enum_add2(Message_CurrentComboChangedP1,m_pPlayerState->m_PlayerNumber) );
	}

	// TODO: networking code
}
void InputHandler_Win32_Pump::HandleInput( int iDevice, int iEvent )
{
	static const int bits[] = {
	/* P1 */	(1<<9), (1<<12), (1<<13), (1<<11), (1<<10),
	/* ESC */	(1<<16),
	/* P1 */	(1<<17), (1<<20), (1<<21), (1<<19), (1<<18),
	};

	InputDevice id = InputDevice( DEVICE_PUMP1 + iDevice );

	for( int iButton = 0; iButton < ARRAYLEN(bits); ++iButton )
	{
		DeviceInput di( id, enum_add2(JOY_BUTTON_1, iButton), !(iEvent & bits[iButton]) );
		
		/* If we're in a thread, our timestamp is accurate. */
		if( InputThread.IsCreated() )
			di.ts.Touch();

		ButtonPressed( di );
	}
}
Exemple #4
0
static bool UsbKeyToDeviceButton( UInt8 iUsbKey, DeviceButton &buttonOut )
{
	UInt8 usage = iUsbKey;

	if( usage < kHIDUsage_KeyboardA )
		return false;

	if( usage <= kHIDUsage_KeyboardZ )
	{
		buttonOut = enum_add2( KEY_Ca, usage - kHIDUsage_KeyboardA );
		return true;
	}

	// KEY_C0 = KEY_C1 - 1, kHIDUsage_Keyboard0 = kHIDUsage_Keyboard9 + 1
	if( usage <= kHIDUsage_Keyboard9 )
	{
		buttonOut = enum_add2( KEY_C1, usage - kHIDUsage_Keyboard1 );
		return true;
	}

	if( usage >= kHIDUsage_KeyboardF1 && usage <= kHIDUsage_KeyboardF12 )
	{
		buttonOut = enum_add2( KEY_F1, usage - kHIDUsage_KeyboardF1 );
		return true;
	}

	if( usage >= kHIDUsage_KeyboardF13 && usage <= kHIDUsage_KeyboardF16 )
	{
		buttonOut = enum_add2( KEY_F13, usage - kHIDUsage_KeyboardF13 );
		return true;
	}

	// keypad 0 is again backward
	if( usage >= kHIDUsage_Keypad1 && usage <= kHIDUsage_Keypad9 )
	{
		buttonOut = enum_add2( KEY_KP_C1, usage - kHIDUsage_Keypad1 );
		return true;
	}

#define OTHER(n) (enum_add2(KEY_OTHER_0, (n)))

	// [0, 8]
	if( usage >= kHIDUsage_KeyboardF17 && usage <= kHIDUsage_KeyboardExecute )
	{
		buttonOut = OTHER( 0 + usage - kHIDUsage_KeyboardF17 );
		return true;
	}

	// [9, 19]
	if( usage >= kHIDUsage_KeyboardSelect && usage <= kHIDUsage_KeyboardVolumeDown )
	{
		buttonOut = OTHER( 9 + usage - kHIDUsage_KeyboardSelect );
		return true;
	}

	// [20, 41]
	if( usage >= kHIDUsage_KeypadEqualSignAS400 && usage <= kHIDUsage_KeyboardCancel )
	{
		buttonOut = OTHER( 20 + usage - kHIDUsage_KeypadEqualSignAS400 );
		return true;
	}

	// [42, 47]
	// XXX kHIDUsage_KeyboardClearOrAgain
	if( usage >= kHIDUsage_KeyboardSeparator && usage <= kHIDUsage_KeyboardExSel )
	{
		buttonOut = OTHER( 32 + usage - kHIDUsage_KeyboardSeparator );
		return true;
	}

#define X(x,y) case x: buttonOut = y; return true

	// Time for the special cases
	switch( usage )
	{
		X( kHIDUsage_Keyboard0, KEY_C0 );
		X( kHIDUsage_Keypad0, KEY_KP_C0 );
		X( kHIDUsage_KeyboardReturnOrEnter, KEY_ENTER );
		X( kHIDUsage_KeyboardEscape, KEY_ESC );
		X( kHIDUsage_KeyboardDeleteOrBackspace, KEY_BACK );
		X( kHIDUsage_KeyboardTab, KEY_TAB );
		X( kHIDUsage_KeyboardSpacebar, KEY_SPACE );
		X( kHIDUsage_KeyboardHyphen, KEY_HYPHEN );
		X( kHIDUsage_KeyboardEqualSign, KEY_EQUAL );
		X( kHIDUsage_KeyboardOpenBracket, KEY_LBRACKET );
		X( kHIDUsage_KeyboardCloseBracket, KEY_RBRACKET );
		X( kHIDUsage_KeyboardBackslash, KEY_BACKSLASH );
		X( kHIDUsage_KeyboardNonUSPound, KEY_HASH );
		X( kHIDUsage_KeyboardSemicolon, KEY_SEMICOLON );
		X( kHIDUsage_KeyboardQuote, KEY_SQUOTE );
		X( kHIDUsage_KeyboardGraveAccentAndTilde, KEY_ACCENT );
		X( kHIDUsage_KeyboardComma, KEY_COMMA );
		X( kHIDUsage_KeyboardPeriod, KEY_PERIOD );
		X( kHIDUsage_KeyboardSlash, KEY_SLASH );
		X( kHIDUsage_KeyboardCapsLock, KEY_CAPSLOCK );
		X( kHIDUsage_KeyboardPrintScreen, KEY_PRTSC );
		X( kHIDUsage_KeyboardScrollLock, KEY_SCRLLOCK );
		X( kHIDUsage_KeyboardPause, KEY_PAUSE );
		X( kHIDUsage_KeyboardInsert, KEY_INSERT );
		X( kHIDUsage_KeyboardHome, KEY_HOME );
		X( kHIDUsage_KeyboardPageUp, KEY_PGUP );
		X( kHIDUsage_KeyboardDeleteForward, KEY_DEL );
		X( kHIDUsage_KeyboardEnd, KEY_END );
		X( kHIDUsage_KeyboardPageDown, KEY_PGDN );
		X( kHIDUsage_KeyboardRightArrow, KEY_RIGHT );
		X( kHIDUsage_KeyboardLeftArrow, KEY_LEFT );
		X( kHIDUsage_KeyboardDownArrow, KEY_DOWN );
		X( kHIDUsage_KeyboardUpArrow, KEY_UP );
		X( kHIDUsage_KeypadNumLock, KEY_NUMLOCK );
		X( kHIDUsage_KeypadSlash, KEY_KP_SLASH );
		X( kHIDUsage_KeypadEqualSign, KEY_KP_EQUAL );
		X( kHIDUsage_KeypadAsterisk, KEY_KP_ASTERISK );
		X( kHIDUsage_KeypadHyphen, KEY_KP_HYPHEN );
		X( kHIDUsage_KeypadPlus, KEY_KP_PLUS );
		X( kHIDUsage_KeypadEnter, KEY_KP_ENTER );
		X( kHIDUsage_KeypadPeriod, KEY_KP_PERIOD );
		X( kHIDUsage_KeyboardNonUSBackslash, OTHER(48) );
		X( kHIDUsage_KeyboardApplication, OTHER(49) );
		X( kHIDUsage_KeyboardClear, KEY_NUMLOCK ); // XXX
		X( kHIDUsage_KeyboardHelp, KEY_INSERT );
		X( kHIDUsage_KeyboardMenu, KEY_MENU );
		// XXX kHIDUsage_KeyboardLockingCapsLock
		// XXX kHIDUsage_KeyboardLockingNumLock
		// XXX kHIDUsage_KeyboardLockingScrollLock
		X( kHIDUsage_KeypadComma, KEY_KP_PERIOD ); // XXX
		X( kHIDUsage_KeyboardReturn, KEY_ENTER );
		X( kHIDUsage_KeyboardPrior, OTHER(50) );
		X( kHIDUsage_KeyboardLeftControl, KEY_LCTRL );
		X( kHIDUsage_KeyboardLeftShift, KEY_LSHIFT );
		X( kHIDUsage_KeyboardLeftAlt, KEY_LALT );
		X( kHIDUsage_KeyboardLeftGUI, KEY_LMETA );
		X( kHIDUsage_KeyboardRightControl, KEY_RCTRL );
		X( kHIDUsage_KeyboardRightShift, KEY_RSHIFT );
		X( kHIDUsage_KeyboardRightAlt, KEY_RALT );
		X( kHIDUsage_KeyboardRightGUI, KEY_RMETA );
	}
#undef X
#undef OTHER

	return false;
}
void ScoreKeeperNormal::HandleTapRowScore( const NoteData &nd, int iRow )
{
	int iNumHitContinueCombo, iNumHitMaintainCombo, iNumBreakCombo;
	GetRowCounts( nd, iRow, iNumHitContinueCombo, iNumHitMaintainCombo, iNumBreakCombo );

	int iNumTapsInRow = iNumHitContinueCombo + iNumHitMaintainCombo + iNumBreakCombo;
	if( iNumTapsInRow <= 0 )
		return;

	m_iNumNotesHitThisRow = iNumTapsInRow;

	TapNoteScore scoreOfLastTap = NoteDataWithScoring::LastTapNoteWithResult( nd, iRow ).result.tns;
	HandleTapNoteScoreInternal( scoreOfLastTap, TNS_W1, iRow );
	
	if ( GAMESTATE->GetCurrentGame()->m_bCountNotesSeparately )
	{
		HandleComboInternal( iNumHitContinueCombo, iNumHitMaintainCombo, iNumBreakCombo, iRow );
	}
	else
	{
		HandleRowComboInternal( scoreOfLastTap, iNumTapsInRow, iRow ); //This should work?
	}

	if( m_pPlayerState->m_PlayerNumber != PLAYER_INVALID )
		MESSAGEMAN->Broadcast( enum_add2(Message_CurrentComboChangedP1,m_pPlayerState->m_PlayerNumber) );

	AddTapRowScore( scoreOfLastTap, nd, iRow );		// only score once per row

	// handle combo logic
#ifndef DEBUG
	if( (GamePreferences::m_AutoPlay != PC_HUMAN || m_pPlayerState->m_PlayerOptions.GetCurrent().m_fPlayerAutoPlay != 0)
		&& !GAMESTATE->m_bDemonstrationOrJukebox )	// cheaters always prosper >:D -aj comment edit
	{
		m_cur_toasty_combo = 0;
		return;
	}
#endif //DEBUG

	// Toasty combo
	if(scoreOfLastTap >= m_toasty_min_tns)
	{
		m_cur_toasty_combo += iNumTapsInRow;
		if(m_cur_toasty_combo > m_next_toasty_at &&
			!GAMESTATE->m_bDemonstrationOrJukebox)
		{
			++m_cur_toasty_level;
			// Broadcast the message before posting the screen message so that the
			// transition layer can catch the message to know the level and respond
			// accordingly. -Kyz
			Message msg("ToastyAchieved");
			msg.SetParam("PlayerNumber", m_pPlayerState->m_PlayerNumber);
			msg.SetParam("ToastyCombo", m_cur_toasty_combo);
			msg.SetParam("Level", m_cur_toasty_level);
			MESSAGEMAN->Broadcast(msg);
			SCREENMAN->PostMessageToTopScreen(SM_PlayToasty, 0);
			// TODO: keep a pointer to the Profile.  Don't index with m_PlayerNumber
			// TODO: Make the profile count the level and combo of the toasty. -Kyz
			PROFILEMAN->IncrementToastiesCount(m_pPlayerState->m_PlayerNumber);
			m_next_toasty_at= CalcNextToastyAt(m_cur_toasty_level);
		}
	}
	else
	{
		m_cur_toasty_combo = 0;
		m_cur_toasty_level= 0;
		m_next_toasty_at= 0;
		m_next_toasty_at= CalcNextToastyAt(m_cur_toasty_level);
		Message msg("ToastyDropped");
		msg.SetParam( "PlayerNumber", m_pPlayerState->m_PlayerNumber );
		MESSAGEMAN->Broadcast(msg);
	}

	// TODO: Remove indexing with PlayerNumber
	PlayerNumber pn = m_pPlayerState->m_PlayerNumber;
	float offset = NoteDataWithScoring::LastTapNoteWithResult( nd, iRow ).result.fTapNoteOffset;
	NSMAN->ReportScore( pn, scoreOfLastTap,
			m_pPlayerStageStats->m_iScore,
			m_pPlayerStageStats->m_iCurCombo, offset, m_iNumNotesHitThisRow);
	Message msg( "ScoreChanged" );
	msg.SetParam( "PlayerNumber", m_pPlayerState->m_PlayerNumber );
	msg.SetParam( "MultiPlayer", m_pPlayerState->m_mp );
	msg.SetParam( "ToastyCombo", m_cur_toasty_combo );
	MESSAGEMAN->Broadcast( msg );
}
void ScoreKeeperNormal::HandleTapRowScore( const NoteData &nd, int iRow )
{
	int iNumHitContinueCombo, iNumHitMaintainCombo, iNumBreakCombo;
	GetRowCounts( nd, iRow, iNumHitContinueCombo, iNumHitMaintainCombo, iNumBreakCombo );

	int iNumTapsInRow = iNumHitContinueCombo + iNumHitMaintainCombo + iNumBreakCombo;
	if( iNumTapsInRow <= 0 )
		return;

	m_iNumNotesHitThisRow = iNumTapsInRow;

	TapNoteScore scoreOfLastTap = NoteDataWithScoring::LastTapNoteWithResult( nd, iRow ).result.tns;
	HandleTapNoteScoreInternal( scoreOfLastTap, TNS_W1, iRow );
	
	if ( GAMESTATE->GetCurrentGame()->m_bCountNotesSeparately )
	{
		HandleComboInternal( iNumHitContinueCombo, iNumHitMaintainCombo, iNumBreakCombo, iRow );
	}
	else
	{
		HandleRowComboInternal( scoreOfLastTap, iNumTapsInRow, iRow ); //This should work?
	}

	if( m_pPlayerState->m_PlayerNumber != PLAYER_INVALID )
		MESSAGEMAN->Broadcast( enum_add2(Message_CurrentComboChangedP1,m_pPlayerState->m_PlayerNumber) );

	AddTapRowScore( scoreOfLastTap, nd, iRow );		// only score once per row

	// handle combo logic
#ifndef DEBUG
	if( (GamePreferences::m_AutoPlay != PC_HUMAN || m_pPlayerState->m_PlayerOptions.GetCurrent().m_fPlayerAutoPlay != 0)
		&& !GAMESTATE->m_bDemonstrationOrJukebox )	// cheaters always prosper >:D -aj comment edit
	{
		m_iCurToastyCombo = 0;
		return;
	}
#endif //DEBUG

	// Toasty combo
	//vector<int> iToastyMilestones;
	switch( scoreOfLastTap )
	{
	case TNS_W1:
	case TNS_W2:
		m_iCurToastyCombo += iNumTapsInRow;

		/*
		// compile the list of toasty triggers
		{
			Lua *L = LUA->Get();
			m_vToastyTriggers.PushSelf(L);
			LuaHelpers::ReadArrayFromTable(iToastyMilestones, L);
			lua_pop( L, 1 );
			LUA->Release(L);
		}
		// find out which one we're at.
		if(m_iCurToastyTrigger <= int(iToastyMilestones.size()))
		{
			m_iNextToastyAt = iToastyMilestones[m_iCurToastyTrigger];
		}
		else // out of index value? then don't make it toasty!
		{
			m_iNextToastyAt = -1;
		}
		*/

		if( m_iCurToastyCombo >= m_ToastyTrigger &&
			m_iCurToastyCombo - iNumTapsInRow < m_ToastyTrigger &&
			!GAMESTATE->m_bDemonstrationOrJukebox )
		{
			SCREENMAN->PostMessageToTopScreen( SM_PlayToasty, 0 );
			Message msg("ToastyAchieved");
			msg.SetParam( "PlayerNumber", m_pPlayerState->m_PlayerNumber );
			msg.SetParam( "ToastyCombo", m_iCurToastyCombo );
			MESSAGEMAN->Broadcast(msg);

			// TODO: keep a pointer to the Profile.  Don't index with m_PlayerNumber
			PROFILEMAN->IncrementToastiesCount( m_pPlayerState->m_PlayerNumber );

			//m_iCurToastyTrigger++;
		}
		break;
	default:
		m_iCurToastyCombo = 0;
		Message msg("ToastyDropped");
		msg.SetParam( "PlayerNumber", m_pPlayerState->m_PlayerNumber );
		MESSAGEMAN->Broadcast(msg);
		break;
	}

	// TODO: Remove indexing with PlayerNumber
	PlayerNumber pn = m_pPlayerState->m_PlayerNumber;
	float offset = NoteDataWithScoring::LastTapNoteWithResult( nd, iRow ).result.fTapNoteOffset;
	NSMAN->ReportScore( pn, scoreOfLastTap,
			m_pPlayerStageStats->m_iScore,
			m_pPlayerStageStats->m_iCurCombo, offset );
	Message msg( "ScoreChanged" );
	msg.SetParam( "PlayerNumber", m_pPlayerState->m_PlayerNumber );
	msg.SetParam( "MultiPlayer", m_pPlayerState->m_mp );
	msg.SetParam( "ToastyCombo", m_iCurToastyCombo );
	MESSAGEMAN->Broadcast( msg );
}