214 lines
6.7 KiB
C++
214 lines
6.7 KiB
C++
#include "../config.h"
|
|
|
|
#include <azur/azur.h>
|
|
#include <azur/gint/render.h>
|
|
|
|
#include "utilities.h"
|
|
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
#include <fxlibc/printf.h>
|
|
#include <sys/types.h>
|
|
|
|
|
|
extern font_t milifont_prop;
|
|
|
|
void Azur_draw_text(int x, int y, char const *fmt, ...)
|
|
{
|
|
char str[128];
|
|
va_list args;
|
|
va_start(args, fmt);
|
|
vsnprintf(str, 128, fmt, args);
|
|
va_end(args);
|
|
|
|
dfont( &milifont_prop );
|
|
|
|
azrp_text( x, y, C_WHITE, str );
|
|
}
|
|
|
|
|
|
|
|
bool AABB_Collision( SpriteLocator image1, SpriteLocator image2 )
|
|
{
|
|
if( (image2.x >= image1.x + image1.image->width)
|
|
|| (image2.x + image2.image->width <= image1.x)
|
|
|| (image2.y >= image1.y + image1.image->height)
|
|
|| (image2.y + image2.image->height <= image1.y) )
|
|
return false;
|
|
|
|
// no need to do pixel perfect detection
|
|
return true;
|
|
}
|
|
|
|
|
|
|
|
bool Pixel_Perfect_Collision( SpriteLocator image1, SpriteLocator image2 )
|
|
{
|
|
if( !AABB_Collision( image1, image2 ) )
|
|
return false; // bounding boxes not overlapping, impossible to have collision
|
|
|
|
/* if we reach that point, this means that we need to perform pixel perfect collsion detection */
|
|
|
|
/* First we will calculate the corners of the zone to be tested for collision */
|
|
/* as it is not usefull to check for all the surface of the image, only the */
|
|
/* overlapping area will be verified */
|
|
|
|
|
|
|
|
/* WARNING !! */
|
|
/* P4 format is not supported yet has it is currently focused on use with Azur */
|
|
/* that is mostly P8/RGB565 oriented for ultra fast performances */
|
|
if ( IMAGE_IS_P4(image1.image->format) || IMAGE_IS_P4(image2.image->format) )
|
|
return false;
|
|
|
|
|
|
|
|
|
|
int astartx, aendx;
|
|
int astarty, aendy;
|
|
int adeltax, adeltay;
|
|
|
|
int bstartx, bendx;
|
|
int bstarty, bendy;
|
|
int bdeltax, bdeltay;
|
|
|
|
int rows, columns;
|
|
|
|
if (image1.x <= image2.x)
|
|
{
|
|
adeltax = image2.x - image1.x;
|
|
columns = MIN(image1.image->width - adeltax, image2.image->width);
|
|
bdeltax = 0;
|
|
}
|
|
else
|
|
{
|
|
bdeltax = image1.x - image2.x;
|
|
columns = MIN(image2.image->width - bdeltax, image1.image->width);
|
|
adeltax = 0;
|
|
}
|
|
|
|
if (image1.y <= image2.y)
|
|
{
|
|
adeltay = image2.y - image1.y;
|
|
rows = MIN(image1.image->height - adeltay, image2.image->height);
|
|
bdeltay = 0;
|
|
}
|
|
else
|
|
{
|
|
bdeltay = image1.y - image2.y;
|
|
rows = MIN(image2.image->height - bdeltay, image1.image->height);
|
|
adeltay = 0;
|
|
}
|
|
|
|
/* if BOTH images are in a 16bits color format, we will not use masks and will quicken the process */
|
|
if ( IMAGE_IS_RGB16(image1.image->format) && IMAGE_IS_RGB16(image2.image->format) )
|
|
{
|
|
void *data1 = image1.image->data + adeltay * image1.image->stride;
|
|
void *data2 = image2.image->data + bdeltay * image2.image->stride;
|
|
|
|
uint16_t *data_u16_1 = (uint16_t *) data1;
|
|
uint16_t *data_u16_2 = (uint16_t *) data2;
|
|
|
|
int transp1 = image_alpha(image1.image->format);
|
|
int transp2 = image_alpha(image2.image->format);
|
|
|
|
for( int j=0; j<rows; j++)
|
|
{
|
|
for (int i=0; i<columns; i++)
|
|
{
|
|
if( (data_u16_1[ adeltax + i ] != transp1 )
|
|
&& (data_u16_2[ bdeltax + i ] != transp2 ) )
|
|
return true;
|
|
}
|
|
data1 += image1.image->stride;
|
|
data_u16_1 = (uint16_t *) data1;
|
|
data2 += image2.image->stride;
|
|
data_u16_2 = (uint16_t *) data2;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/* if BOTH images are in a 8bits color format, we will not use masks and will quicken the process */
|
|
|
|
if ( IMAGE_IS_P8(image1.image->format) && IMAGE_IS_P8(image2.image->format) )
|
|
{
|
|
void *data1 = image1.image->data + adeltay * image1.image->stride;
|
|
void *data2 = image2.image->data + bdeltay * image2.image->stride;
|
|
|
|
int8_t *data_u8_1 = (int8_t *) data1;
|
|
int8_t *data_u8_2 = (int8_t *) data2;
|
|
|
|
int transp1 = image_alpha(image1.image->format);
|
|
int transp2 = image_alpha(image2.image->format);
|
|
|
|
for( int j=0; j<rows; j++)
|
|
{
|
|
for (int i=0; i<columns; i++)
|
|
{
|
|
if( (data_u8_1[ adeltax + i ] != transp1 )
|
|
&& (data_u8_2[ bdeltax + i ] != transp2 ) )
|
|
return true;
|
|
}
|
|
data1 += image1.image->stride;
|
|
data_u8_1 = (int8_t *) data1;
|
|
data2 += image2.image->stride;
|
|
data_u8_2 = (int8_t *) data2;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/* if we reach that point, this means that images have differnt format and we need to manage this */
|
|
|
|
uint8_t d1;
|
|
uint8_t d2;
|
|
|
|
void *data1 = image1.image->data + adeltay * image1.image->stride;
|
|
void *data2 = image2.image->data + bdeltay * image2.image->stride;
|
|
|
|
int8_t *data_u8_1 = (int8_t *) data1;
|
|
uint16_t *data_u16_1 = (uint16_t *) data1;
|
|
|
|
int8_t *data_u8_2 = (int8_t *) data2;
|
|
uint16_t *data_u16_2 = (uint16_t *) data2;
|
|
|
|
int transp1 = image_alpha(image1.image->format);
|
|
int transp2 = image_alpha(image2.image->format);
|
|
|
|
bool im1_P16 = IMAGE_IS_RGB16(image1.image->format);
|
|
bool im1_P8 = IMAGE_IS_P8(image1.image->format);
|
|
|
|
bool im2_P16 = IMAGE_IS_RGB16(image2.image->format);
|
|
bool im2_P8 = IMAGE_IS_P8(image2.image->format);
|
|
|
|
for( int j=0; j<rows; j++)
|
|
{
|
|
for (int i=0; i<columns; i++)
|
|
{
|
|
/* d1 is set to 1 if pixel of image1 is not transparent and to 0 if transparent */
|
|
/* need to be format dependant here so quite time consumming test at each loop :( )*/
|
|
if (im1_P16)
|
|
d1 = data_u16_1[ adeltax + i ] == transp1 ? 0 : 1;
|
|
else if (im1_P8)
|
|
d1 = data_u8_1[ adeltax + i ] == transp1 ? 0 : 1;
|
|
|
|
/* d2 is set to 1 if pixel of image2 is not transparent and to 0 if transparent */
|
|
/* need to be format dependant here so quite time consumming test at each loop :( )*/
|
|
if (im2_P16)
|
|
d2 = data_u16_2[ bdeltax + i ] == transp2 ? 0 : 1;
|
|
else if (im2_P8)
|
|
d2 = data_u8_2[ bdeltax + i ] == transp2 ? 0 : 1;
|
|
|
|
/* if d1 + d2 = 2 means that both coincident pixels are not transparent and then we have collision*/
|
|
if (d1 + d2 == 2) return true;
|
|
}
|
|
/* we move the pointer to the next line of both images */
|
|
data1 += image1.image->stride;
|
|
data2 += image2.image->stride;
|
|
data_u8_1 = (int8_t *) data1;
|
|
data_u8_2 = (int8_t *) data2;
|
|
data_u16_1 = (uint16_t *) data1;
|
|
data_u16_2 = (uint16_t *) data2;
|
|
}
|
|
return false;
|
|
} |