Tilemap: support Y-flipped tiles
git-svn-id: svn://pulkomandy.tk/GrafX2/trunk@1863 416bcca6-2ee7-4201-b75f-2eb2f807beb1
This commit is contained in:
parent
914ec63c90
commit
3b989f3eb3
@ -353,6 +353,7 @@ GFX2_GLOBAL T_Tile * Main_tilemap;
|
|||||||
|
|
||||||
GFX2_GLOBAL short Main_tilemap_width;
|
GFX2_GLOBAL short Main_tilemap_width;
|
||||||
GFX2_GLOBAL short Main_tilemap_height;
|
GFX2_GLOBAL short Main_tilemap_height;
|
||||||
|
GFX2_GLOBAL byte Main_tilemap_allow_flip; ///< 0:no, 1:horizontally, 2:vertically, 3:both
|
||||||
|
|
||||||
// -- Spare page data
|
// -- Spare page data
|
||||||
|
|
||||||
|
|||||||
@ -547,6 +547,7 @@ typedef struct
|
|||||||
{
|
{
|
||||||
int Previous;
|
int Previous;
|
||||||
int Next;
|
int Next;
|
||||||
|
byte Flipped; ///< 0:no, 1:horizontally, 2:vertically, 3:both
|
||||||
} T_Tile;
|
} T_Tile;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
89
src/tiles.c
89
src/tiles.c
@ -144,13 +144,32 @@ void Tilemap_draw(word x, word y, byte color)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
tile = first_tile = TILE_FOR_COORDS(x,y);
|
tile = first_tile = TILE_FOR_COORDS(x,y);
|
||||||
|
|
||||||
rel_x = (x - Snap_offset_X + Snap_width) % Snap_width;
|
rel_x = (x - Snap_offset_X + Snap_width) % Snap_width;
|
||||||
rel_y = (y - Snap_offset_Y + Snap_height) % Snap_height;
|
rel_y = (y - Snap_offset_Y + Snap_height) % Snap_height;
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
int xx,yy;
|
int xx,yy;
|
||||||
|
switch(Main_tilemap[tile].Flipped ^ Main_tilemap[first_tile].Flipped)
|
||||||
|
{
|
||||||
|
case 0: // no
|
||||||
|
default:
|
||||||
xx = (tile % Main_tilemap_width)*Snap_width+Snap_offset_X + rel_x;
|
xx = (tile % Main_tilemap_width)*Snap_width+Snap_offset_X + rel_x;
|
||||||
yy = (tile / Main_tilemap_width)*Snap_height+Snap_offset_Y + rel_y;
|
yy = (tile / Main_tilemap_width)*Snap_height+Snap_offset_Y + rel_y;
|
||||||
|
break;
|
||||||
|
case 1: // horizontal
|
||||||
|
xx = (tile % Main_tilemap_width)*Snap_width+Snap_offset_X + Snap_width-rel_x-1;
|
||||||
|
yy = (tile / Main_tilemap_width)*Snap_height+Snap_offset_Y + rel_y;
|
||||||
|
break;
|
||||||
|
case 2: // vertical
|
||||||
|
xx = (tile % Main_tilemap_width)*Snap_width+Snap_offset_X + rel_x;
|
||||||
|
yy = (tile / Main_tilemap_width)*Snap_height+Snap_offset_Y + Snap_height - rel_y - 1;
|
||||||
|
break;
|
||||||
|
case 3: // both
|
||||||
|
xx = (tile % Main_tilemap_width)*Snap_width+Snap_offset_X + Snap_width-rel_x-1;
|
||||||
|
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);
|
Pixel_in_current_screen(xx,yy,color,yy>=Limit_top&&yy<=Limit_bottom&&xx>=Limit_left&&xx<=Limit_right);
|
||||||
tile = Main_tilemap[tile].Next;
|
tile = Main_tilemap[tile].Next;
|
||||||
} while (tile != first_tile);
|
} while (tile != first_tile);
|
||||||
@ -175,6 +194,23 @@ int Tile_is_same(int t1, int t2)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
int Tile_is_same_y(int t1, int t2)
|
||||||
|
{
|
||||||
|
byte *bmp1,*bmp2;
|
||||||
|
int y;
|
||||||
|
|
||||||
|
bmp1 = Main_backups->Pages->Image[Main_current_layer].Pixels+(TILE_Y(t1))*Main_image_width+(TILE_X(t1));
|
||||||
|
bmp2 = Main_backups->Pages->Image[Main_current_layer].Pixels+(TILE_Y(t2)+Snap_height-1)*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.
|
/// Create or update a tilemap based on current screen pixels.
|
||||||
void Tilemap_create(void)
|
void Tilemap_create(void)
|
||||||
{
|
{
|
||||||
@ -217,43 +253,66 @@ void Tilemap_create(void)
|
|||||||
Main_tilemap_width=width;
|
Main_tilemap_width=width;
|
||||||
Main_tilemap_height=height;
|
Main_tilemap_height=height;
|
||||||
|
|
||||||
// Init array with all tiles unique by default
|
// Initialize array with all tiles unique by default
|
||||||
for (tile=0; tile<width*height; tile++)
|
for (tile=0; tile<width*height; tile++)
|
||||||
{
|
{
|
||||||
Main_tilemap[tile].Previous = tile;
|
Main_tilemap[tile].Previous = tile;
|
||||||
Main_tilemap[tile].Next = tile;
|
Main_tilemap[tile].Next = tile;
|
||||||
|
Main_tilemap[tile].Flipped = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now find similar tiles and link them in circular linked list
|
// Now find similar tiles and link them in circular linked list
|
||||||
//It will be used to modify all tiles whenever you draw on one.
|
//It will be used to modify all tiles whenever you draw on one.
|
||||||
for (tile=1; tile<width*height; tile++)
|
for (tile=1; tile<width*height; tile++)
|
||||||
{
|
{
|
||||||
int ref_tile=0;
|
int ref_tile;
|
||||||
while(1)
|
|
||||||
|
// Try normal comparison
|
||||||
|
|
||||||
|
for (ref_tile=0; ref_tile<tile; ref_tile++)
|
||||||
{
|
{
|
||||||
if (Main_tilemap[ref_tile].Previous<=ref_tile && Tile_is_same(ref_tile, tile))
|
if (Main_tilemap[ref_tile].Previous<=ref_tile && Tile_is_same(ref_tile, tile))
|
||||||
{
|
{
|
||||||
|
break; // stop loop on ref_tile
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ref_tile<tile)
|
||||||
|
{
|
||||||
|
// New occurence of a known tile
|
||||||
// Insert at the end. classic doubly-linked-list.
|
// Insert at the end. classic doubly-linked-list.
|
||||||
int last_tile=Main_tilemap[ref_tile].Previous;
|
int last_tile=Main_tilemap[ref_tile].Previous;
|
||||||
Main_tilemap[tile].Previous=last_tile;
|
Main_tilemap[tile].Previous=last_tile;
|
||||||
Main_tilemap[tile].Next=ref_tile;
|
Main_tilemap[tile].Next=ref_tile;
|
||||||
|
Main_tilemap[tile].Flipped=Main_tilemap[ref_tile].Flipped;
|
||||||
Main_tilemap[ref_tile].Previous=tile;
|
Main_tilemap[ref_tile].Previous=tile;
|
||||||
Main_tilemap[last_tile].Next=tile;
|
Main_tilemap[last_tile].Next=tile;
|
||||||
|
continue; // next tile
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
// next
|
|
||||||
ref_tile++;
|
|
||||||
|
|
||||||
// end of loop without finding a match
|
// Try flipped-y comparison
|
||||||
if (ref_tile>=tile)
|
|
||||||
|
for (ref_tile=0; ref_tile<tile; ref_tile++)
|
||||||
{
|
{
|
||||||
|
if (Main_tilemap[ref_tile].Previous<=ref_tile && Tile_is_same_y(ref_tile, tile))
|
||||||
|
{
|
||||||
|
break; // stop loop on ref_tile
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ref_tile<tile)
|
||||||
|
{
|
||||||
|
// New occurence of a known tile
|
||||||
|
// Insert at the end. classic doubly-linked-list.
|
||||||
|
int last_tile=Main_tilemap[ref_tile].Previous;
|
||||||
|
Main_tilemap[tile].Previous=last_tile;
|
||||||
|
Main_tilemap[tile].Next=ref_tile;
|
||||||
|
Main_tilemap[tile].Flipped=Main_tilemap[ref_tile].Flipped ^ 2;
|
||||||
|
Main_tilemap[ref_tile].Previous=tile;
|
||||||
|
Main_tilemap[last_tile].Next=tile;
|
||||||
|
continue; // next tile
|
||||||
|
}
|
||||||
|
|
||||||
// This tile is really unique.
|
// This tile is really unique.
|
||||||
// Nothing to do at the moment
|
// Nothing to do at this time: the initialization
|
||||||
break;
|
// has already set the right data for Main_tilemap[tile].
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user