summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author Aaron Giles <aaron@aarongiles.com>2008-06-16 16:34:51 +0000
committer Aaron Giles <aaron@aarongiles.com>2008-06-16 16:34:51 +0000
commit69ba0bd294625f681cb7a479046237618be60c54 (patch)
treee1a4bcb647f4de2cfd87de3f6e029ce7f185e374
parenta93fb6b1bf8407a52efdbfa333e5dc8d128daf13 (diff)
Cleaned up software bilinear filtering code. Added bounds checking.
Enabled by default for snapshots and movie rendering. Added new option: -snapsize, which lets you specify the target resolution for snapshots and movies. The existing behavior is still the default: create snapshots and movies at native pixel resolutions. Added new option: -snapview, which lets you specify a particular view to use for rendering snapshots and movies. The existing behavior is still the default: use a special internal view and render each screen to its own snapshot in its own file. When using this option to specify a view other than 'internal', only a single snapshot file will be produced regardless of how many screens the game has. Improved AVI and MNG recording to properly duplicate/skip frames as appropriate to keep the correct framerate.
-rw-r--r--docs/config.txt23
-rw-r--r--src/emu/debug/debugcmd.c2
-rw-r--r--src/emu/emuopts.c4
-rw-r--r--src/emu/emuopts.h4
-rw-r--r--src/emu/rendersw.c218
-rw-r--r--src/emu/ui.c6
-rw-r--r--src/emu/video.c355
-rw-r--r--src/emu/video.h12
8 files changed, 373 insertions, 251 deletions
diff --git a/docs/config.txt b/docs/config.txt
index 0df7775758d..ad1965044e6 100644
--- a/docs/config.txt
+++ b/docs/config.txt
@@ -467,6 +467,29 @@ Core state/playback options
and names the snapshots under it starting with 0000 and increasing
from there.
+-snapsize <width>x<height>
+
+ Hard-codes the size for snapshots and movie recording. By default,
+ MAME will create snapshots at the game's current resolution in raw
+ pixels, and will create movies at the game's starting resolution in
+ raw pixels. If you specify this option, then MAME will create both
+ snapshots and movies at the size specified, and will bilinear filter
+ the result. Note that this size does not automatically rotate if the
+ game is vertically oriented. The default is 'auto'.
+
+-snapview <viewname>
+
+ Specifies the view to use when rendering snapshots and movies. By
+ default, both use a special 'internal' view, which renders a separate
+ snapshot per screen or renders movies only of the first screen. By
+ specifying this option, you can override this default behavior and
+ select a single view that will apply to all snapshots and movies.
+ Note that <viewname> does not need to be a perfect match; rather, it
+ will select the first view whose name matches all the characters
+ specified by <viewname>. For example, -snapview native will match the
+ "Native (15:14)" view even though it is not a perfect match. The
+ default value is 'internal'.
+
-mngwrite <filename>
Writes each video frame to the given <filename> in MNG format,
diff --git a/src/emu/debug/debugcmd.c b/src/emu/debug/debugcmd.c
index e7ced884bc8..43bb646fadb 100644
--- a/src/emu/debug/debugcmd.c
+++ b/src/emu/debug/debugcmd.c
@@ -2028,7 +2028,7 @@ static void execute_snap(int ref, int params, const char *param[])
return;
}
- video_screen_save_snapshot(screen, fp);
+ video_screen_save_snapshot(screen->machine, screen, fp);
mame_fclose(fp);
debug_console_printf("Saved screen #%d snapshot as '%s'\n", scrnum, filename);
}
diff --git a/src/emu/emuopts.c b/src/emu/emuopts.c
index 0c8568e0935..664a45e2974 100644
--- a/src/emu/emuopts.c
+++ b/src/emu/emuopts.c
@@ -64,10 +64,12 @@ const options_entry mame_core_options[] =
{ "autosave", "0", OPTION_BOOLEAN, "enable automatic restore at startup, and automatic save at exit time" },
{ "playback;pb", NULL, 0, "playback an input file" },
{ "record;rec", NULL, 0, "record an input file" },
- { "snapname", "%g/%i", 0, "override of the default snapshot naming; %g == gamename, %i == index" },
{ "mngwrite", NULL, 0, "optional filename to write a MNG movie of the current session" },
{ "aviwrite", NULL, 0, "optional filename to write an AVI movie of the current session" },
{ "wavwrite", NULL, 0, "optional filename to write a WAV file of the current session" },
+ { "snapname", "%g/%i", 0, "override of the default snapshot/movie naming; %g == gamename, %i == index" },
+ { "snapsize", "auto", 0, "specify snapshot/movie resolution (<width>x<height>) or 'auto' to use minimal size " },
+ { "snapview", "internal", 0, "specify snapshot/movie view or 'internal' to use internal pixel-aspect views" },
/* performance options */
{ NULL, NULL, OPTION_HEADER, "CORE PERFORMANCE OPTIONS" },
diff --git a/src/emu/emuopts.h b/src/emu/emuopts.h
index 6b64baa6072..c6adb680a5d 100644
--- a/src/emu/emuopts.h
+++ b/src/emu/emuopts.h
@@ -63,10 +63,12 @@
#define OPTION_AUTOSAVE "autosave"
#define OPTION_PLAYBACK "playback"
#define OPTION_RECORD "record"
-#define OPTION_SNAPNAME "snapname"
#define OPTION_MNGWRITE "mngwrite"
#define OPTION_AVIWRITE "aviwrite"
#define OPTION_WAVWRITE "wavwrite"
+#define OPTION_SNAPNAME "snapname"
+#define OPTION_SNAPSIZE "snapsize"
+#define OPTION_SNAPVIEW "snapview"
/* core performance options */
#define OPTION_AUTOFRAMESKIP "autoframeskip"
diff --git a/src/emu/rendersw.c b/src/emu/rendersw.c
index 5e87f622580..8050f049fc7 100644
--- a/src/emu/rendersw.c
+++ b/src/emu/rendersw.c
@@ -171,9 +171,10 @@ INLINE UINT32 ycc_to_rgb(UINT32 ycc)
16bpp source
-------------------------------------------------*/
-INLINE UINT32 get_texel_palette16_nearest(const UINT16 *texbase, INT32 texrp, INT32 curu, INT32 curv, const rgb_t *palbase)
+INLINE UINT32 get_texel_palette16_nearest(const render_texinfo *texture, INT32 curu, INT32 curv)
{
- return palbase[texbase[(curv >> 16) * texrp + (curu >> 16)]];
+ const UINT16 *texbase = (const UINT16 *)texture->base + (curv >> 16) * texture->rowpixels + (curu >> 16);
+ return texture->palette[texbase[0]];
}
@@ -183,14 +184,17 @@ INLINE UINT32 get_texel_palette16_nearest(const UINT16 *texbase, INT32 texrp, IN
16bpp source
-------------------------------------------------*/
-INLINE UINT32 get_texel_palette16_bilinear(const UINT16 *texbase, INT32 texrp, INT32 curu, INT32 curv, const rgb_t *palbase)
+INLINE UINT32 get_texel_palette16_bilinear(const render_texinfo *texture, INT32 curu, INT32 curv)
{
+ const UINT16 *texbase = (const UINT16 *)texture->base + (curv >> 16) * texture->rowpixels + (curu >> 16);
+ INT32 u1 = (((curu >> 16) + 1) < texture->width) ? 1 : 0;
+ INT32 v1 = (((curv >> 16) + 1) < texture->height) ? texture->rowpixels : 0;
rgb_t pix00, pix01, pix10, pix11;
- texbase += (curv >> 16) * texrp + (curu >> 16);
- pix00 = palbase[texbase[0]];
- pix01 = palbase[texbase[1]];
- pix10 = palbase[texbase[texrp + 0]];
- pix11 = palbase[texbase[texrp + 1]];
+
+ pix00 = texture->palette[texbase[0]];
+ pix01 = texture->palette[texbase[u1]];
+ pix10 = texture->palette[texbase[v1]];
+ pix11 = texture->palette[texbase[u1 + v1]];
return rgb_bilinear_filter(pix00, pix01, pix10, pix11, curu >> 8, curv >> 8);
}
@@ -200,9 +204,10 @@ INLINE UINT32 get_texel_palette16_bilinear(const UINT16 *texbase, INT32 texrp, I
nearest neighbor texel from a 15bpp RGB source
-------------------------------------------------*/
-INLINE UINT32 get_texel_rgb15_nearest(const UINT16 *texbase, INT32 texrp, INT32 curu, INT32 curv)
+INLINE UINT32 get_texel_rgb15_nearest(const render_texinfo *texture, INT32 curu, INT32 curv)
{
- return texbase[(curv >> 16) * texrp + (curu >> 16)];
+ const UINT16 *texbase = (const UINT16 *)texture->base + (curv >> 16) * texture->rowpixels + (curu >> 16);
+ return texbase[0];
}
@@ -212,14 +217,17 @@ INLINE UINT32 get_texel_rgb15_nearest(const UINT16 *texbase, INT32 texrp, INT32
source
-------------------------------------------------*/
-INLINE UINT32 get_texel_rgb15_bilinear(const UINT16 *texbase, INT32 texrp, INT32 curu, INT32 curv)
+INLINE UINT32 get_texel_rgb15_bilinear(const render_texinfo *texture, INT32 curu, INT32 curv)
{
+ const UINT16 *texbase = (const UINT16 *)texture->base + (curv >> 16) * texture->rowpixels + (curu >> 16);
+ INT32 u1 = (((curu >> 16) + 1) < texture->width) ? 1 : 0;
+ INT32 v1 = (((curv >> 16) + 1) < texture->height) ? texture->rowpixels : 0;
rgb_t pix00, pix01, pix10, pix11, filtered;
- texbase += (curv >> 16) * texrp + (curu >> 16);
+
pix00 = texbase[0];
- pix01 = texbase[1];
- pix10 = texbase[texrp + 0];
- pix11 = texbase[texrp + 1];
+ pix01 = texbase[u1];
+ pix10 = texbase[v1];
+ pix11 = texbase[u1 + v1];
pix00 = ((pix00 & 0x7fe0) << 6) | (pix00 & 0x1f);
pix01 = ((pix01 & 0x7fe0) << 6) | (pix01 & 0x1f);
pix10 = ((pix10 & 0x7fe0) << 6) | (pix10 & 0x1f);
@@ -235,10 +243,10 @@ INLINE UINT32 get_texel_rgb15_bilinear(const UINT16 *texbase, INT32 texrp, INT32
source (pixel is returned as Cr-Cb-Y
-------------------------------------------------*/
-INLINE UINT32 get_texel_yuy16_nearest(const UINT16 *texbase, INT32 texrp, INT32 curu, INT32 curv)
+INLINE UINT32 get_texel_yuy16_nearest(const render_texinfo *texture, INT32 curu, INT32 curv)
{
- const UINT16 *spix = &texbase[(curv >> 16) * texrp + (curu >> 17) * 2];
- return (spix[(curu >> 16) & 1] >> 8) | ((spix[0] & 0xff) << 8) | ((spix[1] & 0xff) << 16);
+ const UINT16 *texbase = (const UINT16 *)texture->base + (curv >> 16) * texture->rowpixels + (curu >> 17) * 2;
+ return (texbase[(curu >> 16) & 1] >> 8) | ((texbase[0] & 0xff) << 8) | ((texbase[1] & 0xff) << 16);
}
@@ -248,29 +256,42 @@ INLINE UINT32 get_texel_yuy16_nearest(const UINT16 *texbase, INT32 texrp, INT32
source (pixel is returned as Cr-Cb-Y
-------------------------------------------------*/
-INLINE UINT32 get_texel_yuy16_bilinear(const UINT16 *texbase, INT32 texrp, INT32 curu, INT32 curv)
+INLINE UINT32 get_texel_yuy16_bilinear(const render_texinfo *texture, INT32 curu, INT32 curv)
{
+ const UINT16 *texbase = (const UINT16 *)texture->base + (curv >> 16) * texture->rowpixels + (curu >> 17) * 2;
+ INT32 u1 = (((curu >> 16) + 1) < texture->width) ? 1 : 0;
+ INT32 v1 = (((curv >> 16) + 1) < texture->height) ? texture->rowpixels : 0;
rgb_t pix00, pix01, pix10, pix11;
- texbase += (curv >> 16) * texrp + (curu >> 17) * 2;
+
if ((curu & 0x10000) == 0)
{
rgb_t cbcr = ((texbase[0] & 0xff) << 8) | ((texbase[1] & 0xff) << 16);
pix00 = (texbase[0] >> 8) | cbcr;
- pix01 = (texbase[1] >> 8) | cbcr;
- cbcr = ((texbase[texrp + 0] & 0xff) << 8) | ((texbase[texrp + 1] & 0xff) << 16);
- pix10 = (texbase[texrp + 0] >> 8) | cbcr;
- pix11 = (texbase[texrp + 1] >> 8) | cbcr;
+ pix01 = u1 ? ((texbase[1] >> 8) | cbcr) : pix00;
+ cbcr = ((texbase[v1 + 0] & 0xff) << 8) | ((texbase[v1 + 1] & 0xff) << 16);
+ pix10 = (texbase[v1 + 0] >> 8) | cbcr;
+ pix11 = u1 ? ((texbase[v1 + 1] >> 8) | cbcr) : pix10;
}
else
{
rgb_t cbcr = ((texbase[0] & 0xff) << 8) | ((texbase[1] & 0xff) << 16);
pix00 = (texbase[1] >> 8) | cbcr;
- cbcr = ((texbase[2] & 0xff) << 8) | ((texbase[3] & 0xff) << 16);
- pix01 = (texbase[2] >> 8) | cbcr;
- cbcr = ((texbase[texrp + 0] & 0xff) << 8) | ((texbase[texrp + 1] & 0xff) << 16);
- pix10 = (texbase[texrp + 1] >> 8) | cbcr;
- cbcr = ((texbase[texrp + 2] & 0xff) << 8) | ((texbase[texrp + 3] & 0xff) << 16);
- pix11 = (texbase[texrp + 2] >> 8) | cbcr;
+ if (u1)
+ {
+ cbcr = ((texbase[2] & 0xff) << 8) | ((texbase[3] & 0xff) << 16);
+ pix01 = (texbase[2] >> 8) | cbcr;
+ }
+ else
+ pix01 = pix00;
+ cbcr = ((texbase[v1 + 0] & 0xff) << 8) | ((texbase[v1 + 1] & 0xff) << 16);
+ pix10 = (texbase[v1 + 1] >> 8) | cbcr;
+ if (u1)
+ {
+ cbcr = ((texbase[v1 + 2] & 0xff) << 8) | ((texbase[v1 + 3] & 0xff) << 16);
+ pix11 = (texbase[v1 + 2] >> 8) | cbcr;
+ }
+ else
+ pix11 = pix10;
}
return rgb_bilinear_filter(pix00, pix01, pix10, pix11, curu >> 8, curv >> 8);
}
@@ -281,9 +302,10 @@ INLINE UINT32 get_texel_yuy16_bilinear(const UINT16 *texbase, INT32 texrp, INT32
nearest neighbor texel from a 32bpp RGB source
-------------------------------------------------*/
-INLINE UINT32 get_texel_rgb32_nearest(const UINT32 *texbase, INT32 texrp, INT32 curu, INT32 curv)
+INLINE UINT32 get_texel_rgb32_nearest(const render_texinfo *texture, INT32 curu, INT32 curv)
{
- return texbase[(curv >> 16) * texrp + (curu >> 16)];
+ const UINT32 *texbase = (const UINT32 *)texture->base + (curv >> 16) * texture->rowpixels + (curu >> 16);
+ return texbase[0];
}
@@ -293,14 +315,17 @@ INLINE UINT32 get_texel_rgb32_nearest(const UINT32 *texbase, INT32 texrp, INT32
source
-------------------------------------------------*/
-INLINE UINT32 get_texel_rgb32_bilinear(const UINT32 *texbase, INT32 texrp, INT32 curu, INT32 curv)
+INLINE UINT32 get_texel_rgb32_bilinear(const render_texinfo *texture, INT32 curu, INT32 curv)
{
+ const UINT32 *texbase = (const UINT32 *)texture->base + (curv >> 16) * texture->rowpixels + (curu >> 16);
+ INT32 u1 = (((curu >> 16) + 1) < texture->width) ? 1 : 0;
+ INT32 v1 = (((curv >> 16) + 1) < texture->height) ? texture->rowpixels : 0;
rgb_t pix00, pix01, pix10, pix11;
- texbase += (curv >> 16) * texrp + (curu >> 16);
+
pix00 = texbase[0];
- pix01 = texbase[1];
- pix10 = texbase[texrp + 0];
- pix11 = texbase[texrp + 1];
+ pix01 = texbase[u1];
+ pix10 = texbase[v1];
+ pix11 = texbase[u1 + v1];
return rgb_bilinear_filter(pix00, pix01, pix10, pix11, curu >> 8, curv >> 8);
}
@@ -311,9 +336,10 @@ INLINE UINT32 get_texel_rgb32_bilinear(const UINT32 *texbase, INT32 texrp, INT32
source
-------------------------------------------------*/
-INLINE UINT32 get_texel_argb32_nearest(const UINT32 *texbase, INT32 texrp, INT32 curu, INT32 curv)
+INLINE UINT32 get_texel_argb32_nearest(const render_texinfo *texture, INT32 curu, INT32 curv)
{
- return texbase[(curv >> 16) * texrp + (curu >> 16)];
+ const UINT32 *texbase = (const UINT32 *)texture->base + (curv >> 16) * texture->rowpixels + (curu >> 16);
+ return texbase[0];
}
@@ -323,14 +349,17 @@ INLINE UINT32 get_texel_argb32_nearest(const UINT32 *texbase, INT32 texrp, INT32
source
-------------------------------------------------*/
-INLINE UINT32 get_texel_argb32_bilinear(const UINT32 *texbase, INT32 texrp, INT32 curu, INT32 curv)
+INLINE UINT32 get_texel_argb32_bilinear(const render_texinfo *texture, INT32 curu, INT32 curv)
{
+ const UINT32 *texbase = (const UINT32 *)texture->base + (curv >> 16) * texture->rowpixels + (curu >> 16);
+ INT32 u1 = (((curu >> 16) + 1) < texture->width) ? 1 : 0;
+ INT32 v1 = (((curv >> 16) + 1) < texture->height) ? texture->rowpixels : 0;
rgb_t pix00, pix01, pix10, pix11;
- texbase += (curv >> 16) * texrp + (curu >> 16);
+
pix00 = texbase[0];
- pix01 = texbase[1];
- pix10 = texbase[texrp + 0];
- pix11 = texbase[texrp + 1];
+ pix01 = texbase[u1];
+ pix10 = texbase[v1];
+ pix11 = texbase[u1 + v1];
return rgba_bilinear_filter(pix00, pix01, pix10, pix11, curu >> 8, curv >> 8);
}
@@ -701,16 +730,13 @@ static void FUNC_PREFIX(draw_rect)(const render_primitive *prim, void *dstdata,
static void FUNC_PREFIX(draw_quad_palette16_none)(const render_primitive *prim, void *dstdata, UINT32 pitch, quad_setup_data *setup)
{
- UINT16 *texbase = prim->texture.base;
- const rgb_t *palbase = prim->texture.palette;
- UINT32 texrp = prim->texture.rowpixels;
INT32 dudx = setup->dudx;
INT32 dvdx = setup->dvdx;
INT32 endx = setup->endx;
INT32 x, y;
/* ensure all parameters are valid */
- assert(palbase != NULL);
+ assert(prim->texture.palette != NULL);
/* fast case: no coloring, no alpha */
if (prim->color.r >= 1.0f && prim->color.g >= 1.0f && prim->color.b >= 1.0f && IS_OPAQUE(prim->color.a))
@@ -725,7 +751,7 @@ static void FUNC_PREFIX(draw_quad_palette16_none)(const render_primitive *prim,
/* loop over cols */
for (x = setup->startx; x < endx; x++)
{
- UINT32 pix = GET_TEXEL(palette16)(texbase, texrp, curu, curv, palbase);
+ UINT32 pix = GET_TEXEL(palette16)(&prim->texture, curu, curv);
*dest++ = SOURCE32_TO_DEST(pix);
curu += dudx;
curv += dvdx;
@@ -755,7 +781,7 @@ static void FUNC_PREFIX(draw_quad_palette16_none)(const render_primitive *prim,
/* loop over cols */
for (x = setup->startx; x < endx; x++)
{
- UINT32 pix = GET_TEXEL(palette16)(texbase, texrp, curu, curv, palbase);
+ UINT32 pix = GET_TEXEL(palette16)(&prim->texture, curu, curv);
UINT32 r = (SOURCE32_R(pix) * sr) >> 8;
UINT32 g = (SOURCE32_G(pix) * sg) >> 8;
UINT32 b = (SOURCE32_B(pix) * sb) >> 8;
@@ -791,7 +817,7 @@ static void FUNC_PREFIX(draw_quad_palette16_none)(const render_primitive *prim,
/* loop over cols */
for (x = setup->startx; x < endx; x++)
{
- UINT32 pix = GET_TEXEL(palette16)(texbase, texrp, curu, curv, palbase);
+ UINT32 pix = GET_TEXEL(palette16)(&prim->texture, curu, curv);
UINT32 dpix = NO_DEST_READ ? 0 : *dest;
UINT32 r = (SOURCE32_R(pix) * sr + DEST_R(dpix) * invsa) >> 8;
UINT32 g = (SOURCE32_G(pix) * sg + DEST_G(dpix) * invsa) >> 8;
@@ -813,16 +839,13 @@ static void FUNC_PREFIX(draw_quad_palette16_none)(const render_primitive *prim,
static void FUNC_PREFIX(draw_quad_palette16_add)(const render_primitive *prim, void *dstdata, UINT32 pitch, quad_setup_data *setup)
{
- UINT16 *texbase = prim->texture.base;
- const rgb_t *palbase = prim->texture.palette;
- UINT32 texrp = prim->texture.rowpixels;
INT32 dudx = setup->dudx;
INT32 dvdx = setup->dvdx;
INT32 endx = setup->endx;
INT32 x, y;
/* ensure all parameters are valid */
- assert(palbase != NULL);
+ assert(prim->texture.palette != NULL);
/* fast case: no coloring, no alpha */
if (prim->color.r >= 1.0f && prim->color.g >= 1.0f && prim->color.b >= 1.0f && IS_OPAQUE(prim->color.a))
@@ -837,7 +860,7 @@ static void FUNC_PREFIX(draw_quad_palette16_add)(const render_primitive *prim, v
/* loop over cols */
for (x = setup->startx; x < endx; x++)
{
- UINT32 pix = GET_TEXEL(palette16)(texbase, texrp, curu, curv, palbase);
+ UINT32 pix = GET_TEXEL(palette16)(&prim->texture, curu, curv);
if ((pix & 0xffffff) != 0)
{
UINT32 dpix = NO_DEST_READ ? 0 : *dest;
@@ -878,7 +901,7 @@ static void FUNC_PREFIX(draw_quad_palette16_add)(const render_primitive *prim, v
/* loop over cols */
for (x = setup->startx; x < endx; x++)
{
- UINT32 pix = GET_TEXEL(palette16)(texbase, texrp, curu, curv, palbase);
+ UINT32 pix = GET_TEXEL(palette16)(&prim->texture, curu, curv);
if ((pix & 0xffffff) != 0)
{
UINT32 dpix = NO_DEST_READ ? 0 : *dest;
@@ -910,16 +933,13 @@ static void FUNC_PREFIX(draw_quad_palette16_add)(const render_primitive *prim, v
static void FUNC_PREFIX(draw_quad_palettea16_alpha)(const render_primitive *prim, void *dstdata, UINT32 pitch, quad_setup_data *setup)
{
- UINT16 *texbase = prim->texture.base;
- const rgb_t *palbase = prim->texture.palette;
- UINT32 texrp = prim->texture.rowpixels;
INT32 dudx = setup->dudx;
INT32 dvdx = setup->dvdx;
INT32 endx = setup->endx;
INT32 x, y;
/* ensure all parameters are valid */
- assert(palbase != NULL);
+ assert(prim->texture.palette != NULL);
/* fast case: no coloring, no alpha */
if (prim->color.r >= 1.0f && prim->color.g >= 1.0f && prim->color.b >= 1.0f && IS_OPAQUE(prim->color.a))
@@ -934,7 +954,7 @@ static void FUNC_PREFIX(draw_quad_palettea16_alpha)(const render_primitive *prim
/* loop over cols */
for (x = setup->startx; x < endx; x++)
{
- UINT32 pix = GET_TEXEL(palette16)(texbase, texrp, curu, curv, palbase);
+ UINT32 pix = GET_TEXEL(palette16)(&prim->texture, curu, curv);
UINT32 ta = pix >> 24;
if (ta != 0)
{
@@ -977,7 +997,7 @@ static void FUNC_PREFIX(draw_quad_palettea16_alpha)(const render_primitive *prim
/* loop over cols */
for (x = setup->startx; x < endx; x++)
{
- UINT32 pix = GET_TEXEL(palette16)(texbase, texrp, curu, curv, palbase);
+ UINT32 pix = GET_TEXEL(palette16)(&prim->texture, curu, curv);
UINT32 ta = (pix >> 24) * sa;
if (ta != 0)
{
@@ -1010,9 +1030,7 @@ static void FUNC_PREFIX(draw_quad_palettea16_alpha)(const render_primitive *prim
static void FUNC_PREFIX(draw_quad_yuy16_none)(const render_primitive *prim, void *dstdata, UINT32 pitch, quad_setup_data *setup)
{
- UINT16 *texbase = prim->texture.base;
const rgb_t *palbase = prim->texture.palette;
- UINT32 texrp = prim->texture.rowpixels;
INT32 dudx = setup->dudx;
INT32 dvdx = setup->dvdx;
INT32 endx = setup->endx;
@@ -1034,7 +1052,7 @@ static void FUNC_PREFIX(draw_quad_yuy16_none)(const render_primitive *prim, void
/* loop over cols */
for (x = setup->startx; x < endx; x++)
{
- UINT32 pix = ycc_to_rgb(GET_TEXEL(yuy16)(texbase, texrp, curu, curv));
+ UINT32 pix = ycc_to_rgb(GET_TEXEL(yuy16)(&prim->texture, curu, curv));
*dest++ = SOURCE32_TO_DEST(pix);
curu += dudx;
curv += dvdx;
@@ -1047,7 +1065,7 @@ static void FUNC_PREFIX(draw_quad_yuy16_none)(const render_primitive *prim, void
/* loop over cols */
for (x = setup->startx; x < endx; x++)
{
- UINT32 pix = ycc_to_rgb(GET_TEXEL(yuy16)(texbase, texrp, curu, curv));
+ UINT32 pix = ycc_to_rgb(GET_TEXEL(yuy16)(&prim->texture, curu, curv));
*dest++ = SOURCE32_TO_DEST(pix);
curu += dudx;
curv += dvdx;
@@ -1081,7 +1099,7 @@ static void FUNC_PREFIX(draw_quad_yuy16_none)(const render_primitive *prim, void
/* loop over cols */
for (x = setup->startx; x < endx; x++)
{
- UINT32 pix = ycc_to_rgb(GET_TEXEL(yuy16)(texbase, texrp, curu, curv));
+ UINT32 pix = ycc_to_rgb(GET_TEXEL(yuy16)(&prim->texture, curu, curv));
UINT32 r = (SOURCE32_R(pix) * sr) >> 8;
UINT32 g = (SOURCE32_G(pix) * sg) >> 8;
UINT32 b = (SOURCE32_B(pix) * sb) >> 8;
@@ -1098,7 +1116,7 @@ static void FUNC_PREFIX(draw_quad_yuy16_none)(const render_primitive *prim, void
/* loop over cols */
for (x = setup->startx; x < endx; x++)
{
- UINT32 pix = ycc_to_rgb(GET_TEXEL(yuy16)(texbase, texrp, curu, curv));
+ UINT32 pix = ycc_to_rgb(GET_TEXEL(yuy16)(&prim->texture, curu, curv));
UINT32 r = (SOURCE32_R(pix) * sr) >> 8;
UINT32 g = (SOURCE32_G(pix) * sg) >> 8;
UINT32 b = (SOURCE32_B(pix) * sb) >> 8;
@@ -1138,7 +1156,7 @@ static void FUNC_PREFIX(draw_quad_yuy16_none)(const render_primitive *prim, void
/* loop over cols */
for (x = setup->startx; x < endx; x++)
{
- UINT32 pix = ycc_to_rgb(GET_TEXEL(yuy16)(texbase, texrp, curu, curv));
+ UINT32 pix = ycc_to_rgb(GET_TEXEL(yuy16)(&prim->texture, curu, curv));
UINT32 dpix = NO_DEST_READ ? 0 : *dest;
UINT32 r = (SOURCE32_R(pix) * sr + DEST_R(dpix) * invsa) >> 8;
UINT32 g = (SOURCE32_G(pix) * sg + DEST_G(dpix) * invsa) >> 8;
@@ -1156,7 +1174,7 @@ static void FUNC_PREFIX(draw_quad_yuy16_none)(const render_primitive *prim, void
/* loop over cols */
for (x = setup->startx; x < endx; x++)
{
- UINT32 pix = ycc_to_rgb(GET_TEXEL(yuy16)(texbase, texrp, curu, curv));
+ UINT32 pix = ycc_to_rgb(GET_TEXEL(yuy16)(&prim->texture, curu, curv));
UINT32 dpix = NO_DEST_READ ? 0 : *dest;
UINT32 r = (SOURCE32_R(pix) * sr + DEST_R(dpix) * invsa) >> 8;
UINT32 g = (SOURCE32_G(pix) * sg + DEST_G(dpix) * invsa) >> 8;
@@ -1183,9 +1201,7 @@ static void FUNC_PREFIX(draw_quad_yuy16_none)(const render_primitive *prim, void
static void FUNC_PREFIX(draw_quad_rgb15)(const render_primitive *prim, void *dstdata, UINT32 pitch, quad_setup_data *setup)
{
- UINT16 *texbase = prim->texture.base;
const rgb_t *palbase = prim->texture.palette;
- UINT32 texrp = prim->texture.rowpixels;
INT32 dudx = setup->dudx;
INT32 dvdx = setup->dvdx;
INT32 endx = setup->endx;
@@ -1207,7 +1223,7 @@ static void FUNC_PREFIX(draw_quad_rgb15)(const render_primitive *prim, void *dst
/* loop over cols */
for (x = setup->startx; x < endx; x++)
{
- UINT32 pix = GET_TEXEL(rgb15)(texbase, texrp, curu, curv);
+ UINT32 pix = GET_TEXEL(rgb15)(&prim->texture, curu, curv);
*dest++ = SOURCE15_TO_DEST(pix);
curu += dudx;
curv += dvdx;
@@ -1220,7 +1236,7 @@ static void FUNC_PREFIX(draw_quad_rgb15)(const render_primitive *prim, void *dst
/* loop over cols */
for (x = setup->startx; x < endx; x++)
{
- UINT32 pix = GET_TEXEL(rgb15)(texbase, texrp, curu, curv);
+ UINT32 pix = GET_TEXEL(rgb15)(&prim->texture, curu, curv);
UINT32 r = palbase[(pix >> 10) & 0x1f] >> SRCSHIFT_R;
UINT32 g = palbase[(pix >> 5) & 0x1f] >> SRCSHIFT_G;
UINT32 b = palbase[(pix >> 0) & 0x1f] >> SRCSHIFT_B;
@@ -1258,7 +1274,7 @@ static void FUNC_PREFIX(draw_quad_rgb15)(const render_primitive *prim, void *dst
/* loop over cols */
for (x = setup->startx; x < endx; x++)
{
- UINT32 pix = GET_TEXEL(rgb15)(texbase, texrp, curu, curv);
+ UINT32 pix = GET_TEXEL(rgb15)(&prim->texture, curu, curv);
UINT32 r = (SOURCE15_R(pix) * sr) >> 8;
UINT32 g = (SOURCE15_G(pix) * sg) >> 8;
UINT32 b = (SOURCE15_B(pix) * sb) >> 8;
@@ -1275,7 +1291,7 @@ static void FUNC_PREFIX(draw_quad_rgb15)(const render_primitive *prim, void *dst
/* loop over cols */
for (x = setup->startx; x < endx; x++)
{
- UINT32 pix = GET_TEXEL(rgb15)(texbase, texrp, curu, curv);
+ UINT32 pix = GET_TEXEL(rgb15)(&prim->texture, curu, curv);
UINT32 r = (palbase[(pix >> 10) & 0x1f] * sr) >> (8 + SRCSHIFT_R);
UINT32 g = (palbase[(pix >> 5) & 0x1f] * sg) >> (8 + SRCSHIFT_G);
UINT32 b = (palbase[(pix >> 0) & 0x1f] * sb) >> (8 + SRCSHIFT_B);
@@ -1315,7 +1331,7 @@ static void FUNC_PREFIX(draw_quad_rgb15)(const render_primitive *prim, void *dst
/* loop over cols */
for (x = setup->startx; x < endx; x++)
{
- UINT32 pix = GET_TEXEL(rgb15)(texbase, texrp, curu, curv);
+ UINT32 pix = GET_TEXEL(rgb15)(&prim->texture, curu, curv);
UINT32 dpix = NO_DEST_READ ? 0 : *dest;
UINT32 r = (SOURCE15_R(pix) * sr + DEST_R(dpix) * invsa) >> 8;
UINT32 g = (SOURCE15_G(pix) * sg + DEST_G(dpix) * invsa) >> 8;
@@ -1333,7 +1349,7 @@ static void FUNC_PREFIX(draw_quad_rgb15)(const render_primitive *prim, void *dst
/* loop over cols */
for (x = setup->startx; x < endx; x++)
{
- UINT32 pix = GET_TEXEL(rgb15)(texbase, texrp, curu, curv);
+ UINT32 pix = GET_TEXEL(rgb15)(&prim->texture, curu, curv);
UINT32 dpix = NO_DEST_READ ? 0 : *dest;
UINT32 r = ((palbase[(pix >> 10) & 0x1f] >> SRCSHIFT_R) * sr + DEST_R(dpix) * invsa) >> 8;
UINT32 g = ((palbase[(pix >> 5) & 0x1f] >> SRCSHIFT_G) * sg + DEST_G(dpix) * invsa) >> 8;
@@ -1361,9 +1377,7 @@ static void FUNC_PREFIX(draw_quad_rgb15)(const render_primitive *prim, void *dst
static void FUNC_PREFIX(draw_quad_rgb32)(const render_primitive *prim, void *dstdata, UINT32 pitch, quad_setup_data *setup)
{
- UINT32 *texbase = prim->texture.base;
const rgb_t *palbase = prim->texture.palette;
- UINT32 texrp = prim->texture.rowpixels;
INT32 dudx = setup->dudx;
INT32 dvdx = setup->dvdx;
INT32 endx = setup->endx;
@@ -1385,7 +1399,7 @@ static void FUNC_PREFIX(draw_quad_rgb32)(const render_primitive *prim, void *dst
/* loop over cols */
for (x = setup->startx; x < endx; x++)
{
- UINT32 pix = GET_TEXEL(rgb32)(texbase, texrp, curu, curv);
+ UINT32 pix = GET_TEXEL(rgb32)(&prim->texture, curu, curv);
*dest++ = SOURCE32_TO_DEST(pix);
curu += dudx;
curv += dvdx;
@@ -1398,7 +1412,7 @@ static void FUNC_PREFIX(draw_quad_rgb32)(const render_primitive *prim, void *dst
/* loop over cols */
for (x = setup->startx; x < endx; x++)
{
- UINT32 pix = GET_TEXEL(rgb32)(texbase, texrp, curu, curv);
+ UINT32 pix = GET_TEXEL(rgb32)(&prim->texture, curu, curv);
UINT32 r = palbase[(pix >> 16) & 0xff] >> SRCSHIFT_R;
UINT32 g = palbase[(pix >> 8) & 0xff] >> SRCSHIFT_G;
UINT32 b = palbase[(pix >> 0) & 0xff] >> SRCSHIFT_B;
@@ -1436,7 +1450,7 @@ static void FUNC_PREFIX(draw_quad_rgb32)(const render_primitive *prim, void *dst
/* loop over cols */
for (x = setup->startx; x < endx; x++)
{
- UINT32 pix = GET_TEXEL(rgb32)(texbase, texrp, curu, curv);
+ UINT32 pix = GET_TEXEL(rgb32)(&prim->texture, curu, curv);
UINT32 r = (SOURCE32_R(pix) * sr) >> 8;
UINT32 g = (SOURCE32_G(pix) * sg) >> 8;
UINT32 b = (SOURCE32_B(pix) * sb) >> 8;
@@ -1453,7 +1467,7 @@ static void FUNC_PREFIX(draw_quad_rgb32)(const render_primitive *prim, void *dst
/* loop over cols */
for (x = setup->startx; x < endx; x++)
{
- UINT32 pix = GET_TEXEL(rgb32)(texbase, texrp, curu, curv);
+ UINT32 pix = GET_TEXEL(rgb32)(&prim->texture, curu, curv);
UINT32 r = (palbase[(pix >> 16) & 0xff] * sr) >> (8 + SRCSHIFT_R);
UINT32 g = (palbase[(pix >> 8) & 0xff] * sg) >> (8 + SRCSHIFT_G);
UINT32 b = (palbase[(pix >> 0) & 0xff] * sb) >> (8 + SRCSHIFT_B);
@@ -1493,7 +1507,7 @@ static void FUNC_PREFIX(draw_quad_rgb32)(const render_primitive *prim, void *dst
/* loop over cols */
for (x = setup->startx; x < endx; x++)
{
- UINT32 pix = GET_TEXEL(rgb32)(texbase, texrp, curu, curv);
+ UINT32 pix = GET_TEXEL(rgb32)(&prim->texture, curu, curv);
UINT32 dpix = NO_DEST_READ ? 0 : *dest;
UINT32 r = (SOURCE32_R(pix) * sr + DEST_R(dpix) * invsa) >> 8;
UINT32 g = (SOURCE32_G(pix) * sg + DEST_G(dpix) * invsa) >> 8;
@@ -1511,7 +1525,7 @@ static void FUNC_PREFIX(draw_quad_rgb32)(const render_primitive *prim, void *dst
/* loop over cols */
for (x = setup->startx; x < endx; x++)
{
- UINT32 pix = GET_TEXEL(rgb32)(texbase, texrp, curu, curv);
+ UINT32 pix = GET_TEXEL(rgb32)(&prim->texture, curu, curv);
UINT32 dpix = NO_DEST_READ ? 0 : *dest;
UINT32 r = ((palbase[(pix >> 16) & 0xff] >> SRCSHIFT_R) * sr + DEST_R(dpix) * invsa) >> 8;
UINT32 g = ((palbase[(pix >> 8) & 0xff] >> SRCSHIFT_G) * sg + DEST_G(dpix) * invsa) >> 8;
@@ -1539,9 +1553,7 @@ static void FUNC_PREFIX(draw_quad_rgb32)(const render_primitive *prim, void *dst
static void FUNC_PREFIX(draw_quad_argb32_alpha)(const render_primitive *prim, void *dstdata, UINT32 pitch, quad_setup_data *setup)
{
- UINT32 *texbase = prim->texture.base;
const rgb_t *palbase = prim->texture.palette;
- UINT32 texrp = prim->texture.rowpixels;
INT32 dudx = setup->dudx;
INT32 dvdx = setup->dvdx;
INT32 endx = setup->endx;
@@ -1563,7 +1575,7 @@ static void FUNC_PREFIX(draw_quad_argb32_alpha)(const render_primitive *prim, vo
/* loop over cols */
for (x = setup->startx; x < endx; x++)
{
- UINT32 pix = GET_TEXEL(argb32)(texbase, texrp, curu, curv);
+ UINT32 pix = GET_TEXEL(argb32)(&prim->texture, curu, curv);
UINT32 ta = pix >> 24;
if (ta != 0)
{
@@ -1587,7 +1599,7 @@ static void FUNC_PREFIX(draw_quad_argb32_alpha)(const render_primitive *prim, vo
/* loop over cols */
for (x = setup->startx; x < endx; x++)
{
- UINT32 pix = GET_TEXEL(argb32)(texbase, texrp, curu, curv);
+ UINT32 pix = GET_TEXEL(argb32)(&prim->texture, curu, curv);
UINT32 ta = pix >> 24;
if (ta != 0)
{
@@ -1634,7 +1646,7 @@ static void FUNC_PREFIX(draw_quad_argb32_alpha)(const render_primitive *prim, vo
/* loop over cols */
for (x = setup->startx; x < endx; x++)
{
- UINT32 pix = GET_TEXEL(argb32)(texbase, texrp, curu, curv);
+ UINT32 pix = GET_TEXEL(argb32)(&prim->texture, curu, curv);
UINT32 ta = (pix >> 24) * sa;
if (ta != 0)
{
@@ -1659,7 +1671,7 @@ static void FUNC_PREFIX(draw_quad_argb32_alpha)(const render_primitive *prim, vo
/* loop over cols */
for (x = setup->startx; x < endx; x++)
{
- UINT32 pix = GET_TEXEL(argb32)(texbase, texrp, curu, curv);
+ UINT32 pix = GET_TEXEL(argb32)(&prim->texture, curu, curv);
UINT32 ta = (pix >> 24) * sa;
if (ta != 0)
{
@@ -1688,9 +1700,7 @@ static void FUNC_PREFIX(draw_quad_argb32_alpha)(const render_primitive *prim, vo
static void FUNC_PREFIX(draw_quad_argb32_multiply)(const render_primitive *prim, void *dstdata, UINT32 pitch, quad_setup_data *setup)
{
- UINT32 *texbase = prim->texture.base;
const rgb_t *palbase = prim->texture.palette;
- UINT32 texrp = prim->texture.rowpixels;
INT32 dudx = setup->dudx;
INT32 dvdx = setup->dvdx;
INT32 endx = setup->endx;
@@ -1716,7 +1726,7 @@ static void FUNC_PREFIX(draw_quad_argb32_multiply)(const render_primitive *prim,
/* loop over cols */
for (x = setup->startx; x < endx; x++)
{
- UINT32 pix = GET_TEXEL(argb32)(texbase, texrp, curu, curv);
+ UINT32 pix = GET_TEXEL(argb32)(&prim->texture, curu, curv);
UINT32 dpix = NO_DEST_READ ? 0 : *dest;
UINT32 r = (SOURCE32_R(pix) * DEST_R(dpix)) >> (8 - SRCSHIFT_R);
UINT32 g = (SOURCE32_G(pix) * DEST_G(dpix)) >> (8 - SRCSHIFT_G);
@@ -1732,7 +1742,7 @@ static void FUNC_PREFIX(draw_quad_argb32_multiply)(const render_primitive *prim,
/* loop over cols */
for (x = setup->startx; x < endx; x++)
{
- UINT32 pix = GET_TEXEL(argb32)(texbase, texrp, curu, curv);
+ UINT32 pix = GET_TEXEL(argb32)(&prim->texture, curu, curv);
UINT32 dpix = NO_DEST_READ ? 0 : *dest;
UINT32 r = (palbase[(pix >> 16) & 0xff] * DEST_R(dpix)) >> 8;
UINT32 g = (palbase[(pix >> 8) & 0xff] * DEST_G(dpix)) >> 8;
@@ -1771,7 +1781,7 @@ static void FUNC_PREFIX(draw_quad_argb32_multiply)(const render_primitive *prim,
/* loop over cols */
for (x = setup->startx; x < endx; x++)
{
- UINT32 pix = GET_TEXEL(argb32)(texbase, texrp, curu, curv);
+ UINT32 pix = GET_TEXEL(argb32)(&prim->texture, curu, curv);
UINT32 dpix = NO_DEST_READ ? 0 : *dest;
UINT32 r = (SOURCE32_R(pix) * sr * DEST_R(dpix)) >> (16 - SRCSHIFT_R);
UINT32 g = (SOURCE32_G(pix) * sg * DEST_G(dpix)) >> (16 - SRCSHIFT_G);
@@ -1787,7 +1797,7 @@ static void FUNC_PREFIX(draw_quad_argb32_multiply)(const render_primitive *prim,
/* loop over cols */
for (x = setup->startx; x < endx; x++)
{
- UINT32 pix = GET_TEXEL(argb32)(texbase, texrp, curu, curv);
+ UINT32 pix = GET_TEXEL(argb32)(&prim->texture, curu, curv);
UINT32 dpix = NO_DEST_READ ? 0 : *dest;
UINT32 r = (palbase[(pix >> 16) & 0xff] * sr * DEST_R(dpix)) >> 16;
UINT32 g = (palbase[(pix >> 8) & 0xff] * sg * DEST_G(dpix)) >> 16;
@@ -1810,9 +1820,7 @@ static void FUNC_PREFIX(draw_quad_argb32_multiply)(const render_primitive *prim,
static void FUNC_PREFIX(draw_quad_argb32_add)(const render_primitive *prim, void *dstdata, UINT32 pitch, quad_setup_data *setup)
{
- UINT32 *texbase = prim->texture.base;
const rgb_t *palbase = prim->texture.palette;
- UINT32 texrp = prim->texture.rowpixels;
INT32 dudx = setup->dudx;
INT32 dvdx = setup->dvdx;
INT32 endx = setup->endx;
@@ -1838,7 +1846,7 @@ static void FUNC_PREFIX(draw_quad_argb32_add)(const render_primitive *prim, void
/* loop over cols */
for (x = setup->startx; x < endx; x++)
{
- UINT32 pix = GET_TEXEL(argb32)(texbase, texrp, curu, curv);
+ UINT32 pix = GET_TEXEL(argb32)(&prim->texture, curu, curv);
UINT32 ta = pix >> 24;
if (ta != 0)
{
@@ -1863,7 +1871,7 @@ static void FUNC_PREFIX(draw_quad_argb32_add)(const render_primitive *prim, void
/* loop over cols */
for (x = setup->startx; x < endx; x++)
{
- UINT32 pix = GET_TEXEL(argb32)(texbase, texrp, curu, curv);
+ UINT32 pix = GET_TEXEL(argb32)(&prim->texture, curu, curv);
UINT32 ta = pix >> 24;
if (ta != 0)
{
@@ -1911,7 +1919,7 @@ static void FUNC_PREFIX(draw_quad_argb32_add)(const render_primitive *prim, void
/* loop over cols */
for (x = setup->startx; x < endx; x++)
{
- UINT32 pix = GET_TEXEL(argb32)(texbase, texrp, curu, curv);
+ UINT32 pix = GET_TEXEL(argb32)(&prim->texture, curu, curv);
UINT32 ta = (pix >> 24) * sa;
if (ta != 0)
{
@@ -1936,7 +1944,7 @@ static void FUNC_PREFIX(draw_quad_argb32_add)(const render_primitive *prim, void
/* loop over cols */
for (x = setup->startx; x < endx; x++)
{
- UINT32 pix = GET_TEXEL(argb32)(texbase, texrp, curu, curv);
+ UINT32 pix = GET_TEXEL(argb32)(&prim->texture, curu, curv);
UINT32 ta = (pix >> 24) * sa;
if (ta != 0)
{
diff --git a/src/emu/ui.c b/src/emu/ui.c
index 425b11390c8..b72d504fe17 100644
--- a/src/emu/ui.c
+++ b/src/emu/ui.c
@@ -1315,14 +1315,14 @@ static UINT32 handler_ingame(running_machine *machine, UINT32 state)
/* toggle movie recording */
if (input_ui_pressed(machine, IPT_UI_RECORD_MOVIE))
{
- if (!video_mng_is_movie_active(machine->primary_screen))
+ if (!video_mng_is_movie_active(machine))
{
- video_mng_begin_recording(machine->primary_screen, NULL);
+ video_mng_begin_recording(machine, NULL);
popmessage("REC START");
}
else
{
- video_mng_end_recording(machine->primary_screen);
+ video_mng_end_recording(machine);
popmessage("REC STOP");
}
}
diff --git a/src/emu/video.c b/src/emu/video.c
index 5beb54bb571..7aa855d14d9 100644
--- a/src/emu/video.c
+++ b/src/emu/video.c
@@ -38,7 +38,8 @@
#define SUBSECONDS_PER_SPEED_UPDATE (ATTOSECONDS_PER_SECOND / 4)
#define PAUSED_REFRESH_RATE (30)
#define MAX_VBLANK_CALLBACKS (10)
-#define DEFAULT_FRAME_PERIOD ATTOTIME_IN_HZ(60)
+#define DEFAULT_FRAME_RATE 60
+#define DEFAULT_FRAME_PERIOD ATTOTIME_IN_HZ(DEFAULT_FRAME_RATE)
@@ -78,11 +79,6 @@ struct _screen_state
/* screen specific VBLANK callbacks */
vblank_state_changed_func vblank_callback[MAX_VBLANK_CALLBACKS]; /* the array of callbacks */
-
- /* movie recording */
- mame_file * mng_file; /* handle to the open movie file */
- avi_file * avi_file; /* handle to the open movie file */
- UINT32 movie_frame; /* current movie frame number */
};
@@ -128,6 +124,16 @@ struct _video_global
/* snapshot stuff */
render_target * snap_target; /* screen shapshot target */
bitmap_t * snap_bitmap; /* screen snapshot bitmap */
+ UINT8 snap_native; /* are we using native per-screen layouts? */
+ INT32 snap_width; /* width of snapshots (0 == auto) */
+ INT32 snap_height; /* height of snapshots (0 == auto) */
+
+ /* movie recording */
+ mame_file * mng_file; /* handle to the open movie file */
+ avi_file * avi_file; /* handle to the open movie file */
+ attotime movie_frame_period; /* period of a single movie frame */
+ attotime movie_next_frame_time; /* time of next frame */
+ UINT32 movie_frame; /* current movie frame number */
};
@@ -190,8 +196,8 @@ static void create_snapshot_bitmap(const device_config *screen);
static file_error mame_fopen_next(running_machine *machine, const char *pathoption, const char *extension, mame_file **file);
/* movie recording */
-static void video_mng_record_frame(const device_config *screen);
-static void video_avi_record_frame(const device_config *screen);
+static void video_mng_record_frame(running_machine *machine);
+static void video_avi_record_frame(running_machine *machine);
/* software rendering */
static void rgb888_draw_primitives(const render_primitive *primlist, void *dstdata, UINT32 width, UINT32 height, UINT32 pitch);
@@ -295,6 +301,7 @@ INLINE int original_speed_setting(void)
void video_init(running_machine *machine)
{
const char *filename;
+ const char *viewname;
/* validate */
assert(machine != NULL);
@@ -339,21 +346,51 @@ void video_init(running_machine *machine)
pdrawgfx_shadow_lowpri = 0;
/* create a render target for snapshots */
- if (machine->primary_screen != NULL)
- {
+ viewname = options_get_string(mame_options(), OPTION_SNAPVIEW);
+ global.snap_native = (machine->primary_screen != NULL && (viewname[0] == 0 || strcmp(viewname, "native") == 0));
+ if (global.snap_native)
global.snap_target = render_target_alloc(layout_snap, RENDER_CREATE_SINGLE_FILE | RENDER_CREATE_HIDDEN);
- assert(global.snap_target != NULL);
+ else
+ global.snap_target = render_target_alloc(NULL, RENDER_CREATE_HIDDEN);
+ assert(global.snap_target != NULL);
+
+ /* if we are using the native layout, turn off all accoutrements */
+ if (global.snap_native)
render_target_set_layer_config(global.snap_target, 0);
+
+ /* otherwise, find the requested view and select it */
+ else
+ {
+ int viewindex;
+
+ /* scan for a match or partial match */
+ for (viewindex = 0; ; viewindex++)
+ {
+ const char *name = render_target_get_view_name(global.snap_target, viewindex);
+
+ /* stop scanning when we hit NULL */
+ if (name == NULL)
+ break;
+ if (mame_strnicmp(name, viewname, strlen(viewname)) == 0)
+ {
+ render_target_set_view(global.snap_target, viewindex);
+ break;
+ }
+ }
}
+
+ /* extract snap resolution if present */
+ if (sscanf(options_get_string(mame_options(), OPTION_SNAPSIZE), "%dx%d", &global.snap_width, &global.snap_height) != 2)
+ global.snap_width = global.snap_height = 0;
/* start recording movie if specified */
filename = options_get_string(mame_options(), OPTION_MNGWRITE);
- if (filename[0] != 0 && machine->primary_screen != NULL)
- video_mng_begin_recording(machine->primary_screen, filename);
+ if (filename[0] != 0)
+ video_mng_begin_recording(machine, filename);
filename = options_get_string(mame_options(), OPTION_AVIWRITE);
- if (filename[0] != 0 && machine->primary_screen != NULL)
- video_avi_begin_recording(machine->primary_screen, filename);
+ if (filename[0] != 0)
+ video_avi_begin_recording(machine, filename);
/* if no screens, create a periodic timer to drive updates */
if (machine->primary_screen == NULL)
@@ -379,8 +416,8 @@ static void video_exit(running_machine *machine)
/* stop recording any movie */
if (machine->primary_screen != NULL)
{
- video_mng_end_recording(machine->primary_screen);
- video_avi_end_recording(machine->primary_screen);
+ video_mng_end_recording(machine);
+ video_avi_end_recording(machine);
}
/* free all the graphics elements */
@@ -1515,13 +1552,6 @@ static int finish_screen_updates(running_machine *machine)
render_container_empty(render_container_get_screen(screen));
render_screen_add_quad(screen, 0.0f, 0.0f, 1.0f, 1.0f, MAKE_ARGB(0xff,0xff,0xff,0xff), state->texture[state->curtexture], PRIMFLAG_BLENDMODE(BLENDMODE_NONE) | PRIMFLAG_SCREENTEX(1));
}
-
- /* update our movie recording state */
- if (!mame_is_paused(machine))
- {
- video_mng_record_frame(screen);
- video_avi_record_frame(screen);
- }
}
/* reset the screen changed flags */
@@ -1530,6 +1560,13 @@ static int finish_screen_updates(running_machine *machine)
state->changed = FALSE;
}
+ /* update our movie recording state */
+ if (!mame_is_paused(machine))
+ {
+ video_mng_record_frame(machine);
+ video_avi_record_frame(machine);
+ }
+
/* draw any crosshairs */
for (screen = video_screen_first(machine->config); screen != NULL; screen = video_screen_next(screen))
crosshair_render(screen);
@@ -2089,7 +2126,7 @@ static void recompute_speed(running_machine *machine, attotime emutime)
filerr = mame_fopen(SEARCHPATH_SCREENSHOT, astring_c(fname), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS, &file);
if (filerr == FILERR_NONE)
{
- video_screen_save_snapshot(machine->primary_screen, file);
+ video_screen_save_snapshot(machine, machine->primary_screen, file);
mame_fclose(file);
}
astring_free(fname);
@@ -2111,15 +2148,15 @@ static void recompute_speed(running_machine *machine, attotime emutime)
to the given file handle
-------------------------------------------------*/
-void video_screen_save_snapshot(const device_config *screen, mame_file *fp)
+void video_screen_save_snapshot(running_machine *machine, const device_config *screen, mame_file *fp)
{
- const rgb_t *palette;
png_info pnginfo = { 0 };
+ const rgb_t *palette;
png_error error;
char text[256];
/* validate */
- assert(screen != NULL);
+ assert(!global.snap_native || screen != NULL);
assert(fp != NULL);
/* create the bitmap to pass in */
@@ -2128,12 +2165,12 @@ void video_screen_save_snapshot(const device_config *screen, mame_file *fp)
/* add two text entries describing the image */
sprintf(text, APPNAME " %s", build_version);
png_add_text(&pnginfo, "Software", text);
- sprintf(text, "%s %s", screen->machine->gamedrv->manufacturer, screen->machine->gamedrv->description);
+ sprintf(text, "%s %s", machine->gamedrv->manufacturer, machine->gamedrv->description);
png_add_text(&pnginfo, "System", text);
/* now do the actual work */
- palette = (screen->machine->palette != NULL) ? palette_entry_list_adjusted(screen->machine->palette) : NULL;
- error = png_write_bitmap(mame_core_file(fp), &pnginfo, global.snap_bitmap, screen->machine->config->total_colors, palette);
+ palette = (machine->palette != NULL) ? palette_entry_list_adjusted(machine->palette) : NULL;
+ error = png_write_bitmap(mame_core_file(fp), &pnginfo, global.snap_bitmap, machine->config->total_colors, palette);
/* free any data allocated */
png_free(&pnginfo);
@@ -2153,18 +2190,33 @@ void video_save_active_screen_snapshots(running_machine *machine)
/* validate */
assert(machine != NULL);
assert(machine->config != NULL);
-
- /* write one snapshot per visible screen */
- for (screen = video_screen_first(machine->config); screen != NULL; screen = video_screen_next(screen))
- if (render_is_live_screen(screen))
- {
- file_error filerr = mame_fopen_next(machine, SEARCHPATH_SCREENSHOT, "png", &fp);
- if (filerr == FILERR_NONE)
+
+ /* if we're native, then write one snapshot per visible screen */
+ if (global.snap_native)
+ {
+ /* write one snapshot per visible screen */
+ for (screen = video_screen_first(machine->config); screen != NULL; screen = video_screen_next(screen))
+ if (render_is_live_screen(screen))
{
- video_screen_save_snapshot(screen, fp);
- mame_fclose(fp);
+ file_error filerr = mame_fopen_next(machine, SEARCHPATH_SCREENSHOT, "png", &fp);
+ if (filerr == FILERR_NONE)
+ {
+ video_screen_save_snapshot(machine, screen, fp);
+ mame_fclose(fp);
+ }
}
+ }
+
+ /* otherwise, just write a single snapshot */
+ else
+ {
+ file_error filerr = mame_fopen_next(machine, SEARCHPATH_SCREENSHOT, "png", &fp);
+ if (filerr == FILERR_NONE)
+ {
+ video_screen_save_snapshot(machine, NULL, fp);
+ mame_fclose(fp);
}
+ }
}
@@ -2181,12 +2233,18 @@ static void create_snapshot_bitmap(const device_config *screen)
int view_index;
/* select the appropriate view in our dummy target */
- view_index = device_list_index(screen->machine->config->devicelist, VIDEO_SCREEN, screen->tag);
- assert(view_index != -1);
- render_target_set_view(global.snap_target, view_index);
+ if (global.snap_native && screen != NULL)
+ {
+ view_index = device_list_index(screen->machine->config->devicelist, VIDEO_SCREEN, screen->tag);
+ assert(view_index != -1);
+ render_target_set_view(global.snap_target, view_index);
+ }
/* get the minimum width/height and set it on the target */
- render_target_get_minimum_size(global.snap_target, &width, &height);
+ width = global.snap_width;
+ height = global.snap_height;
+ if (width == 0 || height == 0)
+ render_target_get_minimum_size(global.snap_target, &width, &height);
render_target_set_bounds(global.snap_target, width, height, 0);
/* if we don't have a bitmap, or if it's not the right size, allocate a new one */
@@ -2285,10 +2343,9 @@ static file_error mame_fopen_next(running_machine *machine, const char *pathopti
MNG movie is currently being recorded
-------------------------------------------------*/
-int video_mng_is_movie_active(const device_config *screen)
+int video_mng_is_movie_active(running_machine *machine)
{
- screen_state *state = get_safe_token(screen);
- return (state->mng_file != NULL);
+ return (global.mng_file != NULL);
}
@@ -2297,21 +2354,43 @@ int video_mng_is_movie_active(const device_config *screen)
of a MNG movie
-------------------------------------------------*/
-void video_mng_begin_recording(const device_config *screen, const char *name)
+void video_mng_begin_recording(running_machine *machine, const char *name)
{
- screen_state *state = get_safe_token(screen);
+ screen_state *state = NULL;
file_error filerr;
+ png_error pngerr;
+ int rate;
/* close any existing movie file */
- if (state->mng_file != NULL)
- video_mng_end_recording(screen);
+ if (global.mng_file != NULL)
+ video_mng_end_recording(machine);
+
+ /* look up the primary screen */
+ if (machine->primary_screen != NULL)
+ state = get_safe_token(machine->primary_screen);
+
+ /* create a snapshot bitmap so we know what the target size is */
+ create_snapshot_bitmap(NULL);
/* create a new movie file and start recording */
if (name != NULL)
- filerr = mame_fopen(SEARCHPATH_MOVIE, name, OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS, &state->mng_file);
+ filerr = mame_fopen(SEARCHPATH_MOVIE, name, OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS, &global.mng_file);
else
- filerr = mame_fopen_next(screen->machine, SEARCHPATH_MOVIE, "mng", &state->mng_file);
- state->movie_frame = 0;
+ filerr = mame_fopen_next(machine, SEARCHPATH_MOVIE, "mng", &global.mng_file);
+
+ /* start the capture */
+ rate = (state != NULL) ? ATTOSECONDS_TO_HZ(state->frame_period) : DEFAULT_FRAME_RATE;
+ pngerr = mng_capture_start(mame_core_file(global.mng_file), global.snap_bitmap, rate);
+ if (pngerr != PNGERR_NONE)
+ {
+ video_mng_end_recording(machine);
+ return;
+ }
+
+ /* compute the frame time */
+ global.movie_next_frame_time = timer_get_time();
+ global.movie_frame_period = ATTOTIME_IN_HZ(rate);
+ global.movie_frame = 0;
}
@@ -2320,17 +2399,15 @@ void video_mng_begin_recording(const device_config *screen, const char *name)
a MNG movie
-------------------------------------------------*/
-void video_mng_end_recording(const device_config *screen)
+void video_mng_end_recording(running_machine *machine)
{
- screen_state *state = get_safe_token(screen);
-
/* close the file if it exists */
- if (state->mng_file != NULL)
+ if (global.mng_file != NULL)
{
- mng_capture_stop(mame_core_file(state->mng_file));
- mame_fclose(state->mng_file);
- state->mng_file = NULL;
- state->movie_frame = 0;
+ mng_capture_stop(mame_core_file(global.mng_file));
+ mame_fclose(global.mng_file);
+ global.mng_file = NULL;
+ global.movie_frame = 0;
}
}
@@ -2340,49 +2417,50 @@ void video_mng_end_recording(const device_config *screen)
movie
-------------------------------------------------*/
-static void video_mng_record_frame(const device_config *screen)
+static void video_mng_record_frame(running_machine *machine)
{
- screen_state *state = get_safe_token(screen);
- const rgb_t *palette;
-
/* only record if we have a file */
- if (state->mng_file != NULL)
+ if (global.mng_file != NULL)
{
+ attotime curtime = timer_get_time();
png_info pnginfo = { 0 };
png_error error;
profiler_mark(PROFILER_MOVIE_REC);
/* create the bitmap */
- create_snapshot_bitmap(screen);
+ create_snapshot_bitmap(NULL);
- /* track frames */
- if (state->movie_frame++ == 0)
+ /* loop until we hit the right time */
+ while (attotime_compare(global.movie_next_frame_time, curtime) <= 0)
{
- char text[256];
+ const rgb_t *palette;
/* set up the text fields in the movie info */
- sprintf(text, APPNAME " %s", build_version);
- png_add_text(&pnginfo, "Software", text);
- sprintf(text, "%s %s", screen->machine->gamedrv->manufacturer, screen->machine->gamedrv->description);
- png_add_text(&pnginfo, "System", text);
+ if (global.movie_frame == 0)
+ {
+ char text[256];
- /* start the capture */
- error = mng_capture_start(mame_core_file(state->mng_file), global.snap_bitmap, ATTOSECONDS_TO_HZ(state->frame_period));
+ sprintf(text, APPNAME " %s", build_version);
+ png_add_text(&pnginfo, "Software", text);
+ sprintf(text, "%s %s", machine->gamedrv->manufacturer, machine->gamedrv->description);
+ png_add_text(&pnginfo, "System", text);
+ }
+
+ /* write the next frame */
+ palette = (machine->palette != NULL) ? palette_entry_list_adjusted(machine->palette) : NULL;
+ error = mng_capture_frame(mame_core_file(global.mng_file), &pnginfo, global.snap_bitmap, machine->config->total_colors, palette);
+ png_free(&pnginfo);
if (error != PNGERR_NONE)
{
- png_free(&pnginfo);
- video_mng_end_recording(screen);
- return;
+ video_mng_end_recording(machine);
+ break;
}
- }
- /* write the next frame */
- palette = (screen->machine->palette != NULL) ? palette_entry_list_adjusted(screen->machine->palette) : NULL;
- error = mng_capture_frame(mame_core_file(state->mng_file), &pnginfo, global.snap_bitmap, screen->machine->config->total_colors, palette);
- png_free(&pnginfo);
- if (error != PNGERR_NONE)
- video_mng_end_recording(screen);
+ /* advance time */
+ global.movie_next_frame_time = attotime_add(global.movie_next_frame_time, global.movie_frame_period);
+ global.movie_frame++;
+ }
profiler_mark(PROFILER_END);
}
@@ -2399,24 +2477,28 @@ static void video_mng_record_frame(const device_config *screen)
of an AVI movie
-------------------------------------------------*/
-void video_avi_begin_recording(const device_config *screen, const char *name)
+void video_avi_begin_recording(running_machine *machine, const char *name)
{
- screen_state *state = get_safe_token(screen);
+ screen_state *state = NULL;
avi_movie_info info;
mame_file *tempfile;
file_error filerr;
avi_error avierr;
/* close any existing movie file */
- if (state->avi_file != NULL)
- video_avi_end_recording(screen);
+ if (global.avi_file != NULL)
+ video_avi_end_recording(machine);
+
+ /* look up the primary screen */
+ if (machine->primary_screen != NULL)
+ state = get_safe_token(machine->primary_screen);
/* create a snapshot bitmap so we know what the target size is */
- create_snapshot_bitmap(screen);
+ create_snapshot_bitmap(NULL);
/* build up information about this new movie */
info.video_format = 0;
- info.video_timescale = 1000 * ATTOSECONDS_TO_HZ(state->frame_period);
+ info.video_timescale = 1000 * ((state != NULL) ? ATTOSECONDS_TO_HZ(state->frame_period) : DEFAULT_FRAME_RATE);
info.video_sampletime = 1000;
info.video_numsamples = 0;
info.video_width = global.snap_bitmap->width;
@@ -2425,18 +2507,22 @@ void video_avi_begin_recording(const device_config *screen, const char *name)
info.audio_format = 0;
info.audio_timescale = 1;
- info.audio_sampletime = screen->machine->sample_rate;
+ info.audio_sampletime = machine->sample_rate;
info.audio_numsamples = 0;
info.audio_channels = 2;
info.audio_samplebits = 16;
- info.audio_samplerate = screen->machine->sample_rate;
+ info.audio_samplerate = machine->sample_rate;
/* create a new temporary movie file */
if (name != NULL)
filerr = mame_fopen(SEARCHPATH_MOVIE, name, OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS, &tempfile);
else
- filerr = mame_fopen_next(screen->machine, SEARCHPATH_MOVIE, "avi", &tempfile);
- state->movie_frame = 0;
+ filerr = mame_fopen_next(machine, SEARCHPATH_MOVIE, "avi", &tempfile);
+
+ /* reset our tracking */
+ global.movie_frame = 0;
+ global.movie_next_frame_time = timer_get_time();
+ global.movie_frame_period = attotime_div(ATTOTIME_IN_SEC(1000), info.video_timescale);
/* if we succeeded, make a copy of the name and create the real file over top */
if (filerr == FILERR_NONE)
@@ -2445,7 +2531,7 @@ void video_avi_begin_recording(const device_config *screen, const char *name)
mame_fclose(tempfile);
/* create the file and free the string */
- avierr = avi_create(astring_c(fullname), &info, &state->avi_file);
+ avierr = avi_create(astring_c(fullname), &info, &global.avi_file);
astring_free(fullname);
}
}
@@ -2456,16 +2542,14 @@ void video_avi_begin_recording(const device_config *screen, const char *name)
a avi movie
-------------------------------------------------*/
-void video_avi_end_recording(const device_config *screen)
+void video_avi_end_recording(running_machine *machine)
{
- screen_state *state = get_safe_token(screen);
-
/* close the file if it exists */
- if (state->avi_file != NULL)
+ if (global.avi_file != NULL)
{
- avi_close(state->avi_file);
- state->avi_file = NULL;
- state->movie_frame = 0;
+ avi_close(global.avi_file);
+ global.avi_file = NULL;
+ global.movie_frame = 0;
}
}
@@ -2475,24 +2559,34 @@ void video_avi_end_recording(const device_config *screen)
movie
-------------------------------------------------*/
-static void video_avi_record_frame(const device_config *screen)
+static void video_avi_record_frame(running_machine *machine)
{
- screen_state *state = get_safe_token(screen);
-
/* only record if we have a file */
- if (state->avi_file != NULL)
+ if (global.avi_file != NULL)
{
+ attotime curtime = timer_get_time();
avi_error avierr;
profiler_mark(PROFILER_MOVIE_REC);
-
+
/* create the bitmap */
- create_snapshot_bitmap(screen);
+ create_snapshot_bitmap(NULL);
- /* write the next frame */
- avierr = avi_append_video_frame_rgb32(state->avi_file, global.snap_bitmap);
- if (avierr != AVIERR_NONE)
- video_avi_end_recording(screen);
+ /* loop until we hit the right time */
+ while (attotime_compare(global.movie_next_frame_time, curtime) <= 0)
+ {
+ /* write the next frame */
+ avierr = avi_append_video_frame_rgb32(global.avi_file, global.snap_bitmap);
+ if (avierr != AVIERR_NONE)
+ {
+ video_avi_end_recording(machine);
+ break;
+ }
+
+ /* advance time */
+ global.movie_next_frame_time = attotime_add(global.movie_next_frame_time, global.movie_frame_period);
+ global.movie_frame++;
+ }
profiler_mark(PROFILER_END);
}
@@ -2506,29 +2600,21 @@ static void video_avi_record_frame(const device_config *screen)
void video_avi_add_sound(running_machine *machine, const INT16 *sound, int numsamples)
{
- const device_config *screen;
-
- /* loop over screens that might be recording */
- for (screen = video_screen_first(machine->config); screen != NULL; screen = video_screen_next(screen))
+ /* only record if we have a file */
+ if (global.avi_file != NULL)
{
- screen_state *state = get_safe_token(screen);
-
- /* only record if we have a file */
- if (state->avi_file != NULL)
- {
- avi_error avierr;
+ avi_error avierr;
- profiler_mark(PROFILER_MOVIE_REC);
+ profiler_mark(PROFILER_MOVIE_REC);
- /* write the next frame */
- avierr = avi_append_sound_samples(state->avi_file, 0, sound + 0, numsamples, 1);
- if (avierr == AVIERR_NONE)
- avierr = avi_append_sound_samples(state->avi_file, 1, sound + 1, numsamples, 1);
- if (avierr != AVIERR_NONE)
- video_avi_end_recording(screen);
+ /* write the next frame */
+ avierr = avi_append_sound_samples(global.avi_file, 0, sound + 0, numsamples, 1);
+ if (avierr == AVIERR_NONE)
+ avierr = avi_append_sound_samples(global.avi_file, 1, sound + 1, numsamples, 1);
+ if (avierr != AVIERR_NONE)
+ video_avi_end_recording(machine);
- profiler_mark(PROFILER_END);
- }
+ profiler_mark(PROFILER_END);
}
}
@@ -2546,5 +2632,6 @@ void video_avi_add_sound(running_machine *machine, const INT16 *sound, int numsa
#define DSTSHIFT_R 16
#define DSTSHIFT_G 8
#define DSTSHIFT_B 0
+#define BILINEAR_FILTER 1
#include "rendersw.c"
diff --git a/src/emu/video.h b/src/emu/video.h
index 902d1a7428a..3910ad898f6 100644
--- a/src/emu/video.h
+++ b/src/emu/video.h
@@ -255,7 +255,7 @@ void video_set_fastforward(int fastforward);
/* ----- snapshots ----- */
/* save a snapshot of a given screen */
-void video_screen_save_snapshot(const device_config *screen, mame_file *fp);
+void video_screen_save_snapshot(running_machine *machine, const device_config *screen, mame_file *fp);
/* save a snapshot of all the active screens */
void video_save_active_screen_snapshots(running_machine *machine);
@@ -263,12 +263,12 @@ void video_save_active_screen_snapshots(running_machine *machine);
/* ----- movie recording ----- */
-int video_mng_is_movie_active(const device_config *screen);
-void video_mng_begin_recording(const device_config *screen, const char *name);
-void video_mng_end_recording(const device_config *screen);
+int video_mng_is_movie_active(running_machine *machine);
+void video_mng_begin_recording(running_machine *machine, const char *name);
+void video_mng_end_recording(running_machine *machine);
-void video_avi_begin_recording(const device_config *screen, const char *name);
-void video_avi_end_recording(const device_config *screen);
+void video_avi_begin_recording(running_machine *machine, const char *name);
+void video_avi_end_recording(running_machine *machine);
void video_avi_add_sound(running_machine *machine, const INT16 *sound, int numsamples);
#endif /* __VIDEO_H__ */