Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Fix Beloved Rapture Menu issues #3293

Merged
merged 8 commits into from
Nov 18, 2024
12 changes: 9 additions & 3 deletions src/cache.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -463,8 +463,16 @@ BitmapRef Cache::Tile(StringView filename, int tile_id) {
}

BitmapRef Cache::SpriteEffect(const BitmapRef& src_bitmap, const Rect& rect, bool flip_x, bool flip_y, const Tone& tone, const Color& blend) {
std::string id = ToString(src_bitmap->GetId());

if (id.empty()) {
// assert caused too many regressions, use the pointer as the unique key and log instead
Output::Debug("Bitmap has no ID. Please report a bug!");
id = fmt::format("{}", (void*)(src_bitmap.get()));
}

const effect_key_type key {
src_bitmap->GetId(),
id,
src_bitmap->GetTransparent(),
rect,
flip_x,
Expand All @@ -473,8 +481,6 @@ BitmapRef Cache::SpriteEffect(const BitmapRef& src_bitmap, const Rect& rect, boo
blend
};

assert(!src_bitmap->GetId().empty());

const auto it = cache_effects.find(key);

if (it == cache_effects.end() || it->second.expired()) {
Expand Down
4 changes: 4 additions & 0 deletions src/game_commonevent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,10 @@ AsyncOp Game_CommonEvent::Update(bool resume_async) {
return {};
}

int Game_CommonEvent::GetId() const {
return common_event_id;
}

int Game_CommonEvent::GetIndex() const {
return common_event_id;
}
Expand Down
7 changes: 7 additions & 0 deletions src/game_commonevent.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,13 @@ class Game_CommonEvent {
*/
AsyncOp Update(bool resume_async);

/**
* Gets common event ID.
*
* @return ID of the common event
*/
int GetId() const;

/**
* Gets common event index.
*
Expand Down
38 changes: 28 additions & 10 deletions src/game_interpreter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3407,21 +3407,33 @@ bool Game_Interpreter::CommandConditionalBranch(lcf::rpg::EventCommand const& co
result = (Main_Data::game_party->GetGold() <= com.parameters[1]);
}
break;
case 4:
case 4: {
// Item
int item_id = com.parameters[1];

if (Player::IsPatchManiac()) {
item_id = ValueOrVariable(com.parameters[3], item_id);
}

if (com.parameters[2] == 0) {
// Having
result = Main_Data::game_party->GetItemCount(com.parameters[1])
+ Main_Data::game_party->GetEquippedItemCount(com.parameters[1]) > 0;
result = Main_Data::game_party->GetItemCount(item_id)
+ Main_Data::game_party->GetEquippedItemCount(item_id) > 0;
} else {
// Not having
result = Main_Data::game_party->GetItemCount(com.parameters[1])
+ Main_Data::game_party->GetEquippedItemCount(com.parameters[1]) == 0;
result = Main_Data::game_party->GetItemCount(item_id)
+ Main_Data::game_party->GetEquippedItemCount(item_id) == 0;
}
break;
}
case 5:
// Hero
actor_id = com.parameters[1];

if (Player::IsPatchManiac()) {
actor_id = ValueOrVariable(com.parameters[4], actor_id);
}

actor = Main_Data::game_actors->GetActor(actor_id);

if (!actor) {
Expand Down Expand Up @@ -3471,13 +3483,20 @@ bool Game_Interpreter::CommandConditionalBranch(lcf::rpg::EventCommand const& co
;
}
break;
case 6:
case 6: {
// Orientation of char
character = GetCharacter(com.parameters[1]);
int chara_id = com.parameters[1];

if (Player::IsPatchManiac()) {
chara_id = ValueOrVariable(com.parameters[3], chara_id);
}

character = GetCharacter(chara_id);
if (character != NULL) {
result = character->GetFacing() == com.parameters[2];
}
break;
}
case 7: {
// Vehicle in use
Game_Vehicle::Type vehicle_id = (Game_Vehicle::Type) (com.parameters[1] + 1);
Expand Down Expand Up @@ -3574,7 +3593,7 @@ bool Game_Interpreter::CommandConditionalBranch(lcf::rpg::EventCommand const& co
}
break;
case 15:
// Maniac: string comparison
// Maniac: String comparison
if (Player::IsPatchManiac()) {
int modes[] = {
(com.parameters[1] ) & 15, //str_l mode: 0 = direct, 1 = indirect
Expand Down Expand Up @@ -4271,9 +4290,8 @@ bool Game_Interpreter::CommandManiacShowStringPicture(lcf::rpg::EventCommand con
// x03 -> indirect reference
// for the displayed string, the id argument is in com.parameters[22]
// here we are capturing all the delimiters, but currently only need to support reading the first one
int i = 0;
std::vector<int> delims;
auto components = Utils::Tokenize(com.string, [p = &delims, &i](char32_t ch) {
auto components = Utils::Tokenize(com.string, [p = &delims](char32_t ch) {
if (ch == '\x01' || ch == '\x02' || ch == '\x03') {
p->push_back(static_cast<int>(ch));
return true;
Expand Down
37 changes: 17 additions & 20 deletions src/game_map.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -104,9 +104,6 @@ void Game_Map::OnContinueFromBattle() {
static Game_Map::Parallax::Params GetParallaxParams();

void Game_Map::Init() {
screen_width = (Player::screen_width / 16) * SCREEN_TILE_SIZE;
screen_height = (Player::screen_height / 16) * SCREEN_TILE_SIZE;

Dispose();

map_info = {};
Expand Down Expand Up @@ -156,8 +153,8 @@ int Game_Map::GetMapSaveCount() {
void Game_Map::Setup(std::unique_ptr<lcf::rpg::Map> map_in) {
Dispose();

screen_width = (Player::screen_width / 16) * SCREEN_TILE_SIZE;
screen_height = (Player::screen_height / 16) * SCREEN_TILE_SIZE;
screen_width = (Player::screen_width / 16.0) * SCREEN_TILE_SIZE;
screen_height = (Player::screen_height / 16.0) * SCREEN_TILE_SIZE;

map = std::move(map_in);

Expand Down Expand Up @@ -637,7 +634,7 @@ void Game_Map::Scroll(int dx, int dy) {
// that acc changed by.
static void ClampingAdd(int low, int high, int& acc, int& inc) {
int original_acc = acc;
acc = std::max(low, std::min(high, acc + inc));
acc = std::clamp(acc + inc, low, high);
inc = acc - original_acc;
}

Expand Down Expand Up @@ -1651,7 +1648,7 @@ void Game_Map::SetPositionX(int x, bool reset_panorama) {
if (LoopHorizontal()) {
x = Utils::PositiveModulo(x, map_width);
} else {
x = std::max(0, std::min(map_width - screen_width, x));
x = std::clamp(x, 0, map_width - screen_width);
}
map_info.position_x = x;
if (reset_panorama) {
Expand All @@ -1673,7 +1670,7 @@ void Game_Map::SetPositionY(int y, bool reset_panorama) {
if (LoopVertical()) {
y = Utils::PositiveModulo(y, map_height);
} else {
y = std::max(0, std::min(map_height - screen_height, y));
y = std::clamp(y, 0, map_height - screen_height);
}
map_info.position_y = y;
if (reset_panorama) {
Expand Down Expand Up @@ -2037,19 +2034,19 @@ void Game_Map::Parallax::ResetPositionX() {
parallax_fake_x = false;

if (!params.scroll_horz && !LoopHorizontal()) {
int screen_width = Player::screen_width;
int pan_screen_width = Player::screen_width;
if (Player::game_config.fake_resolution.Get()) {
screen_width = SCREEN_TARGET_WIDTH;
pan_screen_width = SCREEN_TARGET_WIDTH;
}

int tiles_per_screen = screen_width / TILE_SIZE;
if (screen_width % TILE_SIZE != 0) {
int tiles_per_screen = pan_screen_width / TILE_SIZE;
if (pan_screen_width % TILE_SIZE != 0) {
++tiles_per_screen;
}

if (GetTilesX() > tiles_per_screen && parallax_width > screen_width) {
if (GetTilesX() > tiles_per_screen && parallax_width > pan_screen_width) {
const int w = (GetTilesX() - tiles_per_screen) * TILE_SIZE;
const int ph = 2 * std::min(w, parallax_width - screen_width) * map_info.position_x / w;
const int ph = 2 * std::min(w, parallax_width - pan_screen_width) * map_info.position_x / w;
if (Player::IsRPG2k()) {
SetPositionX(ph);
} else {
Expand All @@ -2075,19 +2072,19 @@ void Game_Map::Parallax::ResetPositionY() {
parallax_fake_y = false;

if (!params.scroll_vert && !Game_Map::LoopVertical()) {
int screen_height = Player::screen_height;
int pan_screen_height = Player::screen_height;
if (Player::game_config.fake_resolution.Get()) {
screen_height = SCREEN_TARGET_HEIGHT;
pan_screen_height = SCREEN_TARGET_HEIGHT;
}

int tiles_per_screen = screen_height / TILE_SIZE;
if (screen_height % TILE_SIZE != 0) {
int tiles_per_screen = pan_screen_height / TILE_SIZE;
if (pan_screen_height % TILE_SIZE != 0) {
++tiles_per_screen;
}

if (GetTilesY() > tiles_per_screen && parallax_height > screen_height) {
if (GetTilesY() > tiles_per_screen && parallax_height > pan_screen_height) {
const int h = (GetTilesY() - tiles_per_screen) * TILE_SIZE;
const int pv = 2 * std::min(h, parallax_height - screen_height) * map_info.position_y / h;
const int pv = 2 * std::min(h, parallax_height - pan_screen_height) * map_info.position_y / h;
SetPositionY(pv);
} else {
panorama.pan_y = 0;
Expand Down
5 changes: 4 additions & 1 deletion src/game_pictures.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -498,7 +498,10 @@ void Game_Pictures::Picture::AttachWindow(const Window_Base& window) {

CreateSprite();

sprite->SetBitmap(std::make_shared<Bitmap>(window.GetWidth(), window.GetHeight(), data.use_transparent_color));
auto bmp = std::make_shared<Bitmap>(window.GetWidth(), window.GetHeight(), data.use_transparent_color);
bmp->SetId(fmt::format("Window:addr={},w={},h={}", (void*)&window, window.GetWidth(), window.GetHeight()));

sprite->SetBitmap(bmp);
sprite->OnPictureShow();
sprite->SetVisible(true);

Expand Down
23 changes: 16 additions & 7 deletions src/game_strings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -106,12 +106,15 @@ int Game_Strings::Split(Str_Params params, const std::string& delimiter, int str
return -1;
}

int splits = 0;
std::string str = ToString(Get(params.string_id));

params.string_id = string_out_id;

int components = 0;

if (delimiter.empty()) {
// Count the characters (or the codepoints in our case)
components = 0;
const char* iter = str.data();
const auto end = str.data() + str.size();

Expand All @@ -127,28 +130,29 @@ int Game_Strings::Split(Str_Params params, const std::string& delimiter, int str
Set(params, std::string(start_copy, iter - start_copy));

params.string_id++;
splits++;
components++;
}
} else {
components = 1;

if (str.find(delimiter) == std::string::npos) {
// token not found -> 1 split
splits = 1;
// token not found
} else {
std::string token;
for (auto index = str.find(delimiter); index != std::string::npos; index = str.find(delimiter)) {
token = str.substr(0, index);
Set(params, token);
params.string_id++;
splits++;
components++;
str.erase(0, index + delimiter.length());
}
}
}

// set the remaining string
Set(params, str);
variables.Set(var_id, splits);
return splits;
variables.Set(var_id, components);
return components;
}

std::string Game_Strings::FromFile(StringView filename, int encoding, bool& do_yield) {
Expand All @@ -171,6 +175,11 @@ std::string Game_Strings::FromFile(StringView filename, int encoding, bool& do_y
if (encoding == 0) {
lcf::Encoder enc(Player::encoding);
enc.Encode(file_content);
} else {
// UTF-8: Remove Byte Order Mask
if (file_content.size() >= 3 && file_content[0] == '\xEF' && file_content[1] == '\xBB' && file_content[2] == '\xBF') {
file_content.erase(0, 3);
}
}

return file_content;
Expand Down
Loading
Loading