From e073662a39412d26ae70d106198115c3e4dfa71c Mon Sep 17 00:00:00 2001 From: BlisterB Date: Tue, 30 Dec 2025 21:37:27 +0100 Subject: [PATCH 1/6] Fix the calculation of the Panorama's offset in case of fakeResolution and small map --- src/game_map.cpp | 14 +++++++++++--- src/spriteset_map.cpp | 4 ++-- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/src/game_map.cpp b/src/game_map.cpp index d6104f3a11..ee97b7891d 100644 --- a/src/game_map.cpp +++ b/src/game_map.cpp @@ -2145,9 +2145,13 @@ void Game_Map::Parallax::ResetPositionX() { parallax_fake_x = false; if (!params.scroll_horz && !LoopHorizontal()) { + // What is the width of the panorama to display on screen? int pan_screen_width = Player::screen_width; - if (Player::game_config.fake_resolution.Get()) { - pan_screen_width = SCREEN_TARGET_WIDTH; + if (Player::game_config.fake_resolution.Get()) { + int map_width = Game_Map::GetTilesX() * TILE_SIZE; + if (map_width < pan_screen_width) { + pan_screen_width = map_width; + } } int tiles_per_screen = pan_screen_width / TILE_SIZE; @@ -2183,9 +2187,13 @@ void Game_Map::Parallax::ResetPositionY() { parallax_fake_y = false; if (!params.scroll_vert && !Game_Map::LoopVertical()) { + // What is the height of the panorama to display on screen? int pan_screen_height = Player::screen_height; if (Player::game_config.fake_resolution.Get()) { - pan_screen_height = SCREEN_TARGET_HEIGHT; + int map_height = Game_Map::GetTilesY() * TILE_SIZE; + if (map_height < pan_screen_height) { + pan_screen_height = map_height; + } } int tiles_per_screen = pan_screen_height / TILE_SIZE; diff --git a/src/spriteset_map.cpp b/src/spriteset_map.cpp index 50ea8a8842..4eb1e2fb8c 100644 --- a/src/spriteset_map.cpp +++ b/src/spriteset_map.cpp @@ -328,10 +328,10 @@ void Spriteset_Map::CalculatePanoramaRenderOffset() { // Resolution hack for Panorama if (Player::game_config.fake_resolution.Get()) { if (Game_Map::Parallax::FakeXPosition()) { - panorama->SetRenderOx((Player::screen_width - SCREEN_TARGET_WIDTH) / 2); + panorama->SetRenderOx((Player::screen_width - (Game_Map::GetTilesX() * TILE_SIZE)) / 2); } if (Game_Map::Parallax::FakeYPosition()) { - panorama->SetRenderOy((Player::screen_height - SCREEN_TARGET_HEIGHT) / 2); + panorama->SetRenderOy((Player::screen_height - (Game_Map::GetTilesY() * TILE_SIZE)) / 2); } } } From ca660b6527d6a83866b180c19176fc9ab4b009e5 Mon Sep 17 00:00:00 2001 From: BlisterB Date: Wed, 31 Dec 2025 19:40:22 +0100 Subject: [PATCH 2/6] [WideScreen] Fix the calculation of Picture's offsets when using fakeResolution --- src/sprite_picture.cpp | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/src/sprite_picture.cpp b/src/sprite_picture.cpp index 3fadea8568..98b0be803d 100644 --- a/src/sprite_picture.cpp +++ b/src/sprite_picture.cpp @@ -24,6 +24,7 @@ #include "game_windows.h" #include "player.h" #include "bitmap.h" +#include "game_map.h" Sprite_Picture::Sprite_Picture(int pic_id, Drawable::Flags flags) : Sprite(flags), @@ -106,8 +107,26 @@ void Sprite_Picture::Draw(Bitmap& dst) { } if (Player::game_config.fake_resolution.Get()) { - SetX(x + Player::menu_offset_x); - SetY(y + Player::menu_offset_y); + if (data.fixed_to_map) { + // If the picture scrolls with the map, apply the black border if the map is too small + int offset_x = 0; + int map_width = Game_Map::GetTilesX() * TILE_SIZE; + if (map_width < Player::screen_width) { + offset_x += (Player::screen_width - map_width) / 2; + } + SetX(x + offset_x); + + int offset_y = 0; + int map_height = Game_Map::GetTilesY() * TILE_SIZE; + if (map_height < Player::screen_height) { + offset_y += (Player::screen_height - map_height) / 2; + } + SetY(y + offset_y); + } else { + // If the picture doesn't scroll with the map, simulate the 340x240 screen + SetX(x + Player::menu_offset_x); + SetY(y + Player::menu_offset_y); + } } else { SetX(x); SetY(y); From 80c471581580e856158ce8a7b844acfbcf4d1bad Mon Sep 17 00:00:00 2001 From: BlisterB Date: Wed, 31 Dec 2025 19:41:33 +0100 Subject: [PATCH 3/6] [FakeResolution] When retrieving an Event X/Y screen position, don't apply an offset --- src/game_interpreter_control_variables.cpp | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/src/game_interpreter_control_variables.cpp b/src/game_interpreter_control_variables.cpp index aa241b3af3..e459695109 100644 --- a/src/game_interpreter_control_variables.cpp +++ b/src/game_interpreter_control_variables.cpp @@ -190,21 +190,11 @@ int ControlVariables::Event(int op, int event_id, const Game_BaseInterpreterCont break; case 4: { // Screen X - if (Player::game_config.fake_resolution.Get()) { - int pan_delta = (Game_Player::GetDefaultPanX() - lcf::rpg::SavePartyLocation::kPanXDefault) / TILE_SIZE; - return character->GetScreenX() - pan_delta; - } else { - return character->GetScreenX(); - } + return character->GetScreenX(); } case 5: { // Screen Y - if (Player::game_config.fake_resolution.Get()) { - int pan_delta = (Game_Player::GetDefaultPanY() - lcf::rpg::SavePartyLocation::kPanYDefault) / TILE_SIZE; - return character->GetScreenY() - pan_delta; - } else { - return character->GetScreenY(); - } + return character->GetScreenY(); } case 6: // Event ID From c60093df1eeeba8c6aedd19005f878e8368267e4 Mon Sep 17 00:00:00 2001 From: BlisterB Date: Sat, 3 Jan 2026 19:30:24 +0100 Subject: [PATCH 4/6] [FakeResolution] Correctly centers the camera at the startup of a looping map --- src/game_map.cpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/game_map.cpp b/src/game_map.cpp index ee97b7891d..7f4d7168f2 100644 --- a/src/game_map.cpp +++ b/src/game_map.cpp @@ -1724,6 +1724,14 @@ void Game_Map::SetPositionX(int x, bool reset_panorama) { const int map_width = GetTilesX() * SCREEN_TILE_SIZE; if (LoopHorizontal()) { x = Utils::PositiveModulo(x, map_width); + + // If the map is too small to fit in the screen, add an offset corresponding to the black border's size + if (Player::game_config.fake_resolution.Get()) { + int map_width_in_pixels = Game_Map::GetTilesX() * TILE_SIZE; + if (map_width_in_pixels < Player::screen_width) { + x += ((Player::screen_width - map_width_in_pixels) / 2 / TILE_SIZE) * SCREEN_TILE_SIZE; + } + } } else { // Do not use std::clamp here. When the map is smaller than the screen the // upper bound is smaller than the lower bound making the function fail. @@ -1748,6 +1756,14 @@ void Game_Map::SetPositionY(int y, bool reset_panorama) { const int map_height = GetTilesY() * SCREEN_TILE_SIZE; if (LoopVertical()) { y = Utils::PositiveModulo(y, map_height); + + // If the map is too small to fit in the screen, add an offset corresponding to the black border's size + if (Player::game_config.fake_resolution.Get()) { + int map_height_in_pixels = Game_Map::GetTilesY() * TILE_SIZE; + if (map_height_in_pixels < Player::screen_height) { + y += ((Player::screen_height - map_height_in_pixels) / 2 / TILE_SIZE) * SCREEN_TILE_SIZE; + } + } } else { // Do not use std::clamp here. When the map is smaller than the screen the // upper bound is smaller than the lower bound making the function fail. From d580fce99ad792430aa3998ebb53857aa2919721 Mon Sep 17 00:00:00 2001 From: BlisterB Date: Sun, 4 Jan 2026 11:18:23 +0100 Subject: [PATCH 5/6] [FakeResolution] Fix the camera's scrolling on a small looping map --- src/game_player.cpp | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/src/game_player.cpp b/src/game_player.cpp index 6ffa40082c..ce34065a00 100644 --- a/src/game_player.cpp +++ b/src/game_player.cpp @@ -191,15 +191,33 @@ void Game_Player::UpdateScroll(int amount, bool was_jumping) { return; } - auto dx = (GetX() * SCREEN_TILE_SIZE) - Game_Map::GetPositionX() - GetPanX(); - auto dy = (GetY() * SCREEN_TILE_SIZE) - Game_Map::GetPositionY() - GetPanY(); + const auto map_width = Game_Map::GetTilesX() * SCREEN_TILE_SIZE; + const auto map_height = Game_Map::GetTilesY() * SCREEN_TILE_SIZE; + + // When using FakeResolution mode, if the map is too small to fit the screen + // we need to calculate the black border offset, in case of a looping map for example + int screen_offset_x = 0; + if (Player::game_config.fake_resolution.Get()) { + int map_width_in_pixels = Game_Map::GetTilesX() * TILE_SIZE; + if (map_width_in_pixels < Player::screen_width) { + screen_offset_x = ((Player::screen_width - map_width_in_pixels) / 2 / TILE_SIZE) * SCREEN_TILE_SIZE; + } + } + int screen_offset_y = 0; + if (Player::game_config.fake_resolution.Get()) { + int map_height_in_pixels = Game_Map::GetTilesY() * TILE_SIZE; + if (map_height_in_pixels < Player::screen_height) { + screen_offset_y = ((Player::screen_height - map_height_in_pixels) / 2 / TILE_SIZE) * SCREEN_TILE_SIZE; + } + } - const auto w = Game_Map::GetTilesX() * SCREEN_TILE_SIZE; - const auto h = Game_Map::GetTilesY() * SCREEN_TILE_SIZE; + auto dx = (GetX() * SCREEN_TILE_SIZE) - Game_Map::GetPositionX() - GetPanX() + screen_offset_x; + auto dy = (GetY() * SCREEN_TILE_SIZE) - Game_Map::GetPositionY() - GetPanY() + screen_offset_y; - dx = Utils::PositiveModulo(dx + w / 2, w) - w / 2; - dy = Utils::PositiveModulo(dy + h / 2, h) - h / 2; + dx = Utils::PositiveModulo(dx + map_width / 2, map_width) - map_width / 2; + dy = Utils::PositiveModulo(dy + map_height / 2, map_height) - map_height / 2; + // If sx or sy equals zero, no scrolling is needed in the corresponding direction const auto sx = Utils::Signum(dx); const auto sy = Utils::Signum(dy); From 47213ec64474843f8a6c7bdc39850c12dfc4a5c1 Mon Sep 17 00:00:00 2001 From: BlisterB Date: Sun, 11 Jan 2026 21:17:09 +0100 Subject: [PATCH 6/6] [WideScreen][FakeResolution] Apply the offset on the Panorama only if the map is too small to fit the screen --- src/spriteset_map.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/spriteset_map.cpp b/src/spriteset_map.cpp index 4eb1e2fb8c..47a0f1f644 100644 --- a/src/spriteset_map.cpp +++ b/src/spriteset_map.cpp @@ -326,12 +326,16 @@ void Spriteset_Map::CalculateMapRenderOffset() { void Spriteset_Map::CalculatePanoramaRenderOffset() { // Resolution hack for Panorama + // If the map is too small to fit in the screen, add an offset corresponding to the black border's size if (Player::game_config.fake_resolution.Get()) { - if (Game_Map::Parallax::FakeXPosition()) { - panorama->SetRenderOx((Player::screen_width - (Game_Map::GetTilesX() * TILE_SIZE)) / 2); + int map_width_in_pixels = Game_Map::GetTilesX() * TILE_SIZE; + if (map_width_in_pixels < Player::screen_width) { + panorama->SetRenderOx((Player::screen_width - map_width_in_pixels) / 2); } - if (Game_Map::Parallax::FakeYPosition()) { - panorama->SetRenderOy((Player::screen_height - (Game_Map::GetTilesY() * TILE_SIZE)) / 2); + + int map_height_in_pixels = Game_Map::GetTilesY() * TILE_SIZE; + if (map_height_in_pixels < Player::screen_height) { + panorama->SetRenderOy((Player::screen_height - map_height_in_pixels) / 2); } } }