diff --git a/src/buttons_effects.c b/src/buttons_effects.c index 4ac4a88c..77aac882 100644 --- a/src/buttons_effects.c +++ b/src/buttons_effects.c @@ -352,6 +352,68 @@ static void Convert_to_hgr(void) } } +/// convert a picture to the DHGR mode +/// +/// Recognize monochrome pictures. +static void Convert_to_dhgr(void) +{ + int i; + word count, x, y; + dword usage[256]; + + count = Count_used_colors(usage); + if (count <= 1) // blank picture, nothing to do :) + return; + if (count == 2) // monochrome ! + { + byte bg, fg; + i = 0; + while (usage[i] == 0 && i < 256) + i++; + bg = (byte)i; + i++; + while (usage[i] == 0 && i < 256) + i++; + fg = (byte)i; + GFX2_Log(GFX2_DEBUG, "Convert_to_dhgr() monochrome bg=%u fg=%u\n", bg, fg); + if (!(bg == 0 && fg == 3) && !(bg == 4 && fg == 7)) + { + // convert to B&W + for (y = 0; y < Main.image_height; y++) + { + for (x = 0; x < Main.image_width; x++) + { + byte c = Read_pixel_from_layer(0, x, y); + Pixel_in_layer(0, x, y, (c == fg) ? 15 : 0); + } + } + } + } + else + { + // "convert" color picture to B&W + for (y = 0; y < Main.image_height; y++) + { + for (x = 0; x < Main.image_width; x += 4) + { + byte c = Read_pixel_from_layer(0, x, y); + Pixel_in_layer(0, x, y, c & 0x18); + Pixel_in_layer(0, x + 1, y, c & 0x14); + Pixel_in_layer(0, x + 2, y, c & 0x12); + Pixel_in_layer(0, x + 3, y, c & 0x11); + } + } + } + // update color layer + for (y = 0; y < Main.image_height; y++) + { + for (x = 0; x < Main.image_width; x += 4) + { + Update_color_dhgr_pixel(x, y, 0); + } + } +} + /// Constaint enforcer/checker /// @@ -415,7 +477,8 @@ void Button_Constraint_mode(void) } if (Selected_Constraint_Mode == IMAGE_MODE_HGR) Convert_to_hgr(); - /// @todo conversion to DHGR + else + Convert_to_dhgr(); break; default: Check_block_constraints(Selected_Constraint_Mode); @@ -454,7 +517,7 @@ void Button_Constraint_menu(void) {IMAGE_MODE_C64MULTI,"C64 Multicolor","4 colors per 4x1 block", 1}, // 160x200 //{IMAGE_MODE_C64FLI, "C64 FLI", "improved multicolor ", 1}, // 160x200 {IMAGE_MODE_HGR, "Apple II HGR", "6 colors ", 1}, // 280x192 - //{IMAGE_MODE_DHGR, "Apple II DHGR", "16 colors ", 1}, // 560x192 + {IMAGE_MODE_DHGR, "Apple II DHGR", "\"Le Chat Mauve\" mode3 ", 1}, // 560x192 }; Open_window(194,95+36,"8-bit constraints"); @@ -607,10 +670,13 @@ void Button_Constraint_menu(void) Snap_height = 999; // maximum value (3 digits) break; case IMAGE_MODE_HGR: - case IMAGE_MODE_DHGR: Snap_width = 7; Snap_height = 999; // maximum value (3 digits) break; + case IMAGE_MODE_DHGR: + Snap_width = 4; + Snap_height = 999; // maximum value (3 digits) + break; default: set_grid = 0; } diff --git a/src/graph.c b/src/graph.c index 8508fd56..ee350c4b 100644 --- a/src/graph.c +++ b/src/graph.c @@ -3668,6 +3668,100 @@ static void Pixel_in_screen_hgr_color_with_opt_preview(word x,word y,byte color, } } +/// Update the color layer of DHGR according to the monochrome layer +/// +/// Emulate \"Le Chat Mauve\" mode 3 (mixed mode). +void Update_color_dhgr_pixel(word x, word y, int preview) +{ + byte b3, b2, b1, b0, color; + + x &= ~3; + // read monochrome pixels + b3 = Read_pixel_from_layer(0, x, y); + b2 = Read_pixel_from_layer(0, x + 1, y); + b1 = Read_pixel_from_layer(0, x + 2, y); + b0 = Read_pixel_from_layer(0, x + 3, y); + if (b3 & 16) + { + // monochrome pixel + Pixel_in_layer_with_opt_preview(1, x, y, b3, preview); + Pixel_in_layer_with_opt_preview(1, x + 1, y, b2, preview); + Pixel_in_layer_with_opt_preview(1, x + 2, y, b1, preview); + Pixel_in_layer_with_opt_preview(1, x + 3, y, b0, preview); + } + else + { + // color pixel + color = (b3 & 8) | (b2 & 4) | (b1 & 2) | (b0 & 1); + Pixel_in_layer_with_opt_preview(1, x, y, color, preview); + Pixel_in_layer_with_opt_preview(1, x + 1, y, color, preview); + Pixel_in_layer_with_opt_preview(1, x + 2, y, color, preview); + Pixel_in_layer_with_opt_preview(1, x + 3, y, color, preview); + } +} + + +/// Paint in the monochrome layer of DHGR +/// +/// also update the color pixels. +static void Pixel_in_screen_dhgr_mono_with_opt_preview(word x,word y,byte color,int preview) +{ + byte oldcolor; + + if (color >= 32) + return; + if ((color & 15) != 0) + color |= 15; // force black or white. + + // put pixel + oldcolor = Read_pixel_from_layer(0, x, y); + if (color == oldcolor) + return; // nothing to do ! + Pixel_in_layer_with_opt_preview(0, x, y, color, preview); + Update_color_dhgr_pixel(x, y, preview); + + // change bit7 if needed. + if ((color & 16) != (oldcolor & 16)) + { + int i; + x -= (x % 7); + for (i = 0; i < 7; i++) + { + oldcolor = Read_pixel_from_layer(0, x, y); + if ((oldcolor & 16) != (color & 16)) + { + Pixel_in_layer_with_opt_preview(0, x, y, (color & 16) | (oldcolor & 15), preview); + Update_color_dhgr_pixel(x, y, preview); + } + x++; + } + } +} + +/// Paint in the color layer of DHGR +/// +/// use of color 16-31 forces the cell to be monochrome. +static void Pixel_in_screen_dhgr_color_with_opt_preview(word x,word y,byte color,int preview) +{ + if (color & 16) + { + // monochrome pixel + Pixel_in_screen_dhgr_mono_with_opt_preview(x, y, color, preview); + // force monochrome for this cell + if ((x & 3) != 0) + Pixel_in_screen_dhgr_mono_with_opt_preview(x & ~3, y, Read_pixel_from_layer(0, x & ~3, y) | 16, preview); + } + else + { + // color pixel + x &= ~3; + Pixel_in_screen_dhgr_mono_with_opt_preview(x, y, color & 8, preview); // also set this cell in color mode + Pixel_in_screen_dhgr_mono_with_opt_preview(x + 1, y, color & 4, preview); + Pixel_in_screen_dhgr_mono_with_opt_preview(x + 2, y, color & 2, preview); + Pixel_in_screen_dhgr_mono_with_opt_preview(x + 3, y, color & 1, preview); + } +} + // end of constraints group /// @} @@ -3723,7 +3817,6 @@ void Update_pixel_renderer(void) // direct Pixel_in_current_screen_with_opt_preview = Pixel_in_screen_direct_with_opt_preview; break; - case IMAGE_MODE_DHGR: // TODO case IMAGE_MODE_LAYERED: // layered Pixel_in_current_screen_with_opt_preview = Pixel_in_screen_layered_with_opt_preview; @@ -3763,5 +3856,12 @@ void Update_pixel_renderer(void) else Pixel_in_current_screen_with_opt_preview = Pixel_in_screen_layered_with_opt_preview; break; + case IMAGE_MODE_DHGR: + if (Main.current_layer == 0) // monochrome layer + Pixel_in_current_screen_with_opt_preview = Pixel_in_screen_dhgr_mono_with_opt_preview; + else if (Main.current_layer == 1) // color layer + Pixel_in_current_screen_with_opt_preview = Pixel_in_screen_dhgr_color_with_opt_preview; + else + Pixel_in_current_screen_with_opt_preview = Pixel_in_screen_layered_with_opt_preview; } } diff --git a/src/graph.h b/src/graph.h index ebbf597b..7513ec14 100644 --- a/src/graph.h +++ b/src/graph.h @@ -154,5 +154,6 @@ extern Func_pixel_opt_preview Pixel_in_current_screen_with_opt_preview; void Update_pixel_renderer(void); void Update_color_hgr_pixel(word x, word y, int preview); +void Update_color_dhgr_pixel(word x, word y, int preview); #endif