mirror of
https://github.com/holub/mame
synced 2025-04-21 07:52:35 +03:00
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.
This commit is contained in:
parent
a93fb6b1bf
commit
69ba0bd294
@ -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,
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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" },
|
||||
|
@ -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"
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
355
src/emu/video.c
355
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);
|
||||
avi_error avierr;
|
||||
|
||||
/* only record if we have a file */
|
||||
if (state->avi_file != NULL)
|
||||
{
|
||||
avi_error avierr;
|
||||
profiler_mark(PROFILER_MOVIE_REC);
|
||||
|
||||
profiler_mark(PROFILER_MOVIE_REC);
|
||||
/* 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);
|
||||
|
||||
/* 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);
|
||||
|
||||
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"
|
||||
|
@ -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__ */
|
||||
|
Loading…
Reference in New Issue
Block a user