From 6056464a24ae3fce571416b6ce1ccf34dce0a062 Mon Sep 17 00:00:00 2001 From: Tool Man Date: Thu, 28 Dec 2023 04:33:01 +0000 Subject: [PATCH 1/3] Maniac Patch: Added separate Width/Height Values for pictures Added: - Separate Width and Height value as per .scale2 parameter in ManiacPatch 211010 - Set Height to Width when using picture effects (as per ManiacPatch) - Set both Width and Height to Magnify when using .scale parameter Bugfix: - Fix ManiacPatch picture rotation not fully working --- src/game_interpreter.cpp | 61 ++++++++++++++++++++++++++++++---------- src/game_pictures.cpp | 13 +++++++-- src/game_pictures.h | 3 +- src/sprite_picture.cpp | 4 +++ 4 files changed, 63 insertions(+), 18 deletions(-) diff --git a/src/game_interpreter.cpp b/src/game_interpreter.cpp index 199bd7a554..9853a682f0 100644 --- a/src/game_interpreter.cpp +++ b/src/game_interpreter.cpp @@ -2707,10 +2707,11 @@ namespace PicPointerPatch { } static void AdjustParams(Game_Pictures::Params& params) { - if (params.magnify > 10000) { - int new_magnify = Main_Data::game_variables->Get(params.magnify - 10000); - Output::Debug("PicPointer: Zoom {} replaced with {}", params.magnify, new_magnify); - params.magnify = new_magnify; + if (params.magnify_width > 10000) { + int new_magnify = Main_Data::game_variables->Get(params.magnify_width - 10000); + Output::Debug("PicPointer: Zoom {} replaced with {}", params.magnify_width, new_magnify); + params.magnify_width = new_magnify; + params.magnify_height = new_magnify; } if (params.top_trans > 10000) { @@ -2795,7 +2796,8 @@ bool Game_Interpreter::CommandShowPicture(lcf::rpg::EventCommand const& com) { / params.position_x = ValueOrVariable(pos_mode, com.parameters[2]); params.position_y = ValueOrVariable(pos_mode, com.parameters[3]); params.fixed_to_map = com.parameters[4] > 0; - params.magnify = com.parameters[5]; + params.magnify_width = com.parameters[5]; + params.magnify_height = params.magnify_width; params.use_transparent_color = com.parameters[7] > 0; params.top_trans = com.parameters[6]; params.red = com.parameters[8]; @@ -2828,7 +2830,16 @@ bool Game_Interpreter::CommandShowPicture(lcf::rpg::EventCommand const& com) { / } params.name = PicPointerPatch::ReplaceName(params.name, var, com.parameters[18]); } - params.magnify = ValueOrVariable(com.parameters[20], params.magnify); + + params.magnify_width = ValueOrVariableBitfield(com.parameters[20], 0, params.magnify_width); + if (Player::IsPatchManiac() && com.parameters.size() > 31 && com.parameters[20] >= 16 && params.effect_mode == 0) { + // The >= 16 check is needed because this bit is set when independent width/height scaling is used + // When using special effects on Maniacs, Height is set to Width + params.magnify_height = ValueOrVariableBitfield((com.parameters[20] >> 1), 1, com.parameters[31]); + } else { + params.magnify_height = params.magnify_width; + } + params.top_trans = ValueOrVariable(com.parameters[21], params.top_trans); if (com.parameters[22] > 0) { // If spritesheet is enabled @@ -2877,7 +2888,8 @@ bool Game_Interpreter::CommandShowPicture(lcf::rpg::EventCommand const& com) { / PicPointerPatch::AdjustShowParams(pic_id, params); // Sanitize input - params.magnify = std::max(0, std::min(params.magnify, 2000)); + params.magnify_width = std::max(0, std::min(params.magnify_width, 2000)); + params.magnify_height = std::max(0, std::min(params.magnify_height, 2000)); params.top_trans = std::max(0, std::min(params.top_trans, 100)); params.bottom_trans = std::max(0, std::min(params.bottom_trans, 100)); @@ -2914,7 +2926,8 @@ bool Game_Interpreter::CommandMovePicture(lcf::rpg::EventCommand const& com) { / int pos_mode = ManiacBitmask(com.parameters[1], 0xFF); params.position_x = ValueOrVariable(pos_mode, com.parameters[2]); params.position_y = ValueOrVariable(pos_mode, com.parameters[3]); - params.magnify = com.parameters[5]; + params.magnify_width = com.parameters[5]; + params.magnify_height = params.magnify_width; params.top_trans = com.parameters[6]; params.red = com.parameters[8]; params.green = com.parameters[9]; @@ -2936,7 +2949,15 @@ bool Game_Interpreter::CommandMovePicture(lcf::rpg::EventCommand const& com) { / // Currently unused by RPG Maker //int chars_to_replace = com.parameters[18]; //int replace_with = com.parameters[19]; - params.magnify = ValueOrVariable(com.parameters[20], params.magnify); + + params.magnify_width = ValueOrVariableBitfield(com.parameters[20], 0, params.magnify_width); + if (Player::IsPatchManiac() && com.parameters.size() > 18 && com.parameters[20] >= 16 && params.effect_mode == 0) { + // The >= 16 check is needed because this bit is set when independent width/height scaling is used + // When using special effects on Maniacs, Height is set to Width + params.magnify_height = ValueOrVariableBitfield((com.parameters[20] >> 1), 1, com.parameters[18]); + } else { + params.magnify_height = params.magnify_width; + } params.top_trans = ValueOrVariable(com.parameters[21], params.top_trans); } @@ -2962,8 +2983,8 @@ bool Game_Interpreter::CommandMovePicture(lcf::rpg::EventCommand const& com) { / params.origin = com.parameters[1] >> 8; if (params.effect_mode == lcf::rpg::SavePicture::Effect_maniac_fixed_angle) { - params.effect_power = ValueOrVariableBitfield(com.parameters[16], 0, params.effect_power); - int divisor = ValueOrVariableBitfield(com.parameters[16], 1, com.parameters[15]); + params.effect_power = ValueOrVariableBitfield(com.parameters[4], 0, params.effect_power); + int divisor = ValueOrVariableBitfield(com.parameters[4], 1, com.parameters[7]); if (divisor == 0) { divisor = 1; } @@ -2978,7 +2999,8 @@ bool Game_Interpreter::CommandMovePicture(lcf::rpg::EventCommand const& com) { / PicPointerPatch::AdjustMoveParams(pic_id, params); // Sanitize input - params.magnify = std::max(0, std::min(params.magnify, 2000)); + params.magnify_width = std::max(0, std::min(params.magnify_width, 2000)); + params.magnify_height = std::max(0, std::min(params.magnify_height, 2000)); params.top_trans = std::max(0, std::min(params.top_trans, 100)); params.bottom_trans = std::max(0, std::min(params.bottom_trans, 100)); params.duration = std::max(Player::IsPatchManiac() ? -10000 : 0, std::min(params.duration, 10000)); @@ -4258,7 +4280,7 @@ bool Game_Interpreter::CommandManiacShowStringPicture(lcf::rpg::EventCommand con params.position_x = ValueOrVariableBitfield(com.parameters[0], 1, com.parameters[2]); params.position_y = ValueOrVariableBitfield(com.parameters[0], 1, com.parameters[3]); - params.magnify = ValueOrVariableBitfield(com.parameters[0], 2, com.parameters[4]); + params.magnify_width = ValueOrVariableBitfield(com.parameters[0], 2, com.parameters[4]); params.top_trans = ValueOrVariableBitfield(com.parameters[0], 3, com.parameters[5]); params.red = com.parameters[6]; params.green = com.parameters[7]; @@ -4271,6 +4293,15 @@ bool Game_Interpreter::CommandManiacShowStringPicture(lcf::rpg::EventCommand con params.battle_layer = com.parameters[16]; params.flags = com.parameters[17]; + params.magnify_width = ValueOrVariableBitfield(com.parameters[0], 2, com.parameters[4]); + if (com.parameters.size() > 23 && com.parameters[0] >= 0x10000000 && params.effect_mode == 0) { + // The >= 0x10000000 check is needed because this bit is set when independent width/height scaling is used + // When using special effects on Maniacs, Height is set to Width + params.magnify_height = ValueOrVariableBitfield((com.parameters[0] >> 1), 7, com.parameters[23]); + } else { + params.magnify_height = params.magnify_width; + } + int flags = com.parameters[12]; int blend_mode = flags & 0xF; if (blend_mode == 1) { @@ -4403,13 +4434,13 @@ bool Game_Interpreter::CommandManiacGetPictureInfo(lcf::rpg::EventCommand const& x = Utils::RoundTo(data.current_x); y = Utils::RoundTo(data.current_y); width = Utils::RoundTo(width * data.current_magnify / 100.0); - height = Utils::RoundTo(height * data.current_magnify / 100.0); + height = Utils::RoundTo(height * data.maniac_current_magnify_height / 100.0); break; case 2: x = Utils::RoundTo(data.finish_x); y = Utils::RoundTo(data.finish_y); width = Utils::RoundTo(width * data.finish_magnify / 100.0); - height = Utils::RoundTo(height * data.finish_magnify / 100.0); + height = Utils::RoundTo(height * data.maniac_finish_magnify_height / 100.0); break; } diff --git a/src/game_pictures.cpp b/src/game_pictures.cpp index 7bcbb4121c..3fc5f26010 100644 --- a/src/game_pictures.cpp +++ b/src/game_pictures.cpp @@ -51,6 +51,7 @@ void SyncCurrentToFinish(lcf::rpg::SavePicture& data) { data.current_blue = data.finish_blue; data.current_sat = data.finish_sat; data.current_magnify = data.finish_magnify; + data.maniac_current_magnify_height = data.maniac_finish_magnify_height; data.current_top_trans = data.finish_top_trans; data.current_bot_trans = data.finish_bot_trans; if (do_effect) { @@ -113,6 +114,11 @@ std::vector Game_Pictures::GetSaveData() const { if (Player::IsRPG2k3E()) { data.frames = frame_counter; } + if (!Player::IsPatchManiac()) { + // Default the values so they are not stored in the savegame + data.maniac_current_magnify_height = 100; + data.maniac_finish_magnify_height = 100; + } save.push_back(std::move(data)); } @@ -534,6 +540,7 @@ void Game_Pictures::Picture::Update(bool is_battle) { data.current_blue = interpolate(data.current_blue, data.finish_blue); data.current_sat = interpolate(data.current_sat, data.finish_sat); data.current_magnify = interpolate(data.current_magnify, data.finish_magnify); + data.maniac_current_magnify_height = interpolate(data.maniac_current_magnify_height, data.maniac_finish_magnify_height); data.current_top_trans = interpolate(data.current_top_trans, data.finish_top_trans); data.current_bot_trans = interpolate(data.current_bot_trans, data.finish_bot_trans); } @@ -601,7 +608,8 @@ Game_Pictures::ShowParams Game_Pictures::Picture::GetShowParams() const { Game_Pictures::ShowParams params; params.position_x = static_cast(data.finish_x); params.position_y = static_cast(data.finish_y); - params.magnify = data.finish_magnify; + params.magnify_width = data.finish_magnify; + params.magnify_height = data.maniac_finish_magnify_height; params.top_trans = data.finish_top_trans; params.bottom_trans = data.finish_bot_trans; params.red = data.finish_red; @@ -631,7 +639,8 @@ void Game_Pictures::Picture::SetNonEffectParams(const Params& params, bool set_p data.finish_x = params.position_x; data.finish_y = params.position_y; } - data.finish_magnify = params.magnify; + data.finish_magnify = params.magnify_width; + data.maniac_finish_magnify_height = params.magnify_height; data.finish_top_trans = params.top_trans; data.finish_bot_trans = params.bottom_trans; data.finish_red = params.red; diff --git a/src/game_pictures.h b/src/game_pictures.h index cb4ab567d5..30d0a0251d 100644 --- a/src/game_pictures.h +++ b/src/game_pictures.h @@ -46,7 +46,6 @@ class Game_Pictures { struct Params { int position_x = 0; int position_y = 0; - int magnify = 100; int top_trans = 0; int bottom_trans = 0; int red = 100; @@ -60,6 +59,8 @@ class Game_Pictures { bool flip_y = false; int blend_mode = 0; int origin = 0; + int magnify_width = 100; // RPG_RT supports magnify, but not independent for w/h + int magnify_height = 100; }; struct ShowParams : Params { std::string name; diff --git a/src/sprite_picture.cpp b/src/sprite_picture.cpp index 47de160f81..2932d60257 100644 --- a/src/sprite_picture.cpp +++ b/src/sprite_picture.cpp @@ -112,8 +112,12 @@ void Sprite_Picture::Draw(Bitmap& dst) { SetX(x); SetY(y); } + SetZoomX(data.current_magnify / 100.0); SetZoomY(data.current_magnify / 100.0); + if (Player::IsPatchManiac()) { + SetZoomY(data.maniac_current_magnify_height / 100.0); + } auto sr = GetSrcRect(); SetOx(sr.width / 2); From 7341f3d7d262262b0e5f1f57d8e59a28e2afc8e4 Mon Sep 17 00:00:00 2001 From: Tool Man Date: Sun, 7 Jan 2024 02:17:30 +0000 Subject: [PATCH 2/3] Maniac Patch: Fix String Vars with ShowPicture Added the following: - Check if we're using a string variable with com.parameters[17] - Set the name parameter to the String Variable Fixed the following: - When using a String Var with ShowPicture, it no longers crash the game with picture ID -1 --- src/game_interpreter.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/game_interpreter.cpp b/src/game_interpreter.cpp index 9853a682f0..133b7ae40c 100644 --- a/src/game_interpreter.cpp +++ b/src/game_interpreter.cpp @@ -2822,7 +2822,12 @@ bool Game_Interpreter::CommandShowPicture(lcf::rpg::EventCommand const& com) { / if (param_size > 16 && (Player::IsRPG2k3ECommands() || Player::IsPatchManiac())) { // Handling of RPG2k3 1.12 chunks - pic_id = ValueOrVariable(com.parameters[17], pic_id); + if (Player::IsPatchManiac()) { + pic_id = ValueOrVariableBitfield(com.parameters[17], 0, pic_id); + params.name = ToString(CommandStringOrVariableBitfield(com, 17, 2, 30)); + } else { + pic_id = ValueOrVariable(com.parameters[17], pic_id); + } if (com.parameters[19] != 0) { int var = 0; if (Main_Data::game_variables->IsValid(com.parameters[19])) { From 1a310f477d94e0dfd073dfb7fe92606445e6cb71 Mon Sep 17 00:00:00 2001 From: Tool Man Date: Sun, 7 Jan 2024 05:45:35 +0000 Subject: [PATCH 3/3] Maniac Patch: Added Var and Var Index support for Picture Tint While testing, I found out the following things: - You cannot mix multiple Variable types for each parameters - When using Variables for Picture Tint, parameter 17 is set to 4096 (0x100), - When using Var Indexes for Picture Tint, parameter 17 is set to 8192 (0x200), - Before, parameters for red, green, blue and saturation were always constants. - Surprisingly this feature doesn't work with ShowStringPicture Added: - Variable and VarIndex support for Tinting using ShowPicture and MovePicture using bitfields --- src/game_interpreter.cpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/game_interpreter.cpp b/src/game_interpreter.cpp index 133b7ae40c..ab2ab86285 100644 --- a/src/game_interpreter.cpp +++ b/src/game_interpreter.cpp @@ -2836,6 +2836,14 @@ bool Game_Interpreter::CommandShowPicture(lcf::rpg::EventCommand const& com) { / params.name = PicPointerPatch::ReplaceName(params.name, var, com.parameters[18]); } + if (Player::IsPatchManiac()) { + // Color tint using variables + params.red = ValueOrVariableBitfield(com.parameters[17], 3, params.red); + params.green = ValueOrVariableBitfield(com.parameters[17], 3, params.green); + params.blue = ValueOrVariableBitfield(com.parameters[17], 3, params.blue); + params.saturation = ValueOrVariableBitfield(com.parameters[17], 3, params.saturation); + } + params.magnify_width = ValueOrVariableBitfield(com.parameters[20], 0, params.magnify_width); if (Player::IsPatchManiac() && com.parameters.size() > 31 && com.parameters[20] >= 16 && params.effect_mode == 0) { // The >= 16 check is needed because this bit is set when independent width/height scaling is used @@ -2955,6 +2963,14 @@ bool Game_Interpreter::CommandMovePicture(lcf::rpg::EventCommand const& com) { / //int chars_to_replace = com.parameters[18]; //int replace_with = com.parameters[19]; + if (com.parameters[17] >= 4096 && Player::IsPatchManiac()) { + // Color tint using variables + params.red = ValueOrVariableBitfield(com.parameters[17], 3, params.red); + params.green = ValueOrVariableBitfield(com.parameters[17], 3, params.green); + params.blue = ValueOrVariableBitfield(com.parameters[17], 3, params.blue); + params.saturation = ValueOrVariableBitfield(com.parameters[17], 3, params.saturation); + } + params.magnify_width = ValueOrVariableBitfield(com.parameters[20], 0, params.magnify_width); if (Player::IsPatchManiac() && com.parameters.size() > 18 && com.parameters[20] >= 16 && params.effect_mode == 0) { // The >= 16 check is needed because this bit is set when independent width/height scaling is used