From 1d2cfc2a8d5ef9f6648ba14d2f28f182231d989e Mon Sep 17 00:00:00 2001 From: Adrien Destugues Date: Wed, 28 Jun 2017 08:24:32 +0200 Subject: [PATCH] ZX: also apply brightness constraint There may only be one brightness per cell: either two light, or two dark colors. --- src/graph.c | 210 +++++++++++++++++++++++++++++++--------------------- 1 file changed, 124 insertions(+), 86 deletions(-) diff --git a/src/graph.c b/src/graph.c index c90011bd..c410b228 100644 --- a/src/graph.c +++ b/src/graph.c @@ -190,7 +190,7 @@ void Update_part_of_screen(short x, short y, short width, short height) r.h=effective_h; r.w=effective_w; SDL_FillRect(Screen_SDL,&r,3);*/ - + // When the grid is displayed in Tilemap mode, this tests if // one edge of the grid has been touched : // In this case, the whole magnified area requires a refreshed grid. @@ -201,7 +201,7 @@ void Update_part_of_screen(short x, short y, short width, short height) y/Snap_height<(y+height)/Snap_height)) { short w,h; - + w=Min(Screen_width-Main_X_zoom, (Main_image_width-Main_magnifier_offset_X)*Main_magnifier_factor); h=Min(Menu_Y, (Main_image_height-Main_magnifier_offset_Y)*Main_magnifier_factor); @@ -241,7 +241,7 @@ int Init_mode_video(int width, int height, int fullscreen, int pix_ratio) static int Wrong_resize; try_again: - + switch (pix_ratio) { default: @@ -300,7 +300,7 @@ try_again: goto try_again; } } - + if (width > 320*pix_width && height > 200*pix_height) Wrong_resize = 0; @@ -331,10 +331,10 @@ try_again: width = (width + 15) & 0xFFFFFFF0; #else //width = (width + 3 ) & 0xFFFFFFFC; - #endif + #endif pixels_changed = (Pixel_ratio!=pix_ratio); - + if (!screen_changed && !pixels_changed) { Resize_width=0; @@ -346,7 +346,7 @@ try_again: { Set_mode_SDL(&width, &height,fullscreen); } - + if (screen_changed || pixels_changed) { Pixel_ratio=pix_ratio; @@ -444,9 +444,9 @@ try_again: Menu_factor_X*=2; else if (Pixel_width>Pixel_height && Screen_height>=Menu_factor_Y*2*200) Menu_factor_Y*=2; - + free(Horizontal_line_buffer); - Horizontal_line_buffer=(byte *)malloc(Pixel_width * + Horizontal_line_buffer=(byte *)malloc(Pixel_width * ((Screen_width>Main_image_width)?Screen_width:Main_image_width)); Set_palette(Main_palette); @@ -466,7 +466,7 @@ try_again: } Change_palette_cells(); - + Menu_Y = Screen_height; if (Menu_is_visible) Menu_Y -= Menu_height * Menu_factor_Y; @@ -482,7 +482,7 @@ try_again: Mouse_Y=Screen_height-1; if (fullscreen) Set_mouse_position(); - + Spare_offset_X=0; // | Il faut penser à éviter les incohérences Spare_offset_Y=0; // |- de décalage du brouillon par rapport à Spare_magnifier_mode=0; // | la résolution. @@ -510,7 +510,7 @@ try_again: Position_screen_according_to_zoom(); Compute_limits(); Compute_paintbrush_coordinates(); - + Resize_width=0; Resize_height=0; return 0; @@ -595,7 +595,7 @@ void Remap_spare(void) // teintes. for (layer=0; layerPages->Nb_layers; layer++) Remap_general_lowlevel(used,Spare_backups->Pages->Image[layer].Pixels,Spare_backups->Pages->Image[layer].Pixels,Spare_image_width,Spare_image_height,Spare_image_width); - + // Change transparent color index Spare_backups->Pages->Transparent_color=used[Spare_backups->Pages->Transparent_color]; } @@ -612,11 +612,11 @@ void Get_colors_from_brush(void) int image_color; //if (Confirmation_box("Modify current palette ?")) - + // Backup with unchanged layers, only palette is modified Backup_layers(LAYER_NONE); - // Init array of new colors + // Init array of new colors for (color=0;color<=255;color++) brush_used[color]=0; @@ -627,7 +627,7 @@ void Get_colors_from_brush(void) // Check used colors in picture (to know which palette entries are free) Count_used_colors(usage); - + // First pass : omit colors that are already in palette for (color=0; color<256; color++) { @@ -642,20 +642,20 @@ void Get_colors_from_brush(void) && Brush_original_palette[color].B==Main_palette[image_color].B) { // Color already in main palette: - + // Tag as used, so that no new color will overwrite it usage[image_color]=1; // Tag as non-new, to avoid it in pass 2 brush_used[color]=0; - + break; } } } } - - // Second pass : For each color to add, find an empty slot in + + // Second pass : For each color to add, find an empty slot in // main palette to add it image_color=0; for (color=0; color<256 && image_color<256; color++) @@ -671,7 +671,7 @@ void Get_colors_from_brush(void) Main_palette[image_color].R=Brush_original_palette[color].R; Main_palette[image_color].G=Brush_original_palette[color].G; Main_palette[image_color].B=Brush_original_palette[color].B; - + image_color++; break; } @@ -931,7 +931,7 @@ void Fill_general(byte fill_color) if (Paintbrush_Y >= (Main_image_height-Snap_offset_Y)/Snap_height*Snap_height+Snap_offset_Y) return; } - + // On suppose que le curseur est déjà caché. // Hide_cursor(); @@ -1009,7 +1009,7 @@ void Fill_general(byte fill_color) Limit_left=old_limit_left; Limit_top=old_limit_top; Limit_bottom=old_limit_bottom; - + for (y_pos=top_reached;y_pos<=bottom_reached;y_pos++) { for (x_pos=left_reached;x_pos<=right_reached;x_pos++) @@ -1018,7 +1018,7 @@ void Fill_general(byte fill_color) // First, restore the color. Pixel_in_current_screen(x_pos,y_pos,Read_pixel_from_backup_layer(x_pos,y_pos)); - + if (filled==2) { // Update the color according to the fill color and all effects @@ -1038,7 +1038,7 @@ void Fill_general(byte fill_color) if(Main_magnifier_mode) { short w,h; - + w=Min(Screen_width-Main_X_zoom, (Main_image_width-Main_magnifier_offset_X)*Main_magnifier_factor); h=Min(Menu_Y, (Main_image_height-Main_magnifier_offset_Y)*Main_magnifier_factor); @@ -1072,7 +1072,7 @@ void Fill_general(byte fill_color) { Draw_paintbrush(x_pos,y_pos,color); Permanent_draw_count ++; - + // Check every 8 pixels if (! (Permanent_draw_count&7)) { @@ -1095,7 +1095,7 @@ void Fill_general(byte fill_color) (y_pos<=Limit_bottom) ) Display_pixel(x_pos,y_pos,color); } - + // Affichage d'un point pour une preview void Pixel_figure_preview(word x_pos,word y_pos,byte color) { @@ -1119,7 +1119,7 @@ void Fill_general(byte fill_color) void Pixel_figure_preview_xor(short x_pos,short y_pos,byte color) { (void)color; // unused - + if ( (x_pos>=Limit_left) && (x_pos<=Limit_right) && (y_pos>=Limit_top) && @@ -1127,26 +1127,26 @@ void Fill_general(byte fill_color) Pixel_preview(x_pos,y_pos,xor_lut[Read_pixel(x_pos-Main_offset_X, y_pos-Main_offset_Y)]); } - + // Affichage d'un point pour une preview en xor additif // (Il lit la couleur depuis la page backup) void Pixel_figure_preview_xorback(word x_pos,word y_pos,byte color) { (void)color; // unused - + if ( (x_pos>=Limit_left) && (x_pos<=Limit_right) && (y_pos>=Limit_top) && (y_pos<=Limit_bottom) ) Pixel_preview(x_pos,y_pos,xor_lut[Main_screen[x_pos+y_pos*Main_image_width]]); } - + // Effacement d'un point de preview void Pixel_figure_clear_preview(word x_pos,word y_pos,byte color) { (void)color; // unused - + if ( (x_pos>=Limit_left) && (x_pos<=Limit_right) && (y_pos>=Limit_top) && @@ -1299,7 +1299,7 @@ int Circle_squared_diameter(int diameter) return result-6; if (diameter==14) return result-4; - + return result; } @@ -1459,18 +1459,18 @@ void Clamp_coordinates_regular_angle(short ax, short ay, short* bx, short* by) float angle; dx = *bx-ax; - dy = *by-ay; + dy = *by-ay; // No mouse move: no need to clamp anything - if (dx==0 || dy == 0) return; + if (dx==0 || dy == 0) return; // Determine angle (heading) angle = atan2(dx, dy); - + // Get absolute values, useful from now on: //dx=abs(dx); //dy=abs(dy); - + // Negative Y if (angle < M_PI*(-15.0/16.0) || angle > M_PI*(15.0/16.0)) { @@ -1587,7 +1587,7 @@ void Draw_line_general(short start_x,short start_y,short end_x,short end_y, byte short incr_x,incr_y; short i,cumul; short delta_x,delta_y; - + x_pos=start_x; y_pos=start_y; @@ -1676,13 +1676,13 @@ void Draw_line_preview(short start_x,short start_y,short end_x,short end_y,byte void Draw_line_preview_xor(short start_x,short start_y,short end_x,short end_y,byte color) { int w, h; - + Pixel_figure=(Func_pixel)Pixel_figure_preview_xor; // Needed a cast because this function supports signed shorts, // (it's usually in image space), while this time it's in screen space // and some line endpoints can be out of screen. Draw_line_general(start_x,start_y,end_x,end_y,color); - + if (start_xPages->Image_mode == IMAGE_MODE_ANIMATION) { - return *((y)*Main_image_width+(x)+Main_backups->Pages->Image[Main_current_layer].Pixels); + return *((y)*Main_image_width+(x)+Main_backups->Pages->Image[Main_current_layer].Pixels); } - - if (Main_backups->Pages->Image_mode == IMAGE_MODE_MODE5) + + if (Main_backups->Pages->Image_mode == IMAGE_MODE_MODE5) if (Main_current_layer==4) return *(Main_backups->Pages->Image[Main_current_layer].Pixels + x+y*Main_image_width); color = *(Main_screen+y*Main_image_width+x); if (color != Main_backups->Pages->Transparent_color) // transparent color return color; - + depth = *(Main_visible_image_depth_buffer.Image+x+y*Main_image_width); return *(Main_backups->Pages->Image[depth].Pixels + x+y*Main_image_width); } @@ -2992,7 +2992,7 @@ void Pixel_in_screen_layered(word x,word y,byte color) if (color == Main_backups->Pages->Transparent_color) // transparent color // fetch pixel color from the topmost visible layer color=*(Main_backups->Pages->Image[depth].Pixels + x+y*Main_image_width); - + *(x+y*Main_image_width+Main_screen)=color; } } @@ -3007,9 +3007,9 @@ void Pixel_in_screen_layered_with_preview(word x,word y,byte color) if (color == Main_backups->Pages->Transparent_color) // transparent color // fetch pixel color from the topmost visible layer color=*(Main_backups->Pages->Image[depth].Pixels + x+y*Main_image_width); - + *(x+y*Main_image_width+Main_screen)=color; - + Pixel_preview(x,y,color); } } @@ -3134,35 +3134,56 @@ void Pixel_in_screen_zx(word x,word y,byte color) uint8_t c1, c2; // The color we are going to replace - c1 = *(Main_backups->Pages->Image[Main_current_layer].Pixels + x+y*Main_image_width); + c1 = *(Main_backups->Pages->Image[Main_current_layer].Pixels + + x + y * Main_image_width); if (c1 == color) return; + // find if there is another color in the cell for (x2 = 0; x2 < 8; x2++) for (y2 = 0; y2 < 8; y2++) { - c2 = *(Main_backups->Pages->Image[Main_current_layer].Pixels + (x2+start)+(y2+starty)*Main_image_width); + c2 = *(Main_backups->Pages->Image[Main_current_layer].Pixels + + (x2 + start) + (y2 + starty) * Main_image_width); + // Pixel is already of the color we are going to add, it is no problem if (c2 == color) continue; + // We have found another color, which is the one we will keep from the cell if (c2 != c1) goto done; } done: - if (c2 == c1 || c2 == color) + if ((c2 == c1 || c2 == color)) { - // There was only one color, so we can add a second one. + // There was only one color, so we can add a second one + + // First make sure we have a single brightness + if ((c2 & 8) != (color & 8)) + { + for (x2 = 0; x2 < 8; x2++) + for (y2 = 0; y2 < 8; y2++) + { + Pixel_in_screen_layered(x2+start,y2+starty,c2 ^ 8); + } + } + Pixel_in_screen_layered(x,y,color); return; } + // Now replace all pixels which are of color c1, with color c2 for (x2 = 0; x2 < 8; x2++) for (y2 = 0; y2 < 8; y2++) { - c2 = *(Main_backups->Pages->Image[Main_current_layer].Pixels + (x2+start)+(y2+starty)*Main_image_width); + c2 = *(Main_backups->Pages->Image[Main_current_layer].Pixels + + (x2 + start) + (y2 + starty) * Main_image_width); if (c2 == c1) { Pixel_in_screen_layered(x2+start,y2+starty,color); + } else { + // Force the brightness bit + Pixel_in_screen_layered(x2+start,y2+starty,(c2 & ~8) | (color & 8)); } } } @@ -3175,7 +3196,8 @@ void Pixel_in_screen_zx_with_preview(word x,word y,byte color) uint8_t c1, c2; // The color we are going to replace - c1 = *(Main_backups->Pages->Image[Main_current_layer].Pixels + x+y*Main_image_width); + c1 = *(Main_backups->Pages->Image[Main_current_layer].Pixels + + x + y * Main_image_width); // Pixel is already of the wanted color: nothing to do if (c1 == color) @@ -3185,7 +3207,8 @@ void Pixel_in_screen_zx_with_preview(word x,word y,byte color) for (x2 = 0; x2 < 8; x2++) for (y2 = 0; y2 < 8; y2++) { - c2 = *(Main_backups->Pages->Image[Main_current_layer].Pixels + (x2+start)+(y2+starty)*Main_image_width); + c2 = *(Main_backups->Pages->Image[Main_current_layer].Pixels + + (x2 + start) + (y2 + starty) * Main_image_width); // Pixel is already of the color we are going to add, it is no problem if (c2 == color) continue; @@ -3195,20 +3218,35 @@ void Pixel_in_screen_zx_with_preview(word x,word y,byte color) } done: - if (c2 == c1 || c2 == color) + if ((c2 == c1 || c2 == color)) { - // There was only one color, so we can add a second one. + // There was only one color, so we can add a second one + + // First make sure we have a single brightness + if ((c2 & 8) != (color & 8)) + { + for (x2 = 0; x2 < 8; x2++) + for (y2 = 0; y2 < 8; y2++) + { + Pixel_in_screen_layered_with_preview(x2+start,y2+starty,c2 ^ 8); + } + } + Pixel_in_screen_layered_with_preview(x,y,color); return; } - // Replace all C1 with C2 + // Replace all C1 with color for (x2 = 0; x2 < 8; x2++) for (y2 = 0; y2 < 8; y2++) { - c2 = *(Main_backups->Pages->Image[Main_current_layer].Pixels + (x2+start)+(y2+starty)*Main_image_width); + c2 = *(Main_backups->Pages->Image[Main_current_layer].Pixels + + (x2 + start) + (y2 + starty) * Main_image_width); if (c2 == c1) { Pixel_in_screen_layered_with_preview(x2+start,y2+starty,color); + } else { + // Force the brightness bit + Pixel_in_screen_layered_with_preview(x2+start,y2+starty,(c2 & ~8) | (color & 8)); } } } @@ -3217,12 +3255,12 @@ done: void Pixel_in_screen_underlay(word x,word y,byte color) { byte depth; - + // Paste in layer *(Main_backups->Pages->Image[Main_current_layer].Pixels + x+y*Main_image_width)=color; // Search depth depth = *(Main_backups->Pages->Image[4].Pixels + x+y*Main_image_width); - + if ( depth == Main_current_layer) { // Draw that color on the visible image buffer @@ -3234,17 +3272,17 @@ void Pixel_in_screen_underlay(word x,word y,byte color) void Pixel_in_screen_underlay_with_preview(word x,word y,byte color) { byte depth; - + // Paste in layer *(Main_backups->Pages->Image[Main_current_layer].Pixels + x+y*Main_image_width)=color; // Search depth depth = *(Main_backups->Pages->Image[4].Pixels + x+y*Main_image_width); - + if ( depth == Main_current_layer) { // Draw that color on the visible image buffer *(x+y*Main_image_width+Main_screen)=color; - + Pixel_preview(x,y,color); } } @@ -3259,8 +3297,8 @@ void Pixel_in_screen_overlay(word x,word y,byte color) // Paste in depth buffer *(Main_visible_image_depth_buffer.Image+x+y*Main_image_width)=color; // Fetch pixel color from the target raster layer - if (Main_layers_visible & (1 << color)) - color=*(Main_backups->Pages->Image[color].Pixels + x+y*Main_image_width); + if (Main_layers_visible & (1 << color)) + color=*(Main_backups->Pages->Image[color].Pixels + x+y*Main_image_width); // Draw that color on the visible image buffer *(x+y*Main_image_width+Main_screen)=color; } @@ -3276,11 +3314,11 @@ void Pixel_in_screen_overlay_with_preview(word x,word y,byte color) // Paste in depth buffer *(Main_visible_image_depth_buffer.Image+x+y*Main_image_width)=color; // Fetch pixel color from the target raster layer - if (Main_layers_visible & (1 << color)) - color=*(Main_backups->Pages->Image[color].Pixels + x+y*Main_image_width); + if (Main_layers_visible & (1 << color)) + color=*(Main_backups->Pages->Image[color].Pixels + x+y*Main_image_width); // Draw that color on the visible image buffer *(x+y*Main_image_width+Main_screen)=color; - + Pixel_preview(x,y,color); } }