From 55d0889bc86c5160518df9ff82935dd0e0facf34 Mon Sep 17 00:00:00 2001 From: Yves Rizoud Date: Wed, 22 Feb 2012 23:47:53 +0000 Subject: [PATCH] Change rendering system to use function pointers, see Issue 31 c38 : preliminary work to make the same executable handle Layers or Anims. Fixed an old issue where Lasso-ing a brush with right mouse button wouldn't erase cleanly (visual). Fixed an old issue where picking colors in layer 5 would not 'see' through layers. git-svn-id: svn://pulkomandy.tk/GrafX2/trunk@1906 416bcca6-2ee7-4201-b75f-2eb2f807beb1 --- src/brush.c | 6 +- src/factory.c | 8 +- src/graph.c | 229 ++++++++++++++++++++++++++++-------------- src/graph.h | 11 +- src/layers.c | 1 + src/loadsave.c | 4 +- src/misc.c | 2 +- src/miscfileformats.c | 10 +- src/pages.c | 1 + src/tiles.c | 6 +- 10 files changed, 189 insertions(+), 89 deletions(-) diff --git a/src/brush.c b/src/brush.c index 654e58d1..29cc7f4c 100644 --- a/src/brush.c +++ b/src/brush.c @@ -350,7 +350,7 @@ void Draw_paintbrush(short x,short y,byte color) for (yy=min_y; yy0 && y_pos >0 && x_posPages->Image[Main_current_layer].Pixels + x+y*Main_image_width); + + if (Constraint_mode) + 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 @@ -3023,85 +3024,127 @@ byte Read_pixel_from_current_screen (word x,word y) #endif } -void Pixel_in_current_screen (word x,word y,byte color,int with_preview) +/// Paint a a single pixel in image only : as-is. +void Pixel_in_screen_direct(word x,word y,byte color) { - #ifndef NOLAYERS - if (!Constraint_mode) + *((y)*Main_image_width+(x)+/*Main_backups->Pages->Image[Main_current_layer].Pixels*/Main_screen)=color; +} + +/// Paint a a single pixel in image and on screen: as-is. +void Pixel_in_screen_direct_with_preview(word x,word y,byte color) +{ + *((y)*Main_image_width+(x)+/*Main_backups->Pages->Image[Main_current_layer].Pixels*/Main_screen)=color; + Pixel_preview(x,y,color); +} + +#ifndef NOLAYERS + +/// Paint a a single pixel in image only : using layered display. +void Pixel_in_screen_layered(word x,word y,byte color) +{ + byte depth = *(Main_visible_image_depth_buffer.Image+x+y*Main_image_width); + *(Main_backups->Pages->Image[Main_current_layer].Pixels + x+y*Main_image_width)=color; + if ( depth <= Main_current_layer) { - byte depth = *(Main_visible_image_depth_buffer.Image+x+y*Main_image_width); - *(Main_backups->Pages->Image[Main_current_layer].Pixels + x+y*Main_image_width)=color; - if ( depth <= Main_current_layer) - { - 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; - - if (with_preview) - Pixel_preview(x,y,color); - } - } - else if ( Main_current_layer == 4) - { - if (color<4) - { - // Paste in layer - *(Main_backups->Pages->Image[Main_current_layer].Pixels + x+y*Main_image_width)=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 - 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; - - if (with_preview) - Pixel_preview(x,y,color); - } - } - else if (Main_current_layer<4 && (Main_layers_visible & (1<<4))) - { - byte depth; + 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; + } +} + +/// Paint a a single pixel in image and on screen : using layered display. +void Pixel_in_screen_layered_with_preview(word x,word y,byte color) +{ + byte depth = *(Main_visible_image_depth_buffer.Image+x+y*Main_image_width); + *(Main_backups->Pages->Image[Main_current_layer].Pixels + x+y*Main_image_width)=color; + if ( depth <= Main_current_layer) + { + 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); + } +} + +/// 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) +{ + 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; + } +} + +/// Paint a a single pixel in image and on screen : in a layer under one that acts as a layer-selector (mode 5). +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); + } +} + +/// Paint a a single pixel in image only : in a layer that acts as a layer-selector (mode 5). +void Pixel_in_screen_overlay(word x,word y,byte color) +{ + if (color<4) + { // 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; - - if (with_preview) - Pixel_preview(x,y,color); - } - } - else - { - byte depth; - - *(Main_backups->Pages->Image[Main_current_layer].Pixels + x+y*Main_image_width)=color; - depth = *(Main_visible_image_depth_buffer.Image+x+y*Main_image_width); - if ( depth <= Main_current_layer) - { - 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; - - if (with_preview) - Pixel_preview(x,y,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 + 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; } - #else - *((y)*Main_image_width+(x)+Main_backups->Pages->Image[Main_current_layer].Pixels)=color; - if (with_preview) - Pixel_preview(x,y,color); - #endif } +/// Paint a a single pixel in image and on screen : in a layer that acts as a layer-selector (mode 5). +void Pixel_in_screen_overlay_with_preview(word x,word y,byte color) +{ + if (color<4) + { + // Paste in layer + *(Main_backups->Pages->Image[Main_current_layer].Pixels + x+y*Main_image_width)=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 + 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); + } +} +#endif + +Func_pixel Pixel_in_current_screen=Pixel_in_screen_direct; +Func_pixel Pixel_in_current_screen_with_preview=Pixel_in_screen_direct_with_preview; + void Pixel_in_spare(word x,word y, byte color) { *((y)*Spare_image_width+(x)+Spare_backups->Pages->Image[Spare_current_layer].Pixels)=color; @@ -3116,3 +3159,37 @@ byte Read_pixel_from_current_layer(word x,word y) { return *((y)*Main_image_width+(x)+Main_backups->Pages->Image[Main_current_layer].Pixels); } + +void Update_pixel_renderer(void) +{ + #ifndef NOLAYERS + if (!Constraint_mode) + { + // layered + Pixel_in_current_screen = Pixel_in_screen_layered; + Pixel_in_current_screen_with_preview = Pixel_in_screen_layered_with_preview; + } + else if ( Main_current_layer == 4) + { + // overlay + Pixel_in_current_screen = Pixel_in_screen_overlay; + Pixel_in_current_screen_with_preview = Pixel_in_screen_overlay_with_preview; + } + else if (Main_current_layer<4 && (Main_layers_visible & (1<<4))) + { + // underlay + Pixel_in_current_screen = Pixel_in_screen_underlay; + Pixel_in_current_screen_with_preview = Pixel_in_screen_underlay_with_preview; + } + else + { + // layered (again) + Pixel_in_current_screen = Pixel_in_screen_layered; + Pixel_in_current_screen_with_preview = Pixel_in_screen_layered_with_preview; + } + #else + // direct + Pixel_in_current_screen = Pixel_in_screen_direct; + Pixel_in_current_screen_with_preview = Pixel_in_screen_direct_with_preview; + #endif +} diff --git a/src/graph.h b/src/graph.h index 9f942099..74d19878 100644 --- a/src/graph.h +++ b/src/graph.h @@ -121,8 +121,17 @@ void Update_part_of_screen(short x, short y, short width, short height); void Redraw_grid(short x, short y, unsigned short w, unsigned short h); -void Pixel_in_current_screen (word x,word y,byte color,int with_preview); void Pixel_in_spare(word x,word y, byte color); void Pixel_in_current_layer(word x,word y, byte color); byte Read_pixel_from_current_screen (word x,word y); byte Read_pixel_from_current_layer(word x,word y); + +/// Paint a single pixel in image only. +extern Func_pixel Pixel_in_current_screen; + +/// Paint a single pixel in image AND on screen. +extern Func_pixel Pixel_in_current_screen_with_preview; + +/// Sets ::Pixel_in_current_screen and ::Pixel_in_current_screen_with_preview +void Update_pixel_renderer(void); + diff --git a/src/layers.c b/src/layers.c index 28b5c58c..430ff88d 100644 --- a/src/layers.c +++ b/src/layers.c @@ -89,6 +89,7 @@ void Layer_activate(int layer, short side) Update_depth_buffer(); // Only need the depth buffer //Download_infos_page_main(Main_backups->Pages); //Update_FX_feedback(Config.FX_Feedback); + Update_pixel_renderer(); Display_all_screen(); Display_layerbar(); Display_cursor(); diff --git a/src/loadsave.c b/src/loadsave.c index fbd2eca5..a2025417 100644 --- a/src/loadsave.c +++ b/src/loadsave.c @@ -189,7 +189,7 @@ void Set_pixel(T_IO_Context *context, short x_pos, short y_pos, byte color) { // Chargement des pixels dans l'écran principal case CONTEXT_MAIN_IMAGE: - Pixel_in_current_screen(x_pos,y_pos,color,0); + Pixel_in_current_screen(x_pos,y_pos,color); break; // Chargement des pixels dans la brosse @@ -1335,6 +1335,8 @@ void Set_loading_layer(T_IO_Context *context, int layer) } Main_current_layer = layer; context->Target_address=Main_backups->Pages->Image[layer].Pixels; + + Update_pixel_renderer(); } } diff --git a/src/misc.c b/src/misc.c index 7e04cce2..64dbc2b2 100644 --- a/src/misc.c +++ b/src/misc.c @@ -238,7 +238,7 @@ void Replace_a_color(byte old_color, byte new_color) for (y=0; yHeight; ty++) for(tx=0; txWidth; tx++) { diff --git a/src/pages.c b/src/pages.c index 1466163c..73ba7bf3 100644 --- a/src/pages.c +++ b/src/pages.c @@ -678,6 +678,7 @@ void Update_screen_targets(void) Main_screen=Main_backups->Pages->Image[Main_current_layer].Pixels; Screen_backup=Main_backups->Pages->Next->Image[Main_current_layer].Pixels; #endif + Update_pixel_renderer(); } /// Update all the special image buffers, if necessary. diff --git a/src/tiles.c b/src/tiles.c index 3f3b4c82..a3b89b35 100644 --- a/src/tiles.c +++ b/src/tiles.c @@ -192,7 +192,11 @@ void Tilemap_draw(word x, word y, byte color) yy = (tile / Main_tilemap_width)*Snap_height+Snap_offset_Y + Snap_height - rel_y - 1; break; } - Pixel_in_current_screen(xx,yy,color,yy>=Limit_top&&yy<=Limit_bottom&&xx>=Limit_left&&xx<=Limit_right); + if (yy>=Limit_top&&yy<=Limit_bottom&&xx>=Limit_left&&xx<=Limit_right) + Pixel_in_current_screen_with_preview(xx,yy,color); + else + Pixel_in_current_screen(xx,yy,color); + tile = Main_tilemap[tile].Next; } while (tile != first_tile);