diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/emu/debug/debugcmd.c | 2 | ||||
-rw-r--r-- | src/emu/emuopts.c | 4 | ||||
-rw-r--r-- | src/emu/emuopts.h | 4 | ||||
-rw-r--r-- | src/emu/rendersw.c | 218 | ||||
-rw-r--r-- | src/emu/ui.c | 6 | ||||
-rw-r--r-- | src/emu/video.c | 355 | ||||
-rw-r--r-- | src/emu/video.h | 12 |
7 files changed, 350 insertions, 251 deletions
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__ */ |