Genlock and screenshot updates.

This commit is contained in:
Toni Wilen 2022-10-01 19:46:49 +03:00
parent 1a7afe84e1
commit f02ee341b4
11 changed files with 438 additions and 58 deletions

View File

@ -9046,6 +9046,29 @@ static void checkautoscalecol0(void)
}
}
bool get_custom_color_reg(int colreg, uae_u8 *r, uae_u8 *g, uae_u8 *b)
{
if (colreg >= 32 && !aga_mode) {
return false;
}
if (colreg >= 256 || colreg < 0) {
return false;
}
if (aga_mode) {
*r = (current_colors.color_regs_aga[colreg] >> 16) & 0xFF;
*g = (current_colors.color_regs_aga[colreg] >> 8) & 0xFF;
*b = current_colors.color_regs_aga[colreg] & 0xFF;
} else {
*r = (current_colors.color_regs_ecs[colreg] >> 8) & 15;
*r |= (*r) << 4;
*g = (current_colors.color_regs_ecs[colreg] >> 4) & 15;
*g |= (*g) << 4;
*b = (current_colors.color_regs_ecs[colreg] >> 0) & 15;
*b |= (*b) << 4;
}
return true;
}
static void COLOR_WRITE(int hpos, uae_u16 v, int num)
{
bool colzero = false;

View File

@ -284,6 +284,7 @@ static int hposblank;
static bool ecs_genlock_features_active;
static uae_u8 ecs_genlock_features_mask;
static bool ecs_genlock_features_colorkey;
static bool aga_genlock_features_zdclken;
static int hsync_shift_hack;
static bool sprite_smaller_than_64, sprite_smaller_than_64_inuse;
static bool full_blank;
@ -3311,18 +3312,22 @@ static void pfield_expand_dp_bplcon(void)
sprite_smaller_than_64_inuse = true;
sprite_smaller_than_64 = (dp_for_drawing->fmode & 0x0c) != 0x0c;
#endif
ecs_genlock_features_active = (ecs_denise && ((dp_for_drawing->bplcon2 & 0x0c00) || ce_is_borderntrans(colors_for_drawing.extra))) || (currprefs.genlock_effects ? 1 : 0);
ecs_genlock_features_active = (ecs_denise && ((dp_for_drawing->bplcon2 & 0x0c00) || ce_is_borderntrans(colors_for_drawing.extra))) ||
(currprefs.genlock_effects ? 1 : 0) || (aga_mode && (dp_for_drawing->bplcon3 & 0x004) && (dp_for_drawing->bplcon0 & 1));
if (ecs_genlock_features_active) {
uae_u16 bc2 = dp_for_drawing->bplcon2;
ecs_genlock_features_colorkey = currprefs.ecs_genlock_features_colorkey_mask[0] || currprefs.ecs_genlock_features_colorkey_mask[1] ||
currprefs.ecs_genlock_features_colorkey_mask[2] || currprefs.ecs_genlock_features_colorkey_mask[3];
ecs_genlock_features_mask = currprefs.ecs_genlock_features_plane_mask;
if (bc2 & 0x0800) {
ecs_genlock_features_mask = 1 << ((bc2 >> 12) & 7);
aga_genlock_features_zdclken = false;
if (dp_for_drawing->bplcon2 & 0x0800) {
ecs_genlock_features_mask = 1 << ((dp_for_drawing->bplcon2 >> 12) & 7);
}
if (bc2 & 0x0400) {
if (dp_for_drawing->bplcon2 & 0x0400) {
ecs_genlock_features_colorkey = true;
}
if ((dp_for_drawing->bplcon3 & 0x0004) && (dp_for_drawing->bplcon0 & 1)) {
aga_genlock_features_zdclken = true;
}
}
if (pfield_mode_changed)
@ -4779,7 +4784,7 @@ static void finish_drawing_frame(bool drawlines)
init_row_map();
pfield_set_linetoscr();
}
emulate_genlock(vb, &vidinfo->tempbuffer);
emulate_genlock(vb, &vidinfo->tempbuffer, aga_genlock_features_zdclken);
vb = vidinfo->outbuffer = &vidinfo->tempbuffer;
if (vb->nativepositioning)
setnativeposition(vb);
@ -5189,6 +5194,9 @@ void reset_drawing(void)
ad->specialmonitoron = false;
bplcolorburst_field = 1;
hsync_shift_hack = 0;
ecs_genlock_features_active = false;
aga_genlock_features_zdclken = false;
ecs_genlock_features_colorkey = false;
}
static void gen_direct_drawing_table(void)

View File

@ -10,7 +10,7 @@ void specialmonitor_reset(void);
bool specialmonitor_need_genlock(void);
bool specialmonitor_uses_control_lines(void);
bool specialmonitor_autoconfig_init(struct autoconfig_info*);
bool emulate_genlock(struct vidbuffer*, struct vidbuffer*);
bool emulate_genlock(struct vidbuffer*, struct vidbuffer*, bool);
bool emulate_grayscale(struct vidbuffer*, struct vidbuffer*);
bool specialmonitor_linebased(void);

View File

@ -12,6 +12,7 @@ extern int avioutput_width, avioutput_height, avioutput_bits;
extern int avioutput_framelimiter, avioutput_nosoundoutput;
extern int avioutput_nosoundsync, avioutput_originalsize;
extern int screenshot_originalsize;
extern int screenshot_paletteindexed;
extern int screenshot_clipmode;
extern int screenshot_multi;

View File

@ -383,7 +383,7 @@ static void to_iff_ilbm(TrapContext *ctx, HBITMAP hbmp)
for (y = 0; y < h; y++) {
uae_u8 *s = (uae_u8*)(((uae_u8*)bmp.bmBits) + y * bmpw);
int b;
for (b = 0; b < 8; b++) {
for (b = 0; b < iffbpp; b++) {
int mask2 = 1 << b;
for (x = 0; x < w; x++) {
int off = x / 8;

View File

@ -972,7 +972,6 @@
#define IDC_UPBM 1650
#define IDC_DISKLISTINSERT 1650
#define IDC_DF1QENABLE 1650
#define IDC_AVIOUTPUT_ORIGINALSIZE2 1650
#define IDC_SCREENSHOT_ORIGINALSIZE 1650
#define IDC_SOUNDCARDLIST 1651
#define IDC_STATE_BUFFERSIZE2 1651
@ -981,9 +980,9 @@
#define IDC_SOUNDFREQ 1652
#define IDC_STATEREC_AUTOPLAY 1652
#define IDC_SOUNDFREQTXT 1653
#define IDC_SCREENSHOT_ORIGINALSIZE2 1653
#define IDC_SCREENSHOT_CLIP 1653
#define IDC_SOUNDFILTERTXT 1654
#define IDC_SCREENSHOT_PALETTED 1654
#define IDC_SOUNDSTEREO 1655
#define IDC_CONFIGTYPE 1655
#define IDC_SOUNDDRIVETXT 1656

View File

@ -877,22 +877,24 @@ BEGIN
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,15,114,176,10
CONTROL "Disable sound sync",IDC_AVIOUTPUT_NOSOUNDSYNC,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,210,114,171,10
CONTROL "AVI output enabled",IDC_AVIOUTPUT_ACTIVATED,"Button",BS_AUTORADIOBUTTON | BS_PUSHLIKE | BS_FLAT,15,129,144,14
GROUPBOX "Ripper",IDC_STATIC,1,155,393,53
GROUPBOX "Ripper",IDC_STATIC,1,155,393,65
PUSHBUTTON "Save screenshot",IDC_SCREENSHOT,28,169,87,14
PUSHBUTTON "Pro Wizard 1.62",IDC_PROWIZARD,162,169,87,14,WS_DISABLED
CONTROL "Take screenshot before filtering",IDC_SCREENSHOT_ORIGINALSIZE,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,11,192,144,10
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,11,192,130,10
CONTROL "Sample ripper",IDC_SAMPLERIPPER_ACTIVATED,"Button",BS_AUTORADIOBUTTON | BS_PUSHLIKE | BS_FLAT,280,169,87,14
GROUPBOX "Re-recorder",IDC_STATIC,1,211,393,70
CONTROL "Play recording",IDC_STATEREC_PLAY,"Button",BS_AUTORADIOBUTTON | BS_PUSHLIKE | BS_FLAT,53,223,87,14
CONTROL "Re-recording enabled",IDC_STATEREC_RECORD,"Button",BS_AUTORADIOBUTTON | BS_PUSHLIKE | BS_FLAT,214,223,118,14
CONTROL "Automatic replay",IDC_STATEREC_AUTOPLAY,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,54,246,129,10
PUSHBUTTON "Save recording",IDC_STATEREC_SAVE,214,241,118,14
RTEXT "Recording rate (seconds):",IDC_STATIC,15,264,121,10,SS_CENTERIMAGE | WS_TABSTOP
COMBOBOX IDC_STATEREC_RATE,141,262,38,65,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP
RTEXT "Recording buffers:",IDC_STATIC,195,264,91,10,SS_CENTERIMAGE | WS_TABSTOP
COMBOBOX IDC_STATEREC_BUFFERSIZE,291,262,38,65,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP
CONTROL "Autoclip screenshot",IDC_SCREENSHOT_CLIP,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,161,192,144,10
GROUPBOX "Re-recorder",IDC_STATIC,1,227,393,70
CONTROL "Play recording",IDC_STATEREC_PLAY,"Button",BS_AUTORADIOBUTTON | BS_PUSHLIKE | BS_FLAT,53,239,87,14
CONTROL "Re-recording enabled",IDC_STATEREC_RECORD,"Button",BS_AUTORADIOBUTTON | BS_PUSHLIKE | BS_FLAT,214,239,118,14
CONTROL "Automatic replay",IDC_STATEREC_AUTOPLAY,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,54,262,129,10
PUSHBUTTON "Save recording",IDC_STATEREC_SAVE,214,257,118,14
RTEXT "Recording rate (seconds):",IDC_STATIC,15,280,121,10,SS_CENTERIMAGE | WS_TABSTOP
COMBOBOX IDC_STATEREC_RATE,141,278,38,65,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP
RTEXT "Recording buffers:",IDC_STATIC,195,280,91,10,SS_CENTERIMAGE | WS_TABSTOP
COMBOBOX IDC_STATEREC_BUFFERSIZE,291,278,38,65,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP
CONTROL "Autoclip screenshot",IDC_SCREENSHOT_CLIP,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,276,192,97,10
CONTROL "Create 256 color palette indexed screenshot if possible",IDC_SCREENSHOT_PALETTED,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,11,206,231,10
END
IDD_INPUT DIALOGEX 0, 0, 396, 316

View File

@ -1,5 +1,6 @@
#define PNG_SCREENSHOTS 1
#define IFF_SCREENSHOTS 2
#include <windows.h>
@ -25,6 +26,7 @@
int screenshotmode = PNG_SCREENSHOTS;
int screenshot_originalsize = 0;
int screenshot_paletteindexed = 0;
int screenshot_clipmode = 0;
int screenshot_multi = 0;
@ -123,7 +125,9 @@ static int screenshot_prepare(int monid, int imagemode, struct vidbuffer *vb, bo
if (!standard) {
regqueryint(NULL, _T("Screenshot_Original"), &screenshot_originalsize);
regqueryint(NULL, _T("Screenshot_PaletteIndexed"), &screenshot_paletteindexed);
regqueryint(NULL, _T("Screenshot_ClipMode"), &screenshot_clipmode);
regqueryint(NULL, _T("Screenshot_Mode"), &screenshotmode);
} else {
screenshot_originalsize = 1;
screenshot_clipmode = 0;
@ -624,6 +628,168 @@ void Screenshot_RGBinfo (int rb, int gb, int bb, int ab, int rs, int gs, int bs,
rgb_as = as;
}
extern bool get_custom_color_reg(int colreg, uae_u8 *r, uae_u8 *g, uae_u8 *b);
static uae_u32 uniquecolors[256] = { 0 };
static int uniquecolorcount, uniquecolordepth;
static uae_u8 *palettebm;
static void count_colors(bool alpha)
{
int h = bi->bmiHeader.biHeight;
int w = bi->bmiHeader.biWidth;
int d = bi->bmiHeader.biBitCount;
uae_u32 customcolors[256] = { 0 };
bool uniquecolorsa[256] = { 0 };
bool palettea[256] = { 0 };
uae_u32 palette[256] = { 0 };
uae_u8 indextab[256] = { 0 };
int palettecount = 0;
uniquecolorcount = 0;
if (d <= 8 || !screenshot_paletteindexed) {
return;
}
if (alpha) {
uniquecolorcount = -1;
return;
}
palettebm = xcalloc(uae_u8, w * h);
if (!palettebm) {
return;
}
for (int i = 0; i < h; i++) {
uae_u8 *p = (uae_u8*)lpvBits + i * ((((w * 24) + 31) & ~31) / 8);
for (int j = 0; j < w; j++) {
uae_u32 co = (p[0] << 16) | (p[1] << 8) | (p[2] << 0);
p += 3;
int c = 0;
if (palettecount >= 1 && co == palette[palettecount - 1]) {
c = palettecount - 1;
} else {
for (c = 0; c < palettecount; c++) {
if (palette[c] == co) {
break;
}
}
}
if (c >= palettecount) {
if (palettecount >= 256) {
// run out of palette slots
write_log("Run out of palette slots when counting colors.");
uniquecolorcount = -1;
xfree(palettebm);
palettebm = NULL;
return;
}
palettea[palettecount] = true;
c = palettecount++;
palette[c] = co;
}
}
}
write_log("Screenshot color count: %d\n", palettecount);
// get custom colors
int customcolorcnt = 0;
for (int i = 0; i < 256; i++) {
uniquecolors[i] = 0;
uniquecolorsa[i] = false;
uae_u8 r, g, b;
if (get_custom_color_reg(i, &r, &g, &b)) {
uniquecolors[i] = (b << 16) | (g << 8) | r;
customcolorcnt = i + 1;
}
}
// find matching colors from bitmap and allocate colors
int match = 0;
for (int i = 0; i < palettecount; i++) {
if (palettea[i]) {
uae_u32 cc = palette[i];
for (int j = 0; j < customcolorcnt; j++) {
uae_u32 cc2 = uniquecolors[j];
if (!uniquecolorsa[i] && cc == cc2) {
uniquecolorsa[i] = true;
if (i >= uniquecolorcount) {
uniquecolorcount = i + 1;
}
palettea[i] = false;
match++;
break;
}
}
}
}
write_log("Screenshot custom register color matches: %d\n", match);
// add remaining colors not yet matched
match = 0;
// use all unused colors if IFF mode to keep total colors as small as possible
// if not iff: try to preserve first 32 colors.
int safecolors = screenshotmode == 2 ? 0 : 32;
if (uniquecolorcount < safecolors) {
uniquecolorcount = safecolors;
}
for (int i = 0; i < 256; i++) {
if (palettea[i]) {
int j = 0;
for (j = safecolors; j < 256 + safecolors; j++) {
int jj = j & 255;
if (!uniquecolorsa[jj]) {
uniquecolors[jj] = palette[i];
uniquecolorsa[jj] = true;
palettea[i] = false;
if (jj > uniquecolorcount) {
uniquecolorcount = jj + 1;
}
match++;
break;
}
}
if (j >= 256 + safecolors) {
// run out of palette slots
write_log("Run out of palette slots when adding remaining colors.");
uniquecolorcount = -1;
xfree(palettebm);
palettebm = NULL;
return;
}
}
}
write_log("Screenshot non-custom register matched colors: %d\n", match);
// create image
int prevc = -1;
for (int i = 0; i < h; i++) {
uae_u8 *p = (uae_u8 *)lpvBits + i * ((((w * 24) + 31) & ~31) / 8);
uae_u8 *dp = palettebm + w * i;
for (int j = 0; j < w; j++) {
uae_u32 co = (p[0] << 16) | (p[1] << 8) | (p[2] << 0);
p += 3;
int c = 0;
if (prevc >= 0 && co == uniquecolors[prevc]) {
c = prevc;
} else {
for (c = 0; c < uniquecolorcount; c++) {
if (uniquecolors[c] == co) {
prevc = c;
break;
}
}
if (c >= uniquecolorcount) {
c++;
}
}
*dp++ = (uae_u8)c;
}
}
// select depth
uniquecolordepth = 1;
for (int i = 0; i < 8; i++) {
if (uniquecolorcount > (1 << i)) {
uniquecolordepth = i + 1;
}
}
}
#if PNG_SCREENSHOTS > 0
static void _cdecl pngtest_blah (png_structp png_ptr, png_const_charp message)
@ -661,28 +827,44 @@ static int savepng(FILE *fp, bool alpha)
return 3;
}
count_colors(alpha);
png_init_io (png_ptr, fp);
png_set_filter (png_ptr, 0, PNG_FILTER_NONE);
png_set_IHDR (png_ptr, info_ptr,
w, h, 8, d <= 8 ? PNG_COLOR_TYPE_PALETTE : (alpha ? PNG_COLOR_TYPE_RGB_ALPHA : PNG_COLOR_TYPE_RGB),
w, h, 8, uniquecolorcount <= 256 && uniquecolorcount >= 0 ? PNG_COLOR_TYPE_PALETTE : (alpha ? PNG_COLOR_TYPE_RGB_ALPHA : PNG_COLOR_TYPE_RGB),
PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
if (d <= 8) {
for (i = 0; i < (1 << d); i++) {
pngpal[i].red = bi->bmiColors[i].rgbRed;
pngpal[i].green = bi->bmiColors[i].rgbGreen;
pngpal[i].blue = bi->bmiColors[i].rgbBlue;
}
png_set_PLTE (png_ptr, info_ptr, pngpal, 1 << d);
}
row_pointers = xmalloc (png_bytep, h);
for (i = 0; i < h; i++) {
int j = h - i - 1;
row_pointers[i] = (uae_u8*)lpvBits + j * (((w * (d <= 8 ? 8 : (alpha ? 32 : 24)) + 31) & ~31) / 8);
if (palettebm) {
for (i = 0; i < (1 << uniquecolordepth); i++) {
pngpal[i].red = (uniquecolors[i] >> 0) & 0xff;
pngpal[i].green = (uniquecolors[i] >> 8) & 0xff;
pngpal[i].blue = (uniquecolors[i] >> 16) & 0xff;
}
png_set_PLTE(png_ptr, info_ptr, pngpal, 1 << uniquecolordepth);
for (i = 0; i < h; i++) {
int j = h - i - 1;
row_pointers[i] = palettebm + j * w;
}
} else {
if (d <= 8) {
for (i = 0; i < (1 << d); i++) {
pngpal[i].red = bi->bmiColors[i].rgbRed;
pngpal[i].green = bi->bmiColors[i].rgbGreen;
pngpal[i].blue = bi->bmiColors[i].rgbBlue;
}
png_set_PLTE(png_ptr, info_ptr, pngpal, 1 << d);
}
for (i = 0; i < h; i++) {
int j = h - i - 1;
row_pointers[i] = (uae_u8 *)lpvBits + j * (((w * (d <= 8 ? 8 : (alpha ? 32 : 24)) + 31) & ~31) / 8);
}
}
png_set_rows (png_ptr, info_ptr, row_pointers);
png_write_png (png_ptr,info_ptr, PNG_TRANSFORM_BGR, NULL);
png_destroy_write_struct (&png_ptr, &info_ptr);
xfree (row_pointers);
xfree(palettebm);
palettebm = NULL;
return 0;
}
@ -695,6 +877,123 @@ static void __cdecl output_flush_fn(png_structp p)
{
}
static int saveiff(FILE *fp, bool alpha)
{
const uae_u8 iffilbm[] = {
'F','O','R','M',0,0,0,0,'I','L','B','M',
'B','M','H','D',0,0,0,20, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
'C','A','M','G',0,0,0, 4, 0,0,0,0,
};
count_colors(alpha);
int h = bi->bmiHeader.biHeight;
int w = bi->bmiHeader.biWidth;
int iffbpp = uniquecolordepth;
if (uniquecolorcount < 0 || uniquecolorcount > 256) {
iffbpp = 24;
}
int bodysize = (((w + 15) & ~15) / 8) * h * iffbpp;
int iffsize = sizeof(iffilbm) + (8 + 256 * 3 + 1) + (4 + 4) + bodysize;
uae_u8 *iff = xcalloc(uae_u8, iffsize);
memcpy(iff, iffilbm, sizeof(iffilbm));
if (!iff) {
return 1;
}
uae_u8 *p = iff + 5 * 4;
// BMHD
p[0] = w >> 8;
p[1] = w;
p[2] = h >> 8;
p[3] = h;
p[8] = iffbpp;
p[14] = 1;
p[15] = 1;
p[16] = w >> 8;
p[17] = w;
p[18] = h >> 8;
p[19] = h;
p = iff + sizeof iffilbm - 4;
// CAMG
if (w > 400)
p[2] |= 0x80; // HIRES
if (h > 300)
p[3] |= 0x04; // LACE
p += 4;
if (iffbpp <= 8) {
int cols = 1 << iffbpp;
int cnt = 0;
memcpy(p, "CMAP", 4);
p[4] = 0;
p[5] = 0;
p[6] = (cols * 3) >> 8;
p[7] = (cols * 3);
p += 8;
for (int i = 0; i < cols; i++) {
*p++ = uniquecolors[i] >> 0;
*p++ = uniquecolors[i] >> 8;
*p++ = uniquecolors[i] >> 16;
cnt += 3;
}
if (cnt & 1)
*p++ = 0;
}
memcpy(p, "BODY", 4);
p[4] = bodysize >> 24;
p[5] = bodysize >> 16;
p[6] = bodysize >> 8;
p[7] = bodysize >> 0;
p += 8;
if (iffbpp <= 8) {
for (int y = 0; y < h; y++) {
uae_u8 *s = palettebm + ((h - 1) - y) * w;
int b;
for (b = 0; b < iffbpp; b++) {
int mask2 = 1 << b;
for (int x = 0; x < w; x++) {
int off = x / 8;
int mask = 1 << (7 - (x & 7));
uae_u8 v = s[x];
if (v & mask2)
p[off] |= mask;
}
p += ((w + 15) & ~15) / 8;
}
}
} else {
for (int y = 0; y < h; y++) {
uae_u32 *s = (uae_u32*)(((uae_u8*)lpvBits) + ((h - 1) - y) * ((w * (alpha ? 32 : 24) + 31) & ~31) / 8);
int b, bb;
for (bb = 0; bb < 3; bb++) {
for (b = 0; b < 8; b++) {
int mask2 = 1 << (((2 - bb) * 8) + b);
for (int x = 0; x < w; x++) {
int off = x / 8;
int mask = 1 << (7 - (x & 7));
uae_u32 v = s[x];
if (v & mask2)
p[off] |= mask;
}
p += ((w + 15) & ~15) / 8;
}
}
}
}
int tsize = (int)(p - iff - 8);
p = iff + 4;
p[0] = tsize >> 24;
p[1] = tsize >> 16;
p[2] = tsize >> 8;
p[3] = tsize >> 0;
fwrite(iff, 1, 8 + tsize + (tsize & 1), fp);
xfree(iff);
return 0;
}
static struct zfile *savepngzfile(bool alpha)
{
png_structp png_ptr;
@ -726,10 +1025,11 @@ static struct zfile *savepngzfile(bool alpha)
return NULL;
}
count_colors(alpha);
png_set_write_fn(png_ptr, zf, write_data_fn, output_flush_fn);
png_set_filter(png_ptr, 0, PNG_FILTER_NONE);
png_set_IHDR(png_ptr, info_ptr,
w, h, 8, d <= 8 ? PNG_COLOR_TYPE_PALETTE : (alpha ? PNG_COLOR_TYPE_RGB_ALPHA : PNG_COLOR_TYPE_RGB),
w, h, 8, uniquecolorcount <= 256 && uniquecolorcount >= 0 ? PNG_COLOR_TYPE_PALETTE : (alpha ? PNG_COLOR_TYPE_RGB_ALPHA : PNG_COLOR_TYPE_RGB),
PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
if (d <= 8) {
for (i = 0; i < (1 << d); i++) {
@ -740,14 +1040,37 @@ static struct zfile *savepngzfile(bool alpha)
png_set_PLTE(png_ptr, info_ptr, pngpal, 1 << d);
}
row_pointers = xmalloc(png_bytep, h);
for (i = 0; i < h; i++) {
int j = h - i - 1;
row_pointers[i] = (uae_u8*)lpvBits + j * (((w * (d <= 8 ? 8 : (alpha ? 32 : 24)) + 31) & ~31) / 8);
if (palettebm) {
for (i = 0; i < (1 << uniquecolordepth); i++) {
pngpal[i].red = (uniquecolors[i] >> 0) & 0xff;
pngpal[i].green = (uniquecolors[i] >> 8) & 0xff;
pngpal[i].blue = (uniquecolors[i] >> 16) & 0xff;
}
png_set_PLTE(png_ptr, info_ptr, pngpal, 1 << uniquecolordepth);
for (i = 0; i < h; i++) {
int j = h - i - 1;
row_pointers[i] = palettebm + j * w;
}
} else {
if (d <= 8) {
for (i = 0; i < (1 << d); i++) {
pngpal[i].red = bi->bmiColors[i].rgbRed;
pngpal[i].green = bi->bmiColors[i].rgbGreen;
pngpal[i].blue = bi->bmiColors[i].rgbBlue;
}
png_set_PLTE(png_ptr, info_ptr, pngpal, 1 << d);
}
for (i = 0; i < h; i++) {
int j = h - i - 1;
row_pointers[i] = (uae_u8 *)lpvBits + j * (((w * (d <= 8 ? 8 : (alpha ? 32 : 24)) + 31) & ~31) / 8);
}
}
png_set_rows(png_ptr, info_ptr, row_pointers);
png_write_png(png_ptr, info_ptr, PNG_TRANSFORM_BGR, NULL);
png_destroy_write_struct(&png_ptr, &info_ptr);
xfree(row_pointers);
xfree(palettebm);
palettebm = NULL;
return zf;
}
@ -823,10 +1146,12 @@ int screenshotf(int monid, const TCHAR *spath, int mode, int doprepare, int imag
fp = _tfopen (spath, _T("wb"));
if (fp) {
#if PNG_SCREENSHOTS > 0
if (screenshotmode)
if (screenshotmode == 1)
failed = savepng (fp, alpha);
else
#endif
if (screenshotmode == 2)
failed = saveiff(fp, alpha);
if (screenshotmode == 0)
failed = savebmp (fp, alpha);
fclose(fp);
fp = NULL;
@ -872,7 +1197,7 @@ int screenshotf(int monid, const TCHAR *spath, int mode, int doprepare, int imag
while(++filenumber < screenshot_max)
{
_stprintf (filename, format, path, name, underline, filenumber, screenshotmode ? _T("png") : _T("bmp"));
_stprintf (filename, format, path, name, underline, filenumber, screenshotmode == 2 ? _T("iff") : (screenshotmode ? _T("png") : _T("bmp")));
if ((fp = _tfopen (filename, _T("rb"))) == NULL) // does file not exist?
{
int nok = 0;
@ -881,10 +1206,12 @@ int screenshotf(int monid, const TCHAR *spath, int mode, int doprepare, int imag
goto oops; // error
}
#if PNG_SCREENSHOTS > 0
if (screenshotmode)
if (screenshotmode == 1)
nok = savepng (fp, alpha);
else
#endif
if (screenshotmode == 2)
nok = saveiff(fp, alpha);
if (screenshotmode == 0)
nok = savebmp (fp, alpha);
fclose(fp);
if (nok && fp) {

View File

@ -6567,6 +6567,10 @@ static int parseargs(const TCHAR *argx, const TCHAR *np, const TCHAR *np2)
screenshotmode = 0;
return 1;
}
if (!_tcscmp(arg, _T("screenshotiff"))) {
screenshotmode = 2;
return 1;
}
if (!_tcscmp(arg, _T("psprintdebug"))) {
postscript_print_debugging = 1;
return 1;

View File

@ -7933,6 +7933,7 @@ static void enable_for_displaydlg (HWND hDlg)
static void enable_for_chipsetdlg (HWND hDlg)
{
int enable = workprefs.cpu_memory_cycle_exact ? FALSE : TRUE;
int genlock = workprefs.genlock || workprefs.genlock_effects;
#if !defined (CPUEMU_13)
ew (hDlg, IDC_CYCLEEXACT, FALSE);
@ -7945,12 +7946,12 @@ static void enable_for_chipsetdlg (HWND hDlg)
}
ew(hDlg, IDC_BLITIMM, !workprefs.cpu_cycle_exact);
ew(hDlg, IDC_GENLOCKMODE, workprefs.genlock ? TRUE : FALSE);
ew(hDlg, IDC_GENLOCKMIX, workprefs.genlock ? TRUE : FALSE);
ew(hDlg, IDC_GENLOCK_ALPHA, workprefs.genlock ? TRUE : FALSE);
ew(hDlg, IDC_GENLOCK_KEEP_ASPECT, workprefs.genlock ? TRUE : FALSE);
ew(hDlg, IDC_GENLOCKFILE, workprefs.genlock && (workprefs.genlock_image >= 6 || (workprefs.genlock_image >= 3 && workprefs.genlock_image < 5)) ? TRUE : FALSE);
ew(hDlg, IDC_GENLOCKFILESELECT, workprefs.genlock && (workprefs.genlock_image >= 6 || (workprefs.genlock_image >= 3 && workprefs.genlock_image < 5)) ? TRUE : FALSE);
ew(hDlg, IDC_GENLOCKMODE, genlock ? TRUE : FALSE);
ew(hDlg, IDC_GENLOCKMIX, genlock ? TRUE : FALSE);
ew(hDlg, IDC_GENLOCK_ALPHA, genlock ? TRUE : FALSE);
ew(hDlg, IDC_GENLOCK_KEEP_ASPECT, genlock ? TRUE : FALSE);
ew(hDlg, IDC_GENLOCKFILE, genlock && (workprefs.genlock_image >= 6 || (workprefs.genlock_image >= 3 && workprefs.genlock_image < 5)) ? TRUE : FALSE);
ew(hDlg, IDC_GENLOCKFILESELECT, genlock && (workprefs.genlock_image >= 6 || (workprefs.genlock_image >= 3 && workprefs.genlock_image < 5)) ? TRUE : FALSE);
ew(hDlg, IDC_MONITOREMU_MON, workprefs.monitoremu != 0);
}
@ -20775,6 +20776,7 @@ static void values_to_avioutputdlg (HWND hDlg)
CheckDlgButton (hDlg, IDC_AVIOUTPUT_ORIGINALSIZE, avioutput_originalsize ? TRUE : FALSE);
CheckDlgButton (hDlg, IDC_AVIOUTPUT_ACTIVATED, avioutput_requested ? BST_CHECKED : BST_UNCHECKED);
CheckDlgButton(hDlg, IDC_SCREENSHOT_ORIGINALSIZE, screenshot_originalsize ? TRUE : FALSE);
CheckDlgButton(hDlg, IDC_SCREENSHOT_PALETTED, screenshot_paletteindexed ? TRUE : FALSE);
CheckDlgButton(hDlg, IDC_SCREENSHOT_CLIP, screenshot_clipmode ? TRUE : FALSE);
CheckDlgButton (hDlg, IDC_SAMPLERIPPER_ACTIVATED, sampleripper_enabled ? BST_CHECKED : BST_UNCHECKED);
CheckDlgButton (hDlg, IDC_STATEREC_RECORD, input_record ? BST_CHECKED : BST_UNCHECKED);
@ -20911,6 +20913,7 @@ static INT_PTR CALLBACK AVIOutputDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LP
currentpage = AVIOUTPUT_ID;
AVIOutput_GetSettings ();
regqueryint(NULL, _T("Screenshot_Original"), &screenshot_originalsize);
regqueryint(NULL, _T("Screenshot_PaletteIndexed"), &screenshot_paletteindexed);
regqueryint(NULL, _T("Screenshot_ClipMode"), &screenshot_clipmode);
enable_for_avioutputdlg (hDlg);
if (!avioutput_filename_gui[0]) {
@ -20988,6 +20991,11 @@ static INT_PTR CALLBACK AVIOutputDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LP
regsetint(NULL, _T("Screenshot_Original"), screenshot_originalsize);
screenshot_reset();
break;
case IDC_SCREENSHOT_PALETTED:
screenshot_paletteindexed = ischecked(hDlg, IDC_SCREENSHOT_PALETTED) ? 1 : 0;
regsetint(NULL, _T("Screenshot_PaletteIndexed"), screenshot_paletteindexed);
screenshot_reset();
break;
case IDC_SCREENSHOT_CLIP:
screenshot_clipmode = ischecked(hDlg, IDC_SCREENSHOT_CLIP) ? 1 : 0;
regsetint(NULL, _T("Screenshot_ClipMode"), screenshot_clipmode);

View File

@ -2397,7 +2397,7 @@ end:
return ok;
}
static bool do_genlock(struct vidbuffer *src, struct vidbuffer *dst, bool doublelines, int oddlines)
static bool do_genlock(struct vidbuffer *src, struct vidbuffer *dst, bool doublelines, int oddlines, bool zclken)
{
struct vidbuf_description *avidinfo = &adisplays[dst->monitor_id].gfxvidinfo;
@ -2590,6 +2590,7 @@ skip:
if (yoff >= src->inheight)
continue;
bool ztoggle = false;
uae_u8 *line = src->bufmem + yoff * src->rowbytes;
uae_u8 *lineprev = yoff > 0 ? src->bufmem + (yoff - 1) * src->rowbytes : NULL;
uae_u8 *dstline = dst->bufmem + ((y * 2 + oddlines) - dst->yoffset) * dst->rowbytes;
@ -2604,10 +2605,11 @@ skip:
uae_u8 *s = line;
uae_u8 *d = dstline;
uae_u8 *s_genlock = line_genlock;
int hwidth = 0;
for (x = 0; x < src->inwidth; x++) {
uae_u8 *s2 = s + src->rowbytes;
uae_u8 *d2 = d + dst->rowbytes;
if (is_transparent(*s_genlock)) {
if ((!zclken && is_transparent(*s_genlock)) || (zclken && ztoggle)) {
a = amix2;
if (genlock_error) {
r = 0x00;
@ -2640,6 +2642,12 @@ skip:
s += src->pixbytes;
d += dst->pixbytes;
s_genlock++;
// ZCLKEN hires pixel clock
hwidth += 1 << currprefs.gfx_resolution;
if (hwidth >= 2) {
hwidth = 0;
ztoggle = !ztoggle;
}
}
}
@ -2647,25 +2655,25 @@ skip:
return true;
}
bool emulate_genlock(struct vidbuffer *src, struct vidbuffer *dst)
bool emulate_genlock(struct vidbuffer *src, struct vidbuffer *dst, bool zclken)
{
bool v;
if (interlace_seen) {
if (currprefs.gfx_iscanlines) {
v = do_genlock(src, dst, false, lof_store ? 0 : 1);
v = do_genlock(src, dst, false, lof_store ? 0 : 1, zclken);
if (v && currprefs.gfx_iscanlines > 1)
blank_generic(src, dst, lof_store ? 1 : 0);
} else {
v = do_genlock(src, dst, false, 0);
v |= do_genlock(src, dst, false, 1);
v = do_genlock(src, dst, false, 0, zclken);
v |= do_genlock(src, dst, false, 1, zclken);
}
} else {
if (currprefs.gfx_pscanlines) {
v = do_genlock(src, dst, false, lof_store ? 0 : 1);
v = do_genlock(src, dst, false, lof_store ? 0 : 1, zclken);
if (v && currprefs.gfx_pscanlines >= 2)
do_genlock(src, dst, false, lof_store ? 1 : 0);
do_genlock(src, dst, false, lof_store ? 1 : 0, zclken);
} else {
v = do_genlock(src, dst, true, 0);
v = do_genlock(src, dst, true, 0, zclken);
}
}
return v;