Skip to content

Commit

Permalink
FF7: Implemented analogue controls in fields
Browse files Browse the repository at this point in the history
  • Loading branch information
CosmosXIII committed Aug 29, 2021
1 parent 716dcf9 commit 0f81196
Show file tree
Hide file tree
Showing 4 changed files with 117 additions and 0 deletions.
9 changes: 9 additions & 0 deletions misc/FFNx.toml
Expand Up @@ -208,6 +208,15 @@ enable_ffmpeg_videos = -1
#~~~~~~~~~~~~~~~~~~~~~~~~~~~
ffmpeg_video_ext = "avi"

###########################
# Controller Options
###########################

#[ANALOGUE CONTROLS]
# This flag will enable analogue joystick input for controlling the player.
#~~~~~~~~~~~~~~~~~~~~~~~~~~~
enable_analogue_controls = false

###############################
# MUST SET FOR VERSIONS BELOW
# FF7 2012 FF7 STEAM
Expand Down
2 changes: 2 additions & 0 deletions src/cfg.cpp
Expand Up @@ -99,6 +99,7 @@ double speedhack_min;
bool enable_animated_textures;
long ff7_fps_limiter;
bool ff7_footsteps;
bool enable_analogue_controls;

std::vector<std::string> get_string_or_array_of_strings(const toml::node_view<toml::node> &node)
{
Expand Down Expand Up @@ -212,6 +213,7 @@ void read_cfg()
enable_animated_textures = config["enable_animated_textures"].value_or(false);
ff7_fps_limiter = config["ff7_fps_limiter"].value_or(FF7_LIMITER_DEFAULT);
ff7_footsteps = config["ff7_footsteps"].value_or(false);
enable_analogue_controls = config["enable_analogue_controls"].value_or(false);

// Windows x or y size can't be less then 0
if (window_size_x < 0) window_size_x = 0;
Expand Down
1 change: 1 addition & 0 deletions src/cfg.h
Expand Up @@ -112,5 +112,6 @@ extern double speedhack_min;
extern bool enable_animated_textures;
extern long ff7_fps_limiter;
extern bool ff7_footsteps;
extern bool enable_analogue_controls;

void read_cfg();
105 changes: 105 additions & 0 deletions src/ff7/misc.cpp
Expand Up @@ -94,6 +94,107 @@ void ff7_wm_activateapp(bool hasFocus)

}

int ff7_get_control_direction()
{
byte* level_data = *ff7_externals.field_level_data_pointer;

if (level_data != nullptr)
{
uint32_t triggers_offset = *(uint32_t*)(level_data + 0x22);
signed short* control_direction_data = (signed short*)(level_data + triggers_offset + 4 + 9);

return static_cast<int>(*control_direction_data);
}

return 0;
}

void ff7_set_control_direction(int x)
{
byte* level_data = *ff7_externals.field_level_data_pointer;

if (level_data != nullptr)
{
uint32_t triggers_offset = *(uint32_t*)(level_data + 0x22);
signed short* control_direction_data = (signed short*)(level_data + triggers_offset + 4 + 9);

*control_direction_data = static_cast<signed short>(x);
}
}

void ff7_use_analogue_controls()
{
static WORD last_field_id = 0;
static int base_control_direction = 0;
if (last_field_id != *ff7_externals.field_id)
{
last_field_id = *ff7_externals.field_id;
base_control_direction = ff7_get_control_direction();
}

point3d joyDir = {0.0f, 0.0f, 0.0f};
point3d inputDir = {0.0f, 0.0f, 0.0f};
if(xinput_connected)
{
joyDir = {gamepad.leftStickX, gamepad.leftStickY, 0.0f};

if(gamepad.leftStickY > 0.5f && !(gamepad.leftStickX < -0.5f || gamepad.leftStickX > 0.5f))
inputDir = {0.0f, 1.0f, 0.0f};
else if(gamepad.leftStickY > 0.5f && gamepad.leftStickX < -0.5f)
inputDir = {-0.707f, 0.707f, 0.0f};
else if(gamepad.leftStickY > 0.5f && gamepad.leftStickX > 0.5f)
inputDir = {0.707f, 0.707f, 0.0f};
else if(gamepad.leftStickX < -0.5f &&!(gamepad.leftStickY > 0.5f || gamepad.leftStickY < -0.5f))
inputDir = {-1.0f, 0.0f, 0.0f};
else if(gamepad.leftStickX > 0.5f && !(gamepad.leftStickY > 0.5f || gamepad.leftStickY < -0.5f))
inputDir = {1.0f, 0.0f, 0.0f};
else if(gamepad.leftStickY < -0.5f && gamepad.leftStickX < -0.5f)
inputDir = {-0.707f, -0.707f, 0.0f};
else if(gamepad.leftStickY < -0.5f && gamepad.leftStickX > 0.5f)
inputDir = {0.707f, -0.707f, 0.0f};
else if(gamepad.leftStickY < -0.5f && !(gamepad.leftStickX < -0.5f || gamepad.leftStickX > 0.5f))
inputDir = {0.0f, -1.0f, 0.0f};
}
else
{
joyDir = {static_cast<float>(joystick.GetState()->lX), -static_cast<float>(joystick.GetState()->lY), 0.0f};

if(joystick.GetState()->lY < joystick.GetDeadZone(-0.5f) &&
!(joystick.GetState()->lX < joystick.GetDeadZone(-0.5f) || joystick.GetState()->lX > joystick.GetDeadZone(0.5f)))
inputDir = {0.0f, 1.0f, 0.0f};
else if(joystick.GetState()->lY < joystick.GetDeadZone(-0.5f) && joystick.GetState()->lX < joystick.GetDeadZone(-0.5f))
inputDir = {-0.707f, 0.707f, 0.0f};
else if(joystick.GetState()->lY < joystick.GetDeadZone(-0.5f) && joystick.GetState()->lX > joystick.GetDeadZone(0.5f))
inputDir = {0.707f, 0.707f, 0.0f};
else if(joystick.GetState()->lX < joystick.GetDeadZone(-0.5f) &&
!(joystick.GetState()->lY < joystick.GetDeadZone(-0.5f) || joystick.GetState()->lY > joystick.GetDeadZone(0.5f)))
inputDir = {-1.0f, 0.0f, 0.0f};
else if(joystick.GetState()->lX > joystick.GetDeadZone(0.5f) &&
!(joystick.GetState()->lY < joystick.GetDeadZone(-0.5f) || joystick.GetState()->lY > joystick.GetDeadZone(0.5f)))
inputDir = {1.0f, 0.0f, 0.0f};
else if(joystick.GetState()->lY > joystick.GetDeadZone(0.5f) && joystick.GetState()->lX < joystick.GetDeadZone(-0.5f))
inputDir = {-0.707f, -0.707f, 0.0f};
else if(joystick.GetState()->lY > joystick.GetDeadZone(0.5f) && joystick.GetState()->lX > joystick.GetDeadZone(0.5f))
inputDir = {0.707f, -0.707f, 0.0f};
else if(joystick.GetState()->lY > joystick.GetDeadZone(0.5f) &&
!(joystick.GetState()->lX < joystick.GetDeadZone(-0.5f) || joystick.GetState()->lX > joystick.GetDeadZone(0.5f)))
inputDir = {0.0f, -1.0f, 0.0f};
}

float inputDirLength = vector_length(&inputDir);
if(inputDirLength > 0.0f)
{
normalize_vector(&joyDir);
float angle = atan2( inputDir.x*joyDir.y - inputDir.y*joyDir.x, inputDir.x*joyDir.x + inputDir.y*joyDir.y );
int offset = std::max(-128, std::min(128, static_cast<int>(128.0f * angle / M_PI)));
ff7_set_control_direction(base_control_direction + offset);
}
else
{
ff7_set_control_direction(base_control_direction);
}
}

int ff7_get_gamepad()
{
if (simulate_OK_button)
Expand Down Expand Up @@ -148,6 +249,8 @@ struct ff7_gamepad_status* ff7_update_gamepad_status()
{
if (gamepad.Refresh())
{
if(enable_analogue_controls) ff7_use_analogue_controls();

ff7_externals.gamepad_status->pos_x = gamepad.leftStickX;
ff7_externals.gamepad_status->pos_y = gamepad.leftStickY;
ff7_externals.gamepad_status->dpad_up = (gamepad.leftStickY > 0.5f) || gamepad.IsPressed(XINPUT_GAMEPAD_DPAD_UP); // UP
Expand All @@ -173,6 +276,8 @@ struct ff7_gamepad_status* ff7_update_gamepad_status()
{
if (joystick.Refresh())
{
if(enable_analogue_controls) ff7_use_analogue_controls();

ff7_externals.gamepad_status->pos_x = joystick.GetState()->lX;
ff7_externals.gamepad_status->pos_y = joystick.GetState()->lY;
ff7_externals.gamepad_status->dpad_up = (joystick.GetState()->lY < joystick.GetDeadZone(-0.5f)) || joystick.GetState()->rgdwPOV[0] == 0; // UP
Expand Down

0 comments on commit 0f81196

Please sign in to comment.