yaze 0.2.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
bitmap.cc
Go to the documentation of this file.
1#include "bitmap.h"
2
3#include <SDL.h>
4#if YAZE_LIB_PNG == 1
5#include <png.h>
6#endif
7
8#include <cstdint>
9#include <future>
10#include <memory>
11
16
17namespace yaze {
18namespace gfx {
19
21
22#if YAZE_LIB_PNG == 1
23
24namespace png_internal {
25
26void PngWriteCallback(png_structp png_ptr, png_bytep data, png_size_t length) {
27 std::vector<uint8_t> *p = (std::vector<uint8_t> *)png_get_io_ptr(png_ptr);
28 p->insert(p->end(), data, data + length);
29}
30
31void PngReadCallback(png_structp png_ptr, png_bytep outBytes,
32 png_size_t byteCountToRead) {
33 png_voidp io_ptr = png_get_io_ptr(png_ptr);
34 if (!io_ptr) return;
35
36 std::vector<uint8_t> *png_data =
37 reinterpret_cast<std::vector<uint8_t> *>(io_ptr);
38 static size_t pos = 0; // Position to read from
39
40 if (pos + byteCountToRead <= png_data->size()) {
41 memcpy(outBytes, png_data->data() + pos, byteCountToRead);
42 pos += byteCountToRead;
43 } else {
44 png_error(png_ptr, "Read error in PngReadCallback");
45 }
46}
47
48} // namespace png_internal
49
50bool ConvertSurfaceToPng(SDL_Surface *surface, std::vector<uint8_t> &buffer) {
51 png_structp png_ptr = png_create_write_struct("1.6.40", NULL, NULL, NULL);
52 if (!png_ptr) {
53 SDL_Log("Failed to create PNG write struct");
54 return false;
55 }
56
57 png_infop info_ptr = png_create_info_struct(png_ptr);
58 if (!info_ptr) {
59 png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
60 SDL_Log("Failed to create PNG info struct");
61 return false;
62 }
63
64 if (setjmp(png_jmpbuf(png_ptr))) {
65 png_destroy_write_struct(&png_ptr, &info_ptr);
66 SDL_Log("Error during PNG write");
67 return false;
68 }
69
70 png_set_write_fn(png_ptr, &buffer, png_internal::PngWriteCallback, NULL);
71
72 png_colorp pal_ptr;
73
74 /* Prepare chunks */
75 int colortype = PNG_COLOR_MASK_COLOR;
76 int i = 0;
77 SDL_Palette *pal;
78 if (surface->format->BytesPerPixel > 0 &&
79 surface->format->BytesPerPixel <= 8 && (pal = surface->format->palette)) {
80 SDL_Log("Writing PNG image with palette");
81 colortype |= PNG_COLOR_MASK_PALETTE;
82 pal_ptr = (png_colorp)malloc(pal->ncolors * sizeof(png_color));
83 for (i = 0; i < pal->ncolors; i++) {
84 pal_ptr[i].red = pal->colors[i].r;
85 pal_ptr[i].green = pal->colors[i].g;
86 pal_ptr[i].blue = pal->colors[i].b;
87 }
88 png_set_PLTE(png_ptr, info_ptr, pal_ptr, pal->ncolors);
89 free(pal_ptr);
90 }
91
92 if (surface->format->Amask) { // Check for alpha channel
93 colortype |= PNG_COLOR_MASK_ALPHA;
94 }
95
96 auto depth = surface->format->BitsPerPixel;
97
98 // Set image attributes.
99 png_set_IHDR(png_ptr, info_ptr, surface->w, surface->h, depth, colortype,
100 PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT,
101 PNG_FILTER_TYPE_DEFAULT);
102
103 png_set_bgr(png_ptr);
104
105 // Write the image data.
106 std::vector<png_bytep> row_pointers(surface->h);
107 for (int y = 0; y < surface->h; ++y) {
108 row_pointers[y] = (png_bytep)(surface->pixels) + y * surface->pitch;
109 }
110
111 png_set_rows(png_ptr, info_ptr, row_pointers.data());
112
113 SDL_Log("Writing PNG image...");
114 png_write_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, NULL);
115 SDL_Log("PNG image write complete");
116
117 png_destroy_write_struct(&png_ptr, &info_ptr);
118
119 return true;
120}
121
122void ConvertPngToSurface(const std::vector<uint8_t> &png_data,
123 SDL_Surface **outSurface) {
124 std::vector<uint8_t> data(png_data);
125 png_structp png_ptr = png_create_read_struct("1.6.40", NULL, NULL, NULL);
126 if (!png_ptr) {
127 throw std::runtime_error("Failed to create PNG read struct");
128 }
129
130 png_infop info_ptr = png_create_info_struct(png_ptr);
131 if (!info_ptr) {
132 png_destroy_read_struct(&png_ptr, NULL, NULL);
133 throw std::runtime_error("Failed to create PNG info struct");
134 }
135
136 if (setjmp(png_jmpbuf(png_ptr))) {
137 png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
138 throw std::runtime_error("Error during PNG read");
139 }
140
141 // Set our custom read function
142 png_set_read_fn(png_ptr, &data, png_internal::PngReadCallback);
143
144 // Read the PNG info
145 png_read_info(png_ptr, info_ptr);
146
147 uint32_t width = png_get_image_width(png_ptr, info_ptr);
148 uint32_t height = png_get_image_height(png_ptr, info_ptr);
149 png_byte color_type = png_get_color_type(png_ptr, info_ptr);
150 png_byte bit_depth = png_get_bit_depth(png_ptr, info_ptr);
151
152 // Apply necessary transformations...
153 // (Same as in your existing code)
154
155 // Update info structure with transformations
156 png_read_update_info(png_ptr, info_ptr);
157
158 // Read the file
159 std::vector<uint8_t> raw_data(width * height *
160 4); // Assuming 4 bytes per pixel (RGBA)
161 std::vector<png_bytep> row_pointers(height);
162 for (size_t y = 0; y < height; y++) {
163 row_pointers[y] = raw_data.data() + y * width * 4;
164 }
165
166 png_read_image(png_ptr, row_pointers.data());
167 png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
168
169 // Create an SDL_Surface
170 *outSurface = SDL_CreateRGBSurfaceWithFormat(0, width, height, 32,
171 SDL_PIXELFORMAT_RGBA32);
172 if (*outSurface == nullptr) {
173 SDL_Log("SDL_CreateRGBSurfaceWithFormat failed: %s\n", SDL_GetError());
174 return;
175 }
176
177 // Copy the raw data into the SDL_Surface
178 SDL_LockSurface(*outSurface);
179 memcpy((*outSurface)->pixels, raw_data.data(), raw_data.size());
180 SDL_UnlockSurface(*outSurface);
181
182 SDL_Log("Successfully created SDL_Surface from PNG data");
183}
184
185#endif // YAZE_LIB_PNG
186
187// Utility functions
188Uint32 GetSnesPixelFormat(int format) {
189 switch (format) {
190 case 0:
191 return SDL_PIXELFORMAT_INDEX8;
192 case 1:
194 case 2:
196 case 3:
198 }
199 return SDL_PIXELFORMAT_INDEX8;
200}
201
202// Custom allocator for SDL_Surface
203SDL_Surface *AllocateSurface(int width, int height, int depth, Uint32 format) {
204 SDL_Surface *surface =
205 SDL_CreateRGBSurfaceWithFormat(0, width, height, depth, format);
206 if (surface) {
208 surface, width * height * (depth / 8), "SDL_Surface");
209 }
210 return surface;
211}
212
213// Custom allocator for SDL_Texture
214SDL_Texture *AllocateTexture(SDL_Renderer *renderer, Uint32 format, int access,
215 int width, int height) {
216 SDL_Texture *texture =
217 SDL_CreateTexture(renderer, format, access, width, height);
218 if (texture) {
219 // Estimate size (this is approximate)
220 size_t estimated_size = width * height * 4; // Assume 4 bytes per pixel
221 core::MemoryTracker::GetInstance().TrackAllocation(texture, estimated_size,
222 "SDL_Texture");
223 }
224 return texture;
225}
226
227// Bitmap class implementation
229 const std::vector<uint8_t> &data)
232}
233
235 const std::vector<uint8_t> &data, const SnesPalette &palette)
236 : width_(width),
238 depth_(depth),
239 data_(data),
243}
244
245void Bitmap::SaveSurfaceToFile(std::string_view filename) {
246 SDL_SaveBMP(surface_.get(), filename.data());
247}
248
250 std::span<uint8_t> &data) {
251 width_ = width;
252 height_ = height;
253 depth_ = depth;
254 data_ = std::vector<uint8_t>(data.begin(), data.end());
255}
256
257void Bitmap::Create(int width, int height, int depth, std::span<uint8_t> data) {
258 data_ = std::vector<uint8_t>(data.begin(), data.end());
260}
261
262void Bitmap::Create(int width, int height, int depth,
263 const std::vector<uint8_t> &data) {
264 Create(width, height, depth, static_cast<int>(BitmapFormat::kIndexed), data);
265}
266
267void Bitmap::Create(int width, int height, int depth, int format,
268 const std::vector<uint8_t> &data) {
269 if (data.empty()) {
270 SDL_Log("Bitmap data is empty\n");
271 active_ = false;
272 return;
273 }
274 active_ = true;
275 width_ = width;
276 height_ = height;
277 depth_ = depth;
278 data_size_ = data.size();
279 if (data_size_ == 0) {
280 SDL_Log("Data provided to Bitmap is empty.\n");
281 return;
282 }
283 data_.reserve(data_size_);
284 data_ = data;
285 pixel_data_ = data_.data();
286 surface_ = std::shared_ptr<SDL_Surface>{
289 if (surface_ == nullptr) {
290 SDL_Log("Bitmap::Create.SDL_CreateRGBSurfaceWithFormat failed: %s\n",
291 SDL_GetError());
292 active_ = false;
293 return;
294 }
295 surface_->pixels = pixel_data_;
296 active_ = true;
297}
298
299void Bitmap::Reformat(int format) {
300 surface_ = std::unique_ptr<SDL_Surface, SDL_Surface_Deleter>(
303 surface_->pixels = pixel_data_;
304 active_ = true;
306}
307
308void Bitmap::UpdateTexture(SDL_Renderer *renderer) {
309 auto converted_surface = std::unique_ptr<SDL_Surface, SDL_Surface_Deleter>(
310 SDL_ConvertSurfaceFormat(surface_.get(), SDL_PIXELFORMAT_ARGB8888, 0),
312 if (converted_surface == nullptr) {
313 SDL_Log("SDL_ConvertSurfaceFormat failed: %s\n", SDL_GetError());
314 }
315
316 SDL_LockTexture(texture_.get(), nullptr, (void **)&texture_pixels,
317 &converted_surface->pitch);
318 memcpy(texture_pixels, converted_surface->pixels,
319 converted_surface->h * converted_surface->pitch);
320 SDL_UnlockTexture(texture_.get());
321}
322
323void Bitmap::CreateTexture(SDL_Renderer *renderer) {
324 if (!renderer) {
325 SDL_Log("Invalid renderer passed to CreateTexture");
326 return;
327 }
328
329 if (width_ <= 0 || height_ <= 0) {
330 SDL_Log("Invalid texture dimensions: width=%d, height=%d\n", width_,
331 height_);
332 return;
333 }
334
335 // If we already have a texture, don't create a new one
336 if (texture_) {
337 texture_in_use_ = true;
338 last_used_time_ = SDL_GetTicks64();
339 return;
340 }
341
342 // Get a texture from the pool
343 SDL_Texture *raw_texture = TexturePool::GetInstance().GetTexture(
344 renderer, width_, height_, SDL_PIXELFORMAT_RGB888);
345
346 if (!raw_texture) {
347 SDL_Log("Bitmap::CreateTexture failed to get texture from pool: %s\n",
348 SDL_GetError());
349 return;
350 }
351
352 // Create a shared_ptr with a custom deleter that returns the texture to the
353 // pool
354 texture_ = std::shared_ptr<SDL_Texture>(raw_texture, [this](SDL_Texture *t) {
355 if (t) {
357 SDL_PIXELFORMAT_RGB888);
358 }
359 });
360
361 texture_in_use_ = true;
362 last_used_time_ = SDL_GetTicks64();
363
365}
366
368 if (!texture_ || !surface_) {
369 return;
370 }
371
372 auto converted_surface = std::unique_ptr<SDL_Surface, SDL_Surface_Deleter>(
373 SDL_ConvertSurfaceFormat(surface_.get(), SDL_PIXELFORMAT_ARGB8888, 0),
375
376 if (converted_surface == nullptr) {
377 SDL_Log("SDL_ConvertSurfaceFormat failed: %s\n", SDL_GetError());
378 return;
379 }
380
381 void *pixels;
382 int pitch;
383 if (SDL_LockTexture(texture_.get(), nullptr, &pixels, &pitch) != 0) {
384 SDL_Log("SDL_LockTexture failed: %s\n", SDL_GetError());
385 return;
386 }
387
388 memcpy(pixels, converted_surface->pixels,
389 converted_surface->h * converted_surface->pitch);
390
391 SDL_UnlockTexture(texture_.get());
392 modified_ = false;
393}
394
395void Bitmap::CleanupUnusedTexture(uint64_t current_time, uint64_t timeout) {
396 if (texture_ && !texture_in_use_ &&
397 (current_time - last_used_time_ > timeout)) {
398 // Release the texture back to the pool
399 texture_ = nullptr;
400 }
401}
402
404 if (surface_ == nullptr) {
405 throw std::runtime_error("Surface is null. Palette not applied");
406 }
407 if (surface_->format == nullptr || surface_->format->palette == nullptr) {
408 throw std::runtime_error(
409 "Surface format or palette is null. Palette not applied.");
410 }
412
413 SDL_Palette *sdl_palette = surface_->format->palette;
414 if (sdl_palette == nullptr) {
415 throw std::runtime_error("Failed to get SDL palette");
416 }
417
418 SDL_UnlockSurface(surface_.get());
419 for (size_t i = 0; i < palette.size(); ++i) {
420 auto pal_color = palette[i];
421 sdl_palette->colors[i].r = pal_color.rgb().x;
422 sdl_palette->colors[i].g = pal_color.rgb().y;
423 sdl_palette->colors[i].b = pal_color.rgb().z;
424 sdl_palette->colors[i].a = pal_color.rgb().w;
425 }
426 SDL_LockSurface(surface_.get());
427}
428
430 int palette_id) {
431 auto start_index = palette_id * 8;
432 palette_ = palette.sub_palette(start_index, start_index + 8);
433 SDL_UnlockSurface(surface_.get());
434 for (size_t i = 0; i < palette_.size(); ++i) {
435 auto pal_color = palette_[i];
436 if (pal_color.is_transparent()) {
437 surface_->format->palette->colors[i].r = 0;
438 surface_->format->palette->colors[i].g = 0;
439 surface_->format->palette->colors[i].b = 0;
440 surface_->format->palette->colors[i].a = 0;
441 } else {
442 surface_->format->palette->colors[i].r = pal_color.rgb().x;
443 surface_->format->palette->colors[i].g = pal_color.rgb().y;
444 surface_->format->palette->colors[i].b = pal_color.rgb().z;
445 surface_->format->palette->colors[i].a = pal_color.rgb().w;
446 }
447 }
448 SDL_LockSurface(surface_.get());
449}
450
452 int length) {
453 if (index < 0 || index >= palette.size()) {
454 throw std::invalid_argument("Invalid palette index");
455 }
456
457 if (length < 0 || length > palette.size()) {
458 throw std::invalid_argument("Invalid palette length");
459 }
460
461 if (index + length > palette.size()) {
462 throw std::invalid_argument("Palette index + length exceeds size");
463 }
464
465 if (surface_ == nullptr) {
466 throw std::runtime_error("Surface is null. Palette not applied");
467 }
468
469 auto start_index = index * 7;
470 palette_ = palette.sub_palette(start_index, start_index + 7);
471 std::vector<ImVec4> colors;
472 colors.push_back(ImVec4(0, 0, 0, 0));
473 for (int i = start_index; i < start_index + 7; ++i) {
474 auto pal_color = palette[i];
475 colors.push_back(pal_color.rgb());
476 }
477
478 SDL_UnlockSurface(surface_.get());
479 int i = 0;
480 for (auto &each : colors) {
481 surface_->format->palette->colors[i].r = each.x;
482 surface_->format->palette->colors[i].g = each.y;
483 surface_->format->palette->colors[i].b = each.z;
484 surface_->format->palette->colors[i].a = each.w;
485 i++;
486 }
487 SDL_LockSurface(surface_.get());
488}
489
490void Bitmap::SetPalette(const std::vector<SDL_Color> &palette) {
491 SDL_UnlockSurface(surface_.get());
492 for (size_t i = 0; i < palette.size(); ++i) {
493 surface_->format->palette->colors[i].r = palette[i].r;
494 surface_->format->palette->colors[i].g = palette[i].g;
495 surface_->format->palette->colors[i].b = palette[i].b;
496 surface_->format->palette->colors[i].a = palette[i].a;
497 }
498 SDL_LockSurface(surface_.get());
499}
500
501void Bitmap::WriteToPixel(int position, uint8_t value) {
502 if (pixel_data_ == nullptr) {
503 pixel_data_ = data_.data();
504 }
505 pixel_data_[position] = value;
506 modified_ = true;
507}
508
509void Bitmap::WriteColor(int position, const ImVec4 &color) {
510 // Convert ImVec4 (RGBA) to SDL_Color (RGBA)
511 SDL_Color sdl_color;
512 sdl_color.r = static_cast<Uint8>(color.x * 255);
513 sdl_color.g = static_cast<Uint8>(color.y * 255);
514 sdl_color.b = static_cast<Uint8>(color.z * 255);
515 sdl_color.a = static_cast<Uint8>(color.w * 255);
516
517 // Map SDL_Color to the nearest color index in the surface's palette
518 Uint8 index =
519 SDL_MapRGB(surface_->format, sdl_color.r, sdl_color.g, sdl_color.b);
520
521 // Write the color index to the pixel data
522 pixel_data_[position] = index;
523 data_[position] = ConvertRgbToSnes(color);
524
525 modified_ = true;
526}
527
528void Bitmap::Get8x8Tile(int tile_index, int x, int y,
529 std::vector<uint8_t> &tile_data,
530 int &tile_data_offset) {
531 int tile_offset = tile_index * (width_ * height_);
532 int tile_x = (x * 8) % width_;
533 int tile_y = (y * 8) % height_;
534 for (int i = 0; i < 8; i++) {
535 for (int j = 0; j < 8; j++) {
536 int pixel_offset = tile_offset + (tile_y + i) * width_ + tile_x + j;
537 int pixel_value = data_[pixel_offset];
538 tile_data[tile_data_offset] = pixel_value;
539 tile_data_offset++;
540 }
541 }
542}
543
544void Bitmap::Get16x16Tile(int tile_x, int tile_y,
545 std::vector<uint8_t> &tile_data,
546 int &tile_data_offset) {
547 for (int ty = 0; ty < 16; ty++) {
548 for (int tx = 0; tx < 16; tx++) {
549 // Calculate the pixel position in the bitmap
550 int pixel_x = tile_x + tx;
551 int pixel_y = tile_y + ty;
552 int pixel_offset = (pixel_y * width_) + pixel_x;
553 int pixel_value = data_[pixel_offset];
554
555 // Store the pixel value in the tile data
556 tile_data[tile_data_offset++] = pixel_value;
557 }
558 }
559}
560
562 active_ = false;
563 width_ = 0;
564 height_ = 0;
565 depth_ = 0;
566 data_size_ = 0;
567 palette_.clear();
568}
569
571 active_ = false;
572 width_ = 0;
573 height_ = 0;
574 depth_ = 0;
575 data_size_ = 0;
576 data_.clear();
577 pixel_data_ = nullptr;
578 texture_pixels = nullptr;
579}
580
581#if YAZE_LIB_PNG == 1
582std::vector<uint8_t> Bitmap::GetPngData() {
583 std::vector<uint8_t> png_data;
584 ConvertSurfaceToPng(surface_.get(), png_data);
585 return png_data;
586}
587#endif
588
589std::vector<gfx::Bitmap> ExtractTile8Bitmaps(const gfx::Bitmap &source_bmp,
590 const gfx::SnesPalette &palette,
591 uint8_t palette_index) {
592 constexpr int kTileCount = 1024;
593 constexpr int kTileSize = 8;
594 std::vector<gfx::Bitmap> tile_bitmaps;
595 tile_bitmaps.reserve(kTileCount);
596
597 std::vector<std::future<gfx::Bitmap>> futures;
598
599 for (int index = 0; index < kTileCount; ++index) {
600 futures.emplace_back(std::async(
601 std::launch::async, [&source_bmp, &palette, palette_index, index]() {
602 std::array<uint8_t, 0x40> tile_data;
603
604 int num_columns = source_bmp.width() / kTileSize;
605
606 for (int ty = 0; ty < kTileSize; ++ty) {
607 for (int tx = 0; tx < kTileSize; ++tx) {
608 int tile_data_pos = tx + (ty * kTileSize);
609 int src_x = (index % num_columns) * kTileSize + tx;
610 int src_y = (index / num_columns) * kTileSize + ty;
611 int gfx_position = src_x + (src_y * 0x100);
612
613 uint8_t value = source_bmp.data()[gfx_position];
614
615 if (value & 0x80) {
616 value -= 0x88;
617 }
618
619 tile_data[tile_data_pos] = value;
620 }
621 }
622
623 gfx::Bitmap tile_bitmap;
624 tile_bitmap.Create(kTileSize, kTileSize, 8, tile_data);
625 tile_bitmap.SetPaletteWithTransparent(palette, palette_index);
626 return tile_bitmap;
627 }));
628 }
629
630 for (auto &future : futures) {
631 tile_bitmaps.push_back(future.get());
632 }
633
634 return tile_bitmaps;
635}
636
637} // namespace gfx
638} // namespace yaze
static MemoryTracker & GetInstance()
void TrackAllocation(const void *ptr, size_t size, const char *type)
Represents a bitmap image.
Definition bitmap.h:66
const uint8_t * data() const
Definition bitmap.h:200
const SnesPalette & palette() const
Definition bitmap.h:194
void WriteToPixel(int position, uint8_t value)
Write a value to a pixel at the given position.
Definition bitmap.cc:501
void Create(int width, int height, int depth, std::span< uint8_t > data)
Create a bitmap with the given dimensions and data.
Definition bitmap.cc:257
void UpdateTexture(SDL_Renderer *renderer)
Updates the underlying SDL_Texture when it already exists.
Definition bitmap.cc:308
void Reformat(int format)
Reformat the bitmap to use a different pixel format.
Definition bitmap.cc:299
uint64_t last_used_time_
Definition bitmap.h:232
uint8_t * pixel_data_
Definition bitmap.h:238
void SetPaletteFromPaletteGroup(const SnesPalette &palette, int palette_id)
Set the palette from a palette group.
Definition bitmap.cc:429
void SaveSurfaceToFile(std::string_view filename)
Save the bitmap surface to a file.
Definition bitmap.cc:245
void Get8x8Tile(int tile_index, int x, int y, std::vector< uint8_t > &tile_data, int &tile_data_offset)
Extract an 8x8 tile from the bitmap.
Definition bitmap.cc:528
void Initialize(int width, int height, int depth, std::span< uint8_t > &data)
Initialize the bitmap with the given dimensions and data.
Definition bitmap.cc:249
void WriteColor(int position, const ImVec4 &color)
Write a color to a pixel at the given position.
Definition bitmap.cc:509
int height() const
Definition bitmap.h:197
std::shared_ptr< SDL_Texture > texture_
Definition bitmap.h:250
void SetPalette(const SnesPalette &palette)
Set the palette for the bitmap.
Definition bitmap.cc:403
int width() const
Definition bitmap.h:196
std::vector< uint8_t > data_
Definition bitmap.h:244
int depth() const
Definition bitmap.h:198
std::shared_ptr< SDL_Surface > surface_
Definition bitmap.h:247
void CreateTexture(SDL_Renderer *renderer)
Creates the underlying SDL_Texture to be displayed.
Definition bitmap.cc:323
void Cleanup()
Clean up the bitmap resources.
Definition bitmap.cc:561
void CleanupUnusedTexture(uint64_t current_time, uint64_t timeout)
Clean up unused textures after a timeout.
Definition bitmap.cc:395
void SetPaletteWithTransparent(const SnesPalette &palette, size_t index, int length=7)
Set the palette with a transparent color.
Definition bitmap.cc:451
void * texture_pixels
Definition bitmap.h:235
bool texture_in_use_
Definition bitmap.h:229
void Get16x16Tile(int tile_x, int tile_y, std::vector< uint8_t > &tile_data, int &tile_data_offset)
Extract a 16x16 tile from the bitmap.
Definition bitmap.cc:544
gfx::SnesPalette palette_
Definition bitmap.h:241
void UpdateTextureData()
Updates the texture data from the surface.
Definition bitmap.cc:367
void Clear()
Clear the bitmap data.
Definition bitmap.cc:570
Represents a palette of colors for the Super Nintendo Entertainment System (SNES).
SDL_Texture * GetTexture(SDL_Renderer *renderer, int width, int height, Uint32 format)
void ReturnTexture(SDL_Texture *texture, int width, int height, Uint32 format)
static TexturePool & GetInstance()
Contains classes for handling graphical data.
Definition bitmap.cc:18
@ kIndexed
Definition bitmap.h:39
uint16_t ConvertRgbToSnes(const snes_color &color)
Definition snes_color.cc:33
constexpr Uint32 SNES_PIXELFORMAT_8BPP
Definition bitmap.h:34
SDL_Texture * AllocateTexture(SDL_Renderer *renderer, Uint32 format, int access, int width, int height)
Allocate an SDL texture with the given dimensions and format.
Definition bitmap.cc:214
constexpr Uint32 SNES_PIXELFORMAT_4BPP
Definition bitmap.h:30
Uint32 GetSnesPixelFormat(int format)
Get the SDL pixel format for a given bitmap format.
Definition bitmap.cc:188
constexpr Uint32 SNES_PIXELFORMAT_2BPP
Definition bitmap.h:26
std::vector< gfx::Bitmap > ExtractTile8Bitmaps(const gfx::Bitmap &source_bmp, const gfx::SnesPalette &palette, uint8_t palette_index)
Extract 8x8 tiles from a source bitmap.
Definition bitmap.cc:589
SDL_Surface * AllocateSurface(int width, int height, int depth, Uint32 format)
Allocate an SDL surface with the given dimensions and format.
Definition bitmap.cc:203
Main namespace for the application.
Definition controller.cc:18