Skip to content

Commit

Permalink
FF7: Add option to remove top/bottom black bars on the screen (#767)
Browse files Browse the repository at this point in the history
  • Loading branch information
CosmosXIII authored Dec 24, 2024
1 parent c7775f6 commit fe9c938
Show file tree
Hide file tree
Showing 10 changed files with 86 additions and 34 deletions.
4 changes: 4 additions & 0 deletions Changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@

- Music: Add the ability to play a custom `main_menu` music file on the new game screen.

## FF7

- Rendering: Add uncrop option to remove black bars from top/bottom of the screen ( https://github.com/julianxhokaxhiu/FFNx/pull/767 )

## FF8

- SFX: Fix incorrect volume assignment when playing sfx effects using the external layer
Expand Down
5 changes: 5 additions & 0 deletions misc/FFNx.toml
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,11 @@ internal_resolution_scale = 0
#~~~~~~~~~~~~~~~~~~~~~~~~~~~
aspect_ratio = 0

#[UNCROP]
# Uncrops the image to remove the black bars on the top and bottom of the screen.
#~~~~~~~~~~~~~~~~~~~~~~~~~~~
enable_uncrop = false

#[ENABLE VSYNC]
#~~~~~~~~~~~~~~~~~~~~~~~~~~~
enable_vsync = true
Expand Down
2 changes: 2 additions & 0 deletions src/cfg.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ long window_size_x;
long window_size_y;
long internal_resolution_scale;
long aspect_ratio;
bool enable_uncrop;
bool fullscreen;
bool borderless;
long refresh_rate;
Expand Down Expand Up @@ -249,6 +250,7 @@ void read_cfg()
window_size_y = config["window_size_y"].value_or(0);
internal_resolution_scale = config["internal_resolution_scale"].value_or(0);
aspect_ratio = config["aspect_ratio"].value_or(0);
enable_uncrop = config["enable_uncrop"].value_or(false);
fullscreen = config["fullscreen"].value_or(false);
borderless = config["borderless"].value_or(false);
refresh_rate = config["refresh_rate"].value_or(0);
Expand Down
1 change: 1 addition & 0 deletions src/cfg.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ extern long window_size_x;
extern long window_size_y;
extern long internal_resolution_scale;
extern long aspect_ratio;
extern bool enable_uncrop;
extern bool fullscreen;
extern bool borderless;
extern long refresh_rate;
Expand Down
62 changes: 46 additions & 16 deletions src/ff7/field/background.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -127,10 +127,10 @@ namespace ff7::field
{
const int left_offset = 352 + (is_fieldmap_wide() ? abs(wide_viewport_x) : 0);
const int right_offset = is_fieldmap_wide() ? abs(wide_viewport_x) : 0;
const int top_offset = 256 + (widescreen_enabled ? 8 : 0);
const int bottom_offset = widescreen_enabled ? 8 : 0;
const int top_offset = 256 + (enable_uncrop ? 8 : 0);
const int bottom_offset = enable_uncrop ? 8 : 0;
const int half_width = is_fieldmap_wide() ? ceil(wide_viewport_width / 4) : 160;
const int half_height = widescreen_enabled ? 120 : 112;
const int half_height = enable_uncrop ? 120 : 112;

if(tile_position->x <= bg_position->x - left_offset || tile_position->x >= bg_position->x + right_offset)
tile_position->x += (tile_position->x >= bg_position->x - half_width) ? -layer3_width : layer3_width;
Expand Down Expand Up @@ -167,14 +167,14 @@ namespace ff7::field
else
z_value = 0.9998;

const bool do_increase_height = widescreen_enabled;
const bool do_increase_height = enable_uncrop;
const bool do_increase_width = is_fieldmap_wide() && (*ff7_externals.field_triggers_header)->bg3_width < ceil(wide_viewport_width / 2);
const int layer3_width = (*ff7_externals.field_triggers_header)->bg3_width * (do_increase_width ? 2 : 1);
const int layer3_height = (*ff7_externals.field_triggers_header)->bg3_height * (do_increase_height ? 2 : 1);
const int left_offset = 352 + (is_fieldmap_wide() ? abs(wide_viewport_x) : 0);
const int right_offset = is_fieldmap_wide() ? abs(wide_viewport_x) : 0;
const int top_offset = 256 + (widescreen_enabled ? 8 : 0);
const int bottom_offset = widescreen_enabled ? 8 : 0;
const int top_offset = 256 + (enable_uncrop ? 8 : 0);
const int bottom_offset = enable_uncrop ? 8 : 0;

for(int i = 0; i < *ff7_externals.field_layer3_tiles_num; i++)
{
Expand Down Expand Up @@ -202,7 +202,7 @@ namespace ff7::field
layer3_tiles[tile_index].v, layer3_tiles[tile_index].palette_index, page);
}

if(widescreen_enabled)
if(widescreen_enabled || enable_uncrop)
{
// Apply repeat x-y for background layer 4 tiles
std::vector<vector2<int>> tile_offsets;
Expand Down Expand Up @@ -250,8 +250,8 @@ namespace ff7::field
{
const int left_offset = 352 + (is_fieldmap_wide() ? abs(wide_viewport_x) : 0);
const int right_offset = is_fieldmap_wide() ? abs(wide_viewport_x) : 0;
const int top_offset = 256 + (widescreen_enabled ? 8 : 0);
const int bottom_offset = widescreen_enabled ? 8 : 0;
const int top_offset = 256 + (enable_uncrop ? 8 : 0);
const int bottom_offset = enable_uncrop ? 8 : 0;
const int half_width = is_fieldmap_wide() ? ceil(wide_viewport_width / 4) : 160;

if(tile_position->x <= bg_position->x - left_offset || tile_position->x >= bg_position->x + right_offset)
Expand Down Expand Up @@ -289,14 +289,14 @@ namespace ff7::field
initial_pos.y = ((ff7_field_center ? 232 : 224) - bg_position.y) * field_bg_multiplier;
float z_value = ff7_externals.field_layer_sub_623C0F(ff7_externals.field_camera_rotation_matrix_CFF3D8, ff7_externals.modules_global_object->field_AE, 0, 0);

const bool do_increase_height = widescreen_enabled;
const bool do_increase_height = enable_uncrop;
const bool do_increase_width = is_fieldmap_wide() && (*ff7_externals.field_triggers_header)->bg4_width < ceil(wide_viewport_width / 2);
const int layer4_width = (*ff7_externals.field_triggers_header)->bg4_width * (do_increase_width ? 2 : 1);
const int layer4_height = (*ff7_externals.field_triggers_header)->bg4_height * (do_increase_height ? 2 : 1);
const int left_offset = 352 + (is_fieldmap_wide() ? abs(wide_viewport_x) : 0);
const int right_offset = is_fieldmap_wide() ? abs(wide_viewport_x) : 0;
const int top_offset = 256 + (widescreen_enabled ? 8 : 0);
const int bottom_offset = widescreen_enabled ? 8 : 0;
const int top_offset = 256 + (enable_uncrop ? 8 : 0);
const int bottom_offset = enable_uncrop ? 8 : 0;

for(int i = 0; i < *ff7_externals.field_layer4_tiles_num; i++)
{
Expand Down Expand Up @@ -326,7 +326,7 @@ namespace ff7::field
}
}

if(widescreen_enabled)
if(widescreen_enabled || enable_uncrop)
{
// Apply repeat x-y for background layer 4 tiles
std::vector<vector2<int>> tile_offsets;
Expand Down Expand Up @@ -420,10 +420,13 @@ namespace ff7::field
float half_width = 160;
auto camera_range = field_triggers_header_ptr->camera_range;

if(widescreen_enabled && is_fieldmap_wide())
if(widescreen_enabled || enable_uncrop)
{
camera_range = widescreen.getCameraRange();
}

if(is_fieldmap_wide())
{
// Adjustment to prevent scrolling stopping one pixel too early
camera_range.left += 1;
camera_range.right -= 1;
Expand Down Expand Up @@ -480,10 +483,13 @@ namespace ff7::field
float half_width = 160;
auto camera_range = trigger_header->camera_range;

if(widescreen_enabled && is_fieldmap_wide())
if (enable_uncrop || widescreen_enabled)
{
camera_range = widescreen.getCameraRange();
}

if(is_fieldmap_wide())
{
// This centers the background if necessary
int cameraRangeSize = camera_range.right - camera_range.left;
half_width = 160 + std::min(53, cameraRangeSize / 2 - 160);
Expand Down Expand Up @@ -543,12 +549,23 @@ namespace ff7::field
float half_width = 160 + std::min(53, cameraRangeSize / 2 - 160);

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

if (point->x > camera_range.right - half_width)
point->x = camera_range.right - half_width;
if (point->x < camera_range.left + half_width)
point->x = camera_range.left + half_width;
}

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

auto camera_range = widescreen.getCameraRange();

point->y += widescreen.getVerticalOffset();

if(widescreen.isScriptedVerticalClipEnabled())
{
Expand Down Expand Up @@ -642,6 +659,9 @@ namespace ff7::field

if(is_fieldmap_wide())
field_widescreen_width_clip_with_camera_range(&world_pos);
if(is_fieldmap_uncropped())
field_uncropped_height_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;
Expand All @@ -653,6 +673,8 @@ namespace ff7::field
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);
if(is_fieldmap_uncropped())
field_uncropped_height_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;
Expand All @@ -667,13 +689,17 @@ namespace ff7::field
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);
if(is_fieldmap_uncropped())
field_uncropped_height_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;

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);
if(is_fieldmap_uncropped())
field_uncropped_height_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;
Expand Down Expand Up @@ -776,6 +802,8 @@ namespace ff7::field
field_widescreen_width_clip_with_camera_range(&world_pos);
*ff7_externals.scripted_world_initial_pos_x = -world_pos.x;
}
if(is_fieldmap_uncropped())
field_uncropped_height_clip_with_camera_range(&world_pos);

std::function<int(int, int, int, int)> field_get_interpolated_value = ff7_externals.modules_global_object->world_move_mode == 5 ?
ff7_externals.field_get_linear_interpolated_value : ff7_externals.field_get_smooth_interpolated_value;
Expand Down Expand Up @@ -831,6 +859,8 @@ namespace ff7::field
field_widescreen_width_clip_with_camera_range(&world_pos);
*ff7_externals.field_curr_delta_world_pos_x = -world_pos.x;
}
if(is_fieldmap_uncropped())
field_uncropped_height_clip_with_camera_range(&world_pos);
}

if(is_position_valid(field_curr_delta_world_pos))
Expand Down
2 changes: 1 addition & 1 deletion src/ff7/field/enter.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,6 @@ namespace ff7::field
external_data.blinkFrameIndex = BLINKING_FRAMES;
}

if(widescreen_enabled) widescreen.initParamsFromConfig();
if(widescreen_enabled || enable_uncrop) widescreen.initParamsFromConfig();
}
}
5 changes: 4 additions & 1 deletion src/ff7/field/field.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -154,8 +154,11 @@ namespace ff7::field
if(widescreen_enabled)
{
x -= abs(wide_viewport_x);
y -= ff7_field_center ? 16 : 0;
width += (wide_viewport_width - game_width);
}
if(enable_uncrop)
{
y -= ff7_field_center ? 16 : 0;
height += 32;
}
ff7_externals.field_sub_63AC3F(x, y, width, height);
Expand Down
5 changes: 5 additions & 0 deletions src/ff7/field/utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,11 @@ namespace ff7::field
return widescreen_enabled && widescreen.getMode() != WM_DISABLED;
}

inline bool is_fieldmap_uncropped()
{
return enable_uncrop && widescreen.getMode() != WM_DISABLED;
}

inline float field_get_linear_interpolated_value_float(float initial_value, float final_value, int n_steps, int step_idx)
{
return std::lerp(initial_value, final_value, step_idx / (float)n_steps);
Expand Down
4 changes: 2 additions & 2 deletions src/ff7_opengl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -204,9 +204,9 @@ void ff7_init_hooks(struct game_obj *_game_object)
replace_call_function(ff7_externals.battle_set_do_render_menu_call, ff7::battle::battle_menu_enter);

// #####################
// widescreen
// widescreen / uncrop
// #####################
if(widescreen_enabled)
if(widescreen_enabled || enable_uncrop)
ff7_widescreen_hook_init();

if (enable_time_cycle)
Expand Down
30 changes: 16 additions & 14 deletions src/renderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1722,6 +1722,22 @@ void Renderer::setScissor(uint16_t x, uint16_t y, uint16_t width, uint16_t heigh
scissorWidth = getInternalCoordX(width);
scissorHeight = getInternalCoordY(height);

// This removes the black bars on the top and bottom of the screen
if (enable_uncrop)
{
bool is_movie_playing = *ff7_externals.word_CC1638 && !ff7_externals.modules_global_object->BGMOVIE_flag;
if((is_movie_playing && widescreen.getMovieMode() == WM_DISABLED))
{
return;
}

if(y == 16 && height == 448)
{
scissorOffsetY = getInternalCoordY(0.0);
scissorHeight = getInternalCoordY(480);
}
}

if(!widescreen_enabled) return;

struct game_mode* mode = getmode_cached();
Expand All @@ -1743,13 +1759,6 @@ void Renderer::setScissor(uint16_t x, uint16_t y, uint16_t width, uint16_t heigh
return;
}

// This removes the black bars on the top and bottom of the screen
if(y == 16 && height == 448)
{
scissorOffsetY = getInternalCoordY(0.0);
scissorHeight = getInternalCoordY(480);
}

// This changes the scissor width and makes it bigger to fit widescreen
if(x == 0 && width == game_width)
scissorWidth = getInternalCoordX(wide_viewport_width);
Expand All @@ -1759,13 +1768,6 @@ void Renderer::setScissor(uint16_t x, uint16_t y, uint16_t width, uint16_t heigh
break;
case MODE_SWIRL:
{
// This removes the black bars on the top and bottom of the screen
if(y == 16 && height == 448)
{
scissorOffsetY = getInternalCoordY(0.0);
scissorHeight = getInternalCoordY(480);
}

// This changes the scissor width and makes it bigger to fit widescreen
if(x == 0 && width == game_width)
scissorWidth = getInternalCoordX(wide_viewport_width);
Expand Down

0 comments on commit fe9c938

Please sign in to comment.