2006-03-20 17:12:09 +00:00
/*
2014-06-01 17:55:23 +00:00
* Portions of this file are copyright Rebirth contributors and licensed as
* described in COPYING . txt .
* Portions of this file are copyright Parallax Software and licensed
* according to the Parallax license below .
* See COPYING . txt for license details .
2006-03-20 17:12:09 +00:00
THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
SOFTWARE CORPORATION ( " PARALLAX " ) . PARALLAX , IN DISTRIBUTING THE CODE TO
END - USERS , AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN , GRANTS A
ROYALTY - FREE , PERPETUAL LICENSE TO SUCH END - USERS FOR USE BY SUCH END - USERS
IN USING , DISPLAYING , AND CREATING DERIVATIVE WORKS THEREOF , SO LONG AS
SUCH USE , DISPLAY OR CREATION IS FOR NON - COMMERCIAL , ROYALTY OR REVENUE
FREE PURPOSES . IN NO EVENT SHALL THE END - USER USE THE COMPUTER CODE
CONTAINED HEREIN FOR REVENUE - BEARING PURPOSES . THE END - USER UNDERSTANDS
AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE .
COPYRIGHT 1993 - 1999 PARALLAX SOFTWARE CORPORATION . ALL RIGHTS RESERVED .
*/
/*
*
* Routines to configure keyboard , joystick , etc . .
*
*/
2013-11-03 02:56:01 +00:00
# include <algorithm>
2006-03-20 17:12:09 +00:00
# include <stdio.h>
# include <stdlib.h>
# include <string.h>
# include <stdarg.h>
# include <ctype.h>
2013-11-02 18:16:00 +00:00
# include <cstddef>
2013-11-03 23:15:09 +00:00
# include <stdexcept>
2015-04-29 10:34:37 +00:00
# include <functional>
2006-03-20 17:12:09 +00:00
2012-07-07 18:35:06 +00:00
# include "dxxerror.h"
2006-03-20 17:12:09 +00:00
# include "pstypes.h"
# include "gr.h"
2010-01-18 05:53:13 +00:00
# include "window.h"
2008-04-06 20:23:28 +00:00
# include "console.h"
2006-03-20 17:12:09 +00:00
# include "palette.h"
2014-07-20 01:09:55 +00:00
# include "physfsx.h"
2006-03-20 17:12:09 +00:00
# include "game.h"
# include "gamefont.h"
# include "u_mem.h"
# include "kconfig.h"
# include "digi.h"
2015-04-19 04:18:51 +00:00
# include "key.h"
# include "mouse.h"
2006-03-20 17:12:09 +00:00
# include "newmenu.h"
# include "multi.h"
# include "timer.h"
# include "text.h"
# include "player.h"
# include "args.h"
2008-04-13 00:28:36 +00:00
# include "playsave.h"
2015-11-01 21:15:38 +00:00
# include "screens.h"
2006-03-20 17:12:09 +00:00
2020-07-05 23:34:33 +00:00
# include "d_array.h"
2020-08-28 00:18:45 +00:00
# include "d_range.h"
2020-07-05 23:34:33 +00:00
# include "d_zip.h"
2020-08-28 00:18:45 +00:00
# include "partial_range.h"
2013-11-16 00:42:04 +00:00
2013-11-03 02:56:01 +00:00
using std : : min ;
using std : : max ;
2013-12-07 21:34:53 +00:00
using std : : plus ;
using std : : minus ;
2013-11-03 02:56:01 +00:00
2020-04-19 20:47:07 +00:00
namespace dcx {
2006-03-20 17:12:09 +00:00
// Array used to 'blink' the cursor while waiting for a keypress.
2020-08-28 00:18:45 +00:00
const std : : array < int8_t , 64 > fades { {
2015-04-02 02:36:52 +00:00
1 , 1 , 1 , 2 , 2 , 3 , 4 , 4 , 5 , 6 , 8 , 9 , 10 , 12 , 13 , 15 ,
16 , 17 , 19 , 20 , 22 , 23 , 24 , 26 , 27 , 28 , 28 , 29 , 30 , 30 , 31 , 31 ,
31 , 31 , 31 , 30 , 30 , 29 , 28 , 28 , 27 , 26 , 24 , 23 , 22 , 20 , 19 , 17 ,
16 , 15 , 13 , 12 , 10 , 9 , 8 , 6 , 5 , 4 , 4 , 3 , 2 , 2 , 1 , 1
} } ;
2006-03-20 17:12:09 +00:00
2020-05-02 21:18:42 +00:00
const std : : array < char [ 2 ] , 2 > invert_text { { " N " , " Y " } } ;
2020-07-16 02:31:04 +00:00
# if DXX_MAX_JOYSTICKS
2013-11-09 23:31:19 +00:00
joybutton_text_t joybutton_text ;
2015-11-01 21:15:40 +00:00
# endif
2016-09-25 04:52:49 +00:00
# if DXX_MAX_AXES_PER_JOYSTICK
2013-11-09 23:17:28 +00:00
joyaxis_text_t joyaxis_text ;
2015-11-01 21:15:40 +00:00
# endif
2016-07-16 16:52:04 +00:00
constexpr char mouseaxis_text [ ] [ 8 ] = { " L/R " , " F/B " , " WHEEL " } ;
constexpr char mousebutton_text [ ] [ 8 ] = { " LEFT " , " RIGHT " , " MID " , " M4 " , " M5 " , " M6 " , " M7 " , " M8 " , " M9 " , " M10 " , " M11 " , " M12 " , " M13 " , " M14 " , " M15 " , " M16 " } ;
2006-03-20 17:12:09 +00:00
2020-05-02 21:18:42 +00:00
const std : : array < uint8_t , 19 > system_keys { {
2015-03-22 18:49:21 +00:00
KEY_ESC , KEY_F1 , KEY_F2 , KEY_F3 , KEY_F4 , KEY_F5 , KEY_F6 , KEY_F7 , KEY_F8 , KEY_F9 , KEY_F10 , KEY_F11 , KEY_F12 , KEY_MINUS , KEY_EQUAL , KEY_PRINT_SCREEN ,
// KEY_*LOCK should always be last since we wanna skip these if -nostickykeys
KEY_CAPSLOCK , KEY_SCROLLOCK , KEY_NUMLOCK
} } ;
2006-03-20 17:12:09 +00:00
fix Cruise_speed = 0 ;
2007-03-06 10:36:37 +00:00
# define INFO_Y (188)
2006-03-20 17:12:09 +00:00
2020-05-02 21:18:42 +00:00
const std : : array < uint8_t , MAX_DXX_REBIRTH_CONTROLS > DefaultKeySettingsRebirth { { 0x2 , 0xff , 0xff , 0x3 , 0xff , 0xff , 0x4 , 0xff , 0xff , 0x5 , 0xff , 0xff , 0x6 , 0xff , 0xff , 0x7 , 0xff , 0xff , 0x8 , 0xff , 0xff , 0x9 , 0xff , 0xff , 0xa , 0xff , 0xff , 0xb , 0xff , 0xff } } ;
2016-12-22 05:21:16 +00:00
2020-05-28 03:21:22 +00:00
void kconfig_begin_loop ( control_info & Controls )
{
Controls . pitch_time = Controls . vertical_thrust_time = Controls . heading_time = Controls . sideways_thrust_time = Controls . bank_time = Controls . forward_thrust_time = 0 ;
}
2015-08-12 03:11:46 +00:00
namespace {
2020-08-28 00:18:45 +00:00
struct kc_mitem {
uint8_t oldvalue ;
uint8_t value ; // what key,button,etc
} ;
2019-12-22 05:34:08 +00:00
enum kc_type : uint8_t
{
BT_KEY = 0 ,
BT_MOUSE_BUTTON = 1 ,
BT_MOUSE_AXIS = 2 ,
BT_JOY_BUTTON = 3 ,
BT_JOY_AXIS = 4 ,
BT_INVERT = 5 ,
} ;
enum kc_state : uint8_t
{
STATE_NONE = 0 ,
STATE_BIT1 = 1 ,
STATE_BIT2 = 2 ,
STATE_BIT3 = 4 ,
STATE_BIT4 = 8 ,
STATE_BIT5 = 16 ,
} ;
2020-08-28 00:18:45 +00:00
static void kc_drawquestion ( grs_canvas & canvas , const grs_font & cv_font , uint8_t & menu_fade_index , const short item_xinput , const short item_y , const int8_t item_w2 , const color_palette_index color )
{
if ( + + menu_fade_index > 63 )
menu_fade_index = 0 ;
2021-09-12 16:20:52 +00:00
const auto & & [ w , h ] = gr_get_string_size ( cv_font , " ? " ) ;
2020-08-28 00:18:45 +00:00
const auto & & fspacx = FSPACX ( ) ;
const auto & & fspacy = FSPACY ( ) ;
const auto & & fspacx_item_xinput = fspacx ( item_xinput ) ;
const auto & & fspacy_item_y = fspacy ( item_y ) ;
gr_urect ( canvas , fspacx_item_xinput , fspacy ( item_y - 1 ) , fspacx ( item_xinput + item_w2 ) , fspacy_item_y + h , color ) ;
gr_set_fontcolor ( canvas , BM_XRGB ( 28 , 28 , 28 ) , - 1 ) ;
const auto x = fspacx_item_xinput + ( ( fspacx ( item_w2 ) - w ) / 2 ) ;
gr_string ( canvas , cv_font , x , fspacy_item_y , " ? " , w , h ) ;
}
}
}
namespace dsx {
control_info Controls ;
namespace {
2019-12-22 05:34:08 +00:00
# define kc_item kc_item
2013-12-22 22:03:07 +00:00
struct kc_item
{
2012-07-22 23:17:54 +00:00
const short x , y ; // x, y pos of label
2013-11-02 17:02:03 +00:00
const short xinput ; // x pos of input field
2016-12-22 05:21:16 +00:00
const int8_t w2 ; // length of input field
const uint8_t u , d , l , r ; // neighboring field ids for cursor navigation
2019-12-22 05:34:08 +00:00
const kc_type type ;
const kc_state state_bit ;
2013-11-09 00:25:56 +00:00
union {
2016-12-22 05:21:16 +00:00
uint8_t control_info : : state_controls_t : : * const ci_state_ptr ;
uint8_t control_info : : state_controls_t : : * const ci_count_ptr ;
2013-11-09 00:25:56 +00:00
} ;
2013-12-22 22:03:07 +00:00
} ;
2006-03-20 17:12:09 +00:00
2020-08-28 00:18:45 +00:00
struct kc_menu : window
2010-01-18 05:53:13 +00:00
{
2020-08-28 00:18:45 +00:00
using window : : window ;
2013-11-27 22:39:47 +00:00
const char * litems ;
2013-11-08 23:59:03 +00:00
const kc_item * items ;
kc_mitem * mitems ;
2012-07-22 23:17:54 +00:00
const char * title ;
2013-10-09 01:54:12 +00:00
unsigned nitems ;
2020-10-22 02:26:16 +00:00
unsigned citem = 0 ;
uint8_t changing = 0 ;
2010-01-18 05:53:13 +00:00
ubyte q_fade_i ; // for flashing the question mark
2020-10-22 02:26:16 +00:00
uint8_t mouse_state = 0 ;
2020-05-02 21:18:42 +00:00
std : : array < int , 3 > old_maxis ;
2016-09-25 04:52:49 +00:00
# if DXX_MAX_AXES_PER_JOYSTICK
2020-05-02 21:18:42 +00:00
std : : array < int , JOY_MAX_AXES > old_jaxis ;
2015-11-01 21:15:40 +00:00
# endif
2020-08-28 00:18:45 +00:00
virtual window_event_result event_handler ( const d_event & ) override ;
2013-12-22 22:03:07 +00:00
} ;
2006-03-20 17:12:09 +00:00
2015-08-12 03:11:46 +00:00
}
2017-12-05 05:29:55 +00:00
const struct player_config : : KeySettings DefaultKeySettings {
2020-07-05 23:34:33 +00:00
/* Keyboard */ { { {
2013-03-03 01:03:33 +00:00
# if defined(DXX_BUILD_DESCENT_I)
2018-05-12 21:13:05 +00:00
KEY_UP , KEY_PAD8 , KEY_DOWN , KEY_PAD2 , KEY_LEFT , KEY_PAD4 , KEY_RIGHT , KEY_PAD6 , KEY_LALT , 0xff , KEY_A , KEY_PAD1 , KEY_D , KEY_PAD3 , KEY_C , KEY_PADMINUS , KEY_X , KEY_PADPLUS , 0xff , 0xff , KEY_Q , KEY_PAD7 , KEY_E , KEY_PAD9 , KEY_LCTRL , KEY_RCTRL , KEY_SPACEBAR , 0xff , KEY_F , 0xff , KEY_W , 0xff , KEY_S , 0xff , KEY_B , 0xff , KEY_R , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , KEY_TAB , 0xff , KEY_COMMA , 0x0 , KEY_PERIOD , 0x0
2013-03-03 01:03:33 +00:00
# elif defined(DXX_BUILD_DESCENT_II)
2018-05-12 21:13:05 +00:00
KEY_UP , KEY_PAD8 , KEY_DOWN , KEY_PAD2 , KEY_LEFT , KEY_PAD4 , KEY_RIGHT , KEY_PAD6 , KEY_LALT , 0xff , KEY_A , KEY_PAD1 , KEY_D , KEY_PAD3 , KEY_C , KEY_PADMINUS , KEY_X , KEY_PADPLUS , 0xff , 0xff , KEY_Q , KEY_PAD7 , KEY_E , KEY_PAD9 , KEY_LCTRL , KEY_RCTRL , KEY_SPACEBAR , 0xff , KEY_F , 0xff , KEY_W , 0xff , KEY_S , 0xff , KEY_B , 0xff , KEY_R , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , KEY_TAB , 0xff , KEY_LSHIFT , 0xff , KEY_COMMA , 0xff , KEY_PERIOD , 0xff , KEY_H , 0xff , KEY_T , 0xff , 0xff , 0xff , 0x0 , 0x0
2013-03-03 01:03:33 +00:00
# endif
2020-07-05 23:34:33 +00:00
} } } ,
2017-12-05 05:29:55 +00:00
# if DXX_MAX_JOYSTICKS
2020-07-05 23:34:33 +00:00
{ { {
2017-12-05 05:29:55 +00:00
# if defined(DXX_BUILD_DESCENT_I)
2020-06-29 21:16:04 +00:00
0x0 , 0x1 , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0x1 , 0x0 , 0x0 , 0x0 , 0xff , 0x0 , 0xff , 0x0 , 0xff , 0x0 , 0xff , 0x0 , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff
2017-12-05 05:29:55 +00:00
# elif defined(DXX_BUILD_DESCENT_II)
2020-06-29 21:16:04 +00:00
0x0 , 0x1 , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0x1 , 0x0 , 0x0 , 0x0 , 0xff , 0x0 , 0xff , 0x0 , 0xff , 0x0 , 0xff , 0x0 , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff
2017-12-05 05:29:55 +00:00
# endif
2020-07-05 23:34:33 +00:00
} } } ,
2017-12-05 05:29:55 +00:00
# endif
2020-07-05 23:34:33 +00:00
/* Mouse */ { { {
2017-12-05 05:29:55 +00:00
# if defined(DXX_BUILD_DESCENT_I)
0x0 , 0x1 , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0x1 , 0x0 , 0x0 , 0x0 , 0xff , 0x0 , 0xff , 0x0 , 0xff , 0x0 , 0xff , 0x0 , 0xff , 0xff , 0xff , 0xff , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0
# elif defined(DXX_BUILD_DESCENT_II)
0x0 , 0x1 , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0x1 , 0x0 , 0x0 , 0x0 , 0xff , 0x0 , 0xff , 0x0 , 0xff , 0x0 , 0xff , 0x0 , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0x0 , 0x0 , 0x0 , 0x0 , 0x0
# endif
2020-07-05 23:34:33 +00:00
} } }
2017-12-05 05:29:55 +00:00
} ;
2006-03-20 17:12:09 +00:00
2020-07-05 23:34:33 +00:00
# if defined(DXX_BUILD_DESCENT_I)
2020-08-10 03:45:14 +00:00
# include /* generated by similar/main/generate-kconfig-udlr.py */ "d1x-rebirth / kconfig.udlr.h"
2020-07-05 23:34:33 +00:00
# elif defined(DXX_BUILD_DESCENT_II)
2020-08-10 03:45:14 +00:00
# include /* generated by similar/main/generate-kconfig-udlr.py */ "d2x-rebirth / kconfig.udlr.h"
2020-07-05 23:34:33 +00:00
# endif
2018-02-01 05:38:47 +00:00
namespace {
2006-03-20 17:12:09 +00:00
2013-03-03 01:03:33 +00:00
# if defined(DXX_BUILD_DESCENT_I)
# define D2X_EXTENDED_WEAPON_STRING(X)
# elif defined(DXX_BUILD_DESCENT_II)
2013-08-16 02:43:25 +00:00
# define D2X_EXTENDED_WEAPON_STRING(X) X
2013-03-03 01:03:33 +00:00
# endif
2013-08-16 02:43:25 +00:00
# define WEAPON_STRING_LASER D2X_EXTENDED_WEAPON_STRING("(SUPER)") "LASER CANNON"
# define WEAPON_STRING_VULCAN "VULCAN" D2X_EXTENDED_WEAPON_STRING(" / GAUSS") " CANNON"
# define WEAPON_STRING_SPREADFIRE "SPREADFIRE" D2X_EXTENDED_WEAPON_STRING(" / HELIX") " CANNON"
# define WEAPON_STRING_PLASMA "PLASMA" D2X_EXTENDED_WEAPON_STRING(" / PHOENIX") " CANNON"
# define WEAPON_STRING_FUSION "FUSION" D2X_EXTENDED_WEAPON_STRING(" / OMEGA") " CANNON"
# define WEAPON_STRING_CONCUSSION "CONCUSSION" D2X_EXTENDED_WEAPON_STRING(" / FLASH") " MISSILE"
# define WEAPON_STRING_HOMING "HOMING" D2X_EXTENDED_WEAPON_STRING(" / GUIDED") " MISSILE"
# define WEAPON_STRING_PROXIMITY "PROXIMITY BOMB" D2X_EXTENDED_WEAPON_STRING(" / SMART MINE")
# define WEAPON_STRING_SMART "SMART" D2X_EXTENDED_WEAPON_STRING(" / MERCURY") " MISSILE"
# define WEAPON_STRING_MEGA "MEGA" D2X_EXTENDED_WEAPON_STRING(" / EARTHSHAKER") " MISSILE"
2016-09-25 04:52:49 +00:00
# if DXX_MAX_BUTTONS_PER_JOYSTICK || DXX_MAX_HATS_PER_JOYSTICK
2015-11-01 21:15:40 +00:00
# define DXX_KCONFIG_ITEM_JOY_WIDTH(I) I
# else
# define DXX_KCONFIG_ITEM_JOY_WIDTH(I) (static_cast<void>(I), 0)
# endif
2017-12-24 00:28:35 +00:00
# include "kconfig.ui-table.cpp"
2020-07-05 23:34:33 +00:00
static enumerated_array < kc_mitem , std : : size ( kc_keyboard ) , dxx_kconfig_ui_kc_keyboard > kcm_keyboard ;
2017-12-24 00:28:35 +00:00
# if DXX_MAX_JOYSTICKS
2020-07-05 23:34:33 +00:00
static enumerated_array < kc_mitem , std : : size ( kc_joystick ) , dxx_kconfig_ui_kc_joystick > kcm_joystick ;
2017-12-24 00:28:35 +00:00
# endif
2020-07-05 23:34:33 +00:00
static enumerated_array < kc_mitem , std : : size ( kc_mouse ) , dxx_kconfig_ui_kc_mouse > kcm_mouse ;
2020-07-05 23:34:32 +00:00
static std : : array < kc_mitem , std : : size ( kc_rebirth ) > kcm_rebirth ;
2006-03-20 17:12:09 +00:00
2020-08-28 00:18:45 +00:00
static void kconfig_start_changing ( kc_menu & menu )
{
const auto citem = menu . citem ;
if ( menu . items [ citem ] . type = = BT_INVERT )
{
menu . changing = 0 ; // in case we were changing something else
auto & value = menu . mitems [ citem ] . value ;
value = value ? 0 : 1 ;
return ;
}
menu . q_fade_i = 0 ; // start question mark flasher
menu . changing = 1 ;
}
2020-08-28 00:18:45 +00:00
static void kc_set_exclusive_binding ( kc_menu & menu , kc_mitem & mitem , const unsigned type , const unsigned value )
{
const auto nitems = menu . nitems ;
for ( auto & & [ iterate_mitem , iterate_item ] : zip ( unchecked_partial_range ( menu . mitems , nitems ) , unchecked_partial_range ( menu . items , nitems ) ) )
{
if ( & iterate_mitem ! = & mitem & & iterate_mitem . value = = value & & iterate_item . type = = type )
iterate_mitem . value = 255 ;
}
mitem . value = value ;
menu . changing = 0 ;
}
2018-02-01 05:38:47 +00:00
}
2016-12-22 05:21:16 +00:00
}
2018-05-19 23:21:42 +00:00
static void kc_drawinput ( grs_canvas & , const grs_font & , const kc_item & item , kc_mitem & mitem , int is_current , const char * label ) ;
2014-10-04 21:47:13 +00:00
static void kc_change_key ( kc_menu & menu , const d_event & event , kc_mitem & mitem ) ;
2016-09-25 04:52:49 +00:00
# if DXX_MAX_BUTTONS_PER_JOYSTICK || DXX_MAX_HATS_PER_JOYSTICK
2014-10-04 21:47:13 +00:00
static void kc_change_joybutton ( kc_menu & menu , const d_event & event , kc_mitem & mitem ) ;
2015-11-01 21:15:40 +00:00
# endif
2014-10-04 21:47:13 +00:00
static void kc_change_mousebutton ( kc_menu & menu , const d_event & event , kc_mitem & mitem ) ;
2016-09-25 04:52:49 +00:00
# if DXX_MAX_AXES_PER_JOYSTICK
2014-10-04 21:47:13 +00:00
static void kc_change_joyaxis ( kc_menu & menu , const d_event & event , kc_mitem & mitem ) ;
2015-11-01 21:15:40 +00:00
# endif
2014-10-04 21:47:13 +00:00
static void kc_change_mouseaxis ( kc_menu & menu , const d_event & event , kc_mitem & mitem ) ;
2006-03-20 17:12:09 +00:00
2013-11-08 23:59:03 +00:00
static const char * get_item_text ( const kc_item & item , const kc_mitem & mitem , char ( & buf ) [ 10 ] )
2006-03-20 17:12:09 +00:00
{
2013-11-08 23:59:03 +00:00
if ( mitem . value = = 255 ) {
2013-11-02 18:25:44 +00:00
return " " ;
2006-03-20 17:12:09 +00:00
} else {
2013-11-08 23:59:03 +00:00
switch ( item . type ) {
2006-03-20 17:12:09 +00:00
case BT_KEY :
2013-11-08 23:59:03 +00:00
return key_properties [ mitem . value ] . key_text ;
2006-03-20 17:12:09 +00:00
case BT_MOUSE_BUTTON :
2013-11-08 23:59:03 +00:00
return mousebutton_text [ mitem . value ] ;
2006-03-20 17:12:09 +00:00
case BT_MOUSE_AXIS :
2013-11-08 23:59:03 +00:00
return mouseaxis_text [ mitem . value ] ;
2016-09-25 04:52:49 +00:00
# if DXX_MAX_BUTTONS_PER_JOYSTICK || DXX_MAX_HATS_PER_JOYSTICK
2006-03-20 17:12:09 +00:00
case BT_JOY_BUTTON :
2013-11-08 23:59:03 +00:00
if ( joybutton_text . size ( ) > mitem . value )
return & joybutton_text [ mitem . value ] [ 0 ] ;
2006-03-20 17:12:09 +00:00
else
2013-10-08 02:02:26 +00:00
{
2013-11-08 23:59:03 +00:00
snprintf ( buf , sizeof ( buf ) , " BTN%2d " , mitem . value + 1 ) ;
2013-11-02 18:25:44 +00:00
return buf ;
2013-10-08 02:02:26 +00:00
}
2006-03-20 17:12:09 +00:00
break ;
2015-11-01 21:15:40 +00:00
# else
( void ) buf ;
# endif
2016-09-25 04:52:49 +00:00
# if DXX_MAX_AXES_PER_JOYSTICK
2006-03-20 17:12:09 +00:00
case BT_JOY_AXIS :
2013-11-08 23:59:03 +00:00
if ( joyaxis_text . size ( ) > mitem . value )
return & joyaxis_text [ mitem . value ] [ 0 ] ;
2006-03-20 17:12:09 +00:00
else
2013-10-08 02:02:26 +00:00
{
2013-11-08 23:59:03 +00:00
snprintf ( buf , sizeof ( buf ) , " AXIS%2d " , mitem . value + 1 ) ;
2013-11-02 18:25:44 +00:00
return buf ;
2013-10-08 02:02:26 +00:00
}
2006-03-20 17:12:09 +00:00
break ;
2015-11-01 21:15:40 +00:00
# else
( void ) buf ;
# endif
2006-03-20 17:12:09 +00:00
case BT_INVERT :
2013-11-08 23:59:03 +00:00
return invert_text [ mitem . value ] ;
2013-10-08 02:02:26 +00:00
default :
2013-11-02 18:25:44 +00:00
return NULL ;
2006-03-20 17:12:09 +00:00
}
}
2013-11-02 18:25:44 +00:00
}
2017-03-10 01:22:29 +00:00
static int get_item_height ( const grs_font & cv_font , const kc_item & item , const kc_mitem & mitem )
2013-11-02 18:25:44 +00:00
{
char buf [ 10 ] ;
const char * btext ;
2013-11-08 23:59:03 +00:00
btext = get_item_text ( item , mitem , buf ) ;
2013-11-02 18:25:44 +00:00
if ( ! btext )
return 0 ;
2021-09-12 16:20:52 +00:00
const auto h = gr_get_string_size ( cv_font , btext ) . height ;
2006-03-20 17:12:09 +00:00
return h ;
}
2018-05-19 23:21:42 +00:00
static void kc_gr_2y_string ( grs_canvas & canvas , const grs_font & cv_font , const char * const s , const font_y_scaled_float y , const font_x_scaled_float x0 , const font_x_scaled_float x1 )
2016-10-15 00:53:15 +00:00
{
2021-09-12 16:20:52 +00:00
const auto & & [ w , h ] = gr_get_string_size ( cv_font , s ) ;
2018-05-19 23:21:42 +00:00
gr_string ( canvas , cv_font , x0 , y , s , w , h ) ;
gr_string ( canvas , cv_font , x1 , y , s , w , h ) ;
2016-10-15 00:53:15 +00:00
}
2020-08-28 00:18:45 +00:00
static void kconfig_draw ( kc_menu & menu )
2007-04-14 08:43:49 +00:00
{
2017-11-05 20:49:08 +00:00
grs_canvas & save_canvas = * grd_curcanv ;
2015-06-13 22:42:20 +00:00
const auto & & fspacx = FSPACX ( ) ;
2015-06-13 22:42:20 +00:00
const auto & & fspacy = FSPACY ( ) ;
2021-02-25 03:53:49 +00:00
int w = menu . w_canv . cv_bitmap . bm_w , h = menu . w_canv . cv_bitmap . bm_h ;
2007-04-14 08:43:49 +00:00
2017-11-05 20:49:08 +00:00
gr_set_default_canvas ( ) ;
2017-04-08 16:48:20 +00:00
nm_draw_background ( * grd_curcanv , ( ( SWIDTH - w ) / 2 ) - BORDERX , ( ( SHEIGHT - h ) / 2 ) - BORDERY , ( ( SWIDTH - w ) / 2 ) + w + BORDERX , ( ( SHEIGHT - h ) / 2 ) + h + BORDERY ) ;
2007-04-14 08:43:49 +00:00
2020-08-28 00:18:45 +00:00
gr_set_current_canvas ( menu . w_canv ) ;
2017-03-10 01:22:32 +00:00
auto & canvas = * grd_curcanv ;
2007-04-14 08:43:49 +00:00
2017-03-10 01:22:32 +00:00
const grs_font * save_font = canvas . cv_font ;
2007-04-14 08:43:49 +00:00
2018-05-19 23:21:42 +00:00
auto & medium3_font = * MEDIUM3_FONT ;
2020-08-28 00:18:45 +00:00
gr_string ( canvas , medium3_font , 0x8000 , fspacy ( 8 ) , menu . title ) ;
2007-04-14 08:43:49 +00:00
2018-05-19 23:21:42 +00:00
auto & game_font = * GAME_FONT ;
2017-03-10 01:22:32 +00:00
gr_set_fontcolor ( canvas , BM_XRGB ( 28 , 28 , 28 ) , - 1 ) ;
2018-05-19 23:21:42 +00:00
gr_string ( canvas , game_font , 0x8000 , fspacy ( 21 ) , " Enter changes, ctrl-d deletes, ctrl-r resets defaults, ESC exits " ) ;
2008-02-24 14:41:27 +00:00
2020-08-28 00:18:45 +00:00
if ( menu . items = = kc_keyboard )
2008-02-24 14:41:27 +00:00
{
2017-03-10 01:22:32 +00:00
gr_set_fontcolor ( canvas , BM_XRGB ( 31 , 27 , 6 ) , - 1 ) ;
2016-02-12 04:02:28 +00:00
const uint8_t color = BM_XRGB ( 31 , 27 , 6 ) ;
2015-06-13 22:42:20 +00:00
const auto & & fspacx98 = fspacx ( 98 ) ;
const auto & & fspacx128 = fspacx ( 128 ) ;
const auto & & fspacy42 = fspacy ( 42 ) ;
2017-03-10 01:22:32 +00:00
gr_rect ( canvas , fspacx98 , fspacy42 , fspacx ( 106 ) , fspacy42 , color ) ; // horiz/left
gr_rect ( canvas , fspacx ( 120 ) , fspacy42 , fspacx128 , fspacy42 , color ) ; // horiz/right
2015-06-13 22:42:20 +00:00
const auto & & fspacy44 = fspacy ( 44 ) ;
2017-03-10 01:22:32 +00:00
gr_rect ( canvas , fspacx98 , fspacy42 , fspacx98 , fspacy44 , color ) ; // vert/left
gr_rect ( canvas , fspacx128 , fspacy42 , fspacx128 , fspacy44 , color ) ; // vert/right
2015-06-13 22:42:20 +00:00
const auto & & fspacx253 = fspacx ( 253 ) ;
const auto & & fspacx283 = fspacx ( 283 ) ;
2017-03-10 01:22:32 +00:00
gr_rect ( canvas , fspacx253 , fspacy42 , fspacx ( 261 ) , fspacy42 , color ) ; // horiz/left
gr_rect ( canvas , fspacx ( 275 ) , fspacy42 , fspacx283 , fspacy42 , color ) ; // horiz/right
gr_rect ( canvas , fspacx253 , fspacy42 , fspacx253 , fspacy44 , color ) ; // vert/left
gr_rect ( canvas , fspacx283 , fspacy42 , fspacx283 , fspacy44 , color ) ; // vert/right
2015-06-13 22:42:20 +00:00
2018-05-19 23:21:42 +00:00
kc_gr_2y_string ( canvas , game_font , " OR " , fspacy ( 40 ) , fspacx ( 109 ) , fspacx ( 264 ) ) ;
2008-02-24 14:41:27 +00:00
}
2016-09-25 04:52:48 +00:00
# if DXX_MAX_JOYSTICKS
2020-08-28 00:18:45 +00:00
else if ( menu . items = = kc_joystick )
2008-02-24 14:41:27 +00:00
{
2018-02-01 05:38:47 +00:00
const uint8_t color = BM_XRGB ( 31 , 27 , 6 ) ;
gr_set_fontcolor ( canvas , color , - 1 ) ;
2016-09-25 04:52:49 +00:00
# if DXX_MAX_AXES_PER_JOYSTICK
2018-02-01 05:38:47 +00:00
constexpr auto kconfig_axis_labels_top_y = DXX_KCONFIG_UI_JOYSTICK_AXES_TOP_Y + 8 ;
const auto & & fspacy_lower_label2 = fspacy ( kconfig_axis_labels_top_y ) ;
2018-05-19 23:21:42 +00:00
gr_string ( canvas , game_font , 0x8000 , fspacy ( DXX_KCONFIG_UI_JOYSTICK_AXES_TOP_Y ) , TXT_AXES ) ;
2017-03-10 01:22:32 +00:00
gr_set_fontcolor ( canvas , BM_XRGB ( 28 , 28 , 28 ) , - 1 ) ;
2018-05-19 23:21:42 +00:00
kc_gr_2y_string ( canvas , game_font , TXT_AXIS , fspacy_lower_label2 , fspacx ( 81 ) , fspacx ( 230 ) ) ;
kc_gr_2y_string ( canvas , game_font , TXT_INVERT , fspacy_lower_label2 , fspacx ( 111 ) , fspacx ( 260 ) ) ;
2018-02-01 05:38:47 +00:00
gr_set_fontcolor ( canvas , color , - 1 ) ;
2015-11-01 21:15:40 +00:00
# endif
2007-04-14 08:43:49 +00:00
2016-09-25 04:52:49 +00:00
# if DXX_MAX_BUTTONS_PER_JOYSTICK || DXX_MAX_HATS_PER_JOYSTICK
2018-02-01 05:38:47 +00:00
constexpr auto kconfig_buttons_top_y = DXX_KCONFIG_UI_JOYSTICK_TOP_Y + 6 ;
constexpr auto kconfig_buttons_labels_top_y = kconfig_buttons_top_y + 4 ;
2018-05-19 23:21:42 +00:00
gr_string ( canvas , game_font , 0x8000 , fspacy ( DXX_KCONFIG_UI_JOYSTICK_TOP_Y ) , TXT_BUTTONS ) ;
2016-04-02 21:26:00 +00:00
const auto & & fspacx115 = fspacx ( 115 ) ;
2018-02-01 05:38:47 +00:00
const auto & & fspacy_horiz_OR_line = fspacy ( kconfig_buttons_labels_top_y ) ;
gr_rect ( canvas , fspacx115 , fspacy_horiz_OR_line , fspacx ( 123 ) , fspacy_horiz_OR_line , color ) ; // horiz/left
2016-04-02 21:26:00 +00:00
const auto & & fspacx145 = fspacx ( 145 ) ;
2018-02-01 05:38:47 +00:00
gr_rect ( canvas , fspacx ( 137 ) , fspacy_horiz_OR_line , fspacx145 , fspacy_horiz_OR_line , color ) ; // horiz/right
2016-04-02 21:26:00 +00:00
const auto & & fspacx261 = fspacx ( 261 ) ;
2018-02-01 05:38:47 +00:00
gr_rect ( canvas , fspacx261 , fspacy_horiz_OR_line , fspacx ( 269 ) , fspacy_horiz_OR_line , color ) ; // horiz/left
2016-04-02 21:26:00 +00:00
const auto & & fspacx291 = fspacx ( 291 ) ;
2018-02-01 05:38:47 +00:00
gr_rect ( canvas , fspacx ( 283 ) , fspacy_horiz_OR_line , fspacx291 , fspacy_horiz_OR_line , color ) ; // horiz/right
2007-04-14 08:43:49 +00:00
2018-02-01 05:38:47 +00:00
const auto & & fspacy_vert_OR_line = fspacy ( kconfig_buttons_labels_top_y + 2 ) ;
gr_rect ( canvas , fspacx115 , fspacy_horiz_OR_line , fspacx115 , fspacy_vert_OR_line , color ) ; // vert/left
gr_rect ( canvas , fspacx145 , fspacy_horiz_OR_line , fspacx145 , fspacy_vert_OR_line , color ) ; // vert/right
gr_rect ( canvas , fspacx261 , fspacy_horiz_OR_line , fspacx261 , fspacy_vert_OR_line , color ) ; // vert/left
gr_rect ( canvas , fspacx291 , fspacy_horiz_OR_line , fspacx291 , fspacy_vert_OR_line , color ) ; // vert/right
2016-04-02 21:26:00 +00:00
2018-05-19 23:21:42 +00:00
kc_gr_2y_string ( canvas , game_font , " OR " , fspacy ( kconfig_buttons_top_y + 2 ) , fspacx ( 126 ) , fspacx ( 272 ) ) ;
2015-11-01 21:15:40 +00:00
# endif
2008-02-24 14:41:27 +00:00
}
2015-11-01 21:15:40 +00:00
# endif
2020-08-28 00:18:45 +00:00
else if ( menu . items = = kc_mouse )
2008-02-24 14:41:27 +00:00
{
2017-03-10 01:22:32 +00:00
gr_set_fontcolor ( canvas , BM_XRGB ( 31 , 27 , 6 ) , - 1 ) ;
2018-05-19 23:21:42 +00:00
gr_string ( canvas , game_font , 0x8000 , fspacy ( 37 ) , TXT_BUTTONS ) ;
gr_string ( canvas , game_font , 0x8000 , fspacy ( 137 ) , TXT_AXES ) ;
2017-03-10 01:22:32 +00:00
gr_set_fontcolor ( canvas , BM_XRGB ( 28 , 28 , 28 ) , - 1 ) ;
2016-04-02 21:26:00 +00:00
const auto & & fspacy145 = fspacy ( 145 ) ;
2018-05-19 23:21:42 +00:00
kc_gr_2y_string ( canvas , game_font , TXT_AXIS , fspacy145 , fspacx ( 87 ) , fspacx ( 242 ) ) ;
kc_gr_2y_string ( canvas , game_font , TXT_INVERT , fspacy145 , fspacx ( 120 ) , fspacx ( 274 ) ) ;
2007-04-14 08:43:49 +00:00
}
2020-08-28 00:18:45 +00:00
else if ( menu . items = = kc_rebirth )
2007-04-14 08:43:49 +00:00
{
2017-03-10 01:22:32 +00:00
gr_set_fontcolor ( canvas , BM_XRGB ( 31 , 27 , 6 ) , - 1 ) ;
2007-04-14 08:43:49 +00:00
2016-04-02 21:26:00 +00:00
const auto & & fspacy60 = fspacy ( 60 ) ;
2018-05-19 23:21:42 +00:00
gr_string ( canvas , game_font , fspacx ( 152 ) , fspacy60 , " KEYBOARD " ) ;
2016-09-25 04:52:49 +00:00
# if DXX_MAX_BUTTONS_PER_JOYSTICK || DXX_MAX_HATS_PER_JOYSTICK
2018-05-19 23:21:42 +00:00
gr_string ( canvas , game_font , fspacx ( 210 ) , fspacy60 , " JOYSTICK " ) ;
2015-11-01 21:15:40 +00:00
# endif
2018-05-19 23:21:42 +00:00
gr_string ( canvas , game_font , fspacx ( 273 ) , fspacy60 , " MOUSE " ) ;
2007-04-14 08:43:49 +00:00
}
2020-08-28 00:18:45 +00:00
unsigned citem = menu . citem ;
2013-11-27 22:39:47 +00:00
const char * current_label = NULL ;
2020-08-28 00:18:45 +00:00
const char * litem = menu . litems ;
const auto nitems = menu . nitems ;
for ( const auto i : xrange ( nitems ) )
{
auto next_label = ( i + 1 > = menu . nitems | | menu . items [ i + 1 ] . y ! = menu . items [ i ] . y ) ? litem : nullptr ;
2013-11-27 22:39:47 +00:00
if ( i = = citem )
current_label = litem ;
2020-08-28 00:18:45 +00:00
else if ( menu . items [ i ] . w2 )
kc_drawinput ( canvas , game_font , menu . items [ i ] , menu . mitems [ i ] , 0 , next_label ) ;
2013-11-27 22:39:47 +00:00
if ( next_label )
litem + = strlen ( litem ) + 1 ;
2010-01-18 05:53:13 +00:00
}
2020-08-28 00:18:45 +00:00
kc_drawinput ( canvas , game_font , menu . items [ citem ] , menu . mitems [ citem ] , 1 , current_label ) ;
2010-01-18 05:53:13 +00:00
2017-12-15 04:47:30 +00:00
gr_set_fontcolor ( canvas , BM_XRGB ( 28 , 28 , 28 ) , - 1 ) ;
2020-08-28 00:18:45 +00:00
if ( menu . changing )
2010-01-18 05:53:13 +00:00
{
2016-04-02 21:26:00 +00:00
const char * s ;
2020-08-28 00:18:45 +00:00
switch ( menu . items [ menu . citem ] . type )
2010-01-18 05:53:13 +00:00
{
2016-04-02 21:26:00 +00:00
case BT_KEY :
s = TXT_PRESS_NEW_KEY ;
break ;
case BT_MOUSE_BUTTON :
s = TXT_PRESS_NEW_MBUTTON ;
break ;
case BT_MOUSE_AXIS :
s = TXT_MOVE_NEW_MSE_AXIS ;
break ;
2016-09-25 04:52:49 +00:00
# if DXX_MAX_BUTTONS_PER_JOYSTICK || DXX_MAX_HATS_PER_JOYSTICK
2016-04-02 21:26:00 +00:00
case BT_JOY_BUTTON :
s = TXT_PRESS_NEW_JBUTTON ;
break ;
2015-11-01 21:15:40 +00:00
# endif
2016-09-25 04:52:49 +00:00
# if DXX_MAX_AXES_PER_JOYSTICK
2016-04-02 21:26:00 +00:00
case BT_JOY_AXIS :
s = TXT_MOVE_NEW_JOY_AXIS ;
break ;
2015-11-01 21:15:40 +00:00
# endif
2016-04-02 21:26:00 +00:00
default :
s = nullptr ;
break ;
2010-01-18 05:53:13 +00:00
}
2016-04-02 21:26:00 +00:00
if ( s )
2018-05-19 23:21:42 +00:00
gr_string ( canvas , game_font , 0x8000 , fspacy ( INFO_Y ) , s ) ;
2020-08-28 00:18:45 +00:00
auto & item = menu . items [ menu . citem ] ;
auto & menu_fade_index = menu . q_fade_i ;
2020-08-28 00:18:45 +00:00
const auto fade_element = fades [ menu_fade_index ] ;
# if defined(DXX_BUILD_DESCENT_I)
2021-09-19 10:53:48 +00:00
const auto color = gr_fade_table [ static_cast < gr_fade_level > ( fade_element ) ] [ BM_XRGB ( 21 , 0 , 24 ) ] ;
2020-08-28 00:18:45 +00:00
# elif defined(DXX_BUILD_DESCENT_II)
const auto color = BM_XRGB ( 21 * fade_element / 31 , 0 , 24 * fade_element / 31 ) ;
# endif
kc_drawquestion ( canvas , game_font , menu_fade_index , item . xinput , item . y , item . w2 , color ) ;
2007-04-14 08:43:49 +00:00
}
2017-03-10 01:22:32 +00:00
canvas . cv_font = save_font ;
2010-01-18 05:53:13 +00:00
gr_set_current_canvas ( save_canvas ) ;
2007-04-14 08:43:49 +00:00
}
2013-11-02 19:07:55 +00:00
static inline int in_bounds ( unsigned mx , unsigned my , unsigned x1 , unsigned xw , unsigned y1 , unsigned yh )
{
if ( mx < = x1 )
return 0 ;
if ( my < = y1 )
return 0 ;
if ( mx > = x1 + xw )
return 0 ;
if ( my > = y1 + yh )
return 0 ;
return 1 ;
}
2020-08-28 00:18:45 +00:00
namespace dsx {
namespace {
static window_event_result kconfig_mouse ( kc_menu & menu , const d_event & event )
2010-01-18 05:53:13 +00:00
{
2017-11-05 20:49:08 +00:00
grs_canvas & save_canvas = * grd_curcanv ;
2013-11-02 19:07:55 +00:00
int mx , my , mz , x1 , y1 ;
2014-08-06 02:10:49 +00:00
window_event_result rval = window_event_result : : ignored ;
2010-03-24 07:26:52 +00:00
2020-08-28 00:18:45 +00:00
gr_set_current_canvas ( menu . w_canv ) ;
2017-03-10 01:22:33 +00:00
auto & canvas = * grd_curcanv ;
2010-03-24 07:26:52 +00:00
2020-08-28 00:18:45 +00:00
if ( menu . mouse_state )
2010-03-24 07:26:52 +00:00
{
int item_height ;
mouse_get_pos ( & mx , & my , & mz ) ;
2015-06-13 22:42:20 +00:00
const auto & & fspacx = FSPACX ( ) ;
2015-06-13 22:42:20 +00:00
const auto & & fspacy = FSPACY ( ) ;
2020-08-28 00:18:45 +00:00
const auto nitems = menu . nitems ;
for ( const auto i : xrange ( nitems ) )
{
item_height = get_item_height ( * canvas . cv_font , menu . items [ i ] , menu . mitems [ i ] ) ;
x1 = canvas . cv_bitmap . bm_x + fspacx ( menu . items [ i ] . xinput ) ;
y1 = canvas . cv_bitmap . bm_y + fspacy ( menu . items [ i ] . y ) ;
if ( in_bounds ( mx , my , x1 , fspacx ( menu . items [ i ] . w2 ) , y1 , item_height ) ) {
menu . citem = i ;
2014-08-06 02:10:49 +00:00
rval = window_event_result : : handled ;
2010-03-24 07:26:52 +00:00
break ;
}
}
}
2014-10-04 21:47:13 +00:00
else if ( event . type = = EVENT_MOUSE_BUTTON_UP )
2010-03-24 07:26:52 +00:00
{
int item_height ;
mouse_get_pos ( & mx , & my , & mz ) ;
2020-08-28 00:18:45 +00:00
item_height = get_item_height ( * canvas . cv_font , menu . items [ menu . citem ] , menu . mitems [ menu . citem ] ) ;
2015-06-13 22:42:20 +00:00
const auto & & fspacx = FSPACX ( ) ;
2020-08-28 00:18:45 +00:00
x1 = canvas . cv_bitmap . bm_x + fspacx ( menu . items [ menu . citem ] . xinput ) ;
y1 = canvas . cv_bitmap . bm_y + FSPACY ( menu . items [ menu . citem ] . y ) ;
if ( in_bounds ( mx , my , x1 , fspacx ( menu . items [ menu . citem ] . w2 ) , y1 , item_height ) ) {
kconfig_start_changing ( menu ) ;
2014-08-06 02:10:49 +00:00
rval = window_event_result : : handled ;
2010-03-24 07:26:52 +00:00
}
else
{
// Click out of changing mode - kreatordxx
2020-08-28 00:18:45 +00:00
menu . changing = 0 ;
2014-08-06 02:10:49 +00:00
rval = window_event_result : : handled ;
2010-03-24 07:26:52 +00:00
}
}
2010-01-18 05:53:13 +00:00
2010-03-24 07:26:52 +00:00
gr_set_current_canvas ( save_canvas ) ;
return rval ;
}
2020-08-28 00:18:45 +00:00
}
}
namespace dcx {
namespace {
2013-11-26 00:34:27 +00:00
template < std : : size_t M , std : : size_t C >
2020-08-28 00:18:45 +00:00
static void reset_mitem_values ( std : : array < kc_mitem , M > & m , const std : : array < uint8_t , C > & c )
2013-11-26 00:34:27 +00:00
{
2015-08-12 03:11:46 +00:00
for ( std : : size_t i = 0 ; i ! = min ( M , C ) ; + + i )
2013-11-26 00:34:27 +00:00
m [ i ] . value = c [ i ] ;
}
2016-12-22 05:21:16 +00:00
static void step_citem_past_empty_cell ( unsigned & citem , const kc_item * const items , const uint8_t kc_item : : * const next )
2015-11-01 21:15:38 +00:00
{
do {
citem = items [ citem ] . * next ;
} while ( ! items [ citem ] . w2 ) ;
}
2020-08-28 00:18:45 +00:00
static window_event_result kconfig_key_command ( kc_menu & menu , const d_event & event )
2010-03-24 07:26:52 +00:00
{
2020-08-28 00:18:45 +00:00
auto k = event_key_get ( event ) ;
2010-07-05 07:31:03 +00:00
// when changing, process no keys instead of ESC
2020-08-28 00:18:45 +00:00
if ( menu . changing & & ( k ! = - 2 & & k ! = KEY_ESC ) )
2014-08-06 02:10:49 +00:00
return window_event_result : : ignored ;
2010-03-26 14:05:40 +00:00
switch ( k )
2010-01-18 05:53:13 +00:00
{
case KEY_CTRLED + KEY_D :
2020-08-28 00:18:45 +00:00
menu . mitems [ menu . citem ] . value = 255 ;
2014-08-06 02:10:49 +00:00
return window_event_result : : handled ;
2010-01-18 05:53:13 +00:00
case KEY_CTRLED + KEY_R :
2020-08-28 00:18:45 +00:00
if ( menu . items = = kc_keyboard )
2017-12-05 05:29:55 +00:00
reset_mitem_values ( kcm_keyboard , DefaultKeySettings . Keyboard ) ;
2016-09-25 04:52:48 +00:00
# if DXX_MAX_JOYSTICKS
2020-08-28 00:18:45 +00:00
else if ( menu . items = = kc_joystick )
2017-12-05 05:29:55 +00:00
reset_mitem_values ( kcm_joystick , DefaultKeySettings . Joystick ) ;
2015-11-01 21:15:40 +00:00
# endif
2020-08-28 00:18:45 +00:00
else if ( menu . items = = kc_mouse )
2017-12-05 05:29:55 +00:00
reset_mitem_values ( kcm_mouse , DefaultKeySettings . Mouse ) ;
2020-08-28 00:18:45 +00:00
else if ( menu . items = = kc_rebirth )
2013-11-26 00:34:27 +00:00
reset_mitem_values ( kcm_rebirth , DefaultKeySettingsRebirth ) ;
2014-08-06 02:10:49 +00:00
return window_event_result : : handled ;
2010-01-20 11:04:09 +00:00
case KEY_DELETE :
2020-08-28 00:18:45 +00:00
menu . mitems [ menu . citem ] . value = 255 ;
2014-08-06 02:10:49 +00:00
return window_event_result : : handled ;
2010-01-20 11:04:09 +00:00
case KEY_UP :
case KEY_PAD8 :
2020-08-28 00:18:45 +00:00
step_citem_past_empty_cell ( menu . citem , menu . items , & kc_item : : u ) ;
2014-08-06 02:10:49 +00:00
return window_event_result : : handled ;
2010-01-20 11:04:09 +00:00
case KEY_DOWN :
case KEY_PAD2 :
2020-08-28 00:18:45 +00:00
step_citem_past_empty_cell ( menu . citem , menu . items , & kc_item : : d ) ;
2014-08-06 02:10:49 +00:00
return window_event_result : : handled ;
2010-01-20 11:04:09 +00:00
case KEY_LEFT :
case KEY_PAD4 :
2020-08-28 00:18:45 +00:00
step_citem_past_empty_cell ( menu . citem , menu . items , & kc_item : : l ) ;
2014-08-06 02:10:49 +00:00
return window_event_result : : handled ;
2010-01-20 11:04:09 +00:00
case KEY_RIGHT :
case KEY_PAD6 :
2020-08-28 00:18:45 +00:00
step_citem_past_empty_cell ( menu . citem , menu . items , & kc_item : : r ) ;
2014-08-06 02:10:49 +00:00
return window_event_result : : handled ;
2010-01-20 11:04:09 +00:00
case KEY_ENTER :
case KEY_PADENTER :
2020-08-28 00:18:45 +00:00
kconfig_start_changing ( menu ) ;
2014-08-06 02:10:49 +00:00
return window_event_result : : handled ;
2010-01-20 11:04:09 +00:00
case KEY_ESC :
2020-08-28 00:18:45 +00:00
if ( menu . changing )
menu . changing = 0 ;
2010-03-26 14:05:40 +00:00
else
2014-08-06 02:10:49 +00:00
{
return window_event_result : : close ;
}
return window_event_result : : handled ;
2010-01-20 11:04:09 +00:00
case 0 : // some other event
2010-01-18 05:53:13 +00:00
break ;
2010-01-20 11:04:09 +00:00
default :
2010-01-18 05:53:13 +00:00
break ;
}
2014-08-06 02:10:49 +00:00
return window_event_result : : ignored ;
2010-01-20 11:04:09 +00:00
}
2020-08-28 00:18:45 +00:00
}
}
2016-08-25 04:05:32 +00:00
namespace dsx {
2020-08-28 00:18:45 +00:00
namespace {
window_event_result kc_menu : : event_handler ( const d_event & event )
2010-01-20 11:04:09 +00:00
{
2020-09-11 03:08:02 +00:00
# if DXX_MAX_BUTTONS_PER_JOYSTICK
2020-08-28 00:18:45 +00:00
if ( ! changing & & joy_translate_menu_key ( event ) )
2020-06-28 15:08:26 +00:00
return window_event_result : : handled ;
2020-09-11 03:08:02 +00:00
# endif
2020-06-28 15:08:26 +00:00
2014-10-04 21:47:13 +00:00
switch ( event . type )
2010-01-20 11:04:09 +00:00
{
2010-01-28 04:24:25 +00:00
case EVENT_WINDOW_ACTIVATED :
2020-10-12 03:28:26 +00:00
game_flush_inputs ( Controls ) ;
2010-01-28 04:24:25 +00:00
break ;
2010-03-24 07:26:52 +00:00
case EVENT_WINDOW_DEACTIVATED :
2020-08-28 00:18:45 +00:00
mouse_state = 0 ;
2010-03-24 07:26:52 +00:00
break ;
case EVENT_MOUSE_BUTTON_DOWN :
2010-07-05 07:31:03 +00:00
case EVENT_MOUSE_BUTTON_UP :
2020-08-28 00:18:45 +00:00
if ( changing & & ( items [ citem ] . type = = BT_MOUSE_BUTTON ) & & ( event . type = = EVENT_MOUSE_BUTTON_UP ) )
2010-03-24 07:26:52 +00:00
{
2020-08-28 00:18:45 +00:00
kc_change_mousebutton ( * this , event , mitems [ citem ] ) ;
mouse_state = ( event . type = = EVENT_MOUSE_BUTTON_DOWN ) ;
2014-08-06 02:10:49 +00:00
return window_event_result : : handled ;
2010-03-24 07:26:52 +00:00
}
2011-01-14 09:51:13 +00:00
if ( event_mouse_get_button ( event ) = = MBTN_RIGHT )
2011-01-02 11:25:51 +00:00
{
2020-08-28 00:18:45 +00:00
if ( ! changing )
2014-08-06 02:10:49 +00:00
{
return window_event_result : : close ;
}
return window_event_result : : handled ;
2011-01-02 11:25:51 +00:00
}
2011-01-14 09:51:13 +00:00
else if ( event_mouse_get_button ( event ) ! = MBTN_LEFT )
2014-08-06 02:10:49 +00:00
return window_event_result : : ignored ;
2010-03-24 07:26:52 +00:00
2020-08-28 00:18:45 +00:00
mouse_state = ( event . type = = EVENT_MOUSE_BUTTON_DOWN ) ;
return kconfig_mouse ( * this , event ) ;
2010-03-24 07:26:52 +00:00
2011-02-02 00:36:49 +00:00
case EVENT_MOUSE_MOVED :
2020-08-28 00:18:45 +00:00
if ( changing & & items [ citem ] . type = = BT_MOUSE_AXIS )
kc_change_mouseaxis ( * this , event , mitems [ citem ] ) ;
2011-02-02 00:36:49 +00:00
else
2020-08-28 00:18:45 +00:00
event_mouse_get_delta ( event , & old_maxis [ 0 ] , & old_maxis [ 1 ] , & old_maxis [ 2 ] ) ;
2011-02-02 00:36:49 +00:00
break ;
2010-03-26 14:05:40 +00:00
2016-09-25 04:52:49 +00:00
# if DXX_MAX_BUTTONS_PER_JOYSTICK || DXX_MAX_HATS_PER_JOYSTICK
2011-02-02 00:36:49 +00:00
case EVENT_JOYSTICK_BUTTON_DOWN :
2020-08-28 00:18:45 +00:00
if ( changing & & items [ citem ] . type = = BT_JOY_BUTTON )
kc_change_joybutton ( * this , event , mitems [ citem ] ) ;
2011-02-02 00:36:49 +00:00
break ;
2015-11-01 21:15:40 +00:00
# endif
2010-03-26 14:05:40 +00:00
2016-09-25 04:52:49 +00:00
# if DXX_MAX_AXES_PER_JOYSTICK
2011-02-02 00:36:49 +00:00
case EVENT_JOYSTICK_MOVED :
2020-08-28 00:18:45 +00:00
if ( changing & & items [ citem ] . type = = BT_JOY_AXIS )
kc_change_joyaxis ( * this , event , mitems [ citem ] ) ;
2010-03-26 14:05:40 +00:00
else
{
2015-09-19 23:04:34 +00:00
const auto & av = event_joystick_get_axis ( event ) ;
const auto & axis = av . axis ;
const auto & value = av . value ;
2020-08-28 00:18:45 +00:00
old_jaxis [ axis ] = value ;
2010-03-26 14:05:40 +00:00
}
2010-01-20 11:04:09 +00:00
break ;
2015-11-01 21:15:40 +00:00
# endif
2011-02-02 00:36:49 +00:00
case EVENT_KEY_COMMAND :
{
2020-08-28 00:18:45 +00:00
window_event_result rval = kconfig_key_command ( * this , event ) ;
2014-08-06 02:10:49 +00:00
if ( rval ! = window_event_result : : ignored )
2011-02-02 00:36:49 +00:00
return rval ;
2020-08-28 00:18:45 +00:00
if ( changing & & items [ citem ] . type = = BT_KEY )
kc_change_key ( * this , event , mitems [ citem ] ) ;
2014-08-06 02:10:49 +00:00
return window_event_result : : ignored ;
2011-02-02 00:36:49 +00:00
}
case EVENT_IDLE :
2020-08-28 00:18:45 +00:00
kconfig_mouse ( * this , event ) ;
2011-02-02 00:36:49 +00:00
break ;
2010-01-20 11:04:09 +00:00
case EVENT_WINDOW_DRAW :
2020-08-28 00:18:45 +00:00
if ( changing )
2011-02-02 00:36:49 +00:00
timer_delay ( f0_1 / 10 ) ;
else
timer_delay2 ( 50 ) ;
2020-08-28 00:18:45 +00:00
kconfig_draw ( * this ) ;
2010-01-20 11:04:09 +00:00
break ;
case EVENT_WINDOW_CLOSE :
// Update save values...
2020-08-28 00:18:45 +00:00
for ( auto & & [ kcm , setting ] : zip ( kcm_keyboard , PlayerCfg . KeySettings . Keyboard ) )
2020-07-05 23:34:33 +00:00
setting = kcm . value ;
2016-09-25 04:52:48 +00:00
# if DXX_MAX_JOYSTICKS
2020-08-28 00:18:45 +00:00
for ( auto & & [ kcm , setting ] : zip ( kcm_joystick , PlayerCfg . KeySettings . Joystick ) )
2020-07-05 23:34:33 +00:00
setting = kcm . value ;
2015-11-01 21:15:40 +00:00
# endif
2010-02-21 01:25:27 +00:00
2020-08-28 00:18:45 +00:00
for ( auto & & [ kcm , setting ] : zip ( kcm_mouse , PlayerCfg . KeySettings . Mouse ) )
2020-07-05 23:34:33 +00:00
setting = kcm . value ;
2020-08-28 00:18:45 +00:00
for ( auto & & [ kcm , setting ] : zip ( kcm_rebirth , PlayerCfg . KeySettingsRebirth ) )
2020-07-05 23:34:33 +00:00
setting = kcm . value ;
2014-08-06 02:10:49 +00:00
return window_event_result : : ignored ; // continue closing
2010-01-20 11:04:09 +00:00
default :
2014-08-06 02:10:49 +00:00
return window_event_result : : ignored ;
2010-01-20 11:04:09 +00:00
}
2014-08-06 02:10:49 +00:00
return window_event_result : : handled ;
2010-01-18 05:53:13 +00:00
}
2006-03-20 17:12:09 +00:00
2013-11-27 22:39:47 +00:00
static void kconfig_sub ( const char * litems , const kc_item * items , kc_mitem * mitems , int nitems , const char * title )
2010-01-18 05:53:13 +00:00
{
2015-11-01 21:15:38 +00:00
set_screen_mode ( SCREEN_MENU ) ;
kc_set_controls ( ) ;
2020-08-28 00:18:45 +00:00
const auto & & fspacx = FSPACX ( ) ;
const auto & & fspacy = FSPACY ( ) ;
2021-02-25 03:53:49 +00:00
const uint16_t target_window_width = fspacx ( 320 ) ;
const uint16_t target_window_height = fspacy ( 220 ) ;
const auto swidth = SWIDTH ;
const auto sheight = SHEIGHT ;
const auto window_width = std : : min ( swidth , target_window_width ) ;
const auto window_height = std : : min ( sheight , target_window_height ) ;
auto menu = window_create < kc_menu > ( grd_curscreen - > sc_canvas , ( swidth - window_width ) / 2 , ( sheight - window_height ) / 2 , window_width , window_height ) ;
2010-01-18 05:53:13 +00:00
menu - > items = items ;
2013-11-27 22:39:47 +00:00
menu - > litems = litems ;
2013-11-08 23:59:03 +00:00
menu - > mitems = mitems ;
2010-01-18 05:53:13 +00:00
menu - > nitems = nitems ;
menu - > title = title ;
2015-11-01 21:15:38 +00:00
if ( ! items [ 0 ] . w2 )
step_citem_past_empty_cell ( menu - > citem , items , & kc_item : : r ) ;
2006-03-20 17:12:09 +00:00
}
2013-11-02 18:16:00 +00:00
template < std : : size_t N >
2020-05-02 21:18:42 +00:00
static void kconfig_sub ( const char * litems , const kc_item ( & items ) [ N ] , std : : array < kc_mitem , N > & mitems , const char * title )
2013-11-02 18:16:00 +00:00
{
2015-08-12 03:11:46 +00:00
kconfig_sub ( litems , items , mitems . data ( ) , N , title ) ;
2013-11-02 18:16:00 +00:00
}
2006-03-20 17:12:09 +00:00
2020-08-28 00:18:45 +00:00
}
}
2018-05-19 23:21:42 +00:00
static void kc_drawinput ( grs_canvas & canvas , const grs_font & cv_font , const kc_item & item , kc_mitem & mitem , const int is_current , const char * const label )
2006-03-20 17:12:09 +00:00
{
2013-10-08 02:02:26 +00:00
char buf [ 10 ] ;
const char * btext ;
2015-06-13 22:42:20 +00:00
const auto & & fspacx = FSPACX ( ) ;
2015-06-13 22:42:20 +00:00
const auto & & fspacy = FSPACY ( ) ;
2016-02-12 04:02:28 +00:00
unsigned r , g , b ;
2013-11-27 22:39:47 +00:00
if ( label )
{
2016-04-02 21:26:00 +00:00
if ( is_current )
r = 20 * 2 , g = 20 * 2 , b = 29 * 2 ;
else
r = 15 * 2 , g = 15 * 2 , b = 24 * 2 ;
2017-03-10 01:22:29 +00:00
gr_set_fontcolor ( canvas , gr_find_closest_color ( r , g , b ) , - 1 ) ;
2018-05-19 23:21:42 +00:00
gr_string ( canvas , cv_font , fspacx ( item . x ) , fspacy ( item . y ) , label ) ;
2013-11-27 22:39:47 +00:00
}
2006-03-20 17:12:09 +00:00
2013-11-08 23:59:03 +00:00
btext = get_item_text ( item , mitem , buf ) ;
2013-11-02 18:25:44 +00:00
if ( ! btext )
return ;
2013-03-03 01:03:33 +00:00
{
2016-02-12 04:02:28 +00:00
if ( is_current )
r = 21 * 2 , g = 0 , b = 24 * 2 ;
else
r = 16 * 2 , g = 0 , b = 19 * 2 ;
2015-09-29 02:41:22 +00:00
2021-09-12 16:20:52 +00:00
int x ;
2020-07-16 02:31:04 +00:00
const auto color = gr_find_closest_color ( r , g , b ) ;
2021-09-12 16:20:52 +00:00
const auto & & [ w , h ] = gr_get_string_size ( cv_font , btext ) ;
2016-04-02 21:26:00 +00:00
const auto & & fspacx_item_xinput = fspacx ( item . xinput ) ;
const auto & & fspacy_item_y = fspacy ( item . y ) ;
2017-03-10 01:22:29 +00:00
gr_urect ( canvas , fspacx_item_xinput , fspacy ( item . y - 1 ) , fspacx ( item . xinput + item . w2 ) , fspacy_item_y + h , color ) ;
2006-03-20 17:12:09 +00:00
2017-12-15 04:47:30 +00:00
if ( mitem . oldvalue = = mitem . value )
r = b = 28 * 2 ;
else
r = b = 0 ;
gr_set_fontcolor ( canvas , gr_find_closest_color ( r , 28 * 2 , b ) , - 1 ) ;
2006-03-20 17:12:09 +00:00
2016-04-02 21:26:00 +00:00
x = fspacx_item_xinput + ( ( fspacx ( item . w2 ) - w ) / 2 ) ;
2006-03-20 17:12:09 +00:00
2018-05-19 23:21:42 +00:00
gr_string ( canvas , cv_font , x , fspacy_item_y , btext , w , h ) ;
2006-03-20 17:12:09 +00:00
}
}
2014-10-04 21:47:13 +00:00
static void kc_change_key ( kc_menu & menu , const d_event & event , kc_mitem & mitem )
2006-03-20 17:12:09 +00:00
{
2010-01-18 05:53:13 +00:00
ubyte keycode = 255 ;
2014-10-04 21:47:13 +00:00
Assert ( event . type = = EVENT_KEY_COMMAND ) ;
2011-02-02 00:36:49 +00:00
keycode = event_key_get_raw ( event ) ;
2006-03-20 17:12:09 +00:00
2015-03-22 18:49:21 +00:00
auto e = end ( system_keys ) ;
2015-07-18 21:01:56 +00:00
if ( unlikely ( CGameArg . CtlNoStickyKeys ) )
2015-03-22 18:49:21 +00:00
e = std : : prev ( e , 3 ) ;
const auto predicate = [ keycode ] ( uint8_t k ) { return keycode = = k ; } ;
if ( std : : any_of ( begin ( system_keys ) , e , predicate ) )
return ;
2011-02-02 00:36:49 +00:00
2013-11-08 23:59:03 +00:00
kc_set_exclusive_binding ( menu , mitem , BT_KEY , keycode ) ;
2006-03-20 17:12:09 +00:00
}
2020-09-11 03:08:02 +00:00
# if DXX_MAX_BUTTONS_PER_JOYSTICK
2014-10-04 21:47:13 +00:00
static void kc_change_joybutton ( kc_menu & menu , const d_event & event , kc_mitem & mitem )
2006-03-20 17:12:09 +00:00
{
2013-10-08 02:47:09 +00:00
int button = 255 ;
2011-02-02 00:36:49 +00:00
2014-10-04 21:47:13 +00:00
Assert ( event . type = = EVENT_JOYSTICK_BUTTON_DOWN ) ;
2011-02-02 00:36:49 +00:00
button = event_joystick_get_button ( event ) ;
2006-03-20 17:12:09 +00:00
2013-11-08 23:59:03 +00:00
kc_set_exclusive_binding ( menu , mitem , BT_JOY_BUTTON , button ) ;
2006-03-20 17:12:09 +00:00
}
2015-11-01 21:15:40 +00:00
# endif
2006-03-20 17:12:09 +00:00
2014-10-04 21:47:13 +00:00
static void kc_change_mousebutton ( kc_menu & menu , const d_event & event , kc_mitem & mitem )
2006-03-20 17:12:09 +00:00
{
2013-10-08 02:47:09 +00:00
int button ;
2006-03-20 17:12:09 +00:00
2014-10-04 21:47:13 +00:00
Assert ( event . type = = EVENT_MOUSE_BUTTON_DOWN | | event . type = = EVENT_MOUSE_BUTTON_UP ) ;
2011-02-02 00:36:49 +00:00
button = event_mouse_get_button ( event ) ;
2010-03-24 07:26:52 +00:00
2013-11-08 23:59:03 +00:00
kc_set_exclusive_binding ( menu , mitem , BT_MOUSE_BUTTON , button ) ;
2006-03-20 17:12:09 +00:00
}
2016-09-25 04:52:49 +00:00
# if DXX_MAX_AXES_PER_JOYSTICK
2014-10-04 21:47:13 +00:00
static void kc_change_joyaxis ( kc_menu & menu , const d_event & event , kc_mitem & mitem )
2006-03-20 17:12:09 +00:00
{
2015-09-19 23:04:34 +00:00
const auto & av = event_joystick_get_axis ( event ) ;
const auto & axis = av . axis ;
const auto & value = av . value ;
2006-03-20 17:12:09 +00:00
2013-11-02 18:40:00 +00:00
if ( abs ( value - menu . old_jaxis [ axis ] ) < 32 )
2011-02-02 00:36:49 +00:00
return ;
2013-12-07 00:47:27 +00:00
con_printf ( CON_DEBUG , " Axis Movement detected: Axis %i " , axis ) ;
2006-03-20 17:12:09 +00:00
2013-11-08 23:59:03 +00:00
kc_set_exclusive_binding ( menu , mitem , BT_JOY_AXIS , axis ) ;
2006-03-20 17:12:09 +00:00
}
2015-11-01 21:15:40 +00:00
# endif
2006-03-20 17:12:09 +00:00
2014-10-04 21:47:13 +00:00
static void kc_change_mouseaxis ( kc_menu & menu , const d_event & event , kc_mitem & mitem )
2006-03-20 17:12:09 +00:00
{
2013-10-08 02:47:09 +00:00
int dx , dy , dz ;
2006-03-20 17:12:09 +00:00
2014-10-04 21:47:13 +00:00
Assert ( event . type = = EVENT_MOUSE_MOVED ) ;
2011-02-02 00:36:49 +00:00
event_mouse_get_delta ( event , & dx , & dy , & dz ) ;
2015-05-09 17:39:03 +00:00
uint8_t code ;
if ( abs ( dz ) > 5 )
code = 2 ;
else if ( abs ( dy ) > 5 )
code = 1 ;
else if ( abs ( dx ) > 5 )
code = 0 ;
else
return ;
2016-10-31 10:36:48 +00:00
kc_set_exclusive_binding ( menu , mitem , BT_MOUSE_AXIS , code ) ;
2006-03-20 17:12:09 +00:00
}
2015-11-01 21:15:38 +00:00
void kconfig ( const kconfig_type n )
2006-03-20 17:12:09 +00:00
{
2015-11-01 21:15:38 +00:00
switch ( n )
{
# define kconfig_case(TYPE,TITLE) \
case kconfig_type : : TYPE : \
2018-02-01 05:38:47 +00:00
kconfig_sub ( DXX_KCONFIG_UI_LABEL_kc_ # # TYPE , kc_ # # TYPE , kcm_ # # TYPE , TITLE ) ; \
2015-11-01 21:15:38 +00:00
break ;
kconfig_case ( keyboard , " KEYBOARD " ) ;
2016-09-25 04:52:48 +00:00
# if DXX_MAX_JOYSTICKS
2015-11-01 21:15:38 +00:00
kconfig_case ( joystick , " JOYSTICK " ) ;
2015-11-01 21:15:40 +00:00
# endif
2015-11-01 21:15:38 +00:00
kconfig_case ( mouse , " MOUSE " ) ;
kconfig_case ( rebirth , " WEAPON KEYS " ) ;
# undef kconfig_case
2009-12-02 13:49:54 +00:00
default :
2006-10-07 01:12:25 +00:00
Int3 ( ) ;
return ;
2006-03-20 17:12:09 +00:00
}
}
2020-05-28 03:21:22 +00:00
namespace dsx {
static void input_button_matched ( control_info & Controls , const kc_item & item , int down )
2013-11-09 00:25:56 +00:00
{
if ( item . state_bit )
{
if ( ! item . ci_state_ptr )
throw std : : logic_error ( " NULL state pointer with non-zero state bit " ) ;
if ( down )
2013-11-26 23:15:35 +00:00
Controls . state . * item . ci_state_ptr | = item . state_bit ;
2013-11-09 00:25:56 +00:00
else
2013-11-26 23:15:35 +00:00
Controls . state . * item . ci_state_ptr & = ~ item . state_bit ;
2013-11-09 00:25:56 +00:00
}
else
{
if ( item . ci_count_ptr ! = NULL & & down )
2013-11-26 23:15:35 +00:00
Controls . state . * item . ci_count_ptr + = 1 ;
2013-11-09 00:25:56 +00:00
}
}
2020-05-28 03:21:22 +00:00
}
namespace dcx {
2020-08-28 00:18:45 +00:00
namespace {
2013-12-07 21:34:53 +00:00
template < template < typename > class F >
2015-08-29 13:46:03 +00:00
static void adjust_ramped_keyboard_field ( float & keydown_time , ubyte & state , fix & time , const float & sensitivity , const int & speed_factor , const int & speed_divisor = 1 )
2013-12-07 21:34:53 +00:00
# define adjust_ramped_keyboard_field(F, M, ...) \
( adjust_ramped_keyboard_field < F > ( Controls . down_time . M , Controls . state . M , __VA_ARGS__ ) )
{
if ( state )
{
2015-12-14 14:19:59 +00:00
if ( keydown_time < F1_0 )
2018-05-05 22:33:55 +00:00
keydown_time + = ( static_cast < float > ( FrameTime ) * 6.66 ) * ( ( sensitivity + 1 ) / 17 ) ; // values based on observation that the original game uses a keyboard ramp of 8 frames. Full sensitivity should reflect 60FPS behaviour, half sensitivity reflects 30FPS behaviour (give or take a frame).
2015-12-14 14:19:59 +00:00
time = F < fix > ( ) ( time , speed_factor / speed_divisor * ( keydown_time / F1_0 ) ) ;
2013-12-07 21:34:53 +00:00
}
else
keydown_time = 0 ;
}
2013-11-03 22:51:01 +00:00
template < std : : size_t N >
2020-05-02 21:18:42 +00:00
static void adjust_axis_field ( fix & time , const std : : array < fix , N > & axes , unsigned value , unsigned invert , const int & sensitivity )
2013-11-03 22:51:01 +00:00
{
2013-11-03 23:15:09 +00:00
if ( value = = 255 )
return ;
2015-04-02 02:36:52 +00:00
fix amount = ( axes . at ( value ) * sensitivity ) / 8 ;
2013-11-03 22:51:01 +00:00
if ( ! invert ) // If not inverted...
time - = amount ;
else
time + = amount ;
}
2013-11-03 02:56:01 +00:00
static void clamp_value ( fix & value , const fix & lower , const fix & upper )
{
value = min ( max ( value , lower ) , upper ) ;
}
static void clamp_symmetric_value ( fix & value , const fix & bound )
{
clamp_value ( value , - bound , bound ) ;
}
2016-09-25 04:52:49 +00:00
# if DXX_MAX_AXES_PER_JOYSTICK
2020-05-28 03:21:22 +00:00
static void convert_raw_joy_axis ( control_info : : joystick_axis_values & Controls , const uint_fast32_t player_cfg_index , const uint_fast32_t i )
2015-06-09 23:42:50 +00:00
{
2015-06-23 03:04:47 +00:00
const auto raw_joy_axis = Controls . raw_joy_axis [ i ] ;
const auto joy_axis = ( abs ( raw_joy_axis ) < = ( 128 * PlayerCfg . JoystickLinear [ player_cfg_index ] ) / 16 )
? ( raw_joy_axis * ( FrameTime * PlayerCfg . JoystickSpeed [ player_cfg_index ] ) / 16 )
: ( raw_joy_axis * FrameTime ) ;
Controls . joy_axis [ i ] = joy_axis / 128 ;
}
2020-07-05 23:34:33 +00:00
static void convert_raw_joy_axis ( control_info : : joystick_axis_values & Controls , const dxx_kconfig_ui_kc_joystick kcm_index , const uint_fast32_t player_cfg_index , const uint_fast32_t i )
2015-06-23 03:04:47 +00:00
{
if ( i ! = kcm_joystick [ kcm_index ] . value )
return ;
2020-05-28 03:21:22 +00:00
convert_raw_joy_axis ( Controls , player_cfg_index , i ) ;
2015-06-09 23:42:50 +00:00
}
2015-11-01 21:15:40 +00:00
# endif
2015-06-09 23:42:50 +00:00
2015-06-25 02:48:42 +00:00
static inline void adjust_button_time ( fix & o , uint8_t add , uint8_t sub , fix v )
{
if ( add )
{
if ( sub )
return ;
o + = v ;
}
else if ( sub )
o - = v ;
}
2015-09-24 14:31:10 +00:00
static void clamp_kconfig_control_with_overrun ( fix & value , const fix & bound , fix & excess , const fix & ebound )
{
/* Assume no integer overflow here */
value + = excess ;
const auto ivalue = value ;
clamp_symmetric_value ( value , bound ) ;
excess = ivalue - value ;
clamp_symmetric_value ( excess , ebound ) ;
}
2017-03-25 19:34:02 +00:00
static unsigned allow_uncapped_turning ( )
{
const auto game_mode = Game_mode ;
if ( ! ( game_mode & GM_MULTI ) )
return PlayerCfg . MouselookFlags & MouselookMode : : Singleplayer ;
return PlayerCfg . MouselookFlags &
Netgame . MouselookFlags &
( ( game_mode & GM_MULTI_COOP )
? MouselookMode : : MPCoop
: MouselookMode : : MPAnarchy ) ;
}
2020-05-27 03:07:17 +00:00
}
2020-08-28 00:18:45 +00:00
}
2020-05-28 03:21:22 +00:00
namespace dsx {
void kconfig_read_controls ( control_info & Controls , const d_event & event , int automap_flag )
2006-03-20 17:12:09 +00:00
{
2011-02-02 00:36:49 +00:00
static fix64 mouse_delta_time = 0 ;
2006-03-20 17:12:09 +00:00
2011-02-02 00:36:49 +00:00
# ifndef NDEBUG
// --- Don't do anything if in debug mode ---
if ( keyd_pressed [ KEY_DELETE ] )
{
2014-07-04 03:50:50 +00:00
Controls = { } ;
2011-02-02 00:36:49 +00:00
return ;
}
# endif
2015-06-25 02:48:43 +00:00
const auto frametime = FrameTime ;
2011-02-02 00:36:49 +00:00
2014-10-04 21:47:13 +00:00
switch ( event . type )
2011-02-02 00:36:49 +00:00
{
case EVENT_KEY_COMMAND :
case EVENT_KEY_RELEASE :
2015-06-25 02:48:42 +00:00
{
const auto & & key = event_key_get_raw ( event ) ;
if ( key < 255 )
{
2020-07-05 23:34:33 +00:00
for ( auto & & [ kc , kcm ] : zip ( kc_keyboard , kcm_keyboard ) )
{
if ( kcm . value = = key )
input_button_matched ( Controls , kc , event . type = = EVENT_KEY_COMMAND ) ;
}
2014-10-04 21:47:13 +00:00
if ( ! automap_flag & & event . type = = EVENT_KEY_COMMAND )
2015-04-02 02:36:52 +00:00
for ( uint_fast32_t i = 0 , j = 0 ; i < 28 ; i + = 3 , j + + )
2015-06-25 02:48:42 +00:00
if ( kcm_rebirth [ i ] . value = = key )
2011-02-02 00:36:49 +00:00
{
2013-11-26 22:46:48 +00:00
Controls . state . select_weapon = j + 1 ;
2011-02-02 00:36:49 +00:00
break ;
}
2015-06-25 02:48:42 +00:00
}
}
2011-02-02 00:36:49 +00:00
break ;
2020-09-11 03:08:02 +00:00
# if DXX_MAX_BUTTONS_PER_JOYSTICK
2011-02-02 00:36:49 +00:00
case EVENT_JOYSTICK_BUTTON_DOWN :
case EVENT_JOYSTICK_BUTTON_UP :
if ( ! ( PlayerCfg . ControlType & CONTROL_USING_JOYSTICK ) )
break ;
2015-06-25 02:48:42 +00:00
{
const auto & & button = event_joystick_get_button ( event ) ;
if ( button < 255 )
{
2020-07-05 23:34:33 +00:00
for ( auto & & [ kc , kcm ] : zip ( kc_joystick , kcm_joystick ) )
{
if ( kc . type = = BT_JOY_BUTTON & & kcm . value = = button )
input_button_matched ( Controls , kc , event . type = = EVENT_JOYSTICK_BUTTON_DOWN ) ;
}
2014-10-04 21:47:13 +00:00
if ( ! automap_flag & & event . type = = EVENT_JOYSTICK_BUTTON_DOWN )
2015-04-02 02:36:52 +00:00
for ( uint_fast32_t i = 1 , j = 0 ; i < 29 ; i + = 3 , j + + )
2015-06-25 02:48:42 +00:00
if ( kcm_rebirth [ i ] . value = = button )
2011-02-02 00:36:49 +00:00
{
2013-11-26 22:46:48 +00:00
Controls . state . select_weapon = j + 1 ;
2011-02-02 00:36:49 +00:00
break ;
}
2015-06-25 02:48:42 +00:00
}
2011-02-02 00:36:49 +00:00
break ;
2015-06-25 02:48:42 +00:00
}
2015-11-01 21:15:40 +00:00
# endif
2011-02-02 00:36:49 +00:00
case EVENT_MOUSE_BUTTON_DOWN :
case EVENT_MOUSE_BUTTON_UP :
if ( ! ( PlayerCfg . ControlType & CONTROL_USING_MOUSE ) )
break ;
2015-06-25 02:48:42 +00:00
{
const auto & & button = event_mouse_get_button ( event ) ;
if ( button < 255 )
{
2020-07-05 23:34:33 +00:00
for ( auto & & [ kc , kcm ] : zip ( kc_mouse , kcm_mouse ) )
{
if ( kc . type = = BT_MOUSE_BUTTON & & kcm . value = = button )
input_button_matched ( Controls , kc , event . type = = EVENT_MOUSE_BUTTON_DOWN ) ;
}
2014-10-04 21:47:13 +00:00
if ( ! automap_flag & & event . type = = EVENT_MOUSE_BUTTON_DOWN )
2015-04-02 02:36:52 +00:00
for ( uint_fast32_t i = 2 , j = 0 ; i < 30 ; i + = 3 , j + + )
2015-06-25 02:48:42 +00:00
if ( kcm_rebirth [ i ] . value = = button )
2011-02-02 00:36:49 +00:00
{
2013-11-26 22:46:48 +00:00
Controls . state . select_weapon = j + 1 ;
2011-02-02 00:36:49 +00:00
break ;
}
2015-06-25 02:48:42 +00:00
}
}
2011-02-02 00:36:49 +00:00
break ;
2016-09-25 04:52:49 +00:00
# if DXX_MAX_AXES_PER_JOYSTICK
2011-02-02 00:36:49 +00:00
case EVENT_JOYSTICK_MOVED :
2006-03-20 17:12:09 +00:00
{
2015-09-19 23:04:34 +00:00
int joy_null_value = 0 ;
2011-02-02 00:36:49 +00:00
if ( ! ( PlayerCfg . ControlType & CONTROL_USING_JOYSTICK ) )
break ;
2015-09-19 23:04:34 +00:00
const auto & av = event_joystick_get_axis ( event ) ;
const auto & axis = av . axis ;
2016-10-28 03:39:40 +00:00
auto value = av . value ;
2010-12-28 18:11:10 +00:00
2018-02-01 05:38:47 +00:00
if ( axis = = PlayerCfg . KeySettings . Joystick [ dxx_kconfig_ui_kc_joystick_pitch ] ) // Pitch U/D Deadzone
2010-12-28 18:11:10 +00:00
joy_null_value = PlayerCfg . JoystickDead [ 1 ] * 8 ;
2018-02-01 05:38:47 +00:00
else if ( axis = = PlayerCfg . KeySettings . Joystick [ dxx_kconfig_ui_kc_joystick_turn ] ) // Turn L/R Deadzone
2010-12-28 18:11:10 +00:00
joy_null_value = PlayerCfg . JoystickDead [ 0 ] * 8 ;
2018-02-01 05:38:47 +00:00
else if ( axis = = PlayerCfg . KeySettings . Joystick [ dxx_kconfig_ui_kc_joystick_slide_lr ] ) // Slide L/R Deadzone
2010-12-28 18:11:10 +00:00
joy_null_value = PlayerCfg . JoystickDead [ 2 ] * 8 ;
2018-02-01 05:38:47 +00:00
else if ( axis = = PlayerCfg . KeySettings . Joystick [ dxx_kconfig_ui_kc_joystick_slide_ud ] ) // Slide U/D Deadzone
2010-12-28 18:11:10 +00:00
joy_null_value = PlayerCfg . JoystickDead [ 3 ] * 8 ;
2020-07-05 23:34:33 +00:00
# ifdef dxx_kconfig_ui_kc_joystick_bank
2018-02-01 05:38:47 +00:00
else if ( axis = = PlayerCfg . KeySettings . Joystick [ dxx_kconfig_ui_kc_joystick_bank ] ) // Bank Deadzone
2010-12-28 18:11:10 +00:00
joy_null_value = PlayerCfg . JoystickDead [ 4 ] * 8 ;
2020-07-05 23:34:33 +00:00
# endif
# ifdef dxx_kconfig_ui_kc_joystick_throttle
2018-02-01 05:38:47 +00:00
else if ( axis = = PlayerCfg . KeySettings . Joystick [ dxx_kconfig_ui_kc_joystick_throttle ] ) // Throttle - default deadzone
2011-09-26 18:22:38 +00:00
joy_null_value = PlayerCfg . JoystickDead [ 5 ] * 3 ;
2020-07-05 23:34:33 +00:00
# endif
2006-03-20 17:12:09 +00:00
2019-09-01 14:14:02 +00:00
Controls . raw_joy_axis [ axis ] = apply_deadzone ( value , joy_null_value ) ;
2011-02-02 00:36:49 +00:00
break ;
2007-05-14 13:38:44 +00:00
}
2015-11-01 21:15:40 +00:00
# endif
2011-02-02 00:36:49 +00:00
case EVENT_MOUSE_MOVED :
2011-01-04 10:43:37 +00:00
{
2011-02-02 00:36:49 +00:00
if ( ! ( PlayerCfg . ControlType & CONTROL_USING_MOUSE ) )
break ;
if ( PlayerCfg . MouseFlightSim )
2011-01-04 10:43:37 +00:00
{
2011-02-02 00:36:49 +00:00
int ax [ 3 ] ;
event_mouse_get_delta ( event , & ax [ 0 ] , & ax [ 1 ] , & ax [ 2 ] ) ;
2015-04-02 02:36:52 +00:00
for ( uint_fast32_t i = 0 ; i < = 2 ; i + + )
2011-02-02 00:36:49 +00:00
{
int mouse_null_value = ( i = = 2 ? 16 : PlayerCfg . MouseFSDead * 8 ) ;
Controls . raw_mouse_axis [ i ] + = ax [ i ] ;
2016-10-21 02:16:48 +00:00
clamp_symmetric_value ( Controls . raw_mouse_axis [ i ] , MOUSEFS_DELTA_RANGE ) ;
2011-02-02 00:36:49 +00:00
if ( Controls . raw_mouse_axis [ i ] > mouse_null_value )
2015-06-25 02:48:43 +00:00
Controls . mouse_axis [ i ] = ( ( ( Controls . raw_mouse_axis [ i ] - mouse_null_value ) * MOUSEFS_DELTA_RANGE ) / ( MOUSEFS_DELTA_RANGE - mouse_null_value ) * frametime ) / MOUSEFS_DELTA_RANGE ;
2011-02-02 00:36:49 +00:00
else if ( Controls . raw_mouse_axis [ i ] < - mouse_null_value )
2015-06-25 02:48:43 +00:00
Controls . mouse_axis [ i ] = ( ( ( Controls . raw_mouse_axis [ i ] + mouse_null_value ) * MOUSEFS_DELTA_RANGE ) / ( MOUSEFS_DELTA_RANGE - mouse_null_value ) * frametime ) / MOUSEFS_DELTA_RANGE ;
2011-02-02 00:36:49 +00:00
else
Controls . mouse_axis [ i ] = 0 ;
}
2011-01-04 10:43:37 +00:00
}
2011-04-22 11:01:38 +00:00
else
2011-02-02 00:36:49 +00:00
{
event_mouse_get_delta ( event , & Controls . raw_mouse_axis [ 0 ] , & Controls . raw_mouse_axis [ 1 ] , & Controls . raw_mouse_axis [ 2 ] ) ;
2015-09-25 10:07:30 +00:00
Controls . mouse_axis [ 0 ] = ( Controls . raw_mouse_axis [ 0 ] * frametime ) / 8 ;
Controls . mouse_axis [ 1 ] = ( Controls . raw_mouse_axis [ 1 ] * frametime ) / 8 ;
2015-06-25 02:48:43 +00:00
Controls . mouse_axis [ 2 ] = ( Controls . raw_mouse_axis [ 2 ] * frametime ) ;
2013-08-08 20:07:29 +00:00
mouse_delta_time = timer_query ( ) + DESIGNATED_GAME_FRAMETIME ;
2011-02-02 00:36:49 +00:00
}
break ;
2011-01-04 10:43:37 +00:00
}
2011-02-02 00:36:49 +00:00
case EVENT_IDLE :
default :
if ( ! PlayerCfg . MouseFlightSim & & mouse_delta_time < timer_query ( ) )
2011-04-22 11:01:38 +00:00
{
2011-02-02 00:36:49 +00:00
Controls . mouse_axis [ 0 ] = Controls . mouse_axis [ 1 ] = Controls . mouse_axis [ 2 ] = 0 ;
2013-08-08 20:07:29 +00:00
mouse_delta_time = timer_query ( ) + DESIGNATED_GAME_FRAMETIME ;
2011-04-22 11:01:38 +00:00
}
2011-02-02 00:36:49 +00:00
break ;
2006-03-20 17:12:09 +00:00
}
2015-06-09 23:42:50 +00:00
2016-09-25 04:52:49 +00:00
# if DXX_MAX_AXES_PER_JOYSTICK
2015-06-09 23:42:50 +00:00
for ( int i = 0 ; i < JOY_MAX_AXES ; i + + ) {
2020-07-05 23:34:33 +00:00
convert_raw_joy_axis ( Controls , dxx_kconfig_ui_kc_joystick_turn , 0 , i ) ; // Turn L/R
convert_raw_joy_axis ( Controls , dxx_kconfig_ui_kc_joystick_pitch , 1 , i ) ; // Pitch U/D
convert_raw_joy_axis ( Controls , dxx_kconfig_ui_kc_joystick_slide_lr , 2 , i ) ; // Slide L/R
convert_raw_joy_axis ( Controls , dxx_kconfig_ui_kc_joystick_slide_ud , 3 , i ) ; // Slide U/D
convert_raw_joy_axis ( Controls , dxx_kconfig_ui_kc_joystick_bank , 4 , i ) ; // Bank
convert_raw_joy_axis ( Controls , dxx_kconfig_ui_kc_joystick_throttle , 5 , i ) ; // Throttle
2015-06-09 23:42:50 +00:00
}
2015-11-01 21:15:40 +00:00
# endif
2015-06-09 23:42:50 +00:00
2015-06-25 02:48:43 +00:00
const auto speed_factor = ( cheats . turbo ? 2 : 1 ) * frametime ;
2006-03-20 17:12:09 +00:00
2011-02-02 00:36:49 +00:00
//------------ Read pitch_time -----------
2013-11-26 22:46:48 +00:00
if ( ! Controls . state . slide_on )
2006-03-20 17:12:09 +00:00
{
2012-06-01 09:53:59 +00:00
// From keyboard...
2015-12-14 14:19:59 +00:00
adjust_ramped_keyboard_field ( plus , key_pitch_forward , Controls . pitch_time , PlayerCfg . KeyboardSens [ 1 ] , speed_factor , 2 ) ;
adjust_ramped_keyboard_field ( minus , key_pitch_backward , Controls . pitch_time , PlayerCfg . KeyboardSens [ 1 ] , speed_factor , 2 ) ;
2006-03-20 17:12:09 +00:00
// From joystick...
2020-07-05 23:34:33 +00:00
# ifdef dxx_kconfig_ui_kc_joystick_pitch
adjust_axis_field ( Controls . pitch_time , Controls . joy_axis , kcm_joystick [ dxx_kconfig_ui_kc_joystick_pitch ] . value , kcm_joystick [ dxx_kconfig_ui_kc_joystick_invert_pitch ] . value , PlayerCfg . JoystickSens [ 1 ] ) ;
2015-11-01 21:15:40 +00:00
# endif
2006-03-20 17:12:09 +00:00
// From mouse...
2020-07-05 23:34:33 +00:00
# ifdef dxx_kconfig_ui_kc_mouse_pitch
adjust_axis_field ( Controls . pitch_time , Controls . mouse_axis , kcm_mouse [ dxx_kconfig_ui_kc_mouse_pitch ] . value , kcm_mouse [ dxx_kconfig_ui_kc_mouse_invert_pitch ] . value , PlayerCfg . MouseSens [ 1 ] ) ;
# endif
2006-03-20 17:12:09 +00:00
}
2011-02-02 00:36:49 +00:00
else Controls . pitch_time = 0 ;
2006-03-20 17:12:09 +00:00
2007-05-14 13:38:44 +00:00
//----------- Read vertical_thrust_time -----------------
2013-11-26 22:46:48 +00:00
if ( Controls . state . slide_on )
2011-02-02 00:36:49 +00:00
{
2012-06-01 09:53:59 +00:00
// From keyboard...
2013-12-07 21:34:53 +00:00
adjust_ramped_keyboard_field ( plus , key_pitch_forward , Controls . vertical_thrust_time , PlayerCfg . KeyboardSens [ 3 ] , speed_factor ) ;
adjust_ramped_keyboard_field ( minus , key_pitch_backward , Controls . vertical_thrust_time , PlayerCfg . KeyboardSens [ 3 ] , speed_factor ) ;
2006-03-20 17:12:09 +00:00
// From joystick...
2013-11-03 22:51:01 +00:00
// NOTE: Use Slide U/D invert setting
2020-07-05 23:34:33 +00:00
# if defined(dxx_kconfig_ui_kc_joystick_pitch) && defined(dxx_kconfig_ui_kc_joystick_slide_ud)
adjust_axis_field ( Controls . vertical_thrust_time , Controls . joy_axis , kcm_joystick [ dxx_kconfig_ui_kc_joystick_pitch ] . value , ! kcm_joystick [ dxx_kconfig_ui_kc_joystick_invert_slide_ud ] . value , PlayerCfg . JoystickSens [ 3 ] ) ;
2015-11-01 21:15:40 +00:00
# endif
2006-03-20 17:12:09 +00:00
// From mouse...
2020-07-05 23:34:33 +00:00
adjust_axis_field ( Controls . vertical_thrust_time , Controls . mouse_axis , kcm_mouse [ dxx_kconfig_ui_kc_mouse_pitch ] . value , kcm_mouse [ dxx_kconfig_ui_kc_mouse_invert_slide_ud ] . value , PlayerCfg . MouseSens [ 3 ] ) ;
2006-03-20 17:12:09 +00:00
}
2012-06-01 09:53:59 +00:00
// From keyboard...
2013-12-07 21:34:53 +00:00
adjust_ramped_keyboard_field ( plus , key_slide_up , Controls . vertical_thrust_time , PlayerCfg . KeyboardSens [ 3 ] , speed_factor ) ;
adjust_ramped_keyboard_field ( minus , key_slide_down , Controls . vertical_thrust_time , PlayerCfg . KeyboardSens [ 3 ] , speed_factor ) ;
2012-06-01 09:53:59 +00:00
// From buttons...
2015-06-25 02:48:42 +00:00
adjust_button_time ( Controls . vertical_thrust_time , Controls . state . btn_slide_up , Controls . state . btn_slide_down , speed_factor ) ;
2011-02-02 00:36:49 +00:00
// From joystick...
2020-07-05 23:34:33 +00:00
# ifdef dxx_kconfig_ui_kc_joystick_slide_ud
adjust_axis_field ( Controls . vertical_thrust_time , Controls . joy_axis , kcm_joystick [ dxx_kconfig_ui_kc_joystick_slide_ud ] . value , ! kcm_joystick [ dxx_kconfig_ui_kc_joystick_invert_slide_ud ] . value , PlayerCfg . JoystickSens [ 3 ] ) ;
2015-11-01 21:15:40 +00:00
# endif
2011-02-02 00:36:49 +00:00
// From mouse...
2020-07-05 23:34:33 +00:00
adjust_axis_field ( Controls . vertical_thrust_time , Controls . mouse_axis , kcm_mouse [ dxx_kconfig_ui_kc_mouse_slide_ud ] . value , ! kcm_mouse [ dxx_kconfig_ui_kc_mouse_invert_slide_ud ] . value , PlayerCfg . MouseSens [ 3 ] ) ;
2006-03-20 17:12:09 +00:00
2011-02-02 00:36:49 +00:00
//---------- Read heading_time -----------
2013-11-26 22:46:48 +00:00
if ( ! Controls . state . slide_on & & ! Controls . state . bank_on )
2011-02-02 00:36:49 +00:00
{
2012-06-01 09:53:59 +00:00
// From keyboard...
2015-12-14 14:19:59 +00:00
adjust_ramped_keyboard_field ( plus , key_heading_right , Controls . heading_time , PlayerCfg . KeyboardSens [ 0 ] , speed_factor ) ;
adjust_ramped_keyboard_field ( minus , key_heading_left , Controls . heading_time , PlayerCfg . KeyboardSens [ 0 ] , speed_factor ) ;
2006-03-20 17:12:09 +00:00
// From joystick...
2020-07-05 23:34:33 +00:00
# ifdef dxx_kconfig_ui_kc_joystick_turn
adjust_axis_field ( Controls . heading_time , Controls . joy_axis , kcm_joystick [ dxx_kconfig_ui_kc_joystick_turn ] . value , ! kcm_joystick [ dxx_kconfig_ui_kc_joystick_invert_turn ] . value , PlayerCfg . JoystickSens [ 0 ] ) ;
2015-11-01 21:15:40 +00:00
# endif
2006-03-20 17:12:09 +00:00
// From mouse...
2020-07-05 23:34:33 +00:00
adjust_axis_field ( Controls . heading_time , Controls . mouse_axis , kcm_mouse [ dxx_kconfig_ui_kc_mouse_turn ] . value , ! kcm_mouse [ dxx_kconfig_ui_kc_mouse_invert_turn ] . value , PlayerCfg . MouseSens [ 0 ] ) ;
2006-03-20 17:12:09 +00:00
}
2011-02-02 00:36:49 +00:00
else Controls . heading_time = 0 ;
2006-03-20 17:12:09 +00:00
2007-05-14 13:38:44 +00:00
//----------- Read sideways_thrust_time -----------------
2013-11-26 22:46:48 +00:00
if ( Controls . state . slide_on )
2011-02-02 00:36:49 +00:00
{
2012-06-01 09:53:59 +00:00
// From keyboard...
2013-12-07 21:34:53 +00:00
adjust_ramped_keyboard_field ( plus , key_heading_right , Controls . sideways_thrust_time , PlayerCfg . KeyboardSens [ 2 ] , speed_factor ) ;
adjust_ramped_keyboard_field ( minus , key_heading_left , Controls . sideways_thrust_time , PlayerCfg . KeyboardSens [ 2 ] , speed_factor ) ;
2006-03-20 17:12:09 +00:00
// From joystick...
2020-07-05 23:34:33 +00:00
# if defined(dxx_kconfig_ui_kc_joystick_turn) && defined(dxx_kconfig_ui_kc_joystick_slide_lr)
adjust_axis_field ( Controls . sideways_thrust_time , Controls . joy_axis , kcm_joystick [ dxx_kconfig_ui_kc_joystick_turn ] . value , ! kcm_joystick [ dxx_kconfig_ui_kc_joystick_invert_slide_lr ] . value , PlayerCfg . JoystickSens [ 2 ] ) ;
2015-11-01 21:15:40 +00:00
# endif
2006-03-20 17:12:09 +00:00
// From mouse...
2020-07-05 23:34:33 +00:00
adjust_axis_field ( Controls . sideways_thrust_time , Controls . mouse_axis , kcm_mouse [ dxx_kconfig_ui_kc_mouse_turn ] . value , ! kcm_mouse [ dxx_kconfig_ui_kc_mouse_invert_slide_lr ] . value , PlayerCfg . MouseSens [ 2 ] ) ;
2006-03-20 17:12:09 +00:00
}
2012-06-01 09:53:59 +00:00
// From keyboard...
2013-12-07 21:34:53 +00:00
adjust_ramped_keyboard_field ( plus , key_slide_right , Controls . sideways_thrust_time , PlayerCfg . KeyboardSens [ 2 ] , speed_factor ) ;
adjust_ramped_keyboard_field ( minus , key_slide_left , Controls . sideways_thrust_time , PlayerCfg . KeyboardSens [ 2 ] , speed_factor ) ;
2012-06-01 09:53:59 +00:00
// From buttons...
2015-06-25 02:48:42 +00:00
adjust_button_time ( Controls . sideways_thrust_time , Controls . state . btn_slide_right , Controls . state . btn_slide_left , speed_factor ) ;
2011-02-02 00:36:49 +00:00
// From joystick...
2020-07-05 23:34:33 +00:00
# ifdef dxx_kconfig_ui_kc_joystick_slide_lr
adjust_axis_field ( Controls . sideways_thrust_time , Controls . joy_axis , kcm_joystick [ dxx_kconfig_ui_kc_joystick_slide_lr ] . value , ! kcm_joystick [ dxx_kconfig_ui_kc_joystick_invert_slide_lr ] . value , PlayerCfg . JoystickSens [ 2 ] ) ;
2015-11-01 21:15:40 +00:00
# endif
2011-02-02 00:36:49 +00:00
// From mouse...
2020-07-05 23:34:33 +00:00
adjust_axis_field ( Controls . sideways_thrust_time , Controls . mouse_axis , kcm_mouse [ dxx_kconfig_ui_kc_mouse_slide_lr ] . value , ! kcm_mouse [ dxx_kconfig_ui_kc_mouse_invert_slide_lr ] . value , PlayerCfg . MouseSens [ 2 ] ) ;
2006-03-20 17:12:09 +00:00
2011-02-02 00:36:49 +00:00
//----------- Read bank_time -----------------
2013-11-26 22:46:48 +00:00
if ( Controls . state . bank_on )
2011-02-02 00:36:49 +00:00
{
2012-06-01 09:53:59 +00:00
// From keyboard...
2013-12-07 21:34:53 +00:00
adjust_ramped_keyboard_field ( plus , key_heading_left , Controls . bank_time , PlayerCfg . KeyboardSens [ 4 ] , speed_factor ) ;
adjust_ramped_keyboard_field ( minus , key_heading_right , Controls . bank_time , PlayerCfg . KeyboardSens [ 4 ] , speed_factor ) ;
2006-03-20 17:12:09 +00:00
// From joystick...
2020-07-05 23:34:33 +00:00
# if defined(dxx_kconfig_ui_kc_joystick_turn) && defined(dxx_kconfig_ui_kc_joystick_bank)
adjust_axis_field ( Controls . bank_time , Controls . joy_axis , kcm_joystick [ dxx_kconfig_ui_kc_joystick_turn ] . value , kcm_joystick [ dxx_kconfig_ui_kc_joystick_invert_bank ] . value , PlayerCfg . JoystickSens [ 4 ] ) ;
2015-11-01 21:15:40 +00:00
# endif
2006-03-20 17:12:09 +00:00
// From mouse...
2020-07-05 23:34:33 +00:00
adjust_axis_field ( Controls . bank_time , Controls . mouse_axis , kcm_mouse [ dxx_kconfig_ui_kc_mouse_turn ] . value , ! kcm_mouse [ dxx_kconfig_ui_kc_mouse_invert_bank ] . value , PlayerCfg . MouseSens [ 4 ] ) ;
2006-03-20 17:12:09 +00:00
}
2012-06-01 09:53:59 +00:00
// From keyboard...
2013-12-07 21:34:53 +00:00
adjust_ramped_keyboard_field ( plus , key_bank_left , Controls . bank_time , PlayerCfg . KeyboardSens [ 4 ] , speed_factor ) ;
adjust_ramped_keyboard_field ( minus , key_bank_right , Controls . bank_time , PlayerCfg . KeyboardSens [ 4 ] , speed_factor ) ;
2012-06-01 09:53:59 +00:00
// From buttons...
2015-06-25 02:48:42 +00:00
adjust_button_time ( Controls . bank_time , Controls . state . btn_bank_left , Controls . state . btn_bank_right , speed_factor ) ;
2011-02-02 00:36:49 +00:00
// From joystick...
2020-07-05 23:34:33 +00:00
# ifdef dxx_kconfig_ui_kc_joystick_bank
adjust_axis_field ( Controls . bank_time , Controls . joy_axis , kcm_joystick [ dxx_kconfig_ui_kc_joystick_bank ] . value , kcm_joystick [ dxx_kconfig_ui_kc_joystick_invert_bank ] . value , PlayerCfg . JoystickSens [ 4 ] ) ;
2015-11-01 21:15:40 +00:00
# endif
2006-03-20 17:12:09 +00:00
// From mouse...
2020-07-05 23:34:33 +00:00
adjust_axis_field ( Controls . bank_time , Controls . mouse_axis , kcm_mouse [ dxx_kconfig_ui_kc_mouse_bank ] . value , ! kcm_mouse [ dxx_kconfig_ui_kc_mouse_invert_bank ] . value , PlayerCfg . MouseSens [ 4 ] ) ;
2006-03-20 17:12:09 +00:00
2007-05-14 13:38:44 +00:00
//----------- Read forward_thrust_time -------------
2011-02-02 00:36:49 +00:00
// From keyboard/buttons...
2015-06-25 02:48:42 +00:00
adjust_button_time ( Controls . forward_thrust_time , Controls . state . accelerate , Controls . state . reverse , speed_factor ) ;
2011-02-02 00:36:49 +00:00
// From joystick...
2020-07-05 23:34:33 +00:00
# ifdef dxx_kconfig_ui_kc_joystick_throttle
adjust_axis_field ( Controls . forward_thrust_time , Controls . joy_axis , kcm_joystick [ dxx_kconfig_ui_kc_joystick_throttle ] . value , kcm_joystick [ dxx_kconfig_ui_kc_joystick_invert_throttle ] . value , PlayerCfg . JoystickSens [ 5 ] ) ;
2015-11-01 21:15:40 +00:00
# endif
2011-02-02 00:36:49 +00:00
// From mouse...
2020-07-05 23:34:33 +00:00
adjust_axis_field ( Controls . forward_thrust_time , Controls . mouse_axis , kcm_mouse [ dxx_kconfig_ui_kc_mouse_throttle ] . value , kcm_mouse [ dxx_kconfig_ui_kc_mouse_invert_throttle ] . value , PlayerCfg . MouseSens [ 5 ] ) ;
2006-03-20 17:12:09 +00:00
2011-02-02 00:36:49 +00:00
//----------- Read cruise-control-type of throttle.
2013-11-26 22:46:48 +00:00
if ( Controls . state . cruise_off > 0 ) Controls . state . cruise_off = Cruise_speed = 0 ;
2015-06-25 02:48:42 +00:00
else
{
adjust_button_time ( Cruise_speed , Controls . state . cruise_plus , Controls . state . cruise_minus , speed_factor * 80 ) ;
clamp_value ( Cruise_speed , 0 , i2f ( 100 ) ) ;
if ( Controls . forward_thrust_time = = 0 )
2015-06-25 02:48:43 +00:00
Controls . forward_thrust_time = fixmul ( Cruise_speed , frametime ) / 100 ;
2015-06-25 02:48:42 +00:00
}
2006-03-20 17:12:09 +00:00
2011-02-02 00:36:49 +00:00
//----------- Clamp values between -FrameTime and FrameTime
2015-09-25 10:07:30 +00:00
clamp_kconfig_control_with_overrun ( Controls . vertical_thrust_time , frametime , Controls . excess_vertical_thrust_time , frametime * PlayerCfg . MouseOverrun [ 3 ] ) ;
clamp_kconfig_control_with_overrun ( Controls . sideways_thrust_time , frametime , Controls . excess_sideways_thrust_time , frametime * PlayerCfg . MouseOverrun [ 2 ] ) ;
clamp_kconfig_control_with_overrun ( Controls . forward_thrust_time , frametime , Controls . excess_forward_thrust_time , frametime * PlayerCfg . MouseOverrun [ 5 ] ) ;
2017-03-25 19:34:02 +00:00
if ( ! allow_uncapped_turning ( ) )
{
clamp_kconfig_control_with_overrun ( Controls . pitch_time , frametime / 2 , Controls . excess_pitch_time , frametime * PlayerCfg . MouseOverrun [ 1 ] ) ;
clamp_kconfig_control_with_overrun ( Controls . heading_time , frametime , Controls . excess_heading_time , frametime * PlayerCfg . MouseOverrun [ 0 ] ) ;
clamp_kconfig_control_with_overrun ( Controls . bank_time , frametime , Controls . excess_bank_time , frametime * PlayerCfg . MouseOverrun [ 4 ] ) ;
}
2006-03-20 17:12:09 +00:00
}
2020-05-28 03:21:22 +00:00
}
2006-03-20 17:12:09 +00:00
void reset_cruise ( void )
{
Cruise_speed = 0 ;
}
void kc_set_controls ( )
{
2020-08-28 00:18:45 +00:00
for ( auto & & [ kcm , setting ] : zip ( kcm_keyboard , PlayerCfg . KeySettings . Keyboard ) )
2020-07-05 23:34:33 +00:00
kcm . oldvalue = kcm . value = setting ;
2006-03-20 17:12:09 +00:00
2016-09-25 04:52:48 +00:00
# if DXX_MAX_JOYSTICKS
2020-08-28 00:18:45 +00:00
for ( auto & & [ kcm , kc , setting ] : zip ( kcm_joystick , kc_joystick , PlayerCfg . KeySettings . Joystick ) )
2009-12-02 13:49:54 +00:00
{
2020-07-05 23:34:33 +00:00
uint8_t value = setting ;
if ( kc . type = = BT_INVERT )
2009-12-02 13:49:54 +00:00
{
2017-12-15 04:47:30 +00:00
if ( value ! = 1 )
value = 0 ;
2020-07-05 23:34:33 +00:00
setting = value ;
2006-03-20 17:12:09 +00:00
}
2020-07-05 23:34:33 +00:00
kcm . oldvalue = kcm . value = value ;
2006-10-07 01:12:25 +00:00
}
2015-11-01 21:15:40 +00:00
# endif
2010-02-21 01:25:27 +00:00
2020-08-28 00:18:45 +00:00
for ( auto & & [ kcm , kc , setting ] : zip ( kcm_mouse , kc_mouse , PlayerCfg . KeySettings . Mouse ) )
2009-12-02 13:49:54 +00:00
{
2020-07-05 23:34:33 +00:00
uint8_t value = setting ;
if ( kc . type = = BT_INVERT )
2009-12-02 13:49:54 +00:00
{
2017-12-15 04:47:30 +00:00
if ( value ! = 1 )
value = 0 ;
2020-07-05 23:34:33 +00:00
setting = value ;
2006-03-20 17:12:09 +00:00
}
2020-07-05 23:34:33 +00:00
kcm . oldvalue = kcm . value = value ;
2006-03-20 17:12:09 +00:00
}
2020-08-28 00:18:45 +00:00
for ( auto & & [ kcm , setting ] : zip ( kcm_rebirth , PlayerCfg . KeySettingsRebirth ) )
2020-07-05 23:34:33 +00:00
kcm . oldvalue = kcm . value = setting ;
2006-03-20 17:12:09 +00:00
}