2005-08-20 22:47:24 +00:00
|
|
|
/*
|
|
|
|
|
* Join players in perparation for ScreenGameplayMultiplayer.
|
|
|
|
|
*/
|
|
|
|
|
#include "global.h"
|
|
|
|
|
#include "ScreenJoinMultiplayer.h"
|
|
|
|
|
#include "RageInput.h"
|
|
|
|
|
class Style;
|
|
|
|
|
#include "GameManager.h"
|
|
|
|
|
#include "GameState.h"
|
|
|
|
|
#include "InputMapper.h"
|
|
|
|
|
#include "GameSoundManager.h"
|
|
|
|
|
#include "GameCommand.h"
|
2005-08-23 20:58:24 +00:00
|
|
|
#include "ScreenPrompt.h"
|
|
|
|
|
#include "ScreenManager.h"
|
2005-09-05 02:26:50 +00:00
|
|
|
#include "InputEventPlus.h"
|
2005-08-20 22:47:24 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
static const CString MultiPlayerStatusNames[] = {
|
|
|
|
|
"Joined",
|
|
|
|
|
"NotJoined",
|
|
|
|
|
"Unplugged",
|
|
|
|
|
"MissingMultitap",
|
|
|
|
|
};
|
|
|
|
|
XToString( MultiPlayerStatus, NUM_MultiPlayerStatus );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
REGISTER_SCREEN_CLASS( ScreenJoinMultiplayer );
|
|
|
|
|
ScreenJoinMultiplayer::ScreenJoinMultiplayer( CString sClassName ) : ScreenWithMenuElements( sClassName )
|
|
|
|
|
{
|
|
|
|
|
FOREACH_MultiPlayer( p )
|
2005-08-30 00:05:04 +00:00
|
|
|
{
|
|
|
|
|
m_InputDeviceState[p] = InputDeviceState_INVALID;
|
|
|
|
|
m_MultiPlayerStatus[p] = MultiPlayerStatus_INVALID;
|
|
|
|
|
}
|
2005-08-20 22:47:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ScreenJoinMultiplayer::Init()
|
|
|
|
|
{
|
|
|
|
|
ScreenWithMenuElements::Init();
|
|
|
|
|
|
2005-08-23 20:58:24 +00:00
|
|
|
GAMESTATE->m_bMultiplayer = true;
|
|
|
|
|
|
2005-08-20 22:47:24 +00:00
|
|
|
// Set Style to the first style (should be a one player style)
|
|
|
|
|
vector<const Style*> v;
|
|
|
|
|
GAMEMAN->GetStylesForGame( GAMESTATE->m_pCurGame, v, false );
|
|
|
|
|
GAMESTATE->m_pCurStyle.Set( v[0] );
|
|
|
|
|
|
2005-08-23 20:58:24 +00:00
|
|
|
GAMESTATE->m_PlayMode.Set( PLAY_MODE_REGULAR );
|
2005-08-28 18:28:42 +00:00
|
|
|
GAMESTATE->m_bTemporaryEventMode = true;
|
2005-08-30 16:22:48 +00:00
|
|
|
GAMESTATE->m_MasterPlayerNumber = PLAYER_1;
|
2005-08-28 18:28:42 +00:00
|
|
|
|
2005-08-20 22:47:24 +00:00
|
|
|
FOREACH_MultiPlayer( p )
|
|
|
|
|
{
|
|
|
|
|
GameCommand gc;
|
|
|
|
|
gc.m_iIndex = p;
|
|
|
|
|
|
|
|
|
|
Lua *L = LUA->Get();
|
|
|
|
|
gc.PushSelf( L );
|
|
|
|
|
lua_setglobal( L, "ThisGameCommand" );
|
|
|
|
|
LUA->Release( L );
|
|
|
|
|
|
|
|
|
|
m_sprPlayer[p].Load( THEME->GetPathG(m_sName, "player") );
|
|
|
|
|
this->AddChild( m_sprPlayer[p] );
|
|
|
|
|
|
|
|
|
|
LUA->UnsetGlobal( "ThisGameCommand" );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
m_exprOnCommandFunction.SetFromExpression( THEME->GetMetric(m_sName,"TranformFunction") );
|
|
|
|
|
|
|
|
|
|
FOREACH_MultiPlayer( p )
|
|
|
|
|
{
|
|
|
|
|
PositionItem( m_sprPlayer[p], p, NUM_MultiPlayer );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
m_soundPlugIn.Load( THEME->GetPathS(m_sName,"PlugIn") );
|
|
|
|
|
m_soundUnplug.Load( THEME->GetPathS(m_sName,"Unplug") );
|
|
|
|
|
m_soundJoin.Load( THEME->GetPathS(m_sName,"Join") );
|
|
|
|
|
m_soundUnjoin.Load( THEME->GetPathS(m_sName,"Unjoin") );
|
|
|
|
|
|
2005-08-30 00:05:04 +00:00
|
|
|
UpdatePlayerStatus( true );
|
2005-08-20 22:47:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ScreenJoinMultiplayer::PositionItem( Actor *pActor, int iItemIndex, int iNumItems )
|
|
|
|
|
{
|
|
|
|
|
Lua *L = LUA->Get();
|
|
|
|
|
m_exprOnCommandFunction.PushSelf( L );
|
|
|
|
|
ASSERT( !lua_isnil(L, -1) );
|
|
|
|
|
pActor->PushSelf( L );
|
|
|
|
|
LuaHelpers::Push( iItemIndex, L );
|
|
|
|
|
LuaHelpers::Push( iNumItems, L );
|
|
|
|
|
lua_call( L, 3, 0 ); // 3 args, 0 results
|
|
|
|
|
LUA->Release(L);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ScreenJoinMultiplayer::HandleScreenMessage( const ScreenMessage SM )
|
|
|
|
|
{
|
|
|
|
|
ScreenWithMenuElements::HandleScreenMessage( SM );
|
|
|
|
|
}
|
|
|
|
|
|
2005-09-05 02:26:50 +00:00
|
|
|
void ScreenJoinMultiplayer::Input( const InputEventPlus &input )
|
2005-08-20 22:47:24 +00:00
|
|
|
{
|
|
|
|
|
if( this->IsTransitioning() )
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
// Translate input and sent to the appropriate player. Assume that all
|
|
|
|
|
// joystick devices are mapped the same as the master player.
|
2005-09-05 02:26:50 +00:00
|
|
|
if( input.type == IET_FIRST_PRESS &&
|
|
|
|
|
input.DeviceI.device >= DEVICE_JOY1 &&
|
|
|
|
|
input.DeviceI.device < DEVICE_JOY1 + NUM_MultiPlayer )
|
2005-08-20 22:47:24 +00:00
|
|
|
{
|
2005-09-05 02:26:50 +00:00
|
|
|
DeviceInput di = input.DeviceI;
|
2005-08-20 22:47:24 +00:00
|
|
|
di.device = DEVICE_JOY1;
|
|
|
|
|
GameInput gi;
|
|
|
|
|
INPUTMAPPER->DeviceToGame( di, gi );
|
|
|
|
|
|
2005-08-30 16:22:48 +00:00
|
|
|
if( gi.IsValid() )
|
2005-08-20 22:47:24 +00:00
|
|
|
{
|
|
|
|
|
MenuInput mi;
|
|
|
|
|
INPUTMAPPER->GameToMenu( gi, mi );
|
|
|
|
|
|
2005-09-05 02:26:50 +00:00
|
|
|
MultiPlayer p = InputMapper::InputDeviceToMultiPlayer( input.DeviceI.device );
|
2005-08-20 22:47:24 +00:00
|
|
|
|
2005-08-26 17:37:30 +00:00
|
|
|
// testing hack
|
|
|
|
|
if( INPUTFILTER->IsBeingPressed( DeviceInput(DEVICE_KEYBOARD,KEY_LSHIFT) ) )
|
|
|
|
|
p = (MultiPlayer)(p + 1);
|
|
|
|
|
if( INPUTFILTER->IsBeingPressed( DeviceInput(DEVICE_KEYBOARD,KEY_LCTRL) ) )
|
|
|
|
|
p = (MultiPlayer)(p + 2);
|
|
|
|
|
if( INPUTFILTER->IsBeingPressed( DeviceInput(DEVICE_KEYBOARD,KEY_LALT) ) )
|
|
|
|
|
p = (MultiPlayer)(p + 4);
|
|
|
|
|
|
2005-08-20 22:47:24 +00:00
|
|
|
ASSERT( p>=0 && p<NUM_MultiPlayer );
|
|
|
|
|
|
2005-08-30 00:05:04 +00:00
|
|
|
MultiPlayerStatus old = m_MultiPlayerStatus[p];
|
2005-08-20 22:47:24 +00:00
|
|
|
|
|
|
|
|
switch( mi.button )
|
|
|
|
|
{
|
|
|
|
|
case MENU_BUTTON_UP:
|
|
|
|
|
if( old == MultiPlayerStatus_NotJoined )
|
|
|
|
|
{
|
|
|
|
|
m_soundJoin.Play();
|
2005-08-30 00:05:04 +00:00
|
|
|
m_MultiPlayerStatus[p] = MultiPlayerStatus_Joined;
|
|
|
|
|
m_sprPlayer[p]->PlayCommand( MultiPlayerStatusToString(m_MultiPlayerStatus[p]) );
|
2005-08-20 22:47:24 +00:00
|
|
|
}
|
|
|
|
|
return; // input handled
|
|
|
|
|
case MENU_BUTTON_DOWN:
|
|
|
|
|
if( old == MultiPlayerStatus_Joined )
|
|
|
|
|
{
|
|
|
|
|
m_soundUnjoin.Play();
|
2005-08-30 00:05:04 +00:00
|
|
|
m_MultiPlayerStatus[p] = MultiPlayerStatus_NotJoined;
|
|
|
|
|
m_sprPlayer[p]->PlayCommand( MultiPlayerStatusToString(m_MultiPlayerStatus[p]) );
|
2005-08-20 22:47:24 +00:00
|
|
|
}
|
|
|
|
|
return; // input handled
|
|
|
|
|
case MENU_BUTTON_BACK:
|
|
|
|
|
MenuBack( GAMESTATE->m_MasterPlayerNumber );
|
|
|
|
|
return; // input handled
|
|
|
|
|
case MENU_BUTTON_START:
|
|
|
|
|
MenuStart( GAMESTATE->m_MasterPlayerNumber );
|
|
|
|
|
return; // input handled
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2005-09-05 02:26:50 +00:00
|
|
|
ScreenWithMenuElements::Input( input );
|
2005-08-20 22:47:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ScreenJoinMultiplayer::Update( float fDeltaTime )
|
|
|
|
|
{
|
|
|
|
|
ScreenWithMenuElements::Update(fDeltaTime);
|
2005-08-30 00:05:04 +00:00
|
|
|
|
|
|
|
|
UpdatePlayerStatus( false );
|
2005-08-20 22:47:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ScreenJoinMultiplayer::DrawPrimitives()
|
|
|
|
|
{
|
|
|
|
|
ScreenWithMenuElements::DrawPrimitives();
|
|
|
|
|
}
|
|
|
|
|
|
2005-08-30 00:05:04 +00:00
|
|
|
void ScreenJoinMultiplayer::UpdatePlayerStatus( bool bFirstUpdate )
|
2005-08-20 22:47:24 +00:00
|
|
|
{
|
|
|
|
|
FOREACH_MultiPlayer( p )
|
|
|
|
|
{
|
2005-08-30 16:22:48 +00:00
|
|
|
InputDevice id = InputMapper::MultiPlayerToInputDevice( p );
|
2005-08-20 22:47:24 +00:00
|
|
|
|
2005-08-30 00:05:04 +00:00
|
|
|
InputDeviceState idsOld = m_InputDeviceState[p];
|
|
|
|
|
bool bWasConnected = idsOld == InputDeviceState_Connected;
|
|
|
|
|
|
|
|
|
|
InputDeviceState idsNew = INPUTMAN->GetInputDeviceState(id);
|
|
|
|
|
if( INPUTFILTER->IsBeingPressed(DeviceInput(DEVICE_KEYBOARD,KEY_LSHIFT)) )
|
|
|
|
|
idsNew = InputDeviceState_Disconnected;
|
|
|
|
|
bool bIsConnected = idsNew == InputDeviceState_Connected;
|
2005-08-20 22:47:24 +00:00
|
|
|
|
2005-08-30 00:05:04 +00:00
|
|
|
MultiPlayerStatus &mps = m_MultiPlayerStatus[p];
|
2005-08-20 22:47:24 +00:00
|
|
|
|
2005-08-30 00:05:04 +00:00
|
|
|
if( bFirstUpdate || idsOld != idsNew )
|
2005-08-20 22:47:24 +00:00
|
|
|
{
|
2005-08-30 00:05:04 +00:00
|
|
|
switch( idsNew )
|
|
|
|
|
{
|
|
|
|
|
default:
|
|
|
|
|
ASSERT(0);
|
|
|
|
|
case InputDeviceState_Connected:
|
|
|
|
|
mps = MultiPlayerStatus_NotJoined;
|
|
|
|
|
break;
|
|
|
|
|
case InputDeviceState_INVALID:
|
|
|
|
|
case InputDeviceState_Disconnected:
|
|
|
|
|
mps = MultiPlayerStatus_Unplugged;
|
|
|
|
|
break;
|
|
|
|
|
case InputDeviceState_MissingMultitap:
|
|
|
|
|
mps = MultiPlayerStatus_MissingMultitap;
|
|
|
|
|
break;
|
|
|
|
|
}
|
2005-08-20 22:47:24 +00:00
|
|
|
|
2005-08-30 00:05:04 +00:00
|
|
|
m_sprPlayer[p]->PlayCommand( MultiPlayerStatusToString(mps) );
|
2005-08-20 22:47:24 +00:00
|
|
|
|
2005-08-30 00:05:04 +00:00
|
|
|
if( idsOld == InputDeviceState_INVALID )
|
|
|
|
|
{
|
|
|
|
|
m_sprPlayer[p]->FinishTweening();
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if( !bWasConnected && bIsConnected )
|
|
|
|
|
m_soundPlugIn.Play();
|
|
|
|
|
else if( bWasConnected && !bIsConnected )
|
|
|
|
|
m_soundUnplug.Play();
|
|
|
|
|
}
|
2005-08-20 22:47:24 +00:00
|
|
|
}
|
2005-08-30 00:05:04 +00:00
|
|
|
|
|
|
|
|
m_InputDeviceState[p] = idsNew;
|
2005-08-20 22:47:24 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ScreenJoinMultiplayer::MenuBack( PlayerNumber pn )
|
|
|
|
|
{
|
|
|
|
|
SOUND->StopMusic();
|
|
|
|
|
Cancel( SM_GoToPrevScreen );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ScreenJoinMultiplayer::MenuStart( PlayerNumber pn )
|
|
|
|
|
{
|
2005-08-23 20:58:24 +00:00
|
|
|
int iNumJoinedPlayers = 0;
|
|
|
|
|
FOREACH_MultiPlayer( p )
|
|
|
|
|
{
|
2005-08-30 00:05:04 +00:00
|
|
|
bool bJoined = m_MultiPlayerStatus[p] == MultiPlayerStatus_Joined;
|
2005-08-23 20:58:24 +00:00
|
|
|
GAMESTATE->m_bIsMultiPlayerJoined[p] = bJoined;
|
|
|
|
|
if( bJoined )
|
|
|
|
|
iNumJoinedPlayers++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SCREENMAN->PlayStartSound();
|
|
|
|
|
|
|
|
|
|
if( iNumJoinedPlayers < 2 )
|
|
|
|
|
{
|
|
|
|
|
ScreenPrompt::Prompt( SM_None, "You must join 2 or more players before continuing." );
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
this->StartTransitioning( SM_GoToNextScreen );
|
2005-08-20 22:47:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* (c) 2005 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.
|
|
|
|
|
*/
|