Skip to content

Commit b315343

Browse files
committed
Command ChangePictureId: Extract Move and SwapPictureId into Functions in Game Pictures
1 parent 3b248c0 commit b315343

3 files changed

Lines changed: 131 additions & 114 deletions

File tree

src/game_interpreter.cpp

Lines changed: 2 additions & 114 deletions
Original file line numberDiff line numberDiff line change
@@ -5060,123 +5060,11 @@ bool Game_Interpreter::CommandManiacChangePictureId(lcf::rpg::EventCommand const
50605060
}
50615061

50625062
auto& pictures = *Main_Data::game_pictures;
5063-
auto& windows = *Main_Data::game_windows;
50645063

50655064
auto isValidId = [](int id) {
50665065
return id > 0;
50675066
};
50685067

5069-
// Helper to move a single picture from src to dst
5070-
auto move_picture = [&](int src, int dst) {
5071-
// Ensure existence in vectors to avoid reference invalidation during assignments
5072-
int max_id = std::max(src, dst);
5073-
pictures.GetPicture(max_id);
5074-
windows.GetWindow(max_id);
5075-
5076-
auto& src_pic = pictures.GetPicture(src);
5077-
auto& dst_pic = pictures.GetPicture(dst);
5078-
5079-
// If source is empty, erase destination
5080-
if (!src_pic.Exists() && !src_pic.IsWindowAttached()) {
5081-
dst_pic.Erase();
5082-
return;
5083-
}
5084-
5085-
// 1. Handle Window Data (String Pictures)
5086-
if (src_pic.IsWindowAttached()) {
5087-
auto& src_win = windows.GetWindow(src);
5088-
auto& dst_win = windows.GetWindow(dst);
5089-
dst_win.data = src_win.data;
5090-
dst_win.data.ID = dst;
5091-
src_win.Erase();
5092-
}
5093-
else {
5094-
// If overwriting a window picture with a normal one, clear the old window data
5095-
// (Safe to call even if dst wasn't a window before)
5096-
windows.GetWindow(dst).Erase();
5097-
}
5098-
5099-
// 2. Handle Picture Data
5100-
BitmapRef src_bmp = src_pic.sprite ? src_pic.sprite->GetBitmap() : nullptr;
5101-
auto request_id = src_pic.request_id;
5102-
src_pic.request_id = nullptr; // Prevent cancellation on Erase
5103-
5104-
dst_pic.data = src_pic.data;
5105-
dst_pic.data.ID = dst;
5106-
dst_pic.request_id = request_id;
5107-
5108-
src_pic.Erase();
5109-
5110-
// 3. Refresh Sprite
5111-
if (dst_pic.IsWindowAttached()) {
5112-
// Re-attach window to generate sprite
5113-
bool async;
5114-
windows.GetWindow(dst).Refresh(async);
5115-
}
5116-
else if (!dst_pic.data.name.empty()) {
5117-
if (!dst_pic.sprite) dst_pic.CreateSprite();
5118-
if (src_bmp) {
5119-
dst_pic.sprite->SetBitmap(src_bmp);
5120-
dst_pic.sprite->OnPictureShow();
5121-
dst_pic.sprite->SetVisible(true);
5122-
}
5123-
}
5124-
else {
5125-
dst_pic.sprite.reset();
5126-
}
5127-
};
5128-
5129-
// Helper to swap two pictures
5130-
auto swap_picture = [&](int id1, int id2) {
5131-
// Ensure existence in vectors to avoid reference invalidation during assignments
5132-
int max_id = std::max(id1, id2);
5133-
pictures.GetPicture(max_id);
5134-
windows.GetWindow(max_id);
5135-
5136-
auto& p1 = pictures.GetPicture(id1);
5137-
auto& p2 = pictures.GetPicture(id2);
5138-
5139-
// Swap Window Data
5140-
auto& w1 = windows.GetWindow(id1);
5141-
auto& w2 = windows.GetWindow(id2);
5142-
std::swap(w1.data, w2.data);
5143-
w1.data.ID = id1;
5144-
w2.data.ID = id2;
5145-
5146-
// Swap Picture Data
5147-
BitmapRef b1 = p1.sprite ? p1.sprite->GetBitmap() : nullptr;
5148-
BitmapRef b2 = p2.sprite ? p2.sprite->GetBitmap() : nullptr;
5149-
5150-
using std::swap;
5151-
swap(p1.data, p2.data);
5152-
swap(p1.request_id, p2.request_id);
5153-
5154-
p1.data.ID = id1;
5155-
p2.data.ID = id2;
5156-
5157-
// Refresh Sprites Helper
5158-
auto refresh = [&](Game_Pictures::Picture& p, BitmapRef bmp) {
5159-
if (p.IsWindowAttached()) {
5160-
bool async;
5161-
windows.GetWindow(p.data.ID).Refresh(async);
5162-
}
5163-
else if (!p.data.name.empty()) {
5164-
if (!p.sprite) p.CreateSprite();
5165-
if (bmp) {
5166-
p.sprite->SetBitmap(bmp);
5167-
p.sprite->OnPictureShow();
5168-
p.sprite->SetVisible(true);
5169-
}
5170-
}
5171-
else {
5172-
p.sprite.reset();
5173-
}
5174-
};
5175-
5176-
refresh(p1, b2);
5177-
refresh(p2, b1);
5178-
};
5179-
51805068
if (operation == 0 || operation == 2) {
51815069
// Move (0) or Slide (2)
51825070
int target2 = (operation == 0) ? arg3 : (target1 + arg3);
@@ -5220,7 +5108,7 @@ bool Game_Interpreter::CommandManiacChangePictureId(lcf::rpg::EventCommand const
52205108
}
52215109

52225110
if (src_id != dst_id) {
5223-
move_picture(src_id, dst_id);
5111+
pictures.MovePictureId(src_id, dst_id);
52245112
}
52255113
}
52265114
}
@@ -5245,7 +5133,7 @@ bool Game_Interpreter::CommandManiacChangePictureId(lcf::rpg::EventCommand const
52455133
}
52465134

52475135
if (valid1 && valid2) {
5248-
swap_picture(id1, id2);
5136+
pictures.SwapPictureId(id1, id2);
52495137
}
52505138
else if (valid1 && !valid2) {
52515139
// Valid swap with invalid -> erase valid

src/game_pictures.cpp

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -658,3 +658,116 @@ void Game_Pictures::Picture::SetNonEffectParams(const Params& params, bool set_p
658658
int Game_Pictures::Picture::NumSpriteSheetFrames() const {
659659
return data.spritesheet_cols * data.spritesheet_rows;
660660
}
661+
662+
void Game_Pictures::MovePictureId(int src_id, int dst_id) {
663+
auto& pictures = *this;
664+
auto& windows = *Main_Data::game_windows;
665+
666+
// Ensure existence in vectors to avoid reference invalidation during assignments
667+
int max_id = std::max(src_id, dst_id);
668+
pictures.GetPicture(max_id);
669+
windows.GetWindow(max_id);
670+
671+
auto& src_pic = pictures.GetPicture(src_id);
672+
auto& dst_pic = pictures.GetPicture(dst_id);
673+
674+
// If source is empty, erase destination
675+
if (!src_pic.Exists() && !src_pic.IsWindowAttached()) {
676+
dst_pic.Erase();
677+
return;
678+
}
679+
680+
// Handle Window Data (String Pictures)
681+
if (src_pic.IsWindowAttached()) {
682+
auto& src_win = windows.GetWindow(src_id);
683+
auto& dst_win = windows.GetWindow(dst_id);
684+
dst_win.data = src_win.data;
685+
dst_win.data.ID = dst_id;
686+
src_win.Erase();
687+
}
688+
else {
689+
// If overwriting a window picture with a normal one, clear the old window data
690+
windows.GetWindow(dst_id).Erase();
691+
}
692+
693+
// Handle Picture Data
694+
BitmapRef src_bmp = src_pic.sprite ? src_pic.sprite->GetBitmap() : nullptr;
695+
auto request_id = src_pic.request_id;
696+
src_pic.request_id = nullptr; // Prevent cancellation on Erase
697+
698+
dst_pic.data = src_pic.data;
699+
dst_pic.data.ID = dst_id;
700+
dst_pic.request_id = request_id;
701+
702+
src_pic.Erase();
703+
704+
// Refresh Sprite
705+
if (dst_pic.IsWindowAttached()) {
706+
bool async;
707+
windows.GetWindow(dst_id).Refresh(async);
708+
}
709+
else if (!dst_pic.data.name.empty()) {
710+
if (!dst_pic.sprite) dst_pic.CreateSprite();
711+
if (src_bmp) {
712+
dst_pic.sprite->SetBitmap(src_bmp);
713+
dst_pic.sprite->OnPictureShow();
714+
dst_pic.sprite->SetVisible(true);
715+
}
716+
}
717+
else {
718+
dst_pic.sprite.reset();
719+
}
720+
}
721+
722+
void Game_Pictures::SwapPictureId(int id1, int id2) {
723+
auto& pictures = *this;
724+
auto& windows = *Main_Data::game_windows;
725+
726+
// Ensure existence in vectors to avoid reference invalidation during assignments
727+
int max_id = std::max(id1, id2);
728+
pictures.GetPicture(max_id);
729+
windows.GetWindow(max_id);
730+
731+
auto& p1 = pictures.GetPicture(id1);
732+
auto& p2 = pictures.GetPicture(id2);
733+
734+
// Swap Window Data
735+
auto& w1 = windows.GetWindow(id1);
736+
auto& w2 = windows.GetWindow(id2);
737+
std::swap(w1.data, w2.data);
738+
w1.data.ID = id1;
739+
w2.data.ID = id2;
740+
741+
// Swap Picture Data
742+
BitmapRef b1 = p1.sprite ? p1.sprite->GetBitmap() : nullptr;
743+
BitmapRef b2 = p2.sprite ? p2.sprite->GetBitmap() : nullptr;
744+
745+
using std::swap;
746+
swap(p1.data, p2.data);
747+
swap(p1.request_id, p2.request_id);
748+
749+
p1.data.ID = id1;
750+
p2.data.ID = id2;
751+
752+
// Rebuild each picture's visual with the other's bitmap
753+
auto refresh = [&](Picture& p, BitmapRef bmp) {
754+
if (p.IsWindowAttached()) {
755+
bool async;
756+
windows.GetWindow(p.data.ID).Refresh(async);
757+
}
758+
else if (!p.data.name.empty()) {
759+
if (!p.sprite) p.CreateSprite();
760+
if (bmp) {
761+
p.sprite->SetBitmap(bmp);
762+
p.sprite->OnPictureShow();
763+
p.sprite->SetVisible(true);
764+
}
765+
}
766+
else {
767+
p.sprite.reset();
768+
}
769+
};
770+
771+
refresh(p1, b2);
772+
refresh(p2, b1);
773+
}

src/game_pictures.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,22 @@ class Game_Pictures {
134134
Picture& GetPicture(int id);
135135
Picture* GetPicturePtr(int id);
136136

137+
/**
138+
* Moves picture data to a different ID
139+
*
140+
* @param src_id Source ID to move from
141+
* @param dst_id Destination ID to move to
142+
*/
143+
void MovePictureId(int src_id, int dst_id);
144+
145+
/**
146+
* Swaps picture data between two IDs
147+
*
148+
* @param id1 First ID to swap with
149+
* @param id2 Second ID to swap with
150+
*/
151+
void SwapPictureId(int id1, int id2);
152+
137153
private:
138154
void RequestPictureSprite(Picture& pic);
139155
void OnPictureSpriteReady(FileRequestResult*, int id);

0 commit comments

Comments
 (0)