From 97d4a60cfb635f59c2e35e144ce3337046f84977 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Mon, 29 Jul 2019 21:04:04 -0700 Subject: GLK: Implemented debugger dumppic command --- engines/glk/debugger.cpp | 90 +++++++++++++++++++++++++++++++++++++++++++++--- engines/glk/debugger.h | 7 ++++ 2 files changed, 92 insertions(+), 5 deletions(-) diff --git a/engines/glk/debugger.cpp b/engines/glk/debugger.cpp index 57188db756..2f13f6bfbd 100644 --- a/engines/glk/debugger.cpp +++ b/engines/glk/debugger.cpp @@ -20,14 +20,17 @@ * */ -#include "common/file.h" -#include "glk/glk.h" #include "glk/debugger.h" +#include "glk/glk.h" +#include "glk/raw_decoder.h" +#include "common/file.h" +#include "graphics/managed_surface.h" +#include "image/png.h" namespace Glk { Debugger::Debugger(GlkEngine *vm) : GUI::Debugger(), _vm(vm) { - registerCmd("dumppic", WRAP_METHOD(Debugger, cmdExit)); + registerCmd("dumppic", WRAP_METHOD(Debugger, cmdDumpPic)); } int Debugger::strToInt(const char *s) { @@ -48,13 +51,90 @@ int Debugger::strToInt(const char *s) { bool Debugger::cmdDumpPic(int argc, const char **argv) { if (argc != 2) { - debugPrintf("Format: dumppic "); + debugPrintf("Format: dumppic \n"); } else { + Common::File f; int picNum = strToInt(argv[1]); - warning("TODO: dumpPic %d", picNum); + + Common::String filename = Common::String::format("pic%d.png", picNum); + if (!f.exists(filename)) + filename = Common::String::format("pic%d.jpg", picNum); + + if (f.open(filename)) { + // png or jpeg file + Common::DumpFile df; + if (df.open(filename)) { + // Write out a copy of the file + byte *data = new byte[f.size()]; + f.read(data, f.size()); + df.write(data, f.size()); + delete[] data; + df.close(); + + debugPrintf("Dumped picture\n"); + } else { + debugPrintf("Could not find specified picture\n"); + } + } else if (f.exists(Common::String::format("pic%d.rect"))) { + debugPrintf("Picture is only a placeholder rectangle\n"); + } else if (f.open(Common::String::format("pic%d.raw", picNum))) { + // Raw picture +#ifdef USE_PNG + Common::DumpFile df; + RawDecoder rd; + + if (rd.loadStream(f) && df.open(Common::String::format("pic%d.png", picNum))) { + saveRawPicture(rd, df); + debugPrintf("Dumped picture\n"); + } else { + debugPrintf("Couldn't save picture\n"); + } +#else + debugPrintf("PNG support needed to dump raw pictures\n"); +#endif + } else { + debugPrintf("No such picture exists\n"); + } } return true; } +void Debugger::saveRawPicture(const RawDecoder &rd, Common::WriteStream &ws) { +#ifdef USE_PNG + const Graphics::Surface *surface = rd.getSurface(); + const byte *palette = rd.getPalette(); + int paletteCount = rd.getPaletteColorCount(); + int palStart = rd.getPaletteStartIndex(); + int transColor = rd.getTransparentColor(); + + // If the image doesn't have a palette, we can directly write out the image + if (!palette) { + Image::writePNG(ws, *surface); + return; + } + + // Create a new RGBA temporary surface + Graphics::PixelFormat format(4, 8, 8, 8, 8, 24, 16, 8, 0); + Graphics::ManagedSurface destSurface(surface->w, surface->h, format); + + for (uint y = 0; y < surface->h; ++y) { + const byte *srcP = (const byte *)surface->getBasePtr(0, y); + uint32 *destP = (uint32 *)destSurface.getBasePtr(0, y); + + for (uint x = 0; x < surface->w; ++x, ++srcP, ++destP) { + if ((int)*srcP == transColor || (int)*srcP < palStart) { + *destP = format.ARGBToColor(0, 0, 0, 0); + } else { + assert(*srcP < paletteCount); + const byte *palP = &palette[*srcP * 3]; + *destP = format.ARGBToColor(255, palP[0], palP[1], palP[2]); + } + } + } + + Image::writePNG(ws, destSurface); +#endif +} + } // End of namespace Glk diff --git a/engines/glk/debugger.h b/engines/glk/debugger.h index d09ef99ae8..0555829a95 100644 --- a/engines/glk/debugger.h +++ b/engines/glk/debugger.h @@ -24,7 +24,9 @@ #define GLK_DEBUGGER_H #include "common/scummsys.h" +#include "common/stream.h" #include "gui/debugger.h" +#include "glk/raw_decoder.h" namespace Glk { @@ -34,6 +36,11 @@ class Debugger : public GUI::Debugger { private: GlkEngine *_vm; + /** + * Saves a decoded raw image to a PNG file + */ + void saveRawPicture(const RawDecoder &rd, Common::WriteStream &ws); + /** * Dump a picture */ -- cgit v1.2.3