1+ /*
2+ ===========================================================================
3+ * Sago Multi Scrambler Puzzle
4+ Copyright (C) 2022-2024 Poul Sander
5+
6+ This program is free software: you can redistribute it and/or modify
7+ it under the terms of the GNU General Public License as published by
8+ the Free Software Foundation, either version 2 of the License, or
9+ (at your option) any later version.
10+
11+ This program is distributed in the hope that it will be useful,
12+ but WITHOUT ANY WARRANTY; without even the implied warranty of
13+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+ GNU General Public License for more details.
15+
16+ You should have received a copy of the GNU General Public License
17+ along with this program. If not, see http://www.gnu.org/licenses/
18+
19+ Source information and contacts persons can be found at
20+ https://github.com/sago007/saland
21+ ===========================================================================
22+ */
23+
24+ #include " SagoTextureSelector.hpp"
25+ #include < iostream>
26+ #include " imgui.h"
27+ #include " backends/imgui_impl_sdl2.h"
28+ #include " backends/imgui_impl_sdlrenderer2.h"
29+ #include < SDL_image.h>
30+ #include " ../../sago/SagoMisc.hpp"
31+ #include " ../global.hpp"
32+
33+
34+ class ChangeSDLColor
35+ {
36+ public:
37+ ChangeSDLColor (SDL_Renderer* renderer, Uint8 r, Uint8 g, Uint8 b, Uint8 a) : renderer(renderer) {
38+ SDL_GetRenderDrawColor (renderer, &oldr, &oldg, &oldb, &olda);
39+ SDL_SetRenderDrawColor (renderer, r, g, b, a);
40+ }
41+
42+ ChangeSDLColor (SDL_Renderer* renderer) : renderer(renderer) {
43+ SDL_GetRenderDrawColor (renderer, &oldr, &oldg, &oldb, &olda);
44+ }
45+
46+ void setRed () {
47+ SDL_SetRenderDrawColor (renderer, 255 , 0 , 0 , SDL_ALPHA_OPAQUE);
48+ }
49+
50+ void setYellow () {
51+ SDL_SetRenderDrawColor (renderer, 255 , 255 , 0 , SDL_ALPHA_OPAQUE);
52+ }
53+
54+ void reset () {
55+ SDL_SetRenderDrawColor (renderer, oldr, oldg, oldb, olda);
56+ }
57+
58+ ~ChangeSDLColor () {
59+ SDL_SetRenderDrawColor (renderer, oldr, oldg, oldb, olda);
60+ }
61+
62+ private:
63+ SDL_Renderer* renderer;
64+ Uint8 oldr, oldg, oldb, olda;
65+ };
66+
67+
68+ static void addLinesToCanvas (SDL_Renderer* renderer, SDL_Texture* texture, int xstep = 32 , int ystep = 32 , int xoffset = 0 , int yoffset = 0 ) {
69+ int width, height;
70+ SDL_QueryTexture (texture, nullptr , nullptr , &width, &height);
71+ Uint8 r, g, b, a;
72+ SDL_GetRenderDrawColor (renderer, &r, &g, &b, &a);
73+
74+ if (xstep > 0 ) {
75+ for (int i = 0 ; i < width+1 ; i += xstep) {
76+ ImGui::GetWindowDrawList ()->AddLine (ImVec2 (i+xoffset, yoffset), ImVec2 (i+xoffset, height+yoffset), IM_COL32 (r, g, b, a));
77+ }
78+ }
79+ if (ystep > 0 ) {
80+ for (int i = 0 ; i < height+1 ; i += ystep) {
81+ ImGui::GetWindowDrawList ()->AddLine (ImVec2 (xoffset, i+yoffset), ImVec2 (width+xoffset, i+yoffset), IM_COL32 (r, g, b, a));
82+ }
83+ }
84+ }
85+
86+ static void addRectableToCanvas (SDL_Renderer* renderer, int topx = 0 , int topy = 0 , int height = 100 , int width = 100 , int xoffset = 0 , int yoffset = 0 ) {
87+ Uint8 r, g, b, a;
88+ SDL_GetRenderDrawColor (renderer, &r, &g, &b, &a);
89+ topx += xoffset;
90+ topy += yoffset;
91+ ImGui::GetWindowDrawList ()->AddLine (ImVec2 (topx, topy), ImVec2 (topx+width, topy), IM_COL32 (r, g, b, a));
92+ ImGui::GetWindowDrawList ()->AddLine (ImVec2 (topx+width, topy), ImVec2 (topx+width, topy+height), IM_COL32 (r, g, b, a));
93+ ImGui::GetWindowDrawList ()->AddLine (ImVec2 (topx+width, topy+height), ImVec2 (topx, topy+height), IM_COL32 (r, g, b, a));
94+ ImGui::GetWindowDrawList ()->AddLine (ImVec2 (topx, topy+height), ImVec2 (topx, topy), IM_COL32 (r, g, b, a));
95+ }
96+
97+ static void addFolderToList (const std::string& folder, std::vector<std::string>& list, const std::string& filter = " " ) {
98+ std::vector<std::string> textures = sago::GetFileList (folder.c_str ());
99+ for (const auto & texture : textures) {
100+ std::cout << " Texture: " << texture << " \n " ;
101+ if (texture.find (" .png" ) == std::string::npos) {
102+ continue ;
103+ }
104+ if (filter.empty () || texture.find (filter) != std::string::npos) {
105+ list.push_back (texture);
106+ }
107+ }
108+ }
109+
110+ static std::vector<std::string> populateTree (const std::string& filter = " " ) {
111+ std::vector<std::string> textures;
112+ addFolderToList (" textures" , textures, filter);
113+ return textures;
114+ }
115+
116+ std::string remove_file_extension (const std::string& filename) {
117+ size_t lastindex = filename.find_last_of (" ." );
118+ return filename.substr (0 , lastindex);
119+ }
120+
121+
122+ static void ImGuiWritePartOfImage (SDL_Texture* texture, int topx, int topy, int w, int h) {
123+ int tex_w, tex_h;
124+ SDL_QueryTexture (texture, nullptr , nullptr , &tex_w, &tex_h);
125+ float sprite_w = w;
126+ float sprite_h = h;
127+ float topxf = topx;
128+ float topyf = topy;
129+ ImVec2 uv0 = ImVec2 (topxf / tex_w, topyf / tex_h);
130+ ImVec2 uv1 = ImVec2 ((topxf + sprite_w) / tex_w, (topyf + sprite_h) / tex_h);
131+ ImGui::Image ((ImTextureID)(intptr_t )texture, ImVec2 ((float )w, (float )h), uv0, uv1);
132+ }
133+
134+ void SagoTextureSelector::runSpriteSelectorFrame (SDL_Renderer* target) {
135+ ImGui::Begin (" SpriteList" , nullptr , ImGuiWindowFlags_NoCollapse);
136+ static char filter[256 ] = " " ;
137+ ImGui::InputText (" Filter" , filter, IM_ARRAYSIZE (filter));
138+ ImGui::Separator ();
139+ for (const auto & sprite : sprites) {
140+ std::string sprite_name = sprite.first ;
141+ if (filter[0 ] == ' \0 ' || sprite_name.find (filter) != std::string::npos) {
142+ if (ImGui::Selectable (sprite_name.c_str (), selected_sprite == sprite_name)) {
143+ selected_sprite = sprite_name;
144+ }
145+ }
146+ }
147+
148+ ImGui::End ();
149+
150+ ImGui::Begin (" SpriteViewer" );
151+ if (selected_sprite.length ()) {
152+ const SagoSprite& current_sprite = sprites[selected_sprite];
153+ SDL_Texture* current_texture = globalData.dataHolder ->getTexturePtr (current_sprite.texture );
154+ ImGui::Text (" Size: %d x %d" , current_sprite.width , current_sprite.height );
155+ ImGui::BeginChild (" Test" );
156+ int offset = current_sprite.width * (SDL_GetTicks ()/current_sprite.frame_time % current_sprite.number_of_frames );
157+ ImGuiWritePartOfImage (current_texture, current_sprite.topx +offset, current_sprite.topy , current_sprite.width , current_sprite.height );
158+ ImGui::EndChild ();
159+ }
160+ ImGui::End ();
161+
162+ ImGui::Begin (" SpriteTexture" );
163+ if (selected_sprite.length () && sprites[selected_sprite].texture .length ()) {
164+ int tex_w, tex_h;
165+ const SagoSprite& current_sprite = sprites[selected_sprite];
166+ SDL_Texture* current_texture = globalData.dataHolder ->getTexturePtr (current_sprite.texture );
167+ SDL_QueryTexture (current_texture, nullptr , nullptr , &tex_w, &tex_h);
168+ ImGui::Text (" Size: %d x %d" , tex_w, tex_h);
169+ ImGui::BeginChild (" Test" );
170+ ImVec2 p = ImGui::GetCursorScreenPos ();
171+ ImGui::Image ((ImTextureID)(intptr_t )current_texture, ImVec2 ((float )tex_w, (float )tex_h));
172+ ChangeSDLColor color (target);
173+ color.setYellow ();
174+ for (int i = 1 ; i < current_sprite.number_of_frames ; i++) {
175+ addRectableToCanvas (target, current_sprite.topx +i*current_sprite.width , current_sprite.topy , current_sprite.height , current_sprite.width , p.x , p.y );
176+ }
177+ color.setRed ();
178+ addRectableToCanvas (target, current_sprite.topx , current_sprite.topy , current_sprite.height , current_sprite.width , p.x , p.y );
179+ ImGui::EndChild ();
180+ }
181+ ImGui::End ();
182+ }
183+
184+ void SagoTextureSelector::runTextureSelectorFrame (SDL_Renderer* target) {
185+ ImGui::Begin (" TextureList" , nullptr , ImGuiWindowFlags_NoCollapse);
186+ static char filter[256 ] = " " ;
187+ ImGui::InputText (" Filter" , filter, IM_ARRAYSIZE (filter));
188+ ImGui::Separator ();
189+ for (const auto & texture : textures) {
190+ if (filter[0 ] == ' \0 ' || texture.find (filter) != std::string::npos) {
191+ if (ImGui::Selectable (texture.c_str (), selected_texture == texture)) {
192+ selected_texture = texture;
193+ }
194+ }
195+ }
196+
197+ ImGui::End ();
198+
199+ ImGui::Begin (" TextureViewer" );
200+ if (selected_texture.length ()) {
201+ int tex_w, tex_h;
202+ SDL_Texture* current_texture = globalData.dataHolder ->getTexturePtr (remove_file_extension (selected_texture));
203+ SDL_QueryTexture (current_texture, nullptr , nullptr , &tex_w, &tex_h);
204+ ImGui::Text (" Size: %d x %d" , tex_w, tex_h);
205+ ImGui::BeginChild (" Test" );
206+ ImVec2 p = ImGui::GetCursorScreenPos ();
207+ ImGui::Image ((ImTextureID)(intptr_t )current_texture, ImVec2 ((float )tex_w, (float )tex_h));
208+ ChangeSDLColor color (target);
209+ color.setRed ();
210+ addLinesToCanvas (target, current_texture, 32 , 32 , p.x , p.y );
211+ ImGui::EndChild ();
212+ }
213+ ImGui::End ();
214+
215+ }
216+
217+
218+
219+ SagoTextureSelector::SagoTextureSelector () {
220+ }
221+
222+ SagoTextureSelector::~SagoTextureSelector () {
223+ }
224+
225+ bool SagoTextureSelector::IsActive () {
226+ return isActive;
227+ }
228+
229+ void SagoTextureSelector::ProcessInput (const SDL_Event& event, bool &processed) {
230+ ImGui_ImplSDL2_ProcessEvent (&event);
231+ }
232+
233+ void SagoTextureSelector::Draw (SDL_Renderer* target) {
234+ runTextureSelectorFrame (target);
235+ runSpriteSelectorFrame (target);
236+ }
237+
238+ void SagoTextureSelector::Update () {
239+ }
240+
241+ void SagoTextureSelector::Init () {
242+ textures = populateTree ();
243+ sprites = LoadSprites ();
244+ }
0 commit comments