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.h=effective_h;
r.w=effective_w; r.w=effective_w;
SDL_FillRect(Screen_SDL,&r,3);*/ SDL_FillRect(Screen_SDL,&r,3);*/
// When the grid is displayed in Tilemap mode, this tests if // When the grid is displayed in Tilemap mode, this tests if
// one edge of the grid has been touched : // one edge of the grid has been touched :
// In this case, the whole magnified area requires a refreshed grid. // 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)) y/Snap_height<(y+height)/Snap_height))
{ {
short w,h; short w,h;
w=Min(Screen_width-Main_X_zoom, (Main_image_width-Main_magnifier_offset_X)*Main_magnifier_factor); 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); 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; static int Wrong_resize;
try_again: try_again:
switch (pix_ratio) switch (pix_ratio)
{ {
default: default:
@ -300,7 +300,7 @@ try_again:
goto try_again; goto try_again;
} }
} }
if (width > 320*pix_width && height > 200*pix_height) if (width > 320*pix_width && height > 200*pix_height)
Wrong_resize = 0; Wrong_resize = 0;
@ -331,10 +331,10 @@ try_again:
width = (width + 15) & 0xFFFFFFF0; width = (width + 15) & 0xFFFFFFF0;
#else #else
//width = (width + 3 ) & 0xFFFFFFFC; //width = (width + 3 ) & 0xFFFFFFFC;
#endif #endif
pixels_changed = (Pixel_ratio!=pix_ratio); pixels_changed = (Pixel_ratio!=pix_ratio);
if (!screen_changed && !pixels_changed) if (!screen_changed && !pixels_changed)
{ {
Resize_width=0; Resize_width=0;
@ -346,7 +346,7 @@ try_again:
{ {
Set_mode_SDL(&width, &height,fullscreen); Set_mode_SDL(&width, &height,fullscreen);
} }
if (screen_changed || pixels_changed) if (screen_changed || pixels_changed)
{ {
Pixel_ratio=pix_ratio; Pixel_ratio=pix_ratio;
@ -444,9 +444,9 @@ try_again:
Menu_factor_X*=2; Menu_factor_X*=2;
else if (Pixel_width>Pixel_height && Screen_height>=Menu_factor_Y*2*200) else if (Pixel_width>Pixel_height && Screen_height>=Menu_factor_Y*2*200)
Menu_factor_Y*=2; Menu_factor_Y*=2;
free(Horizontal_line_buffer); 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)); ((Screen_width>Main_image_width)?Screen_width:Main_image_width));
Set_palette(Main_palette); Set_palette(Main_palette);
@ -466,7 +466,7 @@ try_again:
} }
Change_palette_cells(); Change_palette_cells();
Menu_Y = Screen_height; Menu_Y = Screen_height;
if (Menu_is_visible) if (Menu_is_visible)
Menu_Y -= Menu_height * Menu_factor_Y; Menu_Y -= Menu_height * Menu_factor_Y;
@ -482,7 +482,7 @@ try_again:
Mouse_Y=Screen_height-1; Mouse_Y=Screen_height-1;
if (fullscreen) if (fullscreen)
Set_mouse_position(); Set_mouse_position();
Spare_offset_X=0; // | Il faut penser à éviter les incohérences Spare_offset_X=0; // | Il faut penser à éviter les incohérences
Spare_offset_Y=0; // |- de décalage du brouillon par rapport à Spare_offset_Y=0; // |- de décalage du brouillon par rapport à
Spare_magnifier_mode=0; // | la résolution. Spare_magnifier_mode=0; // | la résolution.
@ -510,7 +510,7 @@ try_again:
Position_screen_according_to_zoom(); Position_screen_according_to_zoom();
Compute_limits(); Compute_limits();
Compute_paintbrush_coordinates(); Compute_paintbrush_coordinates();
Resize_width=0; Resize_width=0;
Resize_height=0; Resize_height=0;
return 0; return 0;
@ -595,7 +595,7 @@ void Remap_spare(void)
// teintes. // teintes.
for (layer=0; layer<Spare_backups->Pages->Nb_layers; layer++) 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); 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 // Change transparent color index
Spare_backups->Pages->Transparent_color=used[Spare_backups->Pages->Transparent_color]; Spare_backups->Pages->Transparent_color=used[Spare_backups->Pages->Transparent_color];
} }
@ -612,11 +612,11 @@ void Get_colors_from_brush(void)
int image_color; int image_color;
//if (Confirmation_box("Modify current palette ?")) //if (Confirmation_box("Modify current palette ?"))
// Backup with unchanged layers, only palette is modified // Backup with unchanged layers, only palette is modified
Backup_layers(LAYER_NONE); Backup_layers(LAYER_NONE);
// Init array of new colors // Init array of new colors
for (color=0;color<=255;color++) for (color=0;color<=255;color++)
brush_used[color]=0; 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) // Check used colors in picture (to know which palette entries are free)
Count_used_colors(usage); Count_used_colors(usage);
// First pass : omit colors that are already in palette // First pass : omit colors that are already in palette
for (color=0; color<256; color++) 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) && Brush_original_palette[color].B==Main_palette[image_color].B)
{ {
// Color already in main palette: // Color already in main palette:
// Tag as used, so that no new color will overwrite it // Tag as used, so that no new color will overwrite it
usage[image_color]=1; usage[image_color]=1;
// Tag as non-new, to avoid it in pass 2 // Tag as non-new, to avoid it in pass 2
brush_used[color]=0; brush_used[color]=0;
break; 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 // main palette to add it
image_color=0; image_color=0;
for (color=0; color<256 && image_color<256; color++) 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].R=Brush_original_palette[color].R;
Main_palette[image_color].G=Brush_original_palette[color].G; Main_palette[image_color].G=Brush_original_palette[color].G;
Main_palette[image_color].B=Brush_original_palette[color].B; Main_palette[image_color].B=Brush_original_palette[color].B;
image_color++; image_color++;
break; 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) if (Paintbrush_Y >= (Main_image_height-Snap_offset_Y)/Snap_height*Snap_height+Snap_offset_Y)
return; return;
} }
// On suppose que le curseur est déjà caché. // On suppose que le curseur est déjà caché.
// Hide_cursor(); // Hide_cursor();
@ -1009,7 +1009,7 @@ void Fill_general(byte fill_color)
Limit_left=old_limit_left; Limit_left=old_limit_left;
Limit_top=old_limit_top; Limit_top=old_limit_top;
Limit_bottom=old_limit_bottom; Limit_bottom=old_limit_bottom;
for (y_pos=top_reached;y_pos<=bottom_reached;y_pos++) for (y_pos=top_reached;y_pos<=bottom_reached;y_pos++)
{ {
for (x_pos=left_reached;x_pos<=right_reached;x_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. // First, restore the color.
Pixel_in_current_screen(x_pos,y_pos,Read_pixel_from_backup_layer(x_pos,y_pos)); Pixel_in_current_screen(x_pos,y_pos,Read_pixel_from_backup_layer(x_pos,y_pos));
if (filled==2) if (filled==2)
{ {
// Update the color according to the fill color and all effects // 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) if(Main_magnifier_mode)
{ {
short w,h; short w,h;
w=Min(Screen_width-Main_X_zoom, (Main_image_width-Main_magnifier_offset_X)*Main_magnifier_factor); 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); 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); Draw_paintbrush(x_pos,y_pos,color);
Permanent_draw_count ++; Permanent_draw_count ++;
// Check every 8 pixels // Check every 8 pixels
if (! (Permanent_draw_count&7)) if (! (Permanent_draw_count&7))
{ {
@ -1095,7 +1095,7 @@ void Fill_general(byte fill_color)
(y_pos<=Limit_bottom) ) (y_pos<=Limit_bottom) )
Display_pixel(x_pos,y_pos,color); Display_pixel(x_pos,y_pos,color);
} }
// Affichage d'un point pour une preview // Affichage d'un point pour une preview
void Pixel_figure_preview(word x_pos,word y_pos,byte color) 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 Pixel_figure_preview_xor(short x_pos,short y_pos,byte color)
{ {
(void)color; // unused (void)color; // unused
if ( (x_pos>=Limit_left) && if ( (x_pos>=Limit_left) &&
(x_pos<=Limit_right) && (x_pos<=Limit_right) &&
(y_pos>=Limit_top) && (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, Pixel_preview(x_pos,y_pos,xor_lut[Read_pixel(x_pos-Main_offset_X,
y_pos-Main_offset_Y)]); y_pos-Main_offset_Y)]);
} }
// Affichage d'un point pour une preview en xor additif // Affichage d'un point pour une preview en xor additif
// (Il lit la couleur depuis la page backup) // (Il lit la couleur depuis la page backup)
void Pixel_figure_preview_xorback(word x_pos,word y_pos,byte color) void Pixel_figure_preview_xorback(word x_pos,word y_pos,byte color)
{ {
(void)color; // unused (void)color; // unused
if ( (x_pos>=Limit_left) && if ( (x_pos>=Limit_left) &&
(x_pos<=Limit_right) && (x_pos<=Limit_right) &&
(y_pos>=Limit_top) && (y_pos>=Limit_top) &&
(y_pos<=Limit_bottom) ) (y_pos<=Limit_bottom) )
Pixel_preview(x_pos,y_pos,xor_lut[Main_screen[x_pos+y_pos*Main_image_width]]); Pixel_preview(x_pos,y_pos,xor_lut[Main_screen[x_pos+y_pos*Main_image_width]]);
} }
// Effacement d'un point de preview // Effacement d'un point de preview
void Pixel_figure_clear_preview(word x_pos,word y_pos,byte color) void Pixel_figure_clear_preview(word x_pos,word y_pos,byte color)
{ {
(void)color; // unused (void)color; // unused
if ( (x_pos>=Limit_left) && if ( (x_pos>=Limit_left) &&
(x_pos<=Limit_right) && (x_pos<=Limit_right) &&
(y_pos>=Limit_top) && (y_pos>=Limit_top) &&
@ -1299,7 +1299,7 @@ int Circle_squared_diameter(int diameter)
return result-6; return result-6;
if (diameter==14) if (diameter==14)
return result-4; return result-4;
return result; return result;
} }
@ -1459,18 +1459,18 @@ void Clamp_coordinates_regular_angle(short ax, short ay, short* bx, short* by)
float angle; float angle;
dx = *bx-ax; dx = *bx-ax;
dy = *by-ay; dy = *by-ay;
// No mouse move: no need to clamp anything // No mouse move: no need to clamp anything
if (dx==0 || dy == 0) return; if (dx==0 || dy == 0) return;
// Determine angle (heading) // Determine angle (heading)
angle = atan2(dx, dy); angle = atan2(dx, dy);
// Get absolute values, useful from now on: // Get absolute values, useful from now on:
//dx=abs(dx); //dx=abs(dx);
//dy=abs(dy); //dy=abs(dy);
// Negative Y // Negative Y
if (angle < M_PI*(-15.0/16.0) || angle > M_PI*(15.0/16.0)) 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 incr_x,incr_y;
short i,cumul; short i,cumul;
short delta_x,delta_y; short delta_x,delta_y;
x_pos=start_x; x_pos=start_x;
y_pos=start_y; 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) void Draw_line_preview_xor(short start_x,short start_y,short end_x,short end_y,byte color)
{ {
int w, h; int w, h;
Pixel_figure=(Func_pixel)Pixel_figure_preview_xor; Pixel_figure=(Func_pixel)Pixel_figure_preview_xor;
// Needed a cast because this function supports signed shorts, // Needed a cast because this function supports signed shorts,
// (it's usually in image space), while this time it's in screen space // (it's usually in image space), while this time it's in screen space
// and some line endpoints can be out of screen. // and some line endpoints can be out of screen.
Draw_line_general(start_x,start_y,end_x,end_y,color); Draw_line_general(start_x,start_y,end_x,end_y,color);
if (start_x<Limit_left) if (start_x<Limit_left)
start_x=Limit_left; start_x=Limit_left;
if (start_y<Limit_top) 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; end_x=Limit_left;
if (end_y<Limit_top) if (end_y<Limit_top)
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; w = end_x-start_x;
h = end_y-start_y; 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); 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: // On trace le rectangle:
Init_permanent_draw(); Init_permanent_draw();
for (x_pos=start_x;x_pos<=end_x;x_pos++) for (x_pos=start_x;x_pos<=end_x;x_pos++)
{ {
Pixel_figure_permanent(x_pos,start_y,color); 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(start_x,y_pos,color);
Pixel_figure_permanent( end_x,y_pos,color); Pixel_figure_permanent( end_x,y_pos,color);
} }
#if defined(__macosx__) || defined(__FreeBSD__) #if defined(__macosx__) || defined(__FreeBSD__)
Update_part_of_screen(start_x,end_x,end_x-start_x,end_y-start_y); Update_part_of_screen(start_x,end_x,end_x-start_x,end_y-start_y);
#endif #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)); Gradient_total_range = sqrt(pow(vby - vay,2)+pow(vbx - vax,2));
a = (float)(vby - vay)/(float)(vbx - vax); a = (float)(vby - vay)/(float)(vbx - vax);
b = vay - a*vax; b = vay - a*vax;
for (y_pos=ray;y_pos<=rby;y_pos++) for (y_pos=ray;y_pos<=rby;y_pos++)
for (x_pos = rax;x_pos<=rbx;x_pos++) for (x_pos = rax;x_pos<=rbx;x_pos++)
{ {
// On calcule ou on en est dans le dégradé // On calcule ou on en est dans le dégradé
distance_x = pow((y_pos - vay),2)+pow((x_pos - vax),2); 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); 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); 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 *edge, *next_edge, *initial_edge;
T_Polygon_edge *active_edges = NULL; T_Polygon_edge *active_edges = NULL;
T_Polygon_edge *inactive_edges = NULL; T_Polygon_edge *inactive_edges = NULL;
if (vertices < 1) if (vertices < 1)
return; return;
top = bottom = points[1]; top = bottom = points[1];
/* allocate some space and fill the edge table */ /* allocate some space and fill the edge table */
initial_edge=edge=(T_Polygon_edge *) malloc(sizeof(T_Polygon_edge) * vertices); 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 // (pixels dessinés plus d'une fois) alors on force le FX Feedback à OFF
Update_FX_feedback(0); Update_FX_feedback(0);
Pixel_figure=Pixel_clipped; Pixel_figure=Pixel_clipped;
Polyfill_general(vertices,points,color); Polyfill_general(vertices,points,color);
// Remarque: pour dessiner la bordure avec la brosse en cours au lieu // Remarque: pour dessiner la bordure avec la brosse en cours au lieu
@ -2615,7 +2615,7 @@ void Replace(byte new_color)
{ {
word x; word x;
word y; word y;
// Update all pixels // Update all pixels
for (y=0; y<Main_image_height; y++) for (y=0; y<Main_image_height; y++)
for (x=0; x<Main_image_width; x++) 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)x; // unused
(void)y; // unused (void)y; // unused
return color; return color;
} }
@ -2740,7 +2740,7 @@ byte No_effect(word x, word y, byte color)
byte Effect_shade(word x,word y,byte color) byte Effect_shade(word x,word y,byte color)
{ {
(void)color; // unused (void)color; // unused
return Shade_table[Read_pixel_from_feedback_screen(x,y)]; 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) byte Effect_tiling(word x,word y,byte color)
{ {
(void)color; // unused (void)color; // unused
return Read_pixel_from_brush((x+Brush_width-Tiling_offset_X)%Brush_width, return Read_pixel_from_brush((x+Brush_width-Tiling_offset_X)%Brush_width,
(y+Brush_height-Tiling_offset_Y)%Brush_height); (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) void Vertical_grid_line(word x_pos,word y_pos,word height)
{ {
int y; int y;
for (y=!(y_pos&1);y<height;y+=2) 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)]); 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; int row, col;
if (!Show_grid) if (!Show_grid)
return; 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; 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) while (row < y+h)
{ {
Horizontal_grid_line(x, row, w); Horizontal_grid_line(x, row, w);
row+= Snap_height*Main_magnifier_factor; 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; 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) 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 Read_pixel_from_current_screen (word x,word y)
{ {
byte depth; byte depth;
byte color; byte color;
if (Main_backups->Pages->Image_mode == IMAGE_MODE_ANIMATION) 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) if (Main_current_layer==4)
return *(Main_backups->Pages->Image[Main_current_layer].Pixels + x+y*Main_image_width); return *(Main_backups->Pages->Image[Main_current_layer].Pixels + x+y*Main_image_width);
color = *(Main_screen+y*Main_image_width+x); color = *(Main_screen+y*Main_image_width+x);
if (color != Main_backups->Pages->Transparent_color) // transparent color if (color != Main_backups->Pages->Transparent_color) // transparent color
return color; return color;
depth = *(Main_visible_image_depth_buffer.Image+x+y*Main_image_width); depth = *(Main_visible_image_depth_buffer.Image+x+y*Main_image_width);
return *(Main_backups->Pages->Image[depth].Pixels + 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 if (color == Main_backups->Pages->Transparent_color) // transparent color
// fetch pixel color from the topmost visible layer // fetch pixel color from the topmost visible layer
color=*(Main_backups->Pages->Image[depth].Pixels + x+y*Main_image_width); color=*(Main_backups->Pages->Image[depth].Pixels + x+y*Main_image_width);
*(x+y*Main_image_width+Main_screen)=color; *(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 if (color == Main_backups->Pages->Transparent_color) // transparent color
// fetch pixel color from the topmost visible layer // fetch pixel color from the topmost visible layer
color=*(Main_backups->Pages->Image[depth].Pixels + x+y*Main_image_width); color=*(Main_backups->Pages->Image[depth].Pixels + x+y*Main_image_width);
*(x+y*Main_image_width+Main_screen)=color; *(x+y*Main_image_width+Main_screen)=color;
Pixel_preview(x,y,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; uint8_t c1, c2;
// The color we are going to replace // 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) if (c1 == color)
return; return;
// find if there is another color in the cell
for (x2 = 0; x2 < 8; x2++) for (x2 = 0; x2 < 8; x2++)
for (y2 = 0; y2 < 8; y2++) 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) if (c2 == color)
continue; continue;
// We have found another color, which is the one we will keep from the cell
if (c2 != c1) if (c2 != c1)
goto done; goto done;
} }
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); Pixel_in_screen_layered(x,y,color);
return; return;
} }
// Now replace all pixels which are of color c1, with color c2
for (x2 = 0; x2 < 8; x2++) for (x2 = 0; x2 < 8; x2++)
for (y2 = 0; y2 < 8; y2++) 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) { if (c2 == c1) {
Pixel_in_screen_layered(x2+start,y2+starty,color); 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; uint8_t c1, c2;
// The color we are going to replace // 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 // Pixel is already of the wanted color: nothing to do
if (c1 == color) 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 (x2 = 0; x2 < 8; x2++)
for (y2 = 0; y2 < 8; y2++) 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 // Pixel is already of the color we are going to add, it is no problem
if (c2 == color) if (c2 == color)
continue; continue;
@ -3195,20 +3218,35 @@ void Pixel_in_screen_zx_with_preview(word x,word y,byte color)
} }
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_with_preview(x2+start,y2+starty,c2 ^ 8);
}
}
Pixel_in_screen_layered_with_preview(x,y,color); Pixel_in_screen_layered_with_preview(x,y,color);
return; return;
} }
// Replace all C1 with C2 // Replace all C1 with color
for (x2 = 0; x2 < 8; x2++) for (x2 = 0; x2 < 8; x2++)
for (y2 = 0; y2 < 8; y2++) 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) { if (c2 == c1) {
Pixel_in_screen_layered_with_preview(x2+start,y2+starty,color); 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) void Pixel_in_screen_underlay(word x,word y,byte color)
{ {
byte depth; byte depth;
// Paste in layer // Paste in layer
*(Main_backups->Pages->Image[Main_current_layer].Pixels + x+y*Main_image_width)=color; *(Main_backups->Pages->Image[Main_current_layer].Pixels + x+y*Main_image_width)=color;
// Search depth // Search depth
depth = *(Main_backups->Pages->Image[4].Pixels + x+y*Main_image_width); depth = *(Main_backups->Pages->Image[4].Pixels + x+y*Main_image_width);
if ( depth == Main_current_layer) if ( depth == Main_current_layer)
{ {
// Draw that color on the visible image buffer // 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) void Pixel_in_screen_underlay_with_preview(word x,word y,byte color)
{ {
byte depth; byte depth;
// Paste in layer // Paste in layer
*(Main_backups->Pages->Image[Main_current_layer].Pixels + x+y*Main_image_width)=color; *(Main_backups->Pages->Image[Main_current_layer].Pixels + x+y*Main_image_width)=color;
// Search depth // Search depth
depth = *(Main_backups->Pages->Image[4].Pixels + x+y*Main_image_width); depth = *(Main_backups->Pages->Image[4].Pixels + x+y*Main_image_width);
if ( depth == Main_current_layer) if ( depth == Main_current_layer)
{ {
// Draw that color on the visible image buffer // Draw that color on the visible image buffer
*(x+y*Main_image_width+Main_screen)=color; *(x+y*Main_image_width+Main_screen)=color;
Pixel_preview(x,y,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 // Paste in depth buffer
*(Main_visible_image_depth_buffer.Image+x+y*Main_image_width)=color; *(Main_visible_image_depth_buffer.Image+x+y*Main_image_width)=color;
// Fetch pixel color from the target raster layer // Fetch pixel color from the target raster layer
if (Main_layers_visible & (1 << color)) if (Main_layers_visible & (1 << color))
color=*(Main_backups->Pages->Image[color].Pixels + x+y*Main_image_width); color=*(Main_backups->Pages->Image[color].Pixels + x+y*Main_image_width);
// Draw that color on the visible image buffer // Draw that color on the visible image buffer
*(x+y*Main_image_width+Main_screen)=color; *(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 // Paste in depth buffer
*(Main_visible_image_depth_buffer.Image+x+y*Main_image_width)=color; *(Main_visible_image_depth_buffer.Image+x+y*Main_image_width)=color;
// Fetch pixel color from the target raster layer // Fetch pixel color from the target raster layer
if (Main_layers_visible & (1 << color)) if (Main_layers_visible & (1 << color))
color=*(Main_backups->Pages->Image[color].Pixels + x+y*Main_image_width); color=*(Main_backups->Pages->Image[color].Pixels + x+y*Main_image_width);
// Draw that color on the visible image buffer // Draw that color on the visible image buffer
*(x+y*Main_image_width+Main_screen)=color; *(x+y*Main_image_width+Main_screen)=color;
Pixel_preview(x,y,color); Pixel_preview(x,y,color);
} }
} }