Constraint modes: Thomson, ZX
This commit is contained in:
parent
9e55b2d995
commit
f2b04e08d0
@ -5610,5 +5610,6 @@ void Button_Brush_container(void)
|
|||||||
|
|
||||||
byte Any_effect_active(void)
|
byte Any_effect_active(void)
|
||||||
{
|
{
|
||||||
return Shade_mode||Quick_shade_mode||Colorize_mode||Smooth_mode||Tiling_mode||Smear_mode||Stencil_mode||Mask_mode||Sieve_mode||Snap_mode||Main_tilemap_mode;
|
return Shade_mode||Quick_shade_mode||Colorize_mode||Smooth_mode||Tiling_mode||Smear_mode
|
||||||
|
||Stencil_mode||Mask_mode||Sieve_mode||Snap_mode||Main_tilemap_mode || (Main_backups->Pages->Image_mode > IMAGE_MODE_ANIMATION);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -215,11 +215,12 @@ void Button_Constraint_menu(void)
|
|||||||
Window_set_normal_button(82,55,51,14,"OK" ,0,1,SDLK_RETURN); // 2
|
Window_set_normal_button(82,55,51,14,"OK" ,0,1,SDLK_RETURN); // 2
|
||||||
|
|
||||||
dropdown = Window_set_dropdown_button(17, 21, 120, 14, 120, "Constraints", 1, 0, 1, RIGHT_SIDE|LEFT_SIDE, 0); // 3
|
dropdown = Window_set_dropdown_button(17, 21, 120, 14, 120, "Constraints", 1, 0, 1, RIGHT_SIDE|LEFT_SIDE, 0); // 3
|
||||||
//Window_dropdown_add_item(dropdown, IMAGE_MODE_ZX, "ZX Spectrum");
|
Window_dropdown_add_item(dropdown, IMAGE_MODE_ZX, "ZX Spectrum");
|
||||||
//Window_dropdown_add_item(dropdown, IMAGE_MODE_GBC, "Game Boy Color");
|
//Window_dropdown_add_item(dropdown, IMAGE_MODE_GBC, "Game Boy Color");
|
||||||
Window_dropdown_add_item(dropdown, IMAGE_MODE_EGX, "EGX (CPC)");
|
Window_dropdown_add_item(dropdown, IMAGE_MODE_THOMSON, "40col (MO/TO)");
|
||||||
Window_dropdown_add_item(dropdown, IMAGE_MODE_EGX2, "EGX2 (CPC)");
|
Window_dropdown_add_item(dropdown, IMAGE_MODE_EGX, "EGX (CPC)");
|
||||||
Window_dropdown_add_item(dropdown, IMAGE_MODE_MODE5, "Mode 5 (CPC)");
|
Window_dropdown_add_item(dropdown, IMAGE_MODE_EGX2, "EGX2 (CPC)");
|
||||||
|
Window_dropdown_add_item(dropdown, IMAGE_MODE_MODE5, "Mode 5 (CPC)");
|
||||||
|
|
||||||
Update_window_area(0,0,Window_width, Window_height);
|
Update_window_area(0,0,Window_width, Window_height);
|
||||||
Display_cursor();
|
Display_cursor();
|
||||||
@ -237,6 +238,8 @@ void Button_Constraint_menu(void)
|
|||||||
|
|
||||||
if (clicked_button==2) // OK
|
if (clicked_button==2) // OK
|
||||||
{
|
{
|
||||||
|
if ((Selected_Constraint_Mode > IMAGE_MODE_ANIMATION)
|
||||||
|
&& (Main_backups->Pages->Image_mode <= IMAGE_MODE_ANIMATION))
|
||||||
Button_Constraint_mode();
|
Button_Constraint_mode();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -591,6 +591,7 @@ enum IMAGE_MODES
|
|||||||
IMAGE_MODE_ANIMATION, ///< Animation
|
IMAGE_MODE_ANIMATION, ///< Animation
|
||||||
IMAGE_MODE_ZX, ///< ZX Spectrum (note "SPECTRUM" is kept for later... Spectrum 512 anyone?)
|
IMAGE_MODE_ZX, ///< ZX Spectrum (note "SPECTRUM" is kept for later... Spectrum 512 anyone?)
|
||||||
IMAGE_MODE_GBC, ///< Game Boy Color
|
IMAGE_MODE_GBC, ///< Game Boy Color
|
||||||
|
IMAGE_MODE_THOMSON, ///< "40 columns" mode on Thomson machines
|
||||||
IMAGE_MODE_EGX, ///< CPC EGX
|
IMAGE_MODE_EGX, ///< CPC EGX
|
||||||
IMAGE_MODE_EGX2, ///< CPC EGX2
|
IMAGE_MODE_EGX2, ///< CPC EGX2
|
||||||
IMAGE_MODE_MODE5, ///< CPC mode 5
|
IMAGE_MODE_MODE5, ///< CPC mode 5
|
||||||
|
|||||||
214
src/graph.c
214
src/graph.c
@ -59,8 +59,11 @@
|
|||||||
// Generic pixel-drawing function.
|
// Generic pixel-drawing function.
|
||||||
Func_pixel Pixel_figure;
|
Func_pixel Pixel_figure;
|
||||||
|
|
||||||
// Fonction qui met à jour la zone de l'image donnée en paramètre sur l'écran.
|
/** Update the picture on screen, for the area passed in parameters.
|
||||||
// Tient compte du décalage X et Y et du zoom, et fait tous les controles nécessaires
|
*
|
||||||
|
* Takes into account the X/Y scrolling and zoom, and performs all safety checks so no updates will
|
||||||
|
* go outside the display area.
|
||||||
|
*/
|
||||||
void Update_part_of_screen(short x, short y, short width, short height)
|
void Update_part_of_screen(short x, short y, short width, short height)
|
||||||
{
|
{
|
||||||
short effective_w, effective_h;
|
short effective_w, effective_h;
|
||||||
@ -68,7 +71,7 @@ void Update_part_of_screen(short x, short y, short width, short height)
|
|||||||
short effective_Y;
|
short effective_Y;
|
||||||
short diff;
|
short diff;
|
||||||
|
|
||||||
// Première étape, si L ou H est négatif, on doit remettre la zone à l'endroit
|
// First make sure the zone is in forward direction (positive width/height)
|
||||||
if (width < 0)
|
if (width < 0)
|
||||||
{
|
{
|
||||||
x += width;
|
x += width;
|
||||||
@ -81,7 +84,14 @@ void Update_part_of_screen(short x, short y, short width, short height)
|
|||||||
height = - height;
|
height = - height;
|
||||||
}
|
}
|
||||||
|
|
||||||
// D'abord on met à jour dans la zone écran normale
|
// Round up to a multiple of 8 pixels, because some special modes (ZX, Thomson, ...) can change
|
||||||
|
// more pixels than expected (attribute clash)
|
||||||
|
x &= 0xFFF8;
|
||||||
|
y &= 0xFFF8;
|
||||||
|
width = ((width - 1) | 0x7) + 1;
|
||||||
|
height = ((height - 1) | 0x7) + 1;
|
||||||
|
|
||||||
|
// Update "normal" view
|
||||||
diff = x-Main_offset_X;
|
diff = x-Main_offset_X;
|
||||||
if (diff<0)
|
if (diff<0)
|
||||||
{
|
{
|
||||||
@ -105,10 +115,10 @@ void Update_part_of_screen(short x, short y, short width, short height)
|
|||||||
effective_Y = diff;
|
effective_Y = diff;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Normalement il ne faudrait pas updater au delà du split quand on est en mode loupe,
|
// Clamp to actually visible area. All tools are normally constrained to this, but there are some
|
||||||
// mais personne ne devrait demander d'update en dehors de cette limite, même le fill est contraint
|
// exceptions:
|
||||||
// a rester dans la zone visible de l'image
|
// - Brush preview requests updates outside the visible screen,
|
||||||
// ...Sauf l'affichage de brosse en preview - yr
|
// - ZX/Thomson constraints can lead to pixel changes outside the visible area.
|
||||||
if(Main_magnifier_mode && effective_X + effective_w > Main_separator_position)
|
if(Main_magnifier_mode && effective_X + effective_w > Main_separator_position)
|
||||||
effective_w = Main_separator_position - effective_X;
|
effective_w = Main_separator_position - effective_X;
|
||||||
else if(effective_X + effective_w > Screen_width)
|
else if(effective_X + effective_w > Screen_width)
|
||||||
@ -116,8 +126,8 @@ void Update_part_of_screen(short x, short y, short width, short height)
|
|||||||
|
|
||||||
if(effective_Y + effective_h > Menu_Y)
|
if(effective_Y + effective_h > Menu_Y)
|
||||||
effective_h = Menu_Y - effective_Y;
|
effective_h = Menu_Y - effective_Y;
|
||||||
|
|
||||||
/*
|
/* (for debug purposes, highlight the rectangle that is updated)
|
||||||
SDL_Rect r;
|
SDL_Rect r;
|
||||||
r.x=effective_X;
|
r.x=effective_X;
|
||||||
r.y=effective_Y;
|
r.y=effective_Y;
|
||||||
@ -127,15 +137,16 @@ void Update_part_of_screen(short x, short y, short width, short height)
|
|||||||
*/
|
*/
|
||||||
Update_rect(effective_X,effective_Y,effective_w,effective_h);
|
Update_rect(effective_X,effective_Y,effective_w,effective_h);
|
||||||
|
|
||||||
// Et ensuite dans la partie zoomée
|
// Now update the "zoomed" part of the display
|
||||||
if(Main_magnifier_mode)
|
if(Main_magnifier_mode)
|
||||||
{
|
{
|
||||||
// Clipping en X
|
// Convert picture to zoomed-screen coordinates
|
||||||
effective_X = (x-Main_magnifier_offset_X)*Main_magnifier_factor;
|
effective_X = (x-Main_magnifier_offset_X)*Main_magnifier_factor;
|
||||||
effective_Y = (y-Main_magnifier_offset_Y)*Main_magnifier_factor;
|
effective_Y = (y-Main_magnifier_offset_Y)*Main_magnifier_factor;
|
||||||
effective_w = width * Main_magnifier_factor;
|
effective_w = width * Main_magnifier_factor;
|
||||||
effective_h = height * Main_magnifier_factor;
|
effective_h = height * Main_magnifier_factor;
|
||||||
|
|
||||||
|
// Apply horizontal clipping
|
||||||
if (effective_X < 0)
|
if (effective_X < 0)
|
||||||
{
|
{
|
||||||
effective_w+=effective_X;
|
effective_w+=effective_X;
|
||||||
@ -155,7 +166,7 @@ void Update_part_of_screen(short x, short y, short width, short height)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Clipping en Y
|
// Vertical clipping
|
||||||
if (effective_Y < 0)
|
if (effective_Y < 0)
|
||||||
{
|
{
|
||||||
effective_h+=effective_Y;
|
effective_h+=effective_Y;
|
||||||
@ -172,7 +183,7 @@ void Update_part_of_screen(short x, short y, short width, short height)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Très utile pour le debug :)
|
// Again, for debugging purposes, display the touched rectangle
|
||||||
/*SDL_Rect r;
|
/*SDL_Rect r;
|
||||||
r.x=effective_X;
|
r.x=effective_X;
|
||||||
r.y=effective_Y;
|
r.y=effective_Y;
|
||||||
@ -3041,6 +3052,167 @@ void Pixel_in_screen_egx_with_preview(word x,word y,byte color)
|
|||||||
Pixel_in_screen_layered_with_preview(x,y,color & mask);
|
Pixel_in_screen_layered_with_preview(x,y,color & mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Pixel_in_screen_thomson(word x,word y,byte color)
|
||||||
|
{
|
||||||
|
word start = x & 0xFFF8;
|
||||||
|
word x2;
|
||||||
|
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);
|
||||||
|
|
||||||
|
if (c1 == color)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (x2 = 0; x2 < 8; x2++)
|
||||||
|
{
|
||||||
|
c2 = *(Main_backups->Pages->Image[Main_current_layer].Pixels + (x2+start)+y*Main_image_width);
|
||||||
|
if (c2 == color)
|
||||||
|
continue;
|
||||||
|
if (c2 != c1)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (c2 == c1 || c2 == color)
|
||||||
|
{
|
||||||
|
// There was only one color, so we can add a second one.
|
||||||
|
Pixel_in_screen_layered(x,y,color);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (x2 = 0; x2 < 8; x2++)
|
||||||
|
{
|
||||||
|
c2 = *(Main_backups->Pages->Image[Main_current_layer].Pixels + (x2+start)+y*Main_image_width);
|
||||||
|
if (c2 == c1) {
|
||||||
|
Pixel_in_screen_layered(x2+start,y,color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Pixel_in_screen_thomson_with_preview(word x,word y,byte color)
|
||||||
|
{
|
||||||
|
word start = x & 0xFFF8;
|
||||||
|
word x2;
|
||||||
|
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);
|
||||||
|
|
||||||
|
if (c1 == color)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (x2 = 0; x2 < 8; x2++)
|
||||||
|
{
|
||||||
|
c2 = *(Main_backups->Pages->Image[Main_current_layer].Pixels + (x2+start)+y*Main_image_width);
|
||||||
|
if (c2 == color)
|
||||||
|
continue;
|
||||||
|
if (c2 != c1)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (c2 == c1 || c2 == color)
|
||||||
|
{
|
||||||
|
// There was only one color, so we can add a second one.
|
||||||
|
Pixel_in_screen_layered_with_preview(x,y,color);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (x2 = 0; x2 < 8; x2++)
|
||||||
|
{
|
||||||
|
c2 = *(Main_backups->Pages->Image[Main_current_layer].Pixels + (x2+start)+y*Main_image_width);
|
||||||
|
if (c2 == c1) {
|
||||||
|
Pixel_in_screen_layered_with_preview(x2+start,y,color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Pixel_in_screen_zx(word x,word y,byte color)
|
||||||
|
{
|
||||||
|
word start = x & 0xFFF8;
|
||||||
|
word starty = y & 0xFFF8;
|
||||||
|
word x2, y2;
|
||||||
|
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);
|
||||||
|
|
||||||
|
if (c1 == color)
|
||||||
|
return;
|
||||||
|
|
||||||
|
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);
|
||||||
|
if (c2 == color)
|
||||||
|
continue;
|
||||||
|
if (c2 != c1)
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
done:
|
||||||
|
|
||||||
|
if (c2 == c1 || c2 == color)
|
||||||
|
{
|
||||||
|
// There was only one color, so we can add a second one.
|
||||||
|
Pixel_in_screen_layered(x,y,color);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
if (c2 == c1) {
|
||||||
|
Pixel_in_screen_layered(x2+start,y2+starty,color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Pixel_in_screen_zx_with_preview(word x,word y,byte color)
|
||||||
|
{
|
||||||
|
word start = x & 0xFFF8;
|
||||||
|
word starty = y & 0xFFF8;
|
||||||
|
word x2,y2;
|
||||||
|
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);
|
||||||
|
|
||||||
|
// Pixel is already of the wanted color: nothing to do
|
||||||
|
if (c1 == color)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Check the whole 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);
|
||||||
|
// 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)
|
||||||
|
{
|
||||||
|
// There was only one color, so we can add a second one.
|
||||||
|
Pixel_in_screen_layered_with_preview(x,y,color);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Replace all C1 with 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);
|
||||||
|
if (c2 == c1) {
|
||||||
|
Pixel_in_screen_layered_with_preview(x2+start,y2+starty,color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Paint a a single pixel in image only : in a layer under one that acts as a layer-selector (mode 5).
|
/// Paint a a single pixel in image only : in a layer under one that acts as a layer-selector (mode 5).
|
||||||
void Pixel_in_screen_underlay(word x,word y,byte color)
|
void Pixel_in_screen_underlay(word x,word y,byte color)
|
||||||
{
|
{
|
||||||
@ -3150,10 +3322,22 @@ void Update_pixel_renderer(void)
|
|||||||
if (Main_backups->Pages->Image_mode == IMAGE_MODE_EGX
|
if (Main_backups->Pages->Image_mode == IMAGE_MODE_EGX
|
||||||
|| Main_backups->Pages->Image_mode == IMAGE_MODE_EGX2)
|
|| Main_backups->Pages->Image_mode == IMAGE_MODE_EGX2)
|
||||||
{
|
{
|
||||||
// layered
|
// special "EGX" mode
|
||||||
Pixel_in_current_screen = Pixel_in_screen_egx;
|
Pixel_in_current_screen = Pixel_in_screen_egx;
|
||||||
Pixel_in_current_screen_with_preview = Pixel_in_screen_egx_with_preview;
|
Pixel_in_current_screen_with_preview = Pixel_in_screen_egx_with_preview;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
if (Main_backups->Pages->Image_mode == IMAGE_MODE_THOMSON)
|
||||||
|
{
|
||||||
|
Pixel_in_current_screen = Pixel_in_screen_thomson;
|
||||||
|
Pixel_in_current_screen_with_preview = Pixel_in_screen_thomson_with_preview;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if (Main_backups->Pages->Image_mode == IMAGE_MODE_ZX)
|
||||||
|
{
|
||||||
|
Pixel_in_current_screen = Pixel_in_screen_zx;
|
||||||
|
Pixel_in_current_screen_with_preview = Pixel_in_screen_zx_with_preview;
|
||||||
|
}
|
||||||
// Implicit else : Image_mode must be IMAGE_MODE_MODE5
|
// Implicit else : Image_mode must be IMAGE_MODE_MODE5
|
||||||
else if ( Main_current_layer == 4)
|
else if ( Main_current_layer == 4)
|
||||||
{
|
{
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user