Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

FF7: Fixed scripted camera clipping when widescreen enabled #664

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
## FF7

- Renderer: Fixed menu not working when using external worldmap mesh ( https://github.com/julianxhokaxhiu/FFNx/pull/657 )
- Widescreen: Fixed scripted camera clipping when widescreen enabled ( https://github.com/julianxhokaxhiu/FFNx/pull/664 )

# 1.18.0

Expand Down
55 changes: 31 additions & 24 deletions src/ff7/field/background.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -528,6 +528,11 @@ namespace ff7::field

void field_widescreen_width_clip_with_camera_range(vector2<short>* point)
{
if(!widescreen.isScriptedClipEnabled())
{
return;
}

auto camera_range = widescreen.getCameraRange();

// Adjustment to prevent scrolling stopping one pixel too early
Expand All @@ -540,8 +545,6 @@ namespace ff7::field

point->x += widescreen.getHorizontalOffset();

if (widescreen.getMode() == WM_EXTEND_ONLY) return;

if (point->x > camera_range.right - half_width)
point->x = camera_range.right - half_width;
if (point->x < camera_range.left + half_width)
Expand Down Expand Up @@ -627,24 +630,24 @@ namespace ff7::field
*ff7_externals.field_bg_flag_CC15E4 = 1;
*ff7_externals.scripted_world_move_n_steps = ff7_externals.modules_global_object->field_20;
*ff7_externals.scripted_world_move_step_index = 0;
world_pos = {*ff7_externals.field_curr_delta_world_pos_x, *ff7_externals.field_curr_delta_world_pos_y};
world_pos = {-(*ff7_externals.field_curr_delta_world_pos_x), -(*ff7_externals.field_curr_delta_world_pos_y)};

if(is_fieldmap_wide())
field_widescreen_width_clip_with_camera_range(&world_pos);

*ff7_externals.scripted_world_initial_pos_x = world_pos.x;
*ff7_externals.scripted_world_initial_pos_y = world_pos.y;
*ff7_externals.scripted_world_initial_pos_x = -world_pos.x;
*ff7_externals.scripted_world_initial_pos_y = -world_pos.y;
ff7_externals.modules_global_object->world_move_status = 1;
break;
case 4:
*ff7_externals.field_bg_flag_CC15E4 = 1;

world_pos = {ff7_externals.modules_global_object->field_A, ff7_externals.modules_global_object->field_C};
world_pos = {-(ff7_externals.modules_global_object->field_A), -(ff7_externals.modules_global_object->field_C)};
if(is_fieldmap_wide())
field_widescreen_width_clip_with_camera_range(&world_pos);

*ff7_externals.field_curr_delta_world_pos_x = world_pos.x;
*ff7_externals.field_curr_delta_world_pos_y = world_pos.y;
*ff7_externals.field_curr_delta_world_pos_x = -world_pos.x;
*ff7_externals.field_curr_delta_world_pos_y = -world_pos.y;
ff7_externals.modules_global_object->world_move_status = 2;
break;
case 5:
Expand All @@ -653,19 +656,19 @@ namespace ff7::field
*ff7_externals.scripted_world_move_n_steps = ff7_externals.modules_global_object->field_20;
*ff7_externals.scripted_world_move_step_index = 0;

world_pos = {*ff7_externals.field_curr_delta_world_pos_x, *ff7_externals.field_curr_delta_world_pos_y};
world_pos = {(-*ff7_externals.field_curr_delta_world_pos_x), -(*ff7_externals.field_curr_delta_world_pos_y)};
if(is_fieldmap_wide())
field_widescreen_width_clip_with_camera_range(&world_pos);

*ff7_externals.scripted_world_initial_pos_x = world_pos.x;
*ff7_externals.scripted_world_initial_pos_y = world_pos.y;
*ff7_externals.scripted_world_initial_pos_x = -world_pos.x;
*ff7_externals.scripted_world_initial_pos_y = -world_pos.y;

world_pos = {ff7_externals.modules_global_object->field_A, ff7_externals.modules_global_object->field_C};
world_pos = {-(ff7_externals.modules_global_object->field_A), -(ff7_externals.modules_global_object->field_C)};
if(is_fieldmap_wide())
field_widescreen_width_clip_with_camera_range(&world_pos);

*ff7_externals.scripted_world_final_pos_x = world_pos.x;
*ff7_externals.scripted_world_final_pos_y = world_pos.y;
*ff7_externals.scripted_world_final_pos_x = -world_pos.x;
*ff7_externals.scripted_world_final_pos_y = -world_pos.y;
ff7_externals.modules_global_object->world_move_status = 1;
break;
default:
Expand Down Expand Up @@ -755,18 +758,15 @@ namespace ff7::field
case 6:
if(*ff7_externals.scripted_world_move_n_steps)
{
field_trigger_header* field_triggers_header_ptr = *ff7_externals.field_triggers_header;
auto camera_range = field_triggers_header_ptr->camera_range;
if(widescreen_enabled && widescreen.getMode() == WM_ZOOM)
if(is_fieldmap_wide())
{
camera_range = widescreen.getCameraRange();

// This centers the background for fields which width is bigger than 320 but less than what is needed to fill the whole screen in 16:9
if(2 * std::abs(wide_viewport_x) - *ff7_externals.scripted_world_final_pos_x > camera_range.right)
*ff7_externals.scripted_world_final_pos_x = std::min(0, static_cast<int>(2 * std::abs(wide_viewport_x) - camera_range.right));
world_pos = {-(*ff7_externals.scripted_world_final_pos_x), -(*ff7_externals.scripted_world_final_pos_y)};
field_widescreen_width_clip_with_camera_range(&world_pos);
*ff7_externals.scripted_world_final_pos_x = -world_pos.x;

if(-2 * std::abs(wide_viewport_x) - *ff7_externals.scripted_world_final_pos_x < camera_range.left)
*ff7_externals.scripted_world_final_pos_x = std::max(0, static_cast<int>(-2 * std::abs(wide_viewport_x) - camera_range.left));
world_pos = {-(*ff7_externals.scripted_world_initial_pos_x), -(*ff7_externals.scripted_world_initial_pos_y)};
field_widescreen_width_clip_with_camera_range(&world_pos);
*ff7_externals.scripted_world_initial_pos_x = -world_pos.x;
}

std::function<int(int, int, int, int)> field_get_interpolated_value = ff7_externals.modules_global_object->world_move_mode == 5 ?
Expand Down Expand Up @@ -816,6 +816,13 @@ namespace ff7::field
default:
break;
}

if(is_fieldmap_wide())
{
world_pos = {-(*ff7_externals.field_curr_delta_world_pos_x), -(*ff7_externals.field_curr_delta_world_pos_y)};
field_widescreen_width_clip_with_camera_range(&world_pos);
*ff7_externals.field_curr_delta_world_pos_x = -world_pos.x;
}
}

if(is_position_valid(field_curr_delta_world_pos))
Expand Down
2 changes: 2 additions & 0 deletions src/ff7/widescreen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -389,6 +389,7 @@ void Widescreen::initParamsFromConfig()
h_offset = 0;
v_offset = 0;
is_reset_vertical_pos = false;
is_scripted_clip_enabled = true;
movie_v_offset.clear();

auto pName = get_current_field_name();
Expand All @@ -405,6 +406,7 @@ void Widescreen::initParamsFromConfig()
if(auto hOffsetNode = node["h_offset"]) h_offset = hOffsetNode.value_or(0);
if(auto vOffsetNode = node["v_offset"]) v_offset = vOffsetNode.value_or(0);
if(auto vResetVerticalPosNode = node["reset_vertical_pos"]) is_reset_vertical_pos = vResetVerticalPosNode.value_or(false);
if(auto vScripteClipNode = node["scripted_clip"]) is_scripted_clip_enabled = vScripteClipNode.value_or(true);

if(auto modeNode = node["mode"]) widescreen_mode = static_cast<WIDESCREEN_MODE>(modeNode.value_or(0));

Expand Down
7 changes: 7 additions & 0 deletions src/ff7/widescreen.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ class Widescreen
int getHorizontalOffset();
int getVerticalOffset();
bool isResetVerticalPos();
bool isScriptedClipEnabled();
WIDESCREEN_MODE getMode();

KeyPair getMovieKeyPair(int frame);
Expand All @@ -91,6 +92,7 @@ class Widescreen
int h_offset = 0;
int v_offset = 0;
bool is_reset_vertical_pos = false;
bool is_scripted_clip_enabled = true;
WIDESCREEN_MODE widescreen_mode = WM_DISABLED;

std::vector<Keyframe> movie_v_offset;
Expand All @@ -117,6 +119,11 @@ inline bool Widescreen::isResetVerticalPos()
return is_reset_vertical_pos;
}

inline bool Widescreen::isScriptedClipEnabled()
{
return is_scripted_clip_enabled;
}

inline WIDESCREEN_MODE Widescreen::getMode()
{
struct game_mode* mode = getmode_cached();
Expand Down