Refactor bitmap palette management across various components to streamline palette setting and improve error handling; remove unnecessary status checks and enhance consistency in palette application methods.
This commit is contained in:
@@ -8,13 +8,11 @@
|
||||
#include <cstdint>
|
||||
#include <future>
|
||||
#include <memory>
|
||||
#include <iostream>
|
||||
|
||||
#include "absl/status/status.h"
|
||||
#include "app/core/platform/memory_tracker.h"
|
||||
#include "app/core/platform/sdl_deleter.h"
|
||||
#include "app/gfx/snes_palette.h"
|
||||
#include "app/gfx/texture_pool.h"
|
||||
#include "util/macro.h"
|
||||
|
||||
namespace yaze {
|
||||
namespace gfx {
|
||||
@@ -202,7 +200,7 @@ Uint32 GetSnesPixelFormat(int format) {
|
||||
}
|
||||
|
||||
// Custom allocator for SDL_Surface
|
||||
SDL_Surface* AllocateSurface(int width, int height, int depth, Uint32 format) {
|
||||
SDL_Surface *AllocateSurface(int width, int height, int depth, Uint32 format) {
|
||||
SDL_Surface *surface =
|
||||
SDL_CreateRGBSurfaceWithFormat(0, width, height, depth, format);
|
||||
if (surface) {
|
||||
@@ -213,7 +211,7 @@ SDL_Surface* AllocateSurface(int width, int height, int depth, Uint32 format) {
|
||||
}
|
||||
|
||||
// Custom allocator for SDL_Texture
|
||||
SDL_Texture* AllocateTexture(SDL_Renderer *renderer, Uint32 format, int access,
|
||||
SDL_Texture *AllocateTexture(SDL_Renderer *renderer, Uint32 format, int access,
|
||||
int width, int height) {
|
||||
SDL_Texture *texture =
|
||||
SDL_CreateTexture(renderer, format, access, width, height);
|
||||
@@ -227,22 +225,21 @@ SDL_Texture* AllocateTexture(SDL_Renderer *renderer, Uint32 format, int access,
|
||||
}
|
||||
|
||||
// Bitmap class implementation
|
||||
Bitmap::Bitmap(int width, int height, int depth, const std::vector<uint8_t> &data)
|
||||
Bitmap::Bitmap(int width, int height, int depth,
|
||||
const std::vector<uint8_t> &data)
|
||||
: width_(width), height_(height), depth_(depth), data_(data) {
|
||||
Create(width, height, depth, data);
|
||||
}
|
||||
|
||||
Bitmap::Bitmap(int width, int height, int depth, const std::vector<uint8_t> &data,
|
||||
const SnesPalette &palette)
|
||||
Bitmap::Bitmap(int width, int height, int depth,
|
||||
const std::vector<uint8_t> &data, const SnesPalette &palette)
|
||||
: width_(width),
|
||||
height_(height),
|
||||
depth_(depth),
|
||||
data_(data),
|
||||
palette_(palette) {
|
||||
Create(width, height, depth, data);
|
||||
if (!SetPalette(palette).ok()) {
|
||||
std::cerr << "Error applying palette in bitmap constructor." << std::endl;
|
||||
}
|
||||
SetPalette(palette);
|
||||
}
|
||||
|
||||
void Bitmap::SaveSurfaceToFile(std::string_view filename) {
|
||||
@@ -305,11 +302,7 @@ void Bitmap::Reformat(int format) {
|
||||
SDL_Surface_Deleter());
|
||||
surface_->pixels = pixel_data_;
|
||||
active_ = true;
|
||||
auto apply_palette = SetPalette(palette_);
|
||||
if (!apply_palette.ok()) {
|
||||
SDL_Log("Failed to apply palette: %s\n", apply_palette.message().data());
|
||||
active_ = false;
|
||||
}
|
||||
SetPalette(palette_);
|
||||
}
|
||||
|
||||
void Bitmap::UpdateTexture(SDL_Renderer *renderer) {
|
||||
@@ -407,41 +400,39 @@ void Bitmap::CleanupUnusedTexture(uint64_t current_time, uint64_t timeout) {
|
||||
}
|
||||
}
|
||||
|
||||
absl::Status Bitmap::SetPalette(const SnesPalette &palette) {
|
||||
void Bitmap::SetPalette(const SnesPalette &palette) {
|
||||
if (surface_ == nullptr) {
|
||||
return absl::FailedPreconditionError(
|
||||
"Surface is null. Palette not applied");
|
||||
throw std::runtime_error("Surface is null. Palette not applied");
|
||||
}
|
||||
if (surface_->format == nullptr || surface_->format->palette == nullptr) {
|
||||
return absl::FailedPreconditionError(
|
||||
throw std::runtime_error(
|
||||
"Surface format or palette is null. Palette not applied.");
|
||||
}
|
||||
palette_ = palette;
|
||||
|
||||
SDL_Palette *sdl_palette = surface_->format->palette;
|
||||
if (sdl_palette == nullptr) {
|
||||
return absl::InternalError("Failed to get SDL palette");
|
||||
throw std::runtime_error("Failed to get SDL palette");
|
||||
}
|
||||
|
||||
SDL_UnlockSurface(surface_.get());
|
||||
for (size_t i = 0; i < palette.size(); ++i) {
|
||||
ASSIGN_OR_RETURN(gfx::SnesColor pal_color, palette.GetColor(i));
|
||||
auto pal_color = palette[i];
|
||||
sdl_palette->colors[i].r = pal_color.rgb().x;
|
||||
sdl_palette->colors[i].g = pal_color.rgb().y;
|
||||
sdl_palette->colors[i].b = pal_color.rgb().z;
|
||||
sdl_palette->colors[i].a = pal_color.rgb().w;
|
||||
}
|
||||
SDL_LockSurface(surface_.get());
|
||||
return absl::OkStatus();
|
||||
}
|
||||
|
||||
absl::Status Bitmap::SetPaletteFromPaletteGroup(const SnesPalette &palette,
|
||||
int palette_id) {
|
||||
void Bitmap::SetPaletteFromPaletteGroup(const SnesPalette &palette,
|
||||
int palette_id) {
|
||||
auto start_index = palette_id * 8;
|
||||
palette_ = palette.sub_palette(start_index, start_index + 8);
|
||||
SDL_UnlockSurface(surface_.get());
|
||||
for (size_t i = 0; i < palette_.size(); ++i) {
|
||||
ASSIGN_OR_RETURN(auto pal_color, palette_.GetColor(i));
|
||||
auto pal_color = palette_[i];
|
||||
if (pal_color.is_transparent()) {
|
||||
surface_->format->palette->colors[i].r = 0;
|
||||
surface_->format->palette->colors[i].g = 0;
|
||||
@@ -455,26 +446,24 @@ absl::Status Bitmap::SetPaletteFromPaletteGroup(const SnesPalette &palette,
|
||||
}
|
||||
}
|
||||
SDL_LockSurface(surface_.get());
|
||||
return absl::OkStatus();
|
||||
}
|
||||
|
||||
absl::Status Bitmap::SetPaletteWithTransparent(const SnesPalette &palette,
|
||||
size_t index, int length) {
|
||||
void Bitmap::SetPaletteWithTransparent(const SnesPalette &palette, size_t index,
|
||||
int length) {
|
||||
if (index < 0 || index >= palette.size()) {
|
||||
return absl::InvalidArgumentError("Invalid palette index");
|
||||
throw std::invalid_argument("Invalid palette index");
|
||||
}
|
||||
|
||||
if (length < 0 || length > palette.size()) {
|
||||
return absl::InvalidArgumentError("Invalid palette length");
|
||||
throw std::invalid_argument("Invalid palette length");
|
||||
}
|
||||
|
||||
if (index + length > palette.size()) {
|
||||
return absl::InvalidArgumentError("Palette index + length exceeds size");
|
||||
throw std::invalid_argument("Palette index + length exceeds size");
|
||||
}
|
||||
|
||||
if (surface_ == nullptr) {
|
||||
return absl::FailedPreconditionError(
|
||||
"Surface is null. Palette not applied");
|
||||
throw std::runtime_error("Surface is null. Palette not applied");
|
||||
}
|
||||
|
||||
auto start_index = index * 7;
|
||||
@@ -482,7 +471,7 @@ absl::Status Bitmap::SetPaletteWithTransparent(const SnesPalette &palette,
|
||||
std::vector<ImVec4> colors;
|
||||
colors.push_back(ImVec4(0, 0, 0, 0));
|
||||
for (int i = start_index; i < start_index + 7; ++i) {
|
||||
ASSIGN_OR_RETURN(auto pal_color, palette.GetColor(i));
|
||||
auto pal_color = palette[i];
|
||||
colors.push_back(pal_color.rgb());
|
||||
}
|
||||
|
||||
@@ -496,7 +485,6 @@ absl::Status Bitmap::SetPaletteWithTransparent(const SnesPalette &palette,
|
||||
i++;
|
||||
}
|
||||
SDL_LockSurface(surface_.get());
|
||||
return absl::OkStatus();
|
||||
}
|
||||
|
||||
void Bitmap::SetPalette(const std::vector<SDL_Color> &palette) {
|
||||
@@ -609,38 +597,34 @@ std::vector<gfx::Bitmap> ExtractTile8Bitmaps(const gfx::Bitmap &source_bmp,
|
||||
std::vector<std::future<gfx::Bitmap>> futures;
|
||||
|
||||
for (int index = 0; index < kTileCount; ++index) {
|
||||
futures.emplace_back(std::async(std::launch::async, [&source_bmp, &palette,
|
||||
palette_index,
|
||||
index]() {
|
||||
std::array<uint8_t, 0x40> tile_data;
|
||||
futures.emplace_back(std::async(
|
||||
std::launch::async, [&source_bmp, &palette, palette_index, index]() {
|
||||
std::array<uint8_t, 0x40> tile_data;
|
||||
|
||||
int num_columns = source_bmp.width() / kTileSize;
|
||||
int num_columns = source_bmp.width() / kTileSize;
|
||||
|
||||
for (int ty = 0; ty < kTileSize; ++ty) {
|
||||
for (int tx = 0; tx < kTileSize; ++tx) {
|
||||
int tile_data_pos = tx + (ty * kTileSize);
|
||||
int src_x = (index % num_columns) * kTileSize + tx;
|
||||
int src_y = (index / num_columns) * kTileSize + ty;
|
||||
int gfx_position = src_x + (src_y * 0x100);
|
||||
for (int ty = 0; ty < kTileSize; ++ty) {
|
||||
for (int tx = 0; tx < kTileSize; ++tx) {
|
||||
int tile_data_pos = tx + (ty * kTileSize);
|
||||
int src_x = (index % num_columns) * kTileSize + tx;
|
||||
int src_y = (index / num_columns) * kTileSize + ty;
|
||||
int gfx_position = src_x + (src_y * 0x100);
|
||||
|
||||
uint8_t value = source_bmp.data()[gfx_position];
|
||||
uint8_t value = source_bmp.data()[gfx_position];
|
||||
|
||||
if (value & 0x80) {
|
||||
value -= 0x88;
|
||||
if (value & 0x80) {
|
||||
value -= 0x88;
|
||||
}
|
||||
|
||||
tile_data[tile_data_pos] = value;
|
||||
}
|
||||
}
|
||||
|
||||
tile_data[tile_data_pos] = value;
|
||||
}
|
||||
}
|
||||
|
||||
gfx::Bitmap tile_bitmap;
|
||||
tile_bitmap.Create(kTileSize, kTileSize, 8, tile_data);
|
||||
if (!tile_bitmap.SetPaletteWithTransparent(palette, palette_index).ok()) {
|
||||
SDL_Log("Failed to set palette for tile %d\n", index);
|
||||
throw std::runtime_error("Failed to set palette for tile");
|
||||
}
|
||||
return tile_bitmap;
|
||||
}));
|
||||
gfx::Bitmap tile_bitmap;
|
||||
tile_bitmap.Create(kTileSize, kTileSize, 8, tile_data);
|
||||
tile_bitmap.SetPaletteWithTransparent(palette, palette_index);
|
||||
return tile_bitmap;
|
||||
}));
|
||||
}
|
||||
|
||||
for (auto &future : futures) {
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/status/status.h"
|
||||
#include "app/gfx/snes_palette.h"
|
||||
|
||||
namespace yaze {
|
||||
@@ -68,12 +67,12 @@ class Bitmap {
|
||||
public:
|
||||
// Constructors
|
||||
Bitmap() = default;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Create a bitmap with the given dimensions and data
|
||||
*/
|
||||
Bitmap(int width, int height, int depth, const std::vector<uint8_t> &data);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Create a bitmap with the given dimensions, data, and palette
|
||||
*/
|
||||
@@ -89,13 +88,13 @@ class Bitmap {
|
||||
* @brief Create a bitmap with the given dimensions and data
|
||||
*/
|
||||
void Create(int width, int height, int depth, std::span<uint8_t> data);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Create a bitmap with the given dimensions and data
|
||||
*/
|
||||
void Create(int width, int height, int depth,
|
||||
const std::vector<uint8_t> &data);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Create a bitmap with the given dimensions, format, and data
|
||||
*/
|
||||
@@ -140,20 +139,19 @@ class Bitmap {
|
||||
/**
|
||||
* @brief Set the palette for the bitmap
|
||||
*/
|
||||
absl::Status SetPalette(const SnesPalette &palette);
|
||||
|
||||
void SetPalette(const SnesPalette &palette);
|
||||
|
||||
/**
|
||||
* @brief Set the palette with a transparent color
|
||||
*/
|
||||
absl::Status SetPaletteWithTransparent(const SnesPalette &palette,
|
||||
size_t index, int length = 7);
|
||||
|
||||
void SetPaletteWithTransparent(const SnesPalette &palette, size_t index,
|
||||
int length = 7);
|
||||
|
||||
/**
|
||||
* @brief Set the palette from a palette group
|
||||
*/
|
||||
absl::Status SetPaletteFromPaletteGroup(const SnesPalette &palette,
|
||||
int palette_id);
|
||||
|
||||
void SetPaletteFromPaletteGroup(const SnesPalette &palette, int palette_id);
|
||||
|
||||
/**
|
||||
* @brief Set the palette using SDL colors
|
||||
*/
|
||||
@@ -164,7 +162,7 @@ class Bitmap {
|
||||
* @brief Write a value to a pixel at the given position
|
||||
*/
|
||||
void WriteToPixel(int position, uint8_t value);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Write a color to a pixel at the given position
|
||||
*/
|
||||
@@ -187,23 +185,23 @@ class Bitmap {
|
||||
* @brief Clean up the bitmap resources
|
||||
*/
|
||||
void Cleanup();
|
||||
|
||||
|
||||
/**
|
||||
* @brief Clear the bitmap data
|
||||
*/
|
||||
void Clear();
|
||||
|
||||
const SnesPalette& palette() const { return palette_; }
|
||||
SnesPalette* mutable_palette() { return &palette_; }
|
||||
const SnesPalette &palette() const { return palette_; }
|
||||
SnesPalette *mutable_palette() { return &palette_; }
|
||||
int width() const { return width_; }
|
||||
int height() const { return height_; }
|
||||
int depth() const { return depth_; }
|
||||
int size() const { return data_size_; }
|
||||
const uint8_t* data() const { return data_.data(); }
|
||||
std::vector<uint8_t>& mutable_data() { return data_; }
|
||||
SDL_Surface* surface() const { return surface_.get(); }
|
||||
SDL_Texture* texture() const { return texture_.get(); }
|
||||
const std::vector<uint8_t>& vector() const { return data_; }
|
||||
const uint8_t *data() const { return data_.data(); }
|
||||
std::vector<uint8_t> &mutable_data() { return data_; }
|
||||
SDL_Surface *surface() const { return surface_.get(); }
|
||||
SDL_Texture *texture() const { return texture_.get(); }
|
||||
const std::vector<uint8_t> &vector() const { return data_; }
|
||||
uint8_t at(int i) const { return data_[i]; }
|
||||
bool modified() const { return modified_; }
|
||||
bool is_active() const { return active_; }
|
||||
@@ -233,7 +231,7 @@ class Bitmap {
|
||||
// Track the last time this texture was used
|
||||
uint64_t last_used_time_ = 0;
|
||||
|
||||
// Pointer to the texture pixels
|
||||
// Pointer to the texture pixels
|
||||
void *texture_pixels = nullptr;
|
||||
|
||||
// Pointer to the pixel data
|
||||
@@ -244,7 +242,7 @@ class Bitmap {
|
||||
|
||||
// Data for the bitmap
|
||||
std::vector<uint8_t> data_;
|
||||
|
||||
|
||||
// Surface for the bitmap
|
||||
std::shared_ptr<SDL_Surface> surface_ = nullptr;
|
||||
|
||||
@@ -271,12 +269,12 @@ Uint32 GetSnesPixelFormat(int format);
|
||||
/**
|
||||
* @brief Allocate an SDL surface with the given dimensions and format
|
||||
*/
|
||||
SDL_Surface* AllocateSurface(int width, int height, int depth, Uint32 format);
|
||||
SDL_Surface *AllocateSurface(int width, int height, int depth, Uint32 format);
|
||||
|
||||
/**
|
||||
* @brief Allocate an SDL texture with the given dimensions and format
|
||||
*/
|
||||
SDL_Texture* AllocateTexture(SDL_Renderer *renderer, Uint32 format, int access,
|
||||
SDL_Texture *AllocateTexture(SDL_Renderer *renderer, Uint32 format, int access,
|
||||
int width, int height);
|
||||
|
||||
} // namespace gfx
|
||||
|
||||
@@ -220,52 +220,6 @@ uint32_t GetPaletteAddress(const std::string &group_name, size_t palette_index,
|
||||
return address;
|
||||
}
|
||||
|
||||
SnesPalette::SnesPalette(char *data) {
|
||||
assert((sizeof(data) % 4 == 0) && (sizeof(data) <= 32));
|
||||
for (unsigned i = 0; i < sizeof(data); i += 2) {
|
||||
SnesColor col;
|
||||
col.set_snes(static_cast<uint8_t>(data[i + 1]) << 8);
|
||||
col.set_snes(col.snes() | static_cast<uint8_t>(data[i]));
|
||||
snes_color mColor = ConvertSnesToRgb(col.snes());
|
||||
col.set_rgb(ImVec4(mColor.red, mColor.green, mColor.blue, 1.f));
|
||||
colors.push_back(col);
|
||||
}
|
||||
}
|
||||
|
||||
SnesPalette::SnesPalette(const unsigned char *snes_pal) {
|
||||
assert((sizeof(snes_pal) % 4 == 0) && (sizeof(snes_pal) <= 32));
|
||||
for (unsigned i = 0; i < sizeof(snes_pal); i += 2) {
|
||||
SnesColor col;
|
||||
col.set_snes(snes_pal[i + 1] << (uint16_t)8);
|
||||
col.set_snes(col.snes() | snes_pal[i]);
|
||||
snes_color mColor = ConvertSnesToRgb(col.snes());
|
||||
col.set_rgb(ImVec4(mColor.red, mColor.green, mColor.blue, 1.f));
|
||||
colors.push_back(col);
|
||||
}
|
||||
}
|
||||
|
||||
SnesPalette::SnesPalette(const std::vector<ImVec4> &cols) {
|
||||
for (const auto &each : cols) {
|
||||
SnesColor scol;
|
||||
scol.set_rgb(each);
|
||||
colors.push_back(scol);
|
||||
}
|
||||
}
|
||||
|
||||
SnesPalette::SnesPalette(const std::vector<snes_color> &cols) {
|
||||
for (const auto &each : cols) {
|
||||
SnesColor scol;
|
||||
scol.set_snes(ConvertRgbToSnes(each));
|
||||
colors.push_back(scol);
|
||||
}
|
||||
}
|
||||
|
||||
SnesPalette::SnesPalette(const std::vector<SnesColor> &cols) {
|
||||
for (const auto &each : cols) {
|
||||
colors.push_back(each);
|
||||
}
|
||||
}
|
||||
|
||||
SnesPalette ReadPaletteFromRom(int offset, int num_colors, const uint8_t *rom) {
|
||||
int color_offset = 0;
|
||||
std::vector<gfx::SnesColor> colors(num_colors);
|
||||
@@ -302,7 +256,7 @@ absl::StatusOr<PaletteGroup> CreatePaletteGroupFromColFile(
|
||||
for (int i = 0; i < palette_rows.size(); i += 8) {
|
||||
SnesPalette palette;
|
||||
for (int j = 0; j < 8; j++) {
|
||||
palette.AddColor(palette_rows[i + j].rom_color());
|
||||
palette.AddColor(palette_rows[i + j]);
|
||||
}
|
||||
palette_group.AddPalette(palette);
|
||||
}
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
#ifndef YAZE_APP_GFX_PALETTE_H
|
||||
#define YAZE_APP_GFX_PALETTE_H
|
||||
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/status/status.h"
|
||||
@@ -48,7 +50,7 @@ static constexpr absl::string_view kPaletteGroupNames[] = {
|
||||
"sprites_aux3", "dungeon_main", "ow_mini_map", "ow_mini_map",
|
||||
"3d_object", "3d_object"};
|
||||
|
||||
constexpr const char *kPaletteGroupAddressesKeys[] = {
|
||||
constexpr const char* kPaletteGroupAddressesKeys[] = {
|
||||
"ow_main", "ow_aux", "ow_animated", "hud",
|
||||
"global_sprites", "armors", "swords", "shields",
|
||||
"sprites_aux1", "sprites_aux2", "sprites_aux3", "dungeon_main",
|
||||
@@ -107,7 +109,7 @@ constexpr int OverworldGrassPalettesMax = 3;
|
||||
constexpr int Object3DPalettesMax = 2;
|
||||
constexpr int OverworldMiniMapPalettesMax = 2;
|
||||
|
||||
uint32_t GetPaletteAddress(const std::string &group_name, size_t palette_index,
|
||||
uint32_t GetPaletteAddress(const std::string& group_name, size_t palette_index,
|
||||
size_t color_index);
|
||||
|
||||
/**
|
||||
@@ -118,94 +120,118 @@ uint32_t GetPaletteAddress(const std::string &group_name, size_t palette_index,
|
||||
* colors in an SNES palette. It supports various constructors to initialize the
|
||||
* palette with different types of data. The palette can be modified by adding
|
||||
* or changing colors, and it can be cleared to remove all colors. Colors in the
|
||||
* palette can be accessed using index-based access or through the `GetColor`
|
||||
* method. The class also provides a method to create a sub-palette by selecting
|
||||
* a range of colors from the original palette.
|
||||
* palette can be accessed using index-based access. The class also provides a
|
||||
* method to create a sub-palette by selecting a range of colors from the
|
||||
* original palette.
|
||||
*/
|
||||
class SnesPalette {
|
||||
public:
|
||||
template <typename T>
|
||||
explicit SnesPalette(const std::vector<T> &data) {
|
||||
for (const auto &item : data) {
|
||||
colors.emplace_back(SnesColor(item));
|
||||
static constexpr size_t kMaxColors = 256;
|
||||
using ColorArray = std::array<SnesColor, kMaxColors>;
|
||||
|
||||
// Default constructor
|
||||
SnesPalette() : size_(0) {}
|
||||
|
||||
// Constructor from vector of uint16_t (SNES color values)
|
||||
explicit SnesPalette(const std::vector<uint16_t>& colors) : size_(0) {
|
||||
for (const auto& color : colors) {
|
||||
if (size_ < kMaxColors) {
|
||||
colors_[size_++] = SnesColor(color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SnesPalette() = default;
|
||||
explicit SnesPalette(char *snesPal);
|
||||
explicit SnesPalette(const unsigned char *snes_pal);
|
||||
explicit SnesPalette(const std::vector<ImVec4> &);
|
||||
explicit SnesPalette(const std::vector<snes_color> &);
|
||||
explicit SnesPalette(const std::vector<SnesColor> &);
|
||||
|
||||
void Create(const std::vector<SnesColor> &cols) {
|
||||
for (const auto &each : cols) {
|
||||
colors.emplace_back(each);
|
||||
// Constructor from vector of SnesColor
|
||||
explicit SnesPalette(const std::vector<SnesColor>& colors) : size_(0) {
|
||||
for (const auto& color : colors) {
|
||||
if (size_ < kMaxColors) {
|
||||
colors_[size_++] = color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Create(std::ranges::range auto &&cols) {
|
||||
std::copy(cols.begin(), cols.end(), std::back_inserter(colors));
|
||||
}
|
||||
|
||||
void AddColor(const SnesColor &color) { colors.emplace_back(color); }
|
||||
void AddColor(const snes_color &color) { colors.emplace_back(color); }
|
||||
void AddColor(uint16_t color) { colors.emplace_back(color); }
|
||||
|
||||
absl::StatusOr<SnesColor> GetColor(int i) const {
|
||||
if (i > colors.size()) {
|
||||
return absl::InvalidArgumentError("SnesPalette: Index out of bounds");
|
||||
// Constructor from raw SNES palette data
|
||||
explicit SnesPalette(const char* data, size_t length) : size_(0) {
|
||||
for (size_t i = 0; i < length && size_ < kMaxColors; i += 2) {
|
||||
uint16_t color = (static_cast<uint8_t>(data[i + 1]) << 8) |
|
||||
static_cast<uint8_t>(data[i]);
|
||||
colors_[size_++] = SnesColor(color);
|
||||
}
|
||||
return colors[i];
|
||||
}
|
||||
|
||||
auto mutable_color(int i) { return &colors[i]; }
|
||||
|
||||
void clear() { colors.clear(); }
|
||||
auto size() const { return colors.size(); }
|
||||
auto empty() const { return colors.empty(); }
|
||||
auto begin() { return colors.begin(); }
|
||||
auto end() { return colors.end(); }
|
||||
|
||||
SnesColor &operator[](int i) {
|
||||
if (i > colors.size()) {
|
||||
std::cout << "SNESPalette: Index out of bounds" << std::endl;
|
||||
return colors[0];
|
||||
// Constructor from ImVec4 colors
|
||||
explicit SnesPalette(const std::vector<ImVec4>& colors) : size_(0) {
|
||||
for (const auto& color : colors) {
|
||||
if (size_ < kMaxColors) {
|
||||
colors_[size_++] = SnesColor(color);
|
||||
}
|
||||
}
|
||||
return colors[i];
|
||||
}
|
||||
|
||||
void operator()(int i, const SnesColor &color) {
|
||||
if (i >= colors.size()) {
|
||||
std::cout << "SNESPalette: Index out of bounds" << std::endl;
|
||||
const SnesColor& operator[](size_t index) const { return colors_[index]; }
|
||||
|
||||
SnesColor& operator[](size_t index) { return colors_[index]; }
|
||||
|
||||
size_t size() const { return size_; }
|
||||
bool empty() const { return size_ == 0; }
|
||||
|
||||
// Iterators
|
||||
auto begin() { return colors_.begin(); }
|
||||
auto end() { return colors_.begin() + size_; }
|
||||
auto begin() const { return colors_.begin(); }
|
||||
auto end() const { return colors_.begin() + size_; }
|
||||
|
||||
// Color manipulation
|
||||
void AddColor(const SnesColor& color) {
|
||||
if (size_ < kMaxColors) {
|
||||
colors_[size_++] = color;
|
||||
}
|
||||
colors[i] = color;
|
||||
}
|
||||
|
||||
void operator()(int i, const ImVec4 &color) {
|
||||
if (i >= colors.size()) {
|
||||
std::cout << "SNESPalette: Index out of bounds" << std::endl;
|
||||
return;
|
||||
void UpdateColor(size_t index, const SnesColor& color) {
|
||||
if (index < size_) {
|
||||
colors_[index] = color;
|
||||
}
|
||||
colors[i].set_rgb(color);
|
||||
colors[i].set_modified(true);
|
||||
}
|
||||
|
||||
SnesPalette sub_palette(int start, int end) const {
|
||||
SnesPalette pal;
|
||||
for (int i = start; i < end; i++) {
|
||||
pal.AddColor(colors[i]);
|
||||
void clear() { size_ = 0; }
|
||||
|
||||
// Sub-palette creation
|
||||
SnesPalette sub_palette(size_t start, size_t length) const {
|
||||
SnesPalette result;
|
||||
if (start >= size_) {
|
||||
return result;
|
||||
}
|
||||
return pal;
|
||||
length = std::min(length, size_ - start);
|
||||
for (size_t i = 0; i < length; ++i) {
|
||||
result.AddColor(colors_[start + i]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// Comparison operators
|
||||
bool operator==(const SnesPalette& other) const {
|
||||
if (size_ != other.size_) {
|
||||
return false;
|
||||
}
|
||||
for (size_t i = 0; i < size_; ++i) {
|
||||
if (colors_[i].snes() != other.colors_[i].snes()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool operator!=(const SnesPalette& other) const { return !(*this == other); }
|
||||
|
||||
private:
|
||||
std::vector<SnesColor> colors; /**< The colors in the palette. */
|
||||
ColorArray colors_;
|
||||
size_t size_;
|
||||
};
|
||||
|
||||
SnesPalette ReadPaletteFromRom(int offset, int num_colors, const uint8_t *rom);
|
||||
SnesPalette ReadPaletteFromRom(int offset, int num_colors, const uint8_t* rom);
|
||||
|
||||
std::array<float, 4> ToFloatArray(const SnesColor &color);
|
||||
std::array<float, 4> ToFloatArray(const SnesColor& color);
|
||||
|
||||
/**
|
||||
* @brief Represents a group of palettes.
|
||||
@@ -215,7 +241,7 @@ std::array<float, 4> ToFloatArray(const SnesColor &color);
|
||||
*/
|
||||
struct PaletteGroup {
|
||||
PaletteGroup() = default;
|
||||
PaletteGroup(const std::string &name) : name_(name) {}
|
||||
PaletteGroup(const std::string& name) : name_(name) {}
|
||||
|
||||
void AddPalette(SnesPalette pal) { palettes.emplace_back(pal); }
|
||||
|
||||
@@ -240,7 +266,7 @@ struct PaletteGroup {
|
||||
return palettes[i];
|
||||
}
|
||||
|
||||
const SnesPalette &operator[](int i) const {
|
||||
const SnesPalette& operator[](int i) const {
|
||||
if (i > palettes.size()) {
|
||||
std::cout << "PaletteGroup: Index out of bounds" << std::endl;
|
||||
return palettes[0];
|
||||
@@ -277,7 +303,7 @@ struct PaletteGroupMap {
|
||||
PaletteGroup object_3d = {kPaletteGroupAddressesKeys[13]};
|
||||
PaletteGroup overworld_mini_map = {kPaletteGroupAddressesKeys[14]};
|
||||
|
||||
auto get_group(const std::string &group_name) {
|
||||
auto get_group(const std::string& group_name) {
|
||||
if (group_name == "ow_main") {
|
||||
return &overworld_main;
|
||||
} else if (group_name == "ow_aux") {
|
||||
@@ -314,7 +340,7 @@ struct PaletteGroupMap {
|
||||
}
|
||||
|
||||
template <typename Func>
|
||||
absl::Status for_each(Func &&func) {
|
||||
absl::Status for_each(Func&& func) {
|
||||
RETURN_IF_ERROR(func(overworld_aux));
|
||||
RETURN_IF_ERROR(func(overworld_animated));
|
||||
RETURN_IF_ERROR(func(hud));
|
||||
@@ -363,13 +389,13 @@ struct PaletteGroupMap {
|
||||
};
|
||||
|
||||
absl::StatusOr<PaletteGroup> CreatePaletteGroupFromColFile(
|
||||
std::vector<SnesColor> &colors);
|
||||
std::vector<SnesColor>& colors);
|
||||
|
||||
/**
|
||||
* @brief Take a SNESPalette, divide it into palettes of 8 colors
|
||||
*/
|
||||
absl::StatusOr<PaletteGroup> CreatePaletteGroupFromLargePalette(
|
||||
SnesPalette &palette, int num_colors = 8);
|
||||
SnesPalette& palette, int num_colors = 8);
|
||||
|
||||
/**
|
||||
* @brief Loads all the palettes for the game.
|
||||
@@ -380,8 +406,8 @@ absl::StatusOr<PaletteGroup> CreatePaletteGroupFromLargePalette(
|
||||
* groups.
|
||||
*
|
||||
*/
|
||||
absl::Status LoadAllPalettes(const std::vector<uint8_t> &rom_data,
|
||||
PaletteGroupMap &groups);
|
||||
absl::Status LoadAllPalettes(const std::vector<uint8_t>& rom_data,
|
||||
PaletteGroupMap& groups);
|
||||
|
||||
/**
|
||||
* @brief Represents a set of palettes used in a SNES graphics system.
|
||||
|
||||
Reference in New Issue
Block a user