UQM: directional input for navigating and for lander

This commit is contained in:
pelya
2010-10-27 18:12:02 +03:00
parent e90045e3d9
commit 98a405a96a
6 changed files with 93 additions and 74 deletions

View File

@@ -19,8 +19,8 @@ RedefinedKeys="RETURN RSHIFT KP_PLUS KP_MINUS ESCAPE F10"
AppTouchscreenKeyboardKeysAmount=2
AppTouchscreenKeyboardKeysAmountAutoFire=0
MultiABI=n
AppVersionCode=1013
AppVersionName="1.0.13"
AppVersionCode=06914
AppVersionName="0.6.9.14 - better controls for accelerometer and on-screen keyboard input"
CompiledLibraries="sdl_image tremor ogg"
CustomBuildScript=n
AppCflags='-O2 -finline-functions -DTHREADLIB_SDL=1 -DTIMELIB=SDL -DOVCODEC_TREMOR=1 -DNETPLAY=1 -DHAVE_REGEX=1 -DHAVE_GETOPT_LONG=1 -DHAVE_ZIP=1 -DHAVE_JOYSTICK=1 -DDIRECTIONAL_JOYSTICK_MELEE=1'

View File

@@ -144,13 +144,7 @@ frameInputHuman (HumanInputContext *context, STARSHIP *StarShipPtr)
{
(void) StarShipPtr;
return CurrentInputToBattleInput (context->playerNr,
#ifdef DIRECTIONAL_JOYSTICK_MELEE
StarShipPtr && VControl_GetJoysticksAmount() > 0 && ( GLOBAL (CurrentActivity) & IN_BATTLE ) ? StarShipPtr->ShipFacing : -1
#else
-1
#endif
);
return CurrentInputToBattleInput (context->playerNr, StarShipPtr ? StarShipPtr->ShipFacing : -1);
}
static void

View File

@@ -112,6 +112,9 @@ BOOLEAN WaitForAnyButtonUntil (BOOLEAN newButton, TimeCount timeOut,
BOOLEAN WaitForNoInput (TimePeriod duration, BOOLEAN resetInput);
BOOLEAN WaitForNoInputUntil (TimeCount timeOut, BOOLEAN resetInput);
/* TODO: only joystick #0 and player #0 supported currently */
extern BATTLE_INPUT_STATE GetDirectionalJoystickInput(int direction);
void DoPopupWindow(const char *msg);
typedef void (InputFrameCallback) (void);

View File

@@ -425,35 +425,6 @@ GetMenuSounds (MENU_SOUND_FLAGS *s0, MENU_SOUND_FLAGS *s1)
*s1 = sound_1;
}
// Fast arctan2, returns angle in radians as integer, with fractional part in lower 16 bits
// Stolen from http://www.dspguru.com/dsp/tricks/fixed-point-atan2-with-self-normalization , precision is said to be 0.07 rads
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif
enum { atan2i_coeff_1 = ((int)(M_PI*65536.0/4)), atan2i_coeff_2 = (3*atan2i_coeff_1), atan2i_PI = (int)(M_PI * 65536.0), SHIP_DIRECTIONS = 16 };
static inline int atan2i(int y, int x)
{
int angle;
int abs_y = abs(y);
if( abs_y == 0 )
abs_y = 1;
if (x>=0)
{
angle = atan2i_coeff_1 - atan2i_coeff_1 * (x - abs_y) / (x + abs_y);
}
else
{
angle = atan2i_coeff_2 - atan2i_coeff_1 * (x + abs_y) / (abs_y - x);
}
if (y < 0)
return(-angle); // negate if in quad III or IV
else
return(angle);
}
static BATTLE_INPUT_STATE
ControlInputToBattleInput (const int *keyState, int direction)
{
@@ -479,33 +450,7 @@ ControlInputToBattleInput (const int *keyState, int direction)
}
else
{
// TODO: only joystick #0 supported currently
int axisX = VControl_GetJoyAxis(0, 0), axisY = VControl_GetJoyAxis(0, 1);
if( axisX != 0 || axisY != 0 )
{
int angle = atan2i(axisY, axisX), diff;
// Convert it to 16 directions used by Melee
angle += atan2i_PI / SHIP_DIRECTIONS;
if( angle < 0 )
angle += atan2i_PI * 2;
if( angle > atan2i_PI * 2 )
angle -= atan2i_PI * 2;
angle = angle * SHIP_DIRECTIONS / atan2i_PI / 2;
diff = angle - direction + SHIP_DIRECTIONS / 4;
while( diff >= SHIP_DIRECTIONS )
diff -= SHIP_DIRECTIONS;
while( diff < 0 )
diff += SHIP_DIRECTIONS;
if( diff < SHIP_DIRECTIONS / 2 )
InputState |= BATTLE_LEFT;
if( diff > SHIP_DIRECTIONS / 2 )
InputState |= BATTLE_RIGHT;
if( ((axisX*axisX)>>1) + ((axisY*axisY)>>1) > (16384*16384)>>1 ) // Force of joystick tilt, equation is clumsy because (axisX*axisX + axisY*axisY) may overflow int32
InputState |= BATTLE_THRUST;
}
InputState |= GetDirectionalJoystickInput(direction);
}
return InputState;
@@ -567,3 +512,80 @@ ConfirmExit (void)
return result;
}
// Fast arctan2, returns angle in radians as integer, with fractional part in lower 16 bits
// Stolen from http://www.dspguru.com/dsp/tricks/fixed-point-atan2-with-self-normalization , precision is said to be 0.07 rads
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif
enum { atan2i_coeff_1 = ((int)(M_PI*65536.0/4)), atan2i_coeff_2 = (3*atan2i_coeff_1), atan2i_PI = (int)(M_PI * 65536.0), SHIP_DIRECTIONS = 16 };
static inline int atan2i(int y, int x)
{
int angle;
int abs_y = abs(y);
if( abs_y == 0 )
abs_y = 1;
if (x>=0)
{
angle = atan2i_coeff_1 - atan2i_coeff_1 * (x - abs_y) / (x + abs_y);
}
else
{
angle = atan2i_coeff_2 - atan2i_coeff_1 * (x + abs_y) / (abs_y - x);
}
if (y < 0)
return(-angle); // negate if in quad III or IV
else
return(angle);
}
BATTLE_INPUT_STATE GetDirectionalJoystickInput(int direction)
{
BATTLE_INPUT_STATE InputState = 0;
#ifdef DIRECTIONAL_JOYSTICK_MELEE
if(VControl_GetJoysticksAmount() <= 0)
#endif
{
if(CurrentInputState.key[PlayerControls[0]][KEY_UP])
InputState |= BATTLE_THRUST;
if (CurrentInputState.key[PlayerControls[0]][KEY_LEFT])
InputState |= BATTLE_LEFT;
if (CurrentInputState.key[PlayerControls[0]][KEY_RIGHT])
InputState |= BATTLE_RIGHT;
}
#ifdef DIRECTIONAL_JOYSTICK_MELEE
else
{
/* TODO: only joystick #0 supported currently */
int axisX = VControl_GetJoyAxis(0, 0), axisY = VControl_GetJoyAxis(0, 1);
if( axisX != 0 || axisY != 0 )
{
int angle = atan2i(axisY, axisX), diff;
// Convert it to 16 directions used by Melee
angle += atan2i_PI / SHIP_DIRECTIONS;
if( angle < 0 )
angle += atan2i_PI * 2;
if( angle > atan2i_PI * 2 )
angle -= atan2i_PI * 2;
angle = angle * SHIP_DIRECTIONS / atan2i_PI / 2;
diff = angle - direction + SHIP_DIRECTIONS / 4;
while( diff >= SHIP_DIRECTIONS )
diff -= SHIP_DIRECTIONS;
while( diff < 0 )
diff += SHIP_DIRECTIONS;
if( diff < SHIP_DIRECTIONS / 2 )
InputState |= BATTLE_LEFT;
if( diff > SHIP_DIRECTIONS / 2 )
InputState |= BATTLE_RIGHT;
if( ((axisX*axisX)>>1) + ((axisY*axisY)>>1) > (16384*16384)>>1 ) // Force of joystick tilt, equation is clumsy because (axisX*axisX + axisY*axisY) may overflow int32
InputState |= BATTLE_THRUST;
}
}
#endif
return InputState;
}

View File

@@ -1669,15 +1669,15 @@ landerSpeedNumer = WORLD_TO_VELOCITY (48);
if (crew_left)
{
SIZE index = GetFrameIndex (LanderFrame[0]);
BATTLE_INPUT_STATE InputState = GetDirectionalJoystickInput(index);
if (turn_wait)
--turn_wait;
else if (CurrentInputState.key[PlayerControls[0]][KEY_LEFT] ||
CurrentInputState.key[PlayerControls[0]][KEY_RIGHT])
else if ((InputState & BATTLE_LEFT) || (InputState & BATTLE_RIGHT))
{
COUNT landerSpeedNumer;
COUNT angle;
if (CurrentInputState.key[PlayerControls[0]][KEY_LEFT])
if (InputState & BATTLE_LEFT)
--index;
else
++index;
@@ -1701,7 +1701,7 @@ landerSpeedNumer = WORLD_TO_VELOCITY (48);
turn_wait = SHUTTLE_TURN_WAIT;
}
if (!CurrentInputState.key[PlayerControls[0]][KEY_UP])
if (!(InputState & BATTLE_THRUST))
{
dx = 0;
dy = 0;

View File

@@ -841,18 +841,19 @@ flagship_inertial_thrust (COUNT CurrentAngle)
static void
ProcessShipControls (void)
{
COUNT index;
COUNT index = GetFrameIndex (GLOBAL (ShipStamp.frame));;
SIZE delta_x, delta_y;
BATTLE_INPUT_STATE InputState = GetDirectionalJoystickInput(index);
if (CurrentInputState.key[PlayerControls[0]][KEY_UP])
if (InputState & BATTLE_THRUST)
delta_y = -1;
else
delta_y = 0;
delta_x = 0;
if (CurrentInputState.key[PlayerControls[0]][KEY_LEFT])
if (InputState & BATTLE_LEFT)
delta_x -= 1;
if (CurrentInputState.key[PlayerControls[0]][KEY_RIGHT])
if (InputState & BATTLE_RIGHT)
delta_x += 1;
if (delta_x || delta_y < 0)
@@ -865,7 +866,6 @@ ProcessShipControls (void)
else
delta_y = 0;
index = GetFrameIndex (GLOBAL (ShipStamp.frame));
if (pSolarSysState->turn_counter)
--pSolarSysState->turn_counter;
else if (delta_x)