From ef030fec3f1ab60aa92df0bc009e645e71bfe311 Mon Sep 17 00:00:00 2001 From: Yves Rizoud Date: Tue, 8 Nov 2011 23:11:18 +0000 Subject: [PATCH] Tilemap mode improved to analyze and detect identical tiles, so you write in real time on all occurences of same tile. Works very well but unfinished, will crash or have other problems when you resize image git-svn-id: svn://pulkomandy.tk/GrafX2/trunk@1859 416bcca6-2ee7-4201-b75f-2eb2f807beb1 --- src/Makefile | 2 +- src/buttons_effects.c | 6 +- src/global.h | 6 ++ src/graph.c | 6 +- src/struct.h | 7 ++ src/tiles.c | 149 +++++++++++++++++++++++++++++++++++++++--- 6 files changed, 160 insertions(+), 16 deletions(-) diff --git a/src/Makefile b/src/Makefile index 13466fff..448e5cab 100644 --- a/src/Makefile +++ b/src/Makefile @@ -391,7 +391,7 @@ endif .PHONY : all debug release clean depend zip version force install uninstall # This is the list of the objects we want to build. Dependancies are built by "make depend" automatically. -OBJ = $(OBJDIR)/main.o $(OBJDIR)/init.o $(OBJDIR)/graph.o $(OBJDIR)/sdlscreen.o $(OBJDIR)/misc.o $(OBJDIR)/special.o $(OBJDIR)/buttons.o $(OBJDIR)/palette.o $(OBJDIR)/help.o $(OBJDIR)/operatio.o $(OBJDIR)/pages.o $(OBJDIR)/loadsave.o $(OBJDIR)/readline.o $(OBJDIR)/engine.o $(OBJDIR)/filesel.o $(OBJDIR)/op_c.o $(OBJDIR)/readini.o $(OBJDIR)/saveini.o $(OBJDIR)/shade.o $(OBJDIR)/keyboard.o $(OBJDIR)/io.o $(OBJDIR)/version.o $(OBJDIR)/text.o $(OBJDIR)/SFont.o $(OBJDIR)/setup.o $(OBJDIR)/pxsimple.o $(OBJDIR)/pxtall.o $(OBJDIR)/pxwide.o $(OBJDIR)/pxdouble.o $(OBJDIR)/pxtriple.o $(OBJDIR)/pxtall2.o $(OBJDIR)/pxwide2.o $(OBJDIR)/pxquad.o $(OBJDIR)/windows.o $(OBJDIR)/brush.o $(OBJDIR)/realpath.o $(OBJDIR)/mountlist.o $(OBJDIR)/input.o $(OBJDIR)/hotkeys.o $(OBJDIR)/transform.o $(OBJDIR)/pversion.o $(OBJDIR)/factory.o $(PLATFORMOBJ) $(OBJDIR)/fileformats.o $(OBJDIR)/miscfileformats.o $(OBJDIR)/libraw2crtc.o $(OBJDIR)/brush_ops.o $(OBJDIR)/buttons_effects.o $(OBJDIR)/layers.o $(OBJDIR)/oldies.o +OBJ = $(OBJDIR)/main.o $(OBJDIR)/init.o $(OBJDIR)/graph.o $(OBJDIR)/sdlscreen.o $(OBJDIR)/misc.o $(OBJDIR)/special.o $(OBJDIR)/buttons.o $(OBJDIR)/palette.o $(OBJDIR)/help.o $(OBJDIR)/operatio.o $(OBJDIR)/pages.o $(OBJDIR)/loadsave.o $(OBJDIR)/readline.o $(OBJDIR)/engine.o $(OBJDIR)/filesel.o $(OBJDIR)/op_c.o $(OBJDIR)/readini.o $(OBJDIR)/saveini.o $(OBJDIR)/shade.o $(OBJDIR)/keyboard.o $(OBJDIR)/io.o $(OBJDIR)/version.o $(OBJDIR)/text.o $(OBJDIR)/SFont.o $(OBJDIR)/setup.o $(OBJDIR)/pxsimple.o $(OBJDIR)/pxtall.o $(OBJDIR)/pxwide.o $(OBJDIR)/pxdouble.o $(OBJDIR)/pxtriple.o $(OBJDIR)/pxtall2.o $(OBJDIR)/pxwide2.o $(OBJDIR)/pxquad.o $(OBJDIR)/windows.o $(OBJDIR)/brush.o $(OBJDIR)/realpath.o $(OBJDIR)/mountlist.o $(OBJDIR)/input.o $(OBJDIR)/hotkeys.o $(OBJDIR)/transform.o $(OBJDIR)/pversion.o $(OBJDIR)/factory.o $(PLATFORMOBJ) $(OBJDIR)/fileformats.o $(OBJDIR)/miscfileformats.o $(OBJDIR)/libraw2crtc.o $(OBJDIR)/brush_ops.o $(OBJDIR)/buttons_effects.o $(OBJDIR)/layers.o $(OBJDIR)/oldies.o $(OBJDIR)/tiles.o SKIN_FILES = ../share/grafx2/skins/skin_classic.png ../share/grafx2/skins/skin_modern.png ../share/grafx2/skins/skin_DPaint.png ../share/grafx2/skins/font_Classic.png ../share/grafx2/skins/font_Fun.png ../share/grafx2/skins/font_Fairlight.png ../share/grafx2/skins/font_Melon.png ../share/grafx2/skins/font_DPaint.png ../share/grafx2/skins/skin_scenish.png ../share/grafx2/skins/font_Seen.png ../share/grafx2/skins/skin_Aurora.png diff --git a/src/buttons_effects.c b/src/buttons_effects.c index ed22df6f..2bf09ba3 100644 --- a/src/buttons_effects.c +++ b/src/buttons_effects.c @@ -193,6 +193,8 @@ void Button_Constraint_menu(void) void Button_Tilemap_mode(void) { Tilemap_mode=!Tilemap_mode; + if (Tilemap_mode) + Tilemap_create(); } void Button_Tilemap_menu(void) @@ -830,7 +832,9 @@ void Effects_off(void) Stencil_mode=0; Mask_mode=0; Sieve_mode=0; - Snap_mode=0; + Snap_mode=0; + Constraint_mode=0; + Tilemap_mode=0; } diff --git a/src/global.h b/src/global.h index 191258cd..961722b6 100644 --- a/src/global.h +++ b/src/global.h @@ -348,6 +348,12 @@ GFX2_GLOBAL Uint32 Main_time_of_safety_backup; /// Letter prefix for the filenames of safety backups. a or b GFX2_GLOBAL byte Main_safety_backup_prefix; +/// Tilemap for the main screen +GFX2_GLOBAL T_Tile * Main_tilemap; + +GFX2_GLOBAL short Main_tilemap_width; +GFX2_GLOBAL short Main_tilemap_height; + // -- Spare page data /// Palette of the spare page diff --git a/src/graph.c b/src/graph.c index f4c024d1..682eb302 100644 --- a/src/graph.c +++ b/src/graph.c @@ -2748,11 +2748,7 @@ void Display_pixel(word x,word y,byte color) color=Effect_function(x,y,color); if (Tilemap_mode) { - int xx,yy; - for (yy=(y-Snap_offset_Y)%Snap_height+Snap_offset_Y;yy=Limit_top&&yy<=Limit_bottom&&xx>=Limit_left&&xx<=Limit_right); - Update_rect(0,0,0,0); + Tilemap_draw(x,y, color); } else Pixel_in_current_screen(x,y,color,1); diff --git a/src/struct.h b/src/struct.h index 25b2c2ea..4042ff00 100644 --- a/src/struct.h +++ b/src/struct.h @@ -543,4 +543,11 @@ typedef enum { MENUBAR_COUNT } T_Menubars; +typedef struct +{ + int Previous_occurence; + int Next_occurence; + int First_occurence; +} T_Tile; + #endif diff --git a/src/tiles.c b/src/tiles.c index 32078abc..5049350e 100644 --- a/src/tiles.c +++ b/src/tiles.c @@ -2,7 +2,8 @@ */ /* Grafx2 - The Ultimate 256-color bitmap paint program - Copyright 2010 Adrien Destugues + Copyright 2011 Yves Rizoud + Copyright 2010-2011 Adrien Destugues Grafx2 is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -18,7 +19,12 @@ along with Grafx2; if not, see */ -/// \file Handle tiles. +#include "struct.h" +#include "global.h" +#include "graph.h" +#include "sdlscreen.h" +#include "tiles.h" + /// Build the tile-area from the current picture void build_tile_area() @@ -28,7 +34,7 @@ void build_tile_area() int* tileArea = malloc(tileAreaWidth*tileAreaHeight*sizeof(int)); - word tile_x, tile_y, pixel_x, pixel_y; + word tile_x, tile_y; // For each tile, we have to crawl up to the top of the picture and // find the first identical tile @@ -36,7 +42,7 @@ void build_tile_area() for(tile_x = 0; tile_x < tileAreaHeight; tile_x++) { // So, this is the "for each tile" - word ctx, cty; + short ctx, cty; // First we compare the tile with the others one in the same line at the left for(ctx = tile_x - 1; ctx >= 0; ctx--) if(compare_tiles(tile_x*Snap_width, tile_y*Snap_height, ctx*Snap_width, tile_y*Snap_height)) @@ -75,14 +81,15 @@ void build_tile_area() tileArea[tile_y*tileAreaWidth+tile_x] = tile_y*tileAreaWidth+ctx; } -found: + found: + ; } } // Compare tiles // The parameters are in pixel-space. -void compare_tiles(word x1, word y1, word x2, word y2) +int compare_tiles(word x1, word y1, word x2, word y2) { word pixel_x, pixel_y; byte c1, c2; @@ -90,14 +97,14 @@ void compare_tiles(word x1, word y1, word x2, word y2) for (pixel_y = 0; pixel_y < Snap_width; pixel_y++) for (pixel_x = 0; pixel_x < Snap_height; pixel_x++) { - c1 = Main_screen + (y1+pixel_y) * Main_image_width + (x1+pixel_x); - c2 = Main_screen + (y2+pixel_y) * Main_image_width + (x2+pixel_x); + c1 = *(Main_screen + (y1+pixel_y) * Main_image_width + (x1+pixel_x)); + c2 = *(Main_screen + (y2+pixel_y) * Main_image_width + (x2+pixel_x)); if (c1 != c2) return 0; } return 1; } - +/* /// Copy a tile pixeldata to all the identical ones // Call this after the end of an operation void update_tile(word pixel_x, word pixel_y) @@ -112,3 +119,127 @@ void update_tile(word pixel_x, word pixel_y) //do the copy of a block starting at (pixel_x, pixel_y) } } +*/ + +/* Basic repeat-all +void Tilemap_draw(word x, word y, byte color) +{ + int xx,yy; + for (yy=(y+Snap_height-Snap_offset_Y)%Snap_height+Snap_offset_Y;yy=Limit_top&&yy<=Limit_bottom&&xx>=Limit_left&&xx<=Limit_right); + Update_rect(0,0,0,0); +} +*/ + +void Tilemap_draw(word x, word y, byte color) +{ + int tile, first_tile; + int rel_x, rel_y; + + if (x < Snap_offset_X + || y < Snap_offset_Y + || x >= Snap_offset_X + Main_tilemap_width*Snap_width + || y >= Snap_offset_Y + Main_tilemap_height*Snap_height) + return; + + tile = first_tile = TILE_FOR_COORDS(x,y); + rel_x = (x + Snap_offset_X + Snap_width) % Snap_width; + rel_y = (y + Snap_offset_Y + Snap_height) % Snap_height; + do + { + int xx,yy; + xx = (tile % Main_tilemap_width)*Snap_width+Snap_offset_X + rel_x; + yy = (tile / Main_tilemap_width)*Snap_height+Snap_offset_Y + rel_y; + Pixel_in_current_screen(xx,yy,color,yy>=Limit_top&&yy<=Limit_bottom&&xx>=Limit_left&&xx<=Limit_right); + tile = Main_tilemap[tile].Next_occurence; + } while (tile != first_tile); + + Update_rect(0,0,0,0); +} + +/// +int Tile_is_same(int t1, int t2) +{ + byte *bmp1,*bmp2; + int y; + + bmp1 = Main_screen+(TILE_Y(t1))*Main_image_width+(TILE_X(t1)); + bmp2 = Main_screen+(TILE_Y(t2))*Main_image_width+(TILE_X(t2)); + + for (y=0; y < Snap_height; y++) + { + if (memcmp(bmp1+y*Main_image_width, bmp2+y*Main_image_width, Snap_width)) + return 0; + } + return 1; +} + +/// Create or update a tilemap based on current screen pixels. +void Tilemap_create(void) +{ + int width; + int height; + int tile; + T_Tile * tile_ptr; + + width=(Main_image_width-Snap_offset_X)/Snap_width; + height=(Main_image_height-Snap_offset_Y)/Snap_height; + + if (width<1 || height<1 || width*height>1000000l + || (tile_ptr=(T_Tile *)malloc(width*height*sizeof(T_Tile))) == NULL) + { + if (Main_tilemap) + { + free(Main_tilemap); + Main_tilemap=NULL; + } + Main_tilemap_width=0; + Main_tilemap_height=0; + Tilemap_mode=0; + return; + } + Main_tilemap_width=width; + Main_tilemap_height=height; + Main_tilemap=tile_ptr; + + // Init array + for (tile=0; tile=tile) + { + // New unique tile + //Main_tilemap[tile].First_occurence=1; + break; + } + } + + } + +} \ No newline at end of file