mirror of
https://github.com/RetroDECK/Supermodel.git
synced 2024-11-22 13:55:38 +00:00
Added a -dump-textures option (config key DumpTextures) that writes texture BMP files, one for each known format (12 in all currently)
This commit is contained in:
parent
646b46fd4b
commit
32933ef9b0
|
@ -1087,9 +1087,37 @@ CReal3D::~CReal3D(void)
|
|||
}
|
||||
else
|
||||
printf("unable to dump %s\n", "texram");
|
||||
Util::WriteSurfaceToBMP<Util::A1RGB5>("textures.bmp", reinterpret_cast<uint8_t *>(textureRAM), 2048, 2048, false);
|
||||
#endif
|
||||
|
||||
// Dump textures if requested
|
||||
if (m_config["DumpTextures"].ValueAsDefault<bool>(false))
|
||||
{
|
||||
Util::WriteSurfaceToBMP<Util::T1RGB5>("textures_t1rgb5.bmp", reinterpret_cast<uint8_t*>(textureRAM), 2048, 2048, false);
|
||||
printf("Wrote textures as T1RGB5 to 'textures_t1rgb5.bmp'\n");
|
||||
Util::WriteSurfaceToBMP<Util::A4L4Low>("textures_a4l4_lo.bmp", reinterpret_cast<uint8_t*>(textureRAM), 2048, 2048, false);
|
||||
printf("Wrote textures as A4L4 (low) to 'textures_a4l4_lo.bmp'\n");
|
||||
Util::WriteSurfaceToBMP<Util::L4A4Low>("textures_l4a4_lo.bmp", reinterpret_cast<uint8_t*>(textureRAM), 2048, 2048, false);
|
||||
printf("Wrote textures as L4A4 (low) to 'textures_l4a4_lo.bmp'\n");
|
||||
Util::WriteSurfaceToBMP<Util::A4L4High>("textures_a4l4_hi.bmp", reinterpret_cast<uint8_t*>(textureRAM), 2048, 2048, false);
|
||||
printf("Wrote textures as A4L4 (high) to 'textures_a4l4_hi.bmp'\n");
|
||||
Util::WriteSurfaceToBMP<Util::L4A4High>("textures_l4a4_hi.bmp", reinterpret_cast<uint8_t*>(textureRAM), 2048, 2048, false);
|
||||
printf("Wrote textures as L4A4 (high) to 'textures_l4a4_hi.bmp'\n");
|
||||
Util::WriteSurfaceToBMP<Util::L8Low>("textures_l8_lo.bmp", reinterpret_cast<uint8_t*>(textureRAM), 2048, 2048, false);
|
||||
printf("Wrote textures as L8 (low) to 'textures_l8_lo.bmp'\n");
|
||||
Util::WriteSurfaceToBMP<Util::L8High>("textures_l8_hi.bmp", reinterpret_cast<uint8_t*>(textureRAM), 2048, 2048, false);
|
||||
printf("Wrote textures as L8 (high) to 'textures_l8_hi.bmp'\n");
|
||||
Util::WriteSurfaceToBMP<Util::RGBA4>("textures_rgba4.bmp", reinterpret_cast<uint8_t*>(textureRAM), 2048, 2048, false);
|
||||
printf("Wrote textures as RGBA4 to 'textures_rgba4.bmp'\n");
|
||||
Util::WriteSurfaceToBMP<Util::L4Channel0>("textures_l4_0.bmp", reinterpret_cast<uint8_t*>(textureRAM), 2048, 2048, false);
|
||||
printf("Wrote textures as L4 (channel 0) to 'textures_l4_0.bmp'\n");
|
||||
Util::WriteSurfaceToBMP<Util::L4Channel1>("textures_l4_1.bmp", reinterpret_cast<uint8_t*>(textureRAM), 2048, 2048, false);
|
||||
printf("Wrote textures as L4 (channel 1) to 'textures_l4_1.bmp'\n");
|
||||
Util::WriteSurfaceToBMP<Util::L4Channel2>("textures_l4_2.bmp", reinterpret_cast<uint8_t*>(textureRAM), 2048, 2048, false);
|
||||
printf("Wrote textures as L4 (channel 2) to 'textures_l4_2.bmp'\n");
|
||||
Util::WriteSurfaceToBMP<Util::L4Channel3>("textures_l4_3.bmp", reinterpret_cast<uint8_t*>(textureRAM), 2048, 2048, false);
|
||||
printf("Wrote textures as L4 (channel 3) to 'textures_l4_3.bmp'\n");
|
||||
}
|
||||
|
||||
Render3D = NULL;
|
||||
if (memoryPool != NULL)
|
||||
{
|
||||
|
|
|
@ -1444,6 +1444,7 @@ static Util::Config::Node DefaultConfig()
|
|||
config.Set("SDLConstForceThreshold", "30");
|
||||
#endif
|
||||
config.Set("Outputs", "none");
|
||||
config.Set("DumpTextures", false);
|
||||
return config;
|
||||
}
|
||||
|
||||
|
@ -1529,8 +1530,9 @@ static void Help(void)
|
|||
#endif
|
||||
puts(" -print-inputs Prints current input configuration");
|
||||
puts("");
|
||||
#ifdef SUPERMODEL_DEBUGGER
|
||||
puts("Debug Options:");
|
||||
puts(" -dump-textures Write textures to bitmap image files on exit");
|
||||
#ifdef SUPERMODEL_DEBUGGER
|
||||
puts(" -disable-debugger Completely disable debugger functionality");
|
||||
puts(" -enter-debugger Enter debugger at start of emulation");
|
||||
puts("");
|
||||
|
@ -1626,7 +1628,7 @@ static ParsedCommandLine ParseCommandLine(int argc, char **argv)
|
|||
#endif
|
||||
{ "-no-force-feedback", { "ForceFeedback", false } },
|
||||
{ "-force-feedback", { "ForceFeedback", true } },
|
||||
|
||||
{ "-dump-textures", { "DumpTextures", true } },
|
||||
};
|
||||
for (int i = 1; i < argc; i++)
|
||||
{
|
||||
|
|
|
@ -31,6 +31,7 @@ namespace Util
|
|||
}
|
||||
};
|
||||
|
||||
// BITMAPV4HEADER
|
||||
struct BMPInfoHeader
|
||||
{
|
||||
uint32_t size;
|
||||
|
@ -44,18 +45,52 @@ namespace Util
|
|||
int32_t vertical_resolution;
|
||||
uint32_t num_palette_colors;
|
||||
uint32_t num_important_colors;
|
||||
uint32_t red_mask;
|
||||
uint32_t green_mask;
|
||||
uint32_t blue_mask;
|
||||
uint32_t alpha_mask;
|
||||
uint32_t color_space;
|
||||
uint32_t endpoints_red_x;
|
||||
uint32_t endpoints_red_y;
|
||||
uint32_t endpoints_red_z;
|
||||
uint32_t endpoints_green_x;
|
||||
uint32_t endpoints_green_y;
|
||||
uint32_t endpoints_green_z;
|
||||
uint32_t endpoints_blue_x;
|
||||
uint32_t endpoints_blue_y;
|
||||
uint32_t endpoints_blue_z;
|
||||
uint32_t gamma_red;
|
||||
uint32_t gamma_green;
|
||||
uint32_t gamma_blue;
|
||||
BMPInfoHeader(int32_t _width, int32_t _height)
|
||||
: size(sizeof(BMPInfoHeader)),
|
||||
width(_width),
|
||||
height(_height),
|
||||
num_planes(1),
|
||||
bits_per_pixel(24),
|
||||
compression_method(0),
|
||||
bits_per_pixel(32),
|
||||
compression_method(3), // BI_BITFIELDS
|
||||
bitmap_size(_width*_height*3),
|
||||
horizontal_resolution(2835), // 72 dpi
|
||||
vertical_resolution(2835),
|
||||
num_palette_colors(0),
|
||||
num_important_colors(0)
|
||||
num_important_colors(0),
|
||||
red_mask(0x00ff0000),
|
||||
green_mask(0x0000ff00),
|
||||
blue_mask(0x000000ff),
|
||||
alpha_mask(0xff000000),
|
||||
color_space(1), // LCS_DEVICE_RGB
|
||||
endpoints_red_x(0),
|
||||
endpoints_red_y(0),
|
||||
endpoints_red_z(0),
|
||||
endpoints_green_x(0),
|
||||
endpoints_green_y(0),
|
||||
endpoints_green_z(0),
|
||||
endpoints_blue_x(0),
|
||||
endpoints_blue_y(0),
|
||||
endpoints_blue_z(0),
|
||||
gamma_red(0),
|
||||
gamma_green(0),
|
||||
gamma_blue(0)
|
||||
{}
|
||||
};
|
||||
|
||||
|
@ -93,7 +128,8 @@ namespace Util
|
|||
}
|
||||
};
|
||||
|
||||
struct A1RGB5
|
||||
// Texture format 0: TRRR RRGG GGGB BBBB, T = contour bit
|
||||
struct T1RGB5
|
||||
{
|
||||
static const unsigned bytes_per_pixel = 2;
|
||||
static inline uint8_t GetRed(const uint8_t *pixel)
|
||||
|
@ -110,10 +146,146 @@ namespace Util
|
|||
}
|
||||
static inline uint8_t GetAlpha(const uint8_t *pixel)
|
||||
{
|
||||
return uint8_t((255.0f / 1.0f) * float((*reinterpret_cast<const uint16_t *>(pixel) >> 15) & 0x1));
|
||||
bool t = (*reinterpret_cast<const uint16_t*>(pixel) >> 15) & 0x1;
|
||||
return t ? uint8_t(0x00) : uint8_t(0xff); // T-bit indicates transparency
|
||||
}
|
||||
};
|
||||
|
||||
// Texture format 1: xxxx xxxx AAAA LLLL
|
||||
struct A4L4Low
|
||||
{
|
||||
static const unsigned bytes_per_pixel = 2;
|
||||
static inline uint8_t GetRed(const uint8_t* pixel)
|
||||
{
|
||||
return uint8_t((255.0f / 15.0f) * float((*reinterpret_cast<const uint16_t*>(pixel) >> 0) & 0xf));
|
||||
}
|
||||
static inline uint8_t GetGreen(const uint8_t* pixel)
|
||||
{
|
||||
return uint8_t((255.0f / 15.0f) * float((*reinterpret_cast<const uint16_t*>(pixel) >> 0) & 0xf));
|
||||
}
|
||||
static inline uint8_t GetBlue(const uint8_t* pixel)
|
||||
{
|
||||
return uint8_t((255.0f / 15.0f) * float((*reinterpret_cast<const uint16_t*>(pixel) >> 0) & 0xf));
|
||||
}
|
||||
static inline uint8_t GetAlpha(const uint8_t* pixel)
|
||||
{
|
||||
return uint8_t((255.0f / 15.0f) * float((*reinterpret_cast<const uint16_t*>(pixel) >> 4) & 0xf));
|
||||
}
|
||||
};
|
||||
|
||||
// Texture format 2: xxxx xxxx LLLL AAAA
|
||||
struct L4A4Low
|
||||
{
|
||||
static const unsigned bytes_per_pixel = 2;
|
||||
static inline uint8_t GetRed(const uint8_t* pixel)
|
||||
{
|
||||
return uint8_t((255.0f / 15.0f) * float((*reinterpret_cast<const uint16_t*>(pixel) >> 4) & 0xf));
|
||||
}
|
||||
static inline uint8_t GetGreen(const uint8_t* pixel)
|
||||
{
|
||||
return uint8_t((255.0f / 15.0f) * float((*reinterpret_cast<const uint16_t*>(pixel) >> 4) & 0xf));
|
||||
}
|
||||
static inline uint8_t GetBlue(const uint8_t* pixel)
|
||||
{
|
||||
return uint8_t((255.0f / 15.0f) * float((*reinterpret_cast<const uint16_t*>(pixel) >> 4) & 0xf));
|
||||
}
|
||||
static inline uint8_t GetAlpha(const uint8_t* pixel)
|
||||
{
|
||||
return uint8_t((255.0f / 15.0f) * float((*reinterpret_cast<const uint16_t*>(pixel) >> 0) & 0xf));
|
||||
}
|
||||
};
|
||||
|
||||
// Texture format 3: AAAA LLLL xxxx xxxx
|
||||
struct A4L4High
|
||||
{
|
||||
static const unsigned bytes_per_pixel = 2;
|
||||
static inline uint8_t GetRed(const uint8_t* pixel)
|
||||
{
|
||||
return uint8_t((255.0f / 15.0f) * float((*reinterpret_cast<const uint16_t*>(pixel) >> 8) & 0xf));
|
||||
}
|
||||
static inline uint8_t GetGreen(const uint8_t* pixel)
|
||||
{
|
||||
return uint8_t((255.0f / 15.0f) * float((*reinterpret_cast<const uint16_t*>(pixel) >> 8) & 0xf));
|
||||
}
|
||||
static inline uint8_t GetBlue(const uint8_t* pixel)
|
||||
{
|
||||
return uint8_t((255.0f / 15.0f) * float((*reinterpret_cast<const uint16_t*>(pixel) >> 8) & 0xf));
|
||||
}
|
||||
static inline uint8_t GetAlpha(const uint8_t* pixel)
|
||||
{
|
||||
return uint8_t((255.0f / 15.0f) * float((*reinterpret_cast<const uint16_t*>(pixel) >> 12) & 0xf));
|
||||
}
|
||||
};
|
||||
|
||||
// Texture format 4: LLLL AAAA xxxx xxxx
|
||||
struct L4A4High
|
||||
{
|
||||
static const unsigned bytes_per_pixel = 2;
|
||||
static inline uint8_t GetRed(const uint8_t* pixel)
|
||||
{
|
||||
return uint8_t((255.0f / 15.0f) * float((*reinterpret_cast<const uint16_t*>(pixel) >> 12) & 0xf));
|
||||
}
|
||||
static inline uint8_t GetGreen(const uint8_t* pixel)
|
||||
{
|
||||
return uint8_t((255.0f / 15.0f) * float((*reinterpret_cast<const uint16_t*>(pixel) >> 12) & 0xf));
|
||||
}
|
||||
static inline uint8_t GetBlue(const uint8_t* pixel)
|
||||
{
|
||||
return uint8_t((255.0f / 15.0f) * float((*reinterpret_cast<const uint16_t*>(pixel) >> 12) & 0xf));
|
||||
}
|
||||
static inline uint8_t GetAlpha(const uint8_t* pixel)
|
||||
{
|
||||
return uint8_t((255.0f / 15.0f) * float((*reinterpret_cast<const uint16_t*>(pixel) >> 8) & 0xf));
|
||||
}
|
||||
};
|
||||
|
||||
// Texture format 5: xxxx xxxx LLLL LLLL, where L=0xff is transparent and L!=0xff is opaque
|
||||
struct L8Low
|
||||
{
|
||||
static const unsigned bytes_per_pixel = 2;
|
||||
static inline uint8_t GetRed(const uint8_t* pixel)
|
||||
{
|
||||
return uint8_t((*reinterpret_cast<const uint16_t*>(pixel) >> 0) & 0xff);
|
||||
}
|
||||
static inline uint8_t GetGreen(const uint8_t* pixel)
|
||||
{
|
||||
return uint8_t((*reinterpret_cast<const uint16_t*>(pixel) >> 0) & 0xff);
|
||||
}
|
||||
static inline uint8_t GetBlue(const uint8_t* pixel)
|
||||
{
|
||||
return uint8_t((*reinterpret_cast<const uint16_t*>(pixel) >> 0) & 0xff);
|
||||
}
|
||||
static inline uint8_t GetAlpha(const uint8_t* pixel)
|
||||
{
|
||||
uint8_t l = uint8_t((*reinterpret_cast<const uint16_t*>(pixel) >> 0) & 0xff);
|
||||
return l == 0xff ? 0 : 0xff;
|
||||
}
|
||||
};
|
||||
|
||||
// Texture format 6: LLLL LLLL xxxx xxxx, where L=0xff is transparent and L!=0xff is opaque
|
||||
struct L8High
|
||||
{
|
||||
static const unsigned bytes_per_pixel = 2;
|
||||
static inline uint8_t GetRed(const uint8_t* pixel)
|
||||
{
|
||||
return uint8_t((*reinterpret_cast<const uint16_t*>(pixel) >> 8) & 0xff);
|
||||
}
|
||||
static inline uint8_t GetGreen(const uint8_t* pixel)
|
||||
{
|
||||
return uint8_t((*reinterpret_cast<const uint16_t*>(pixel) >> 8) & 0xff);
|
||||
}
|
||||
static inline uint8_t GetBlue(const uint8_t* pixel)
|
||||
{
|
||||
return uint8_t((*reinterpret_cast<const uint16_t*>(pixel) >> 8) & 0xff);
|
||||
}
|
||||
static inline uint8_t GetAlpha(const uint8_t* pixel)
|
||||
{
|
||||
uint8_t l = uint8_t((*reinterpret_cast<const uint16_t*>(pixel) >> 8) & 0xff);
|
||||
return l == 0xff ? 0 : 0xff;
|
||||
}
|
||||
};
|
||||
|
||||
// Texture format 7: RRRR GGGG BBBB AAAA
|
||||
struct RGBA4
|
||||
{
|
||||
static const unsigned bytes_per_pixel = 2;
|
||||
|
@ -135,11 +307,43 @@ namespace Util
|
|||
}
|
||||
};
|
||||
|
||||
// Texture format 8: xxxx xxxx xxxx LLLL
|
||||
// Texture format 9: xxxx xxxx LLLL xxxx
|
||||
// Texture format 10: xxxx LLLL xxxx xxxx
|
||||
// Texture format 11: LLLL xxxx xxxx xxxx
|
||||
template <int Channel>
|
||||
struct L4
|
||||
{
|
||||
static const unsigned bytes_per_pixel = 2;
|
||||
static inline uint8_t GetRed(const uint8_t* pixel)
|
||||
{
|
||||
return uint8_t((255.0f / 15.0f) * float((*reinterpret_cast<const uint16_t*>(pixel) >> (Channel * 4)) & 0xf));
|
||||
}
|
||||
static inline uint8_t GetGreen(const uint8_t* pixel)
|
||||
{
|
||||
return uint8_t((255.0f / 15.0f) * float((*reinterpret_cast<const uint16_t*>(pixel) >> (Channel * 4)) & 0xf));
|
||||
}
|
||||
static inline uint8_t GetBlue(const uint8_t* pixel)
|
||||
{
|
||||
return uint8_t((255.0f / 15.0f) * float((*reinterpret_cast<const uint16_t*>(pixel) >> (Channel * 4)) & 0xf));
|
||||
}
|
||||
static inline uint8_t GetAlpha(const uint8_t* pixel)
|
||||
{
|
||||
uint8_t l = (*reinterpret_cast<const uint16_t*>(pixel) >> (Channel * 4)) & 0xf;
|
||||
return l == 0x0f ? 0x00 : 0xff;
|
||||
}
|
||||
};
|
||||
|
||||
using L4Channel0 = struct L4<0>;
|
||||
using L4Channel1 = struct L4<1>;
|
||||
using L4Channel2 = struct L4<2>;
|
||||
using L4Channel3 = struct L4<3>;
|
||||
|
||||
template <class SurfaceFormat>
|
||||
static bool WriteSurfaceToBMP(const std::string &file_name, const uint8_t *pixels, int32_t width, int32_t height, bool flip_vertical)
|
||||
{
|
||||
using namespace detail;
|
||||
size_t file_size = sizeof(FileHeader) + width*height*3;
|
||||
size_t file_size = sizeof(FileHeader) + width*height*4;
|
||||
std::shared_ptr<uint8_t> file(new uint8_t[file_size], std::default_delete<uint8_t[]>());
|
||||
FileHeader *header = new (file.get()) FileHeader(width, height);
|
||||
uint8_t *bmp = file.get() + sizeof(*header);
|
||||
|
@ -153,6 +357,7 @@ namespace Util
|
|||
*bmp++ = SurfaceFormat::GetBlue(src);
|
||||
*bmp++ = SurfaceFormat::GetGreen(src);
|
||||
*bmp++ = SurfaceFormat::GetRed(src);
|
||||
*bmp++ = SurfaceFormat::GetAlpha(src);
|
||||
src += SurfaceFormat::bytes_per_pixel;
|
||||
}
|
||||
}
|
||||
|
@ -167,6 +372,7 @@ namespace Util
|
|||
*bmp++ = SurfaceFormat::GetBlue(src);
|
||||
*bmp++ = SurfaceFormat::GetGreen(src);
|
||||
*bmp++ = SurfaceFormat::GetRed(src);
|
||||
*bmp++ = SurfaceFormat::GetAlpha(src);
|
||||
src += SurfaceFormat::bytes_per_pixel;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue