diff --git a/source/credits.cpp b/source/credits.cpp index 4973409..a61226a 100644 --- a/source/credits.cpp +++ b/source/credits.cpp @@ -171,22 +171,37 @@ void Credits::fillTexture() Screen::get()->clearSurface(stringToColor("transparent")); // Los primeros 8 pixels crea una malla - auto surface = Screen::get()->getRenderSurfaceData(); + auto surface_data = *(Screen::get()->getRenderSurfaceData()); auto color = stringToColor("black"); for (int i = 0; i < 256; i += 2) { - text_surface_->putPixel(surface, i, 0, color); - text_surface_->putPixel(surface, i, 2, color); - text_surface_->putPixel(surface, i, 4, color); - text_surface_->putPixel(surface, i, 6, color); + text_surface_->putPixel(surface_data, i, 0, color); + text_surface_->putPixel(surface_data, i, 2, color); + text_surface_->putPixel(surface_data, i, 4, color); + text_surface_->putPixel(surface_data, i, 6, color); - text_surface_->putPixel(surface, i + 1, 5, color); - text_surface_->putPixel(surface, i + 1, 7, color); + text_surface_->putPixel(surface_data, i + 1, 5, color); + text_surface_->putPixel(surface_data, i + 1, 7, color); } // El resto se rellena de color sólido SDL_Rect rect = {0, 8, 256, 192}; - text_surface_->fillRect(surface, &rect, color); + text_surface_->fillRect(surface_data, &rect, color); + + for (int i = 0; i < 256; i += 2) + { + text_surface_->putPixel(surface_data, i, 0, color); + text_surface_->putPixel(surface_data, i, 2, color); + text_surface_->putPixel(surface_data, i, 4, color); + text_surface_->putPixel(surface_data, i, 6, color); + + text_surface_->putPixel(surface_data, i + 1, 5, color); + text_surface_->putPixel(surface_data, i + 1, 7, color); + } + + // El resto se rellena de color sólido + rect = {0, 8, 256, 192}; + text_surface_->fillRect(surface_data, &rect, color); Screen::get()->setRenderSurfaceData(nullptr); } diff --git a/source/ending.cpp b/source/ending.cpp index 316773b..11b6b42 100644 --- a/source/ending.cpp +++ b/source/ending.cpp @@ -167,7 +167,7 @@ void Ending::iniTexts() const int WIDTH = text->lenght(txt.caption, 1) + 2 + 2; const int HEIGHT = text->getCharacterSize() + 2 + 2; - Uint8 color = stringToColor("black"); + auto color = stringToColor("black"); EndingSurface st; @@ -188,22 +188,22 @@ void Ending::iniTexts() Screen::get()->clearSurface(stringToColor("transparent")); // Crea una malla de 8 pixels de alto - auto surface = Screen::get()->getRenderSurfaceData(); + auto surface_data = *(Screen::get()->getRenderSurfaceData()); color = stringToColor("black"); for (int i = 0; i < WIDTH; i += 2) { - st.cover_surface->putPixel(surface, i, 0, color); - st.cover_surface->putPixel(surface, i, 2, color); - st.cover_surface->putPixel(surface, i, 4, color); - st.cover_surface->putPixel(surface, i, 6, color); + st.cover_surface->putPixel(surface_data, i, 0, color); + st.cover_surface->putPixel(surface_data, i, 2, color); + st.cover_surface->putPixel(surface_data, i, 4, color); + st.cover_surface->putPixel(surface_data, i, 6, color); - st.cover_surface->putPixel(surface, i + 1, 5, color); - st.cover_surface->putPixel(surface, i + 1, 7, color); + st.cover_surface->putPixel(surface_data, i + 1, 5, color); + st.cover_surface->putPixel(surface_data, i + 1, 7, color); } // El resto se rellena de color sólido SDL_Rect rect = {0, 8, WIDTH, HEIGHT}; - st.cover_surface->fillRect(surface, &rect, color); + st.cover_surface->fillRect(surface_data, &rect, color); // Crea el sprite st.cover_sprite = std::make_shared(st.cover_surface, 0, 0, st.cover_surface->getWidth(), st.cover_surface->getHeight() - 8); @@ -255,22 +255,22 @@ void Ending::iniPics() Screen::get()->clearSurface(stringToColor("transparent")); // Crea una malla en los primeros 8 pixels - auto surface = Screen::get()->getRenderSurfaceData(); + auto surface_data = *(Screen::get()->getRenderSurfaceData()); auto color = stringToColor("black"); for (int i = 0; i < WIDTH; i += 2) { - sp.cover_surface->putPixel(surface, i, 0, color); - sp.cover_surface->putPixel(surface, i, 2, color); - sp.cover_surface->putPixel(surface, i, 4, color); - sp.cover_surface->putPixel(surface, i, 6, color); + sp.cover_surface->putPixel(surface_data, i, 0, color); + sp.cover_surface->putPixel(surface_data, i, 2, color); + sp.cover_surface->putPixel(surface_data, i, 4, color); + sp.cover_surface->putPixel(surface_data, i, 6, color); - sp.cover_surface->putPixel(surface, i + 1, 5, color); - sp.cover_surface->putPixel(surface, i + 1, 7, color); + sp.cover_surface->putPixel(surface_data, i + 1, 5, color); + sp.cover_surface->putPixel(surface_data, i + 1, 7, color); } // El resto se rellena de color sólido SDL_Rect rect = {0, 8, WIDTH, HEIGHT}; - sp.cover_surface->fillRect(surface, &rect, color); + sp.cover_surface->fillRect(surface_data, &rect, color); // Crea el sprite sp.cover_sprite = std::make_shared(sp.cover_surface, 0, 0, sp.cover_surface->getWidth(), sp.cover_surface->getHeight() - 8); @@ -477,22 +477,22 @@ void Ending::fillCoverTexture() // Los primeros 8 pixels crea una malla const Uint8 color = stringToColor("black"); - auto surface = Screen::get()->getRenderSurfaceData(); + auto surface_data = *(Screen::get()->getRenderSurfaceData()); for (int i = 0; i < 256; i += 2) { - cover_surface_->putPixel(surface, i + 0, options.game.height + 0, color); - cover_surface_->putPixel(surface, i + 1, options.game.height + 1, color); - cover_surface_->putPixel(surface, i + 0, options.game.height + 2, color); - cover_surface_->putPixel(surface, i + 1, options.game.height + 3, color); + cover_surface_->putPixel(surface_data, i + 0, options.game.height + 0, color); + cover_surface_->putPixel(surface_data, i + 1, options.game.height + 1, color); + cover_surface_->putPixel(surface_data, i + 0, options.game.height + 2, color); + cover_surface_->putPixel(surface_data, i + 1, options.game.height + 3, color); - cover_surface_->putPixel(surface, i, options.game.height + 4, color); - cover_surface_->putPixel(surface, i, options.game.height + 6, color); + cover_surface_->putPixel(surface_data, i, options.game.height + 4, color); + cover_surface_->putPixel(surface_data, i, options.game.height + 6, color); } // El resto se rellena de color sólido SDL_Rect rect = {0, 0, 256, options.game.height}; - cover_surface_->fillRect(surface, &rect, color); + cover_surface_->fillRect(surface_data, &rect, color); Screen::get()->setRenderSurfaceData(nullptr); } diff --git a/source/ending2.cpp b/source/ending2.cpp index cc13fca..4ba1b7d 100644 --- a/source/ending2.cpp +++ b/source/ending2.cpp @@ -115,24 +115,24 @@ void Ending2::render() // Dibuja una trama arriba y abajo Uint8 color = stringToColor("black"); auto surface = std::make_shared(Screen::get()->getRenderSurfaceData(), 1, 1); - auto surfaceData = Screen::get()->getRenderSurfaceData(); + auto surface_data = *(Screen::get()->getRenderSurfaceData()); for (int i = 0; i < 256; i += 2) { - surface->putPixel(surfaceData, i + 0, 0, color); - surface->putPixel(surfaceData, i + 1, 1, color); - surface->putPixel(surfaceData, i + 0, 2, color); - surface->putPixel(surfaceData, i + 1, 3, color); + surface->putPixel(surface_data, i + 0, 0, color); + surface->putPixel(surface_data, i + 1, 1, color); + surface->putPixel(surface_data, i + 0, 2, color); + surface->putPixel(surface_data, i + 1, 3, color); - surface->putPixel(surfaceData, i, 4, color); - surface->putPixel(surfaceData, i, 6, color); + surface->putPixel(surface_data, i, 4, color); + surface->putPixel(surface_data, i, 6, color); - surface->putPixel(surfaceData, i + 0, 191, color); - surface->putPixel(surfaceData, i + 1, 190, color); - surface->putPixel(surfaceData, i + 0, 189, color); - surface->putPixel(surfaceData, i + 1, 188, color); + surface->putPixel(surface_data, i + 0, 191, color); + surface->putPixel(surface_data, i + 1, 190, color); + surface->putPixel(surface_data, i + 0, 189, color); + surface->putPixel(surface_data, i + 1, 188, color); - surface->putPixel(surfaceData, i, 187, color); - surface->putPixel(surfaceData, i, 185, color); + surface->putPixel(surface_data, i, 187, color); + surface->putPixel(surface_data, i, 185, color); } // Vuelca el contenido del renderizador en pantalla diff --git a/source/loading_screen.cpp b/source/loading_screen.cpp index 332840a..41412d3 100644 --- a/source/loading_screen.cpp +++ b/source/loading_screen.cpp @@ -25,8 +25,8 @@ LoadingScreen::LoadingScreen() screen_surface_(std::make_shared(Screen::get()->getRenderSurfaceData(), options.game.width, options.game.height)) { // Cambia el destino de las surfaces - mono_loading_screen_surface_->setSurfaceDataDest(screen_surface_->getSurfaceData()); - color_loading_screen_surface_->setSurfaceDataDest(screen_surface_->getSurfaceData()); + mono_loading_screen_surface_->setSurfaceDataDestRaw(screen_surface_->getSurfaceData()); + color_loading_screen_surface_->setSurfaceDataDestRaw(screen_surface_->getSurfaceData()); // Configura la superficie donde se van a pintar los sprites screen_surface_->setColor(0, 0xFF000000); @@ -155,22 +155,22 @@ void LoadingScreen::renderBorder() color = stringToColor("yellow"); const int WIDTH = options.game.width + (options.video.border.width * 2); const int HEIGHT = options.game.height + (options.video.border.height * 2); - bool drawEnabled = rand() % 2 == 0 ? true : false; - auto surface = Screen::get()->getRenderSurfaceData(); + bool draw_enabled = rand() % 2 == 0 ? true : false; + auto surface_data = *(Screen::get()->getRenderSurfaceData()); int row = 0; while (row < HEIGHT) { const int ROW_HEIGHT = (rand() % 4) + 3; - if (drawEnabled) + if (draw_enabled) { for (int i = row; i < row + ROW_HEIGHT; ++i) { - screen_surface_->drawLine(surface, 0, i, WIDTH, i, color); + screen_surface_->drawLine(surface_data, 0, i, WIDTH, i, color); } } row += ROW_HEIGHT; - drawEnabled = !drawEnabled; + draw_enabled = !draw_enabled; } } diff --git a/source/notifier.cpp b/source/notifier.cpp index 9057250..0907437 100644 --- a/source/notifier.cpp +++ b/source/notifier.cpp @@ -241,20 +241,20 @@ void Notifier::show(std::vector texts, NotificationText text_is, in // Dibuja el fondo de la notificación SDL_Rect rect; - auto surface = Screen::get()->getRenderSurfaceData(); + auto surface_data = *(Screen::get()->getRenderSurfaceData()); if (shape == NotificationShape::ROUNDED) { rect = {4, 0, width - (4 * 2), height}; - n.surface->fillRect(surface, &rect, bg_color_); + n.surface->fillRect(surface_data, &rect, bg_color_); rect = {4 / 2, 1, width - 4, height - 2}; - n.surface->fillRect(surface, &rect, bg_color_); + n.surface->fillRect(surface_data, &rect, bg_color_); rect = {1, 4 / 2, width - 2, height - 4}; - n.surface->fillRect(surface, &rect, bg_color_); + n.surface->fillRect(surface_data, &rect, bg_color_); rect = {0, 4, width, height - (4 * 2)}; - n.surface->fillRect(surface, &rect, bg_color_); + n.surface->fillRect(surface_data, &rect, bg_color_); } else if (shape == NotificationShape::SQUARED) diff --git a/source/resource.cpp b/source/resource.cpp index 40849bf..b44f6cf 100644 --- a/source/resource.cpp +++ b/source/resource.cpp @@ -408,13 +408,14 @@ void Resource::renderProgress() Screen::get()->clearSurface(); auto surface = std::make_shared(Screen::get()->getRenderSurfaceData(), 1, 1); + auto surface_data = *(Screen::get()->getRenderSurfaceData()); const int wired_bar_width = options.game.width - (X_PADDING * 2); SDL_Rect rect_wired = {X_PADDING, bar_position, wired_bar_width, X_PADDING}; - surface->fillRect(Screen::get()->getRenderSurfaceData(), &rect_wired, stringToColor("blue")); + surface->fillRect(surface_data, &rect_wired, stringToColor("blue")); const int full_bar_width = wired_bar_width * count_.getPercentage(); SDL_Rect rect_full = {X_PADDING, bar_position, full_bar_width, X_PADDING}; - surface->fillRect(Screen::get()->getRenderSurfaceData(), &rect_full, stringToColor("white")); + surface->fillRect(surface_data, &rect_full, stringToColor("white")); Screen::get()->renderWithoutNotifier(); } diff --git a/source/screen.cpp b/source/screen.cpp index dcf19d1..22debec 100644 --- a/source/screen.cpp +++ b/source/screen.cpp @@ -54,7 +54,6 @@ Screen::Screen(SDL_Window *window, SDL_Renderer *renderer) // Crea la textura donde se dibujan los graficos del juego game_texture_ = SDL_CreateTexture(renderer_, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, options.game.width, options.game.height); - // game_texture_ = SDL_CreateTexture(renderer_, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_TARGET, options.game.width, options.game.height); if (!game_texture_) { // Registrar el error si está habilitado @@ -66,7 +65,6 @@ Screen::Screen(SDL_Window *window, SDL_Renderer *renderer) // Crea la textura donde se dibuja el borde que rodea el area de juego border_texture_ = SDL_CreateTexture(renderer_, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, options.game.width + options.video.border.width * 2, options.game.height + options.video.border.height * 2); - // border_texture_ = SDL_CreateTexture(renderer_, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_TARGET, options.game.width + options.video.border.width * 2, options.game.height + options.video.border.height * 2); if (!border_texture_) { // Registrar el error si está habilitado @@ -77,7 +75,8 @@ Screen::Screen(SDL_Window *window, SDL_Renderer *renderer) } // Crea la surface donde se dibujan los graficos del juego - game_surface_ = std::make_shared(nullptr, options.game.width, options.game.height); + game_surface_data_ = std::make_shared>(std::make_shared(options.game.width, options.game.height)); + game_surface_ = std::make_shared(game_surface_data_, options.game.width, options.game.height); game_surface_->loadPalette(palettes_.front()); // Crea la surface donde se dibujan los graficos del juego diff --git a/source/screen.h b/source/screen.h index 4b6ff1d..b7dc44a 100644 --- a/source/screen.h +++ b/source/screen.h @@ -26,12 +26,13 @@ private: static Screen *screen_; // Objetos y punteros - SDL_Window *window_; // Ventana de la aplicación - SDL_Renderer *renderer_; // El renderizador de la ventana - SDL_Texture *game_texture_; // Textura donde se dibuja el juego - SDL_Texture *border_texture_; // Textura donde se dibuja el borde del juego - std::shared_ptr game_surface_; // Objeto para trabajar con surfaces - std::shared_ptr border_surface_; // Objeto para trabajar con surfaces + SDL_Window *window_; // Ventana de la aplicación + SDL_Renderer *renderer_; // El renderizador de la ventana + SDL_Texture *game_texture_; // Textura donde se dibuja el juego + SDL_Texture *border_texture_; // Textura donde se dibuja el borde del juego + std::shared_ptr> game_surface_data_; // SurfaceData principal donde van a dibujar el resto de Surfaces + std::shared_ptr game_surface_; // Surface principal para manejar game_surface_data_ + std::shared_ptr border_surface_; // Surface para pintar el el borde de la pantalla // Variables int window_width_; // Ancho de la pantalla o ventana @@ -137,7 +138,7 @@ public: // Getters SDL_Renderer *getRenderer() { return renderer_; } - std::shared_ptr getRenderSurfaceData() { return game_surface_->getSurfaceData(); } + std::shared_ptr> getRenderSurfaceData() { return std::make_shared>(game_surface_->getSurfaceData()); } // Prepara para empezar a dibujar en la textura del borde void startDrawOnBorder() { setRenderSurfaceData(border_surface_); } diff --git a/source/surface.cpp b/source/surface.cpp index 2a24b83..89cdc19 100644 --- a/source/surface.cpp +++ b/source/surface.cpp @@ -10,43 +10,30 @@ #include "asset.h" // for Asset #include "gif.h" // for LoadGif, LoadPalette -Surface::Surface(std::shared_ptr surface_data_dest, int w, int h) +// Constructor +Surface::Surface(std::shared_ptr> surface_dest, int w, int h) + : surface_data_dest_(surface_dest), + surface_data_(std::make_shared(w, h)), + original_surface_data_(surface_data_), + transparent_color_(0) { - // Inicializar surface_data_ con un nuevo SurfaceData - surface_data_ = std::make_shared(w, h); - - // Guardar la copia original de surface_data_ - original_surface_data_ = surface_data_; - - // Si se proporciona un surface_data_dest, enlazamos surface_data_dest_ - if (surface_data_dest) + if (!surface_data_dest_) { - surface_data_dest_ = surface_data_dest; - } - else - { - // Si no se pasa otro puntero, surface_data_dest_ apunta al propio surface_data_ - surface_data_dest_ = surface_data_; + surface_data_dest_ = std::make_shared>(surface_data_); } } -Surface::Surface(std::shared_ptr surface_data_dest, const std::string &file_path) +Surface::Surface(std::shared_ptr> surface_dest, const std::string &file_path) + : surface_data_dest_(surface_dest), + transparent_color_(0) { - // Cargar surface_data_ desde el archivo - surface_data_ = std::make_shared(loadSurface(file_path)); - - // Guardar la copia original de surface_data_ + SurfaceData loadedData = loadSurface(file_path); + surface_data_ = std::make_shared(std::move(loadedData)); original_surface_data_ = surface_data_; - // Si se proporciona un surface_data_dest, enlazamos surface_data_dest_ - if (surface_data_dest) + if (!surface_data_dest_) { - surface_data_dest_ = surface_data_dest; - } - else - { - // Si no se pasa otro puntero, surface_data_dest_ apunta al propio surface_data_ - surface_data_dest_ = surface_data_; + surface_data_dest_ = std::make_shared>(surface_data_); } } @@ -212,16 +199,17 @@ void Surface::drawLine(std::shared_ptr surface_data, int x1, int y1 // Copia una región de la superficie de origen a la de destino void Surface::render(int dx, int dy, int sx, int sy, int w, int h) { - if (!surface_data_ || !surface_data_dest_) - { + if (!surface_data_ || !surface_data_dest_ || !*surface_data_dest_) { throw std::runtime_error("Surface source or destination is null."); } + auto &dest = **surface_data_dest_; + // Limitar la región para evitar accesos fuera de rango w = std::min(w, surface_data_->width - sx); h = std::min(h, surface_data_->height - sy); - w = std::min(w, surface_data_dest_->width - dx); - h = std::min(h, surface_data_dest_->height - dy); + w = std::min(w, dest.width - dx); + h = std::min(h, dest.height - dy); for (int iy = 0; iy < h; ++iy) { @@ -230,7 +218,7 @@ void Surface::render(int dx, int dy, int sx, int sy, int w, int h) Uint8 color = surface_data_->data[(sx + ix) + (sy + iy) * surface_data_->width]; if (color != transparent_color_) { - surface_data_dest_->data[(dx + ix) + (dy + iy) * surface_data_dest_->width] = color; + dest.data[(dx + ix) + (dy + iy) * dest.width] = color; } } } @@ -239,11 +227,12 @@ void Surface::render(int dx, int dy, int sx, int sy, int w, int h) // Copia una región de la superficie de origen a la de destino void Surface::render(int x, int y, SDL_Rect *srcRect, SDL_RendererFlip flip) { - if (!surface_data_ || !surface_data_dest_) - { + if (!surface_data_ || !surface_data_dest_ || !*surface_data_dest_) { throw std::runtime_error("Surface source or destination is null."); } + auto &dest = **surface_data_dest_; + // Determina la región de origen (clip) a renderizar int sx = (srcRect) ? srcRect->x : 0; int sy = (srcRect) ? srcRect->y : 0; @@ -253,8 +242,8 @@ void Surface::render(int x, int y, SDL_Rect *srcRect, SDL_RendererFlip flip) // Limitar la región para evitar accesos fuera de rango w = std::min(w, surface_data_->width - sx); h = std::min(h, surface_data_->height - sy); - w = std::min(w, surface_data_dest_->width - x); - h = std::min(h, surface_data_dest_->height - y); + w = std::min(w, dest.width - x); + h = std::min(h, dest.height - y); // Renderiza píxel por píxel aplicando el flip si es necesario for (int iy = 0; iy < h; ++iy) @@ -273,7 +262,7 @@ void Surface::render(int x, int y, SDL_Rect *srcRect, SDL_RendererFlip flip) Uint8 color = surface_data_->data[src_x + src_y * surface_data_->width]; if (color != transparent_color_) { - surface_data_dest_->data[dest_x + dest_y * surface_data_dest_->width] = color; + dest.data[dest_x + dest_y * dest.width] = color; } } } @@ -282,11 +271,12 @@ void Surface::render(int x, int y, SDL_Rect *srcRect, SDL_RendererFlip flip) // Copia una región de la superficie de origen a la de destino void Surface::render(SDL_Rect *srcRect, SDL_Rect *dstRect, SDL_RendererFlip flip) { - if (!surface_data_ || !surface_data_dest_) - { + if (!surface_data_ || !surface_data_dest_ || !*surface_data_dest_) { throw std::runtime_error("Surface source or destination is null."); } + auto &dest = **surface_data_dest_; + // Si srcRect es nullptr, tomar toda la superficie fuente int sx = (srcRect) ? srcRect->x : 0; int sy = (srcRect) ? srcRect->y : 0; @@ -309,8 +299,8 @@ void Surface::render(SDL_Rect *srcRect, SDL_Rect *dstRect, SDL_RendererFlip flip // Limitar la región para evitar accesos fuera de rango en src y dst sw = std::min(sw, surface_data_->width - sx); sh = std::min(sh, surface_data_->height - sy); - dw = std::min(dw, surface_data_dest_->width - dx); - dh = std::min(dh, surface_data_dest_->height - dy); + dw = std::min(dw, dest.width - dx); + dh = std::min(dh, dest.height - dy); int final_width = std::min(sw, dw); int final_height = std::min(sh, dh); @@ -332,7 +322,7 @@ void Surface::render(SDL_Rect *srcRect, SDL_Rect *dstRect, SDL_RendererFlip flip Uint8 color = surface_data_->data[src_x + src_y * surface_data_->width]; if (color != transparent_color_) { - surface_data_dest_->data[dest_x + dest_y * surface_data_dest_->width] = color; + dest.data[dest_x + dest_y * dest.width] = color; } } } @@ -341,11 +331,12 @@ void Surface::render(SDL_Rect *srcRect, SDL_Rect *dstRect, SDL_RendererFlip flip // Copia una región de la SurfaceData de origen a la SurfaceData de destino reemplazando un color por otro void Surface::renderWithColorReplace(int x, int y, Uint8 source_color, Uint8 target_color, SDL_Rect *srcRect, SDL_RendererFlip flip) { - if (!surface_data_ || !surface_data_dest_) - { + if (!surface_data_ || !surface_data_dest_ || !*surface_data_dest_) { throw std::runtime_error("Surface source or destination is null."); } + auto &dest = **surface_data_dest_; + // Determina la región de origen (clip) a renderizar int sx = (srcRect) ? srcRect->x : 0; int sy = (srcRect) ? srcRect->y : 0; @@ -370,7 +361,7 @@ void Surface::renderWithColorReplace(int x, int y, Uint8 source_color, Uint8 tar int dest_y = y + iy; // Verifica que las coordenadas de destino estén dentro de los límites - if (dest_x < 0 || dest_y < 0 || dest_x >= surface_data_dest_->width || dest_y >= surface_data_dest_->height) + if (dest_x < 0 || dest_y < 0 || dest_x >= dest.width || dest_y >= dest.height) { continue; // Saltar píxeles fuera del rango del destino } @@ -379,7 +370,7 @@ void Surface::renderWithColorReplace(int x, int y, Uint8 source_color, Uint8 tar Uint8 color = surface_data_->data[src_x + src_y * surface_data_->width]; if (color != transparent_color_) { - surface_data_dest_->data[dest_x + dest_y * surface_data_dest_->width] = + dest.data[dest_x + dest_y * dest.width] = (color == source_color) ? target_color : color; } } @@ -455,27 +446,25 @@ bool Surface::fadePalette() return palette_[15] == palette_[0]; } -// Método para redirigir surface_data_ al surface_data_ de otro objeto -void Surface::redirectSurfaceDataTo(const std::shared_ptr& newSurfaceData) +// Permite que una Surface apunte al SurfaceData de otra Surface +void Surface::redirectSurfaceDataTo(const std::shared_ptr &newSurfaceData) { - // Guardar el surface_data_ original para poder restaurarlo - original_surface_data_ = surface_data_; - - // Redirigir surface_data_ al nuevo surface_data_ - surface_data_ = newSurfaceData; + if (surface_data_dest_) + { + *surface_data_dest_ = newSurfaceData; + } } void Surface::redirectSurfaceDataTo(const std::shared_ptr &otherSurface) { - // Guardar el surface_data_ original para poder restaurarlo - original_surface_data_ = surface_data_; - - // Redirigir surface_data_ al nuevo surface_data_ - surface_data_ = otherSurface->getSurfaceData(); + redirectSurfaceDataTo(otherSurface->getSurfaceData()); } -// Método para restaurar surface_data_ al valor original +// Método para restaurar void Surface::restoreOriginalSurfaceData() { - surface_data_ = original_surface_data_; -} + if (surface_data_dest_) + { + *surface_data_dest_ = original_surface_data_; + } +} \ No newline at end of file diff --git a/source/surface.h b/source/surface.h index d218628..2ce3f97 100644 --- a/source/surface.h +++ b/source/surface.h @@ -60,16 +60,16 @@ struct SurfaceData class Surface { private: - std::shared_ptr surface_data_dest_; // Puntero a la SurfaceData remota donde copiar la información - std::shared_ptr surface_data_; // SurfaceData propia - std::shared_ptr original_surface_data_; // SurfaceData original para restauración - std::array palette_; // Paleta para volcar la SurfaceData a una Textura - int transparent_color_; // Indice de la paleta que se omite en la copia de datos + std::shared_ptr> surface_data_dest_; // Puntero a la SurfaceData remota donde copiar la información + std::shared_ptr surface_data_; // SurfaceData propia + std::shared_ptr original_surface_data_; // SurfaceData original para restauración + std::array palette_; // Paleta para volcar la SurfaceData a una Textura + int transparent_color_; // Indice de la paleta que se omite en la copia de datos public: // Constructor - Surface(std::shared_ptr surface_data_dest = nullptr, int w = 0, int h = 0); - Surface(std::shared_ptr surface_data_dest, const std::string &file_path); + Surface(std::shared_ptr> surface_dest, int w, int h); + Surface(std::shared_ptr> surface_dest, const std::string &file_path); // Destructor ~Surface() = default; @@ -120,14 +120,15 @@ public: // Setters void setTransparentColor(int color) { transparent_color_ = color; } - void setSurfaceDataDest(std::shared_ptr surface_data_dest) { surface_data_dest_ = surface_data_dest; } + void setSurfaceDataDest(std::shared_ptr> surface_data_dest) { surface_data_dest_ = surface_data_dest; } + void setSurfaceDataDestRaw(std::shared_ptr surface_data_dest) { surface_data_dest_ = std::make_shared>(surface_data_dest); } void setPalette(const std::array &palette) { palette_ = palette; } void setSurface(std::shared_ptr surface) { surface_data_ = surface; } - // Método para redirigir surface_data_ al surface_data_ de otro objeto + // Permite que una Surface apunte al SurfaceData de otra Surface void redirectSurfaceDataTo(const std::shared_ptr &newSurfaceData); void redirectSurfaceDataTo(const std::shared_ptr &otherSurface); - // Método para restaurar surface_data_ al valor original + // Método para restaurar void restoreOriginalSurfaceData(); }; diff --git a/source/title.cpp b/source/title.cpp index 54ad490..34858bf 100644 --- a/source/title.cpp +++ b/source/title.cpp @@ -33,7 +33,7 @@ Title::Title() pLoadPal(Asset::get()->get("loading_screen_color.gif").c_str()); pSetSource(loading_screen_); - //title_logo_surface_->setSurfaceDataDest(bg_surface_->getSurfaceData()); + //title_logo_surface_->setSurfaceDataDestRaw(bg_surface_->getSurfaceData()); // Inicializa variables state_ = options.section.subsection == Subsection::TITLE_WITH_LOADING_SCREEN ? TitleState::SHOW_LOADING_SCREEN : TitleState::SHOW_MENU; @@ -373,7 +373,8 @@ void Title::createCheevosTexture() cheevoColor = cheevo.completed ? CHEEVO_UNLOCKED_COLOR : CHEEVO_LOCKED_COLOR; pos += CHEEVOS_PADDING; constexpr int HALF = CHEEVOS_PADDING / 2; - cheevos_surface_->drawLine(Screen::get()->getRenderSurfaceData(), LINE_X1, pos - HALF - 1, LINE_X2, pos - HALF - 1, cheevoColor); + auto surface_data = *(Screen::get()->getRenderSurfaceData()); + cheevos_surface_->drawLine(surface_data, LINE_X1, pos - HALF - 1, LINE_X2, pos - HALF - 1, cheevoColor); TEXT->writeDX(TEXT_CENTER | TEXT_COLOR, CHEEVOS_TEXTURE_WIDTH / 2, pos, cheevo.caption, 1, cheevoColor); pos += TEXT->getCharacterSize() + 1; TEXT->writeDX(TEXT_CENTER | TEXT_COLOR, CHEEVOS_TEXTURE_WIDTH / 2, pos, cheevo.description, 1, cheevoColor);