ZX: also apply brightness constraint

There may only be one brightness per cell: either two light, or two dark
colors.
This commit is contained in:
Adrien Destugues 2017-06-28 08:24:32 +02:00
parent f2b04e08d0
commit 1d2cfc2a8d

View File

@ -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; layer<Spare_backups->Pages->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_x<Limit_left)
start_x=Limit_left;
if (start_y<Limit_top)
@ -1691,8 +1691,8 @@ void Draw_line_preview_xor(short start_x,short start_y,short end_x,short end_y,b
end_x=Limit_left;
if (end_y<Limit_top)
end_y=Limit_top;
// bottom & right limits are handled by Update_part_of_screen()
// bottom & right limits are handled by Update_part_of_screen()
w = end_x-start_x;
h = end_y-start_y;
Update_part_of_screen((start_x<end_x)?start_x:end_x,(start_y<end_y)?start_y:end_y,abs(w)+1,abs(h)+1);
@ -1744,7 +1744,7 @@ void Draw_empty_rectangle(short start_x,short start_y,short end_x,short end_y,by
// On trace le rectangle:
Init_permanent_draw();
for (x_pos=start_x;x_pos<=end_x;x_pos++)
{
Pixel_figure_permanent(x_pos,start_y,color);
@ -1756,7 +1756,7 @@ void Draw_empty_rectangle(short start_x,short start_y,short end_x,short end_y,by
Pixel_figure_permanent(start_x,y_pos,color);
Pixel_figure_permanent( end_x,y_pos,color);
}
#if defined(__macosx__) || defined(__FreeBSD__)
Update_part_of_screen(start_x,end_x,end_x-start_x,end_y-start_y);
#endif
@ -2320,14 +2320,14 @@ void Draw_grad_rectangle(short rax,short ray,short rbx,short rby,short vax,short
Gradient_total_range = sqrt(pow(vby - vay,2)+pow(vbx - vax,2));
a = (float)(vby - vay)/(float)(vbx - vax);
b = vay - a*vax;
for (y_pos=ray;y_pos<=rby;y_pos++)
for (x_pos = rax;x_pos<=rbx;x_pos++)
{
// On calcule ou on en est dans le dégradé
distance_x = pow((y_pos - vay),2)+pow((x_pos - vax),2);
distance_y = pow((-a * x_pos + y_pos - b),2)/(a*a+1);
Gradient_function((int)sqrt(distance_x - distance_y),x_pos,y_pos);
}
}
@ -2465,12 +2465,12 @@ void Polyfill_general(int vertices, short * points, int color)
T_Polygon_edge *edge, *next_edge, *initial_edge;
T_Polygon_edge *active_edges = NULL;
T_Polygon_edge *inactive_edges = NULL;
if (vertices < 1)
return;
top = bottom = points[1];
/* allocate some space and fill the edge table */
initial_edge=edge=(T_Polygon_edge *) malloc(sizeof(T_Polygon_edge) * vertices);
@ -2581,7 +2581,7 @@ void Polyfill(int vertices, short * points, int color)
// (pixels dessinés plus d'une fois) alors on force le FX Feedback à OFF
Update_FX_feedback(0);
Pixel_figure=Pixel_clipped;
Pixel_figure=Pixel_clipped;
Polyfill_general(vertices,points,color);
// Remarque: pour dessiner la bordure avec la brosse en cours au lieu
@ -2615,7 +2615,7 @@ void Replace(byte new_color)
{
word x;
word y;
// Update all pixels
for (y=0; y<Main_image_height; y++)
for (x=0; x<Main_image_width; x++)
@ -2731,7 +2731,7 @@ byte No_effect(word x, word y, byte color)
{
(void)x; // unused
(void)y; // unused
return color;
}
@ -2740,7 +2740,7 @@ byte No_effect(word x, word y, byte color)
byte Effect_shade(word x,word y,byte color)
{
(void)color; // unused
return Shade_table[Read_pixel_from_feedback_screen(x,y)];
}
@ -2796,7 +2796,7 @@ byte Effect_quick_shade(word x,word y,byte color)
byte Effect_tiling(word x,word y,byte color)
{
(void)color; // unused
return Read_pixel_from_brush((x+Brush_width-Tiling_offset_X)%Brush_width,
(y+Brush_height-Tiling_offset_Y)%Brush_height);
}
@ -2919,7 +2919,7 @@ void Horizontal_grid_line(word x_pos,word y_pos,word width)
void Vertical_grid_line(word x_pos,word y_pos,word height)
{
int y;
for (y=!(y_pos&1);y<height;y+=2)
Pixel(x_pos, y_pos+y, xor_lut[*(Screen_pixels+(x_pos*Pixel_width-1)+(y_pos*Pixel_height+y*Pixel_height)*VIDEO_LINE_WIDTH)]);
}
@ -2930,14 +2930,14 @@ void Redraw_grid(short x, short y, unsigned short w, unsigned short h)
int row, col;
if (!Show_grid)
return;
row=y+((Snap_height*1000-(y-0)/Main_magnifier_factor-Main_magnifier_offset_Y+Snap_offset_Y-1)%Snap_height)*Main_magnifier_factor+Main_magnifier_factor-1;
while (row < y+h)
{
Horizontal_grid_line(x, row, w);
row+= Snap_height*Main_magnifier_factor;
}
col=x+((Snap_width*1000-(x-Main_X_zoom)/Main_magnifier_factor-Main_magnifier_offset_X+Snap_offset_X-1)%Snap_width)*Main_magnifier_factor+Main_magnifier_factor-1;
while (col < x+w)
{
@ -2948,23 +2948,23 @@ void Redraw_grid(short x, short y, unsigned short w, unsigned short h)
byte Read_pixel_from_current_screen (word x,word y)
{
byte depth;
byte color;
if (Main_backups->Pages->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);
}
}