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
This commit is contained in:
Yves Rizoud 2011-11-08 23:11:18 +00:00
parent a60a33c204
commit ef030fec3f
6 changed files with 160 additions and 16 deletions

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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<Main_image_height;yy+=Snap_height)
for (xx=(x-Snap_offset_X)%Snap_width+Snap_offset_X;xx<Main_image_width;xx+=Snap_width)
Pixel_in_current_screen(xx,yy,color,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);

View File

@ -543,4 +543,11 @@ typedef enum {
MENUBAR_COUNT
} T_Menubars;
typedef struct
{
int Previous_occurence;
int Next_occurence;
int First_occurence;
} T_Tile;
#endif

View File

@ -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 <http://www.gnu.org/licenses/>
*/
/// \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<Main_image_height;yy+=Snap_height)
for (xx=(x+Snap_width-Snap_offset_X)%Snap_width+Snap_offset_X;xx<Main_image_width;xx+=Snap_width)
Pixel_in_current_screen(xx,yy,color,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<width*height; tile++)
{
Main_tilemap[tile].Previous_occurence = tile;
Main_tilemap[tile].Next_occurence = tile;
//Main_tilemap[tile].First_occurence = 1;
}
for (tile=1; tile<width*height; tile++)
{
int ref_tile=0;
while(1)
{
if (Main_tilemap[ref_tile].Previous_occurence<=ref_tile && Tile_is_same(ref_tile, tile))
{
// Insert at end
int last_tile=Main_tilemap[ref_tile].Previous_occurence;
Main_tilemap[tile].Previous_occurence=last_tile;
Main_tilemap[tile].Next_occurence=ref_tile;
//Main_tilemap[tile].First_occurence=0;
Main_tilemap[ref_tile].Previous_occurence=tile;
Main_tilemap[last_tile].Next_occurence=tile;
break;
}
ref_tile++;
if (ref_tile>=tile)
{
// New unique tile
//Main_tilemap[tile].First_occurence=1;
break;
}
}
}
}