2010-04-12 06:49:05 +00:00
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers , whose names
* are too numerous to list here . Please refer to the COPYRIGHT
* file distributed with this source distribution .
*
* This program is free software ; you can redistribute it and / or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation ; either version 2
* of the License , or ( at your option ) any later version .
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
* You should have received a copy of the GNU General Public License
* along with this program ; if not , write to the Free Software
* Foundation , Inc . , 51 Franklin Street , Fifth Floor , Boston , MA 02110 - 1301 , USA .
*
* $ URL : https : //scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/trunk/backends/platform/psp/osys_psp.cpp $
* $ Id : osys_psp . cpp 43618 2009 - 08 - 21 22 : 44 : 49 Z joostp $
*
2010-04-12 07:28:54 +00:00
*/
2010-04-12 06:49:05 +00:00
2010-04-12 07:28:54 +00:00
// Todo: handle events that should fire because of shift going off
2010-04-12 06:49:05 +00:00
// Solution: handle shift on a button-by-button basis, only allowing it when the button is up. Also a inputmap-wide button. At buttonup, shiftstate is inspected per button.
2010-04-12 07:28:54 +00:00
2010-04-12 06:49:05 +00:00
//#define __PSP_DEBUG_FUNCS__ /* Uncomment for debugging the stack */
//#define __PSP_DEBUG_PRINT__ /* Uncomment for debug prints */
2010-04-12 07:28:54 +00:00
2010-04-12 06:49:05 +00:00
# include "backends/platform/psp/trace.h"
2010-05-17 07:22:26 +00:00
# include "backends/platform/psp/psppixelformat.h"
2010-04-12 06:49:05 +00:00
# include "backends/platform/psp/input.h"
// Defines for working with PSP buttons
# define CHANGED(x) (_buttonsChanged & (x))
# define PRESSED(x) ((_buttonsChanged & (x)) && (pad.Buttons & (x)))
# define UNPRESSED(x) ((_buttonsChanged & (x)) && !(pad.Buttons & (x)))
# define DOWN(x) (pad.Buttons & (x))
# define UP(x) (!(pad.Buttons & (x)))
# define PSP_DPAD (PSP_CTRL_DOWN|PSP_CTRL_UP|PSP_CTRL_LEFT|PSP_CTRL_RIGHT)
# define PSP_4BUTTONS (PSP_CTRL_CROSS | PSP_CTRL_CIRCLE | PSP_CTRL_TRIANGLE | PSP_CTRL_SQUARE)
# define PSP_TRIGGERS (PSP_CTRL_LTRIGGER | PSP_CTRL_RTRIGGER)
# define PAD_CHECK_TIME 53
void InputHandler : : init ( ) {
sceCtrlSetSamplingCycle ( 0 ) ; // set sampling to vsync. n = n usecs
sceCtrlSetSamplingMode ( 1 ) ; // analog
}
bool InputHandler : : getAllInputs ( Common : : Event & event ) {
DEBUG_ENTER_FUNC ( ) ;
2010-04-12 07:28:54 +00:00
2010-04-12 06:49:05 +00:00
uint32 time = g_system - > getMillis ( ) ; // may not be necessary with read
if ( time - _lastPadCheckTime < PAD_CHECK_TIME ) {
return false ;
}
_lastPadCheckTime = time ;
SceCtrlData pad ;
sceCtrlPeekBufferPositive ( & pad , 1 ) ; // Peek ignores sleep. Read sleeps thread
bool haveEvent ;
memset ( & event , 0 , sizeof ( event ) ) ;
if ( _keyboard - > isVisible ( ) )
haveEvent = _keyboard - > processInput ( event , pad ) ;
2010-04-12 07:28:54 +00:00
else
2010-04-12 06:49:05 +00:00
haveEvent = getEvent ( event , pad ) ;
2010-04-12 07:28:54 +00:00
if ( haveEvent ) {
2010-04-12 06:49:05 +00:00
PSP_DEBUG_PRINT ( " Have event[%s] \n " , haveEvent ? " true " : " false " ) ;
PSP_DEBUG_PRINT ( " event.type[%d] \n " , event . type ) ;
2010-04-12 07:28:54 +00:00
}
2010-04-12 06:49:05 +00:00
return haveEvent ;
}
bool InputHandler : : getEvent ( Common : : Event & event , SceCtrlData & pad ) {
DEBUG_ENTER_FUNC ( ) ;
_buttonsChanged = pad . Buttons ^ _prevButtons ;
bool haveEvent = false ;
// Collect events from different sources
haveEvent = getDpadEvent ( event , pad ) ;
2010-04-12 07:28:54 +00:00
2010-04-12 06:49:05 +00:00
if ( ! haveEvent )
haveEvent = getButtonEvent ( event , pad ) ;
2010-04-12 07:28:54 +00:00
2010-04-12 06:49:05 +00:00
if ( ! haveEvent )
2010-04-12 07:28:54 +00:00
haveEvent = getNubEvent ( event , pad ) ;
2010-04-12 06:49:05 +00:00
_prevButtons = pad . Buttons ;
2010-04-12 07:28:54 +00:00
2010-04-12 06:49:05 +00:00
return haveEvent ;
}
bool InputHandler : : getDpadEvent ( Common : : Event & event , SceCtrlData & pad ) {
DEBUG_ENTER_FUNC ( ) ;
2010-04-12 07:28:54 +00:00
2010-04-12 06:49:05 +00:00
int newDpadX = 0 , newDpadY = 0 ;
bool haveEvent = false ;
if ( DOWN ( PSP_CTRL_UP ) ) {
newDpadY + + ;
if ( DOWN ( PSP_CTRL_RTRIGGER ) ) // Shifting causes diagonals
newDpadX + + ;
}
if ( DOWN ( PSP_CTRL_RIGHT ) ) {
newDpadX + + ;
if ( DOWN ( PSP_CTRL_RTRIGGER ) )
newDpadY - - ;
}
if ( DOWN ( PSP_CTRL_DOWN ) ) {
newDpadY - - ;
if ( DOWN ( PSP_CTRL_RTRIGGER ) )
newDpadX - - ;
}
if ( DOWN ( PSP_CTRL_LEFT ) ) {
newDpadX - - ;
if ( DOWN ( PSP_CTRL_RTRIGGER ) )
newDpadY + + ;
}
2010-04-12 07:28:54 +00:00
2010-04-12 06:49:05 +00:00
if ( newDpadX ! = _dpadX | | newDpadY ! = _dpadY ) {
if ( _dpadX = = 0 & & _dpadY = = 0 ) { // We were in the middle so we pressed dpad
event . type = Common : : EVENT_KEYDOWN ;
event . kbd . keycode = translateDpad ( newDpadX , newDpadY ) ;
event . kbd . ascii = event . kbd . keycode - Common : : KEYCODE_KP0 + ' 0 ' ; // Get ascii
_dpadX = newDpadX ;
_dpadY = newDpadY ;
2010-04-12 07:28:54 +00:00
} else if ( newDpadX = = 0 & & newDpadY = = 0 ) { // We're now centered so we unpressed dpad
2010-04-12 06:49:05 +00:00
event . type = Common : : EVENT_KEYUP ;
event . kbd . keycode = translateDpad ( _dpadX , _dpadY ) ;
event . kbd . ascii = event . kbd . keycode - Common : : KEYCODE_KP0 + ' 0 ' ;
_dpadX = newDpadX ;
_dpadY = newDpadY ;
} else { // we moved from one pressed dpad direction to another one
event . type = Common : : EVENT_KEYUP ; // first release the last dpad direction
event . kbd . keycode = translateDpad ( _dpadX , _dpadY ) ;
event . kbd . ascii = event . kbd . keycode - Common : : KEYCODE_KP0 + ' 0 ' ;
_dpadX = 0 ; // so that we'll pick up a new dpad movement the next round
_dpadY = 0 ;
}
2010-04-12 07:28:54 +00:00
2010-04-12 06:49:05 +00:00
PSP_DEBUG_PRINT ( " Keypad event. DpadX[%d], DpadY[%d] \n " , _dpadX , _dpadY ) ;
haveEvent = true ;
}
return haveEvent ;
}
inline Common : : KeyCode InputHandler : : translateDpad ( int x , int y ) {
DEBUG_ENTER_FUNC ( ) ;
Common : : KeyCode key ;
if ( x = = - 1 ) {
if ( y = = - 1 )
key = Common : : KEYCODE_KP1 ;
else if ( y = = 0 )
key = Common : : KEYCODE_KP4 ;
else /* y == 1 */
key = Common : : KEYCODE_KP7 ;
} else if ( x = = 0 ) {
if ( y = = - 1 )
key = Common : : KEYCODE_KP2 ;
else /* y == 1 */
key = Common : : KEYCODE_KP8 ;
} else { /* x == 1 */
if ( y = = - 1 )
key = Common : : KEYCODE_KP3 ;
else if ( y = = 0 )
key = Common : : KEYCODE_KP6 ;
else /* y == 1 */
key = Common : : KEYCODE_KP9 ;
}
return key ;
}
bool InputHandler : : getButtonEvent ( Common : : Event & event , SceCtrlData & pad ) {
DEBUG_ENTER_FUNC ( ) ;
bool haveEvent = false ;
if ( PRESSED ( PSP_CTRL_SELECT ) )
_keyboard - > setVisible ( true ) ;
else if ( CHANGED ( PSP_4BUTTONS | PSP_TRIGGERS | PSP_CTRL_START ) ) {
if ( CHANGED ( PSP_CTRL_CROSS ) ) {
event . type = DOWN ( PSP_CTRL_CROSS ) ? Common : : EVENT_LBUTTONDOWN : Common : : EVENT_LBUTTONUP ;
event . mouse . x = _cursor - > getX ( ) ; // Could this have to do with SCI enter problem?
event . mouse . y = _cursor - > getY ( ) ;
2010-04-12 07:28:54 +00:00
PSP_DEBUG_PRINT ( " %s \n " , event . type = = Common : : EVENT_LBUTTONDOWN ? " LButtonDown " : " LButtonUp " ) ;
2010-04-12 06:49:05 +00:00
} else if ( CHANGED ( PSP_CTRL_CIRCLE ) ) {
event . type = DOWN ( PSP_CTRL_CIRCLE ) ? Common : : EVENT_RBUTTONDOWN : Common : : EVENT_RBUTTONUP ;
event . mouse . x = _cursor - > getX ( ) ;
event . mouse . y = _cursor - > getY ( ) ;
PSP_DEBUG_PRINT ( " %s \n " , event . type = = Common : : EVENT_LBUTTONDOWN ? " RButtonDown " : " RButtonUp " ) ;
} else {
//any of the other buttons.
event . type = _buttonsChanged & pad . Buttons ? Common : : EVENT_KEYDOWN : Common : : EVENT_KEYUP ;
event . kbd . ascii = 0 ;
event . kbd . flags = 0 ;
if ( CHANGED ( PSP_CTRL_LTRIGGER ) ) {
event . kbd . keycode = Common : : KEYCODE_ESCAPE ;
event . kbd . ascii = 27 ;
} else if ( CHANGED ( PSP_CTRL_START ) ) {
event . kbd . keycode = Common : : KEYCODE_F5 ;
event . kbd . ascii = Common : : ASCII_F5 ;
if ( DOWN ( PSP_CTRL_RTRIGGER ) ) {
event . kbd . flags | = Common : : KBD_CTRL ; // Main menu to allow RTL
}
} else if ( CHANGED ( PSP_CTRL_SQUARE ) ) {
event . kbd . keycode = Common : : KEYCODE_PERIOD ;
event . kbd . ascii = ' . ' ;
} else if ( CHANGED ( PSP_CTRL_TRIANGLE ) ) {
event . kbd . keycode = Common : : KEYCODE_RETURN ;
event . kbd . ascii = ' \r ' ;
} else if ( DOWN ( PSP_CTRL_RTRIGGER ) ) { // An event
event . kbd . flags | = Common : : KBD_SHIFT ;
}
2010-04-12 07:28:54 +00:00
PSP_DEBUG_PRINT ( " Ascii[%d]. Key %s. \n " , event . kbd . ascii , event . type = = Common : : EVENT_KEYDOWN ? " down " : " up " ) ;
2010-04-12 06:49:05 +00:00
}
2010-04-12 07:28:54 +00:00
2010-04-12 06:49:05 +00:00
haveEvent = true ;
}
2010-04-12 07:28:54 +00:00
2010-04-12 06:49:05 +00:00
return haveEvent ;
}
bool InputHandler : : getNubEvent ( Common : : Event & event , SceCtrlData & pad ) {
DEBUG_ENTER_FUNC ( ) ;
bool haveEvent = false ;
2010-04-12 07:28:54 +00:00
int32 analogStepX = pad . Lx ; // Goes up to 255.
2010-04-12 06:49:05 +00:00
int32 analogStepY = pad . Ly ;
int32 oldX = _cursor - > getX ( ) ;
int32 oldY = _cursor - > getY ( ) ;
analogStepX = modifyNubAxisMotion ( analogStepX ) ;
analogStepY = modifyNubAxisMotion ( analogStepY ) ;
2010-04-12 07:28:54 +00:00
2010-04-12 06:49:05 +00:00
if ( analogStepX ! = 0 | | analogStepY ! = 0 ) {
2010-04-12 07:28:54 +00:00
2010-04-12 06:49:05 +00:00
PSP_DEBUG_PRINT ( " raw x[%d], y[%d] \n " , analogStepX , analogStepY ) ;
2010-04-12 07:28:54 +00:00
2010-04-12 06:49:05 +00:00
// If no movement then this has no effect
if ( DOWN ( PSP_CTRL_RTRIGGER ) ) {
// Fine control mode for analog
2010-04-12 07:28:54 +00:00
if ( analogStepX ! = 0 ) {
if ( analogStepX > 0 )
_cursor - > increaseXY ( 2 , 0 ) ;
else
_cursor - > increaseXY ( - 2 , 0 ) ;
}
2010-04-12 06:49:05 +00:00
2010-04-12 07:28:54 +00:00
if ( analogStepY ! = 0 ) {
if ( analogStepY > 0 )
_cursor - > increaseXY ( 0 , 2 ) ;
else
_cursor - > increaseXY ( 0 , - 2 ) ;
}
2010-04-12 06:49:05 +00:00
} else { // Regular speed movement
_cursor - > increaseXY ( analogStepX , 0 ) ;
_cursor - > increaseXY ( 0 , analogStepY ) ;
}
int32 newX = _cursor - > getX ( ) ;
int32 newY = _cursor - > getY ( ) ;
if ( ( oldX ! = newX ) | | ( oldY ! = newY ) ) {
event . type = Common : : EVENT_MOUSEMOVE ;
event . mouse . x = newX ;
event . mouse . y = newY ;
haveEvent = true ;
2010-04-12 07:28:54 +00:00
2010-04-12 06:49:05 +00:00
PSP_DEBUG_PRINT ( " Nub event. X[%d], Y[%d] \n " , newX , newY ) ;
}
}
return haveEvent ;
}
inline int32 InputHandler : : modifyNubAxisMotion ( int32 input ) {
DEBUG_ENTER_FUNC ( ) ;
const int MIN_NUB_MOTION = 30 ;
2010-04-12 07:28:54 +00:00
2010-04-12 06:49:05 +00:00
input - = 128 ; // Center on 0.
2010-04-12 07:28:54 +00:00
2010-04-12 06:49:05 +00:00
if ( input < - MIN_NUB_MOTION - 1 )
input + = MIN_NUB_MOTION + 1 ; // reduce the velocity
else if ( input > MIN_NUB_MOTION )
input - = MIN_NUB_MOTION ; // same
2010-04-12 07:28:54 +00:00
else // between these points, dampen the response to 0
2010-04-12 06:49:05 +00:00
input = 0 ;
2010-04-12 07:28:54 +00:00
return input ;
2010-04-12 06:49:05 +00:00
}