-midtunit: Add MIDTUNIT_LOG_PNG define, to log unscaled 32bpp PNGs of all DMA draw calls. [Ryan Holtz]

This commit is contained in:
MooglyGuy 2019-07-05 21:52:40 +02:00
parent 0aa539f913
commit f97679a762
2 changed files with 177 additions and 0 deletions

View File

@ -12,6 +12,8 @@
#include "midtunit.ipp"
#include "screen.h"
#include "midtview.ipp"
#include "emuopts.h" // Used by MIDTUNIT_LOG_PNG
#include "png.h" // Used by MIDTUNIT_LOG_PNG
DEFINE_DEVICE_TYPE(MIDTUNIT_VIDEO, midtunit_video_device, "tunitvid", "Midway T-Unit Video")
DEFINE_DEVICE_TYPE(MIDWUNIT_VIDEO, midwunit_video_device, "wunitvid", "Midway W-Unit Video")
@ -65,6 +67,9 @@ void midtunit_video_device::device_start()
#if DEBUG_MIDTUNIT_BLITTER
m_debug_videoram = std::make_unique<uint16_t[]>(0x100000/2);
#endif
#if MIDTUNIT_LOG_PNG
m_logged_rom = std::make_unique<uint64_t[]>(0x4000000);
#endif
m_dma_timer = timer_alloc(TIMER_DMA);
@ -682,6 +687,17 @@ WRITE16_MEMBER(midtunit_video_device::midtunit_dma_w)
m_dma_state.endskip = m_dma_register[DMA_LRSKIP];
}
#if MIDTUNIT_LOG_PNG
if (command & 0x80)
{
log_bitmap(command, bpp ? bpp : 8, true);
}
else
{
log_bitmap(command, bpp ? bpp : 8, false);
}
#endif
/* then draw */
if (m_dma_state.xstep == 0x100 && m_dma_state.ystep == 0x100)
{
@ -741,3 +757,157 @@ TMS340X0_SCANLINE_IND16_CB_MEMBER(midxunit_video_device::scanline_update)
for (int x = params->heblnk; x < params->hsblnk; x++)
dest[x] = src[fulladdr++ & 0x1ff] & 0x7fff;
}
#if MIDTUNIT_LOG_PNG
void midtunit_video_device::log_bitmap(int command, int bpp, bool Skip)
{
const uint32_t raw_offset = m_dma_register[DMA_OFFSETLO] | (m_dma_register[DMA_OFFSETHI] << 16);
if (m_logged_rom[raw_offset >> 6] & (1ULL << (raw_offset & 0x3f)))
return;
int Zero = PIXEL_SKIP;
int NonZero = PIXEL_SKIP;
switch (command & 0xf)
{
case 1: Zero = PIXEL_COPY; NonZero = PIXEL_SKIP; break;
case 2: Zero = PIXEL_SKIP; NonZero = PIXEL_COPY; break;
case 3: Zero = PIXEL_COPY; NonZero = PIXEL_COPY; break;
case 4: Zero = PIXEL_COLOR; NonZero = PIXEL_SKIP; break;
case 5: Zero = PIXEL_COLOR; NonZero = PIXEL_SKIP; break;
case 6: Zero = PIXEL_COLOR; NonZero = PIXEL_COPY; break;
case 7: Zero = PIXEL_COLOR; NonZero = PIXEL_COPY; break;
case 8: Zero = PIXEL_SKIP; NonZero = PIXEL_COLOR; break;
case 9: Zero = PIXEL_COPY; NonZero = PIXEL_COLOR; break;
case 10: Zero = PIXEL_SKIP; NonZero = PIXEL_COLOR; break;
case 11: Zero = PIXEL_COPY; NonZero = PIXEL_COLOR; break;
case 12: Zero = PIXEL_COLOR; NonZero = PIXEL_COLOR; break;
case 13: Zero = PIXEL_COLOR; NonZero = PIXEL_COLOR; break;
case 14: Zero = PIXEL_COLOR; NonZero = PIXEL_COLOR; break;
case 15: Zero = PIXEL_COLOR; NonZero = PIXEL_COLOR; break;
default: return;
}
emu_file file(machine().options().snapshot_directory(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS);
char name_buf[256];
snprintf(name_buf, 255, "0x%08x.png", raw_offset);
auto const filerr = file.open(name_buf);
if (filerr != osd_file::error::NONE)
{
return;
}
m_logged_rom[raw_offset >> 6] |= 1ULL << (raw_offset & 0x3f);
m_log_bitmap.allocate(m_dma_state.width, m_dma_state.height);
m_log_bitmap.fill(0);
uint8_t *base = m_dma_state.gfxrom;
uint32_t offset = m_dma_state.offset;
uint16_t pal = m_dma_state.palette;
uint16_t color = pal | m_dma_state.color;
int mask = (1 << bpp) - 1;
/* loop over the height */
for (int y = 0; y < m_dma_state.height; y++)
{
int startskip = m_dma_state.startskip;
int endskip = m_dma_state.endskip;
int width = m_dma_state.width;
int ix = 0;
int tx;
uint32_t o = offset;
int pre, post;
/* handle skipping */
if (Skip)
{
uint8_t value = EXTRACTGEN(0xff);
o += 8;
/* adjust for preskip */
pre = (value & 0x0f) << m_dma_state.preskip;
tx = pre;
ix += tx;
/* adjust for postskip */
post = ((value >> 4) & 0x0f) << m_dma_state.postskip;
width -= post;
endskip -= post;
}
/* handle start skip */
if (ix < startskip)
{
tx = (startskip - ix);
ix += tx;
o += tx * bpp;
}
/* handle end skip */
if (width > m_dma_state.width - m_dma_state.endskip)
width = m_dma_state.width - m_dma_state.endskip;
bitmap_rgb32::pixel_t *d = &m_log_bitmap.pix(y, ix);
/* determine destination pointer */
/* loop until we draw the entire width */
while (ix < width)
{
/* special case similar handling of zero/non-zero */
if (Zero == NonZero)
{
if (Zero == PIXEL_COLOR)
*d = m_palette->palette()->entry_list_raw()[color];
else if (Zero == PIXEL_COPY)
*d = m_palette->palette()->entry_list_raw()[(EXTRACTGEN(mask)) | pal];
}
/* otherwise, read the pixel and look */
else
{
int pixel = (EXTRACTGEN(mask));
/* non-zero pixel case */
if (pixel)
{
if (NonZero == PIXEL_COLOR)
*d = m_palette->palette()->entry_list_raw()[color];
else if (NonZero == PIXEL_COPY)
*d = m_palette->palette()->entry_list_raw()[pixel | pal];
}
/* zero pixel case */
else
{
if (Zero == PIXEL_COLOR)
*d = m_palette->palette()->entry_list_raw()[color];
else if (Zero == PIXEL_COPY)
*d = m_palette->palette()->entry_list_raw()[pal];
}
}
/* advance to the next pixel */
ix++;
d++;
o += bpp;
}
/* advance to the next row */
width = m_dma_state.width;
if (Skip)
{
offset += 8;
width -= pre + post;
if (width > 0) offset += width * bpp;
}
else
{
offset += width * bpp;
}
}
png_write_bitmap(file, nullptr, m_log_bitmap, 0, nullptr);
}
#endif

View File

@ -17,6 +17,7 @@
#include "emupal.h"
#define DEBUG_MIDTUNIT_BLITTER (0)
#define MIDTUNIT_LOG_PNG (0)
class midtunit_video_device : public device_t
{
@ -165,6 +166,12 @@ protected:
int32_t m_debug_dma_mode;
int32_t m_debug_dma_command;
#endif
#if MIDTUNIT_LOG_PNG
std::unique_ptr<uint64_t[]> m_logged_rom;
bitmap_argb32 m_log_bitmap;
void log_bitmap(int command, int bpp, bool skip);
#endif
};
class midwunit_video_device : public midtunit_video_device