]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
Genlock and screenshot updates.
authorToni Wilen <twilen@winuae.net>
Sat, 1 Oct 2022 16:46:49 +0000 (19:46 +0300)
committerToni Wilen <twilen@winuae.net>
Sat, 1 Oct 2022 16:46:49 +0000 (19:46 +0300)
custom.cpp
drawing.cpp
include/specialmonitors.h
od-win32/avioutput.h
od-win32/clipboard_win32.cpp
od-win32/resources/resource.h
od-win32/resources/winuae.rc
od-win32/screenshot.cpp
od-win32/win32.cpp
od-win32/win32gui.cpp
specialmonitors.cpp

index 15e4e10ec540b80ecbda6044184eb6ec71a1872f..69cb68070d459d3a82f146328226355dce0cae99 100644 (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;
index 771385947f111ffdc1d5be072dff9c3c78d37452..3319581b9a7e71f9b108054bcfce7451489660ad 100644 (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)
index 907194061b6e4e1b40bca24c31832cf01c2c4538..7afc98b369fbdcd7c1b78cd22964ea770d363c07 100644 (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);
 
index 52aa8663a93f70eb8549af672f44ba51c4321396..bf9713b56d2f5dab09ccaeba3279ea10d492164f 100644 (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;
 
index 1c5e388c89d0583aa9823f4a2f98a4b999556e8d..43901f61674ffde57a4d6d5d6d9c78e033573c05 100644 (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;
index e481d94c97f703eeafac6ff992fcda3db8564017..3c48e2945354640c62f9feca8a68e9cdde9fa80c 100644 (file)
 #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
 #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
index 0028f7e9cd96772e798dc8da4cc77f8df97224c2..c27bc141e3f3e27ad58c0f7a6810674b4783e6ba 100644 (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
index aa2c2d7e88ba62e85f6c68b3228b5e29cc26acba..01997513fc93af7c122888dc905cb1bf9f990130 100644 (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) {
index b4394bfdcf582b56ca5db2a20f6e6479e804cb12..71fe152cfea5d71c467a4bd813f5182cbf14d3c1 100644 (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;
index 271a1961d6fb0c94516d0801ffca49b4e1e74b19..fd5cd9105f9fac7d43e3c1b8a8776ddc4aaa4a6c 100644 (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);
index 2feba598c5b5aead1b496a1d0e292427ed80db99..bf2e34721ef1a706a05d66ab4de51e11468b3e5e 100755 (executable)
@@ -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;