fix(editor): update message preview bitmap depth to 8-bit indexed format
- Changed the bitmap depth for message previews from 64 to 8 to support indexed palette mode. - Updated logging to reflect the new depth in message preview creation. - Enhanced Bitmap class with a new method to update surface pixels, ensuring proper pixel data handling in rendering. Benefits: - Improves compatibility with indexed palette formats in message rendering. - Enhances the clarity of logging for bitmap creation processes.
This commit is contained in:
@@ -419,14 +419,14 @@ void MessageEditor::DrawMessagePreview() {
|
|||||||
LOG_DEBUG("MessageEditor", "Updated message preview bitmap (size: %zu) and queued texture update",
|
LOG_DEBUG("MessageEditor", "Updated message preview bitmap (size: %zu) and queued texture update",
|
||||||
message_preview_.current_preview_data_.size());
|
message_preview_.current_preview_data_.size());
|
||||||
} else {
|
} else {
|
||||||
// Create bitmap and queue texture creation
|
// Create bitmap and queue texture creation with 8-bit indexed depth
|
||||||
current_font_gfx16_bitmap_.Create(kCurrentMessageWidth, kCurrentMessageHeight,
|
current_font_gfx16_bitmap_.Create(kCurrentMessageWidth, kCurrentMessageHeight,
|
||||||
64, message_preview_.current_preview_data_);
|
8, message_preview_.current_preview_data_);
|
||||||
current_font_gfx16_bitmap_.SetPalette(font_preview_colors_);
|
current_font_gfx16_bitmap_.SetPalette(font_preview_colors_);
|
||||||
gfx::Arena::Get().QueueTextureCommand(
|
gfx::Arena::Get().QueueTextureCommand(
|
||||||
gfx::Arena::TextureCommandType::CREATE, ¤t_font_gfx16_bitmap_);
|
gfx::Arena::TextureCommandType::CREATE, ¤t_font_gfx16_bitmap_);
|
||||||
|
|
||||||
LOG_INFO("MessageEditor", "Created message preview bitmap (%dx%d) and queued texture creation",
|
LOG_INFO("MessageEditor", "Created message preview bitmap (%dx%d) with 8-bit depth and queued texture creation",
|
||||||
kCurrentMessageWidth, kCurrentMessageHeight);
|
kCurrentMessageWidth, kCurrentMessageHeight);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ constexpr int kGfxFont = 0x70000; // 2bpp format
|
|||||||
constexpr int kCharactersWidth = 0x74ADF;
|
constexpr int kCharactersWidth = 0x74ADF;
|
||||||
constexpr int kNumMessages = 396;
|
constexpr int kNumMessages = 396;
|
||||||
constexpr int kFontGfxMessageSize = 128;
|
constexpr int kFontGfxMessageSize = 128;
|
||||||
constexpr int kFontGfxMessageDepth = 64;
|
constexpr int kFontGfxMessageDepth = 8; // Fixed: Must be 8 for indexed palette mode
|
||||||
constexpr int kFontGfx16Size = 172 * 4096;
|
constexpr int kFontGfx16Size = 172 * 4096;
|
||||||
|
|
||||||
constexpr uint8_t kBlockTerminator = 0x80;
|
constexpr uint8_t kBlockTerminator = 0x80;
|
||||||
|
|||||||
@@ -269,8 +269,8 @@ void Bitmap::ApplyStoredPalette() {
|
|||||||
if (surface_ == nullptr) {
|
if (surface_ == nullptr) {
|
||||||
return; // Can't apply without surface
|
return; // Can't apply without surface
|
||||||
}
|
}
|
||||||
if (surface_->format == nullptr || surface_->format->palette == nullptr) {
|
if (surface_->format == nullptr) {
|
||||||
return; // Can't apply palette to this surface format
|
return; // Invalid surface format
|
||||||
}
|
}
|
||||||
if (palette_.empty()) {
|
if (palette_.empty()) {
|
||||||
return; // No palette to apply
|
return; // No palette to apply
|
||||||
@@ -279,36 +279,58 @@ void Bitmap::ApplyStoredPalette() {
|
|||||||
// Invalidate palette cache when palette changes
|
// Invalidate palette cache when palette changes
|
||||||
InvalidatePaletteCache();
|
InvalidatePaletteCache();
|
||||||
|
|
||||||
|
// For indexed surfaces, ensure palette exists
|
||||||
SDL_Palette *sdl_palette = surface_->format->palette;
|
SDL_Palette *sdl_palette = surface_->format->palette;
|
||||||
if (sdl_palette == nullptr) {
|
if (sdl_palette == nullptr) {
|
||||||
|
// Non-indexed surface or palette not created - can't apply palette
|
||||||
|
SDL_Log("Warning: Bitmap surface has no palette (non-indexed format?)\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_UnlockSurface(surface_);
|
SDL_UnlockSurface(surface_);
|
||||||
|
|
||||||
// Apply all palette colors from the SnesPalette
|
// Build SDL color array from SnesPalette
|
||||||
for (size_t i = 0; i < palette_.size() && i < 256; ++i) {
|
// Only set the colors that exist in the palette - don't fill unused entries
|
||||||
|
std::vector<SDL_Color> colors(palette_.size());
|
||||||
|
for (size_t i = 0; i < palette_.size(); ++i) {
|
||||||
const auto& pal_color = palette_[i];
|
const auto& pal_color = palette_[i];
|
||||||
|
|
||||||
// Get RGB values - stored as 0-255 in ImVec4 (unconventional!)
|
// Get RGB values - stored as 0-255 in ImVec4 (unconventional!)
|
||||||
ImVec4 rgb_255 = pal_color.rgb();
|
ImVec4 rgb_255 = pal_color.rgb();
|
||||||
|
|
||||||
sdl_palette->colors[i].r = static_cast<Uint8>(rgb_255.x);
|
colors[i].r = static_cast<Uint8>(rgb_255.x);
|
||||||
sdl_palette->colors[i].g = static_cast<Uint8>(rgb_255.y);
|
colors[i].g = static_cast<Uint8>(rgb_255.y);
|
||||||
sdl_palette->colors[i].b = static_cast<Uint8>(rgb_255.z);
|
colors[i].b = static_cast<Uint8>(rgb_255.z);
|
||||||
|
|
||||||
// Only apply transparency if explicitly set
|
// Only apply transparency if explicitly set
|
||||||
// (ROM data won't have this set; transparency is added during rendering)
|
|
||||||
if (pal_color.is_transparent()) {
|
if (pal_color.is_transparent()) {
|
||||||
sdl_palette->colors[i].a = 0; // Fully transparent
|
colors[i].a = 0; // Fully transparent
|
||||||
} else {
|
} else {
|
||||||
sdl_palette->colors[i].a = 255; // Fully opaque
|
colors[i].a = 255; // Fully opaque
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Apply palette to surface using SDL_SetPaletteColors
|
||||||
|
// Only set the colors we have - leave rest of palette unchanged
|
||||||
|
// This prevents breaking systems that use small palettes (8-16 colors)
|
||||||
|
SDL_SetPaletteColors(sdl_palette, colors.data(), 0, static_cast<int>(palette_.size()));
|
||||||
|
|
||||||
SDL_LockSurface(surface_);
|
SDL_LockSurface(surface_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Bitmap::UpdateSurfacePixels() {
|
||||||
|
if (!surface_ || data_.empty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy pixel data from data_ vector to SDL surface
|
||||||
|
SDL_LockSurface(surface_);
|
||||||
|
if (surface_->pixels && data_.size() > 0) {
|
||||||
|
memcpy(surface_->pixels, data_.data(), std::min(data_.size(), static_cast<size_t>(surface_->pitch * surface_->h)));
|
||||||
|
}
|
||||||
|
SDL_UnlockSurface(surface_);
|
||||||
|
}
|
||||||
|
|
||||||
void Bitmap::SetPalette(const SnesPalette &palette) {
|
void Bitmap::SetPalette(const SnesPalette &palette) {
|
||||||
// Store palette even if surface isn't ready yet
|
// Store palette even if surface isn't ready yet
|
||||||
palette_ = palette;
|
palette_ = palette;
|
||||||
|
|||||||
@@ -177,6 +177,12 @@ class Bitmap {
|
|||||||
* @brief Apply the stored palette to the surface (internal helper)
|
* @brief Apply the stored palette to the surface (internal helper)
|
||||||
*/
|
*/
|
||||||
void ApplyStoredPalette();
|
void ApplyStoredPalette();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Update SDL surface with current pixel data from data_ vector
|
||||||
|
* Call this after modifying pixel data via mutable_data()
|
||||||
|
*/
|
||||||
|
void UpdateSurfacePixels();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Set the palette using SDL colors
|
* @brief Set the palette using SDL colors
|
||||||
|
|||||||
@@ -218,6 +218,9 @@ absl::Status OverworldMapScreen::RenderMapLayer(bool use_dark_world) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update surface with rendered pixel data
|
||||||
|
map_bitmap_.UpdateSurfacePixels();
|
||||||
|
|
||||||
// Apply appropriate palette
|
// Apply appropriate palette
|
||||||
map_bitmap_.SetPalette(use_dark_world ? dw_palette_ : lw_palette_);
|
map_bitmap_.SetPalette(use_dark_world ? dw_palette_ : lw_palette_);
|
||||||
|
|
||||||
|
|||||||
@@ -279,6 +279,9 @@ absl::Status TitleScreen::RenderBG1Layer() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update surface with rendered pixel data
|
||||||
|
tiles_bg1_bitmap_.UpdateSurfacePixels();
|
||||||
|
|
||||||
return absl::OkStatus();
|
return absl::OkStatus();
|
||||||
}
|
}
|
||||||
@@ -332,6 +335,9 @@ absl::Status TitleScreen::RenderBG2Layer() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update surface with rendered pixel data
|
||||||
|
tiles_bg2_bitmap_.UpdateSurfacePixels();
|
||||||
|
|
||||||
return absl::OkStatus();
|
return absl::OkStatus();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user