Better analog controls; thanks @mickski56; close #77

This commit is contained in:
Dominic Szablewski
2025-04-26 21:33:13 +02:00
parent c3a31407b8
commit 38159b447c
4 changed files with 33 additions and 10 deletions

View File

@@ -418,6 +418,7 @@ save_t save = {
[A_FIRE] = {INPUT_KEY_Z, INPUT_GAMEPAD_X},
[A_CHANGE_VIEW] = {INPUT_KEY_A, INPUT_GAMEPAD_Y},
},
.analog_response = 2, // Exponent for stick turn input
.highscores_name = {0,0,0,0},
.highscores = {
@@ -512,7 +513,7 @@ void game_init(void) {
memcpy(&save, save_file, sizeof(save_t));
}
else {
printf("unexpected size/magic for save data");
printf("unexpected size/magic for save data\n");
}
mem_temp_free(save_file);
}

View File

@@ -252,6 +252,7 @@ typedef struct {
uint32_t has_bonus_circuts;
uint8_t buttons[NUM_GAME_ACTIONS][2];
float analog_response;
char highscores_name[4];
highscores_t highscores[NUM_RACE_CLASSES][NUM_CIRCUTS][NUM_HIGHSCORE_TABS];

View File

@@ -212,7 +212,7 @@ static void page_options_control_draw(menu_t *menu, int data) {
for (int action = 0; action < NUM_GAME_ACTIONS; action++) {
rgba_t text_color = UI_COLOR_DEFAULT;
if (action == data) {
if (action == page->index) {
text_color = UI_COLOR_ACCENT;
}
@@ -236,6 +236,13 @@ static void page_options_control_draw(menu_t *menu, int data) {
}
}
static void toggle_analog_response(menu_t *menu, int data) {
save.analog_response = (float)data + 1;
save.is_dirty = true;
}
static const char *analog_response[] = {"LINEAR", "MODERATE", "HEAVY"};
static void page_options_controls_init(menu_t *menu) {
menu_page_t *page = menu_push(menu, "CONTROLS", page_options_control_draw);
flags_set(page->layout_flags, MENU_VERTICAL | MENU_FIXED);
@@ -256,6 +263,8 @@ static void page_options_controls_init(menu_t *menu) {
menu_page_add_button(page, A_THRUST, "THRUST", page_options_controls_set_init);
menu_page_add_button(page, A_FIRE, "FIRE", page_options_controls_set_init);
menu_page_add_button(page, A_CHANGE_VIEW, "VIEW", page_options_controls_set_init);
menu_page_add_toggle(page, save.analog_response - 1, "ANALOG RESPONSE", analog_response, len(analog_response), toggle_analog_response);
}
// -----------------------------------------------------------------------------

View File

@@ -176,22 +176,34 @@ void ship_player_update_race(ship_t *self) {
// FIXME_PL: make sure revconned is honored
}
// Turning
// For analog input we set a turn_target (exponentiated by the analog_response
// curve) and stop adding to angular acceleration once we exceed that target.
// For digital input (0|1) the powf() and multiplication with turn_rate_max
// will have no influence on the original behavior.
self->angular_acceleration = vec3(0, 0, 0);
if (input_state(A_LEFT)) {
if (self->angular_velocity.y >= 0) {
self->angular_acceleration.y += input_state(A_LEFT) * self->turn_rate;
if (self->angular_velocity.y < 0) {
self->angular_acceleration.y += self->turn_rate * 2;
}
else if (self->angular_velocity.y < 0) {
self->angular_acceleration.y += input_state(A_LEFT) * self->turn_rate * 2;
else {
float turn_target = powf(input_state(A_LEFT), save.analog_response);
if (turn_target * self->turn_rate_max > self->angular_velocity.y) {
self->angular_acceleration.y += self->turn_rate;
}
}
}
else if (input_state(A_RIGHT)) {
if (self->angular_velocity.y <= 0) {
self->angular_acceleration.y -= input_state(A_RIGHT) * self->turn_rate;
if (self->angular_velocity.y > 0) {
self->angular_acceleration.y -= self->turn_rate * 2;
}
else if (self->angular_velocity.y > 0) {
self->angular_acceleration.y -= input_state(A_RIGHT) * self->turn_rate * 2;
else {
float turn_target = powf(input_state(A_RIGHT), save.analog_response);
if (turn_target * -self->turn_rate_max < self->angular_velocity.y) {
self->angular_acceleration.y -= self->turn_rate;
}
}
}