#include "ppport.h" #include "helper.h" typedef struct SDLx_LayerManager { AV *layers; SDL_Surface *saveshot; SDL_Surface *dest; int saved; } SDLx_LayerManager; typedef struct SDLx_Layer { SDLx_LayerManager *manager; int index; int attached; int touched; SDL_Surface *surface; SDL_Rect *clip; SDL_Rect *pos; SDL_Rect *attached_pos; SDL_Rect *attached_rel; HV *data; } SDLx_Layer; int intersection( SDLx_Layer *layer1, SDLx_Layer *layer2 ) { if( /* upper left point inside layer */ ( layer1->pos->x <= layer2->pos->x && layer2->pos->x < layer1->pos->x + layer1->clip->w && layer1->pos->y <= layer2->pos->y && layer2->pos->y < layer1->pos->y + layer1->clip->h ) /* upper right point inside layer */ || ( layer1->pos->x < layer2->pos->x + layer2->clip->w && layer2->pos->x + layer2->clip->w <= layer1->pos->x + layer1->clip->w && layer1->pos->y <= layer2->pos->y && layer2->pos->y < layer1->pos->y + layer1->clip->h ) /* lower left point inside layer */ || ( layer1->pos->x <= layer2->pos->x && layer2->pos->x < layer1->pos->x + layer1->clip->w && layer1->pos->y < layer2->pos->y + layer2->clip->h && layer2->pos->y + layer2->clip->h <= layer1->pos->y + layer1->clip->h ) /* lower right point inside layer */ || ( layer1->pos->x < layer2->pos->x + layer2->clip->w && layer2->pos->x + layer2->clip->w <= layer1->pos->x + layer1->clip->w && layer1->pos->y < layer2->pos->y + layer2->clip->h && layer2->pos->y + layer2->clip->h <= layer1->pos->y + layer1->clip->h ) ){ return 1; } return 0; } AV *layers_behind( SDLx_Layer *layer) { AV *matches = newAV(); int i; int count = 0; for( i = layer->index - 1; i >= 0; i-- ) { SV *bag = *av_fetch(layer->manager->layers, i, 0); SDLx_Layer *layer2 = (SDLx_Layer *)bag2obj(bag); if(intersection( layer, layer2 ) || intersection( layer2, layer )) { /* TODO checking transparency */ SvREFCNT_inc(bag); av_store( matches, count, bag ); count++; } } if(count) { AV *behind = layers_behind((SDLx_Layer *)bag2obj(*av_fetch(matches, av_len(matches), 0))); if(av_len(behind) >= 0) { for( i = 0; i <= av_len(behind); i++ ) { av_store( matches, count, *av_fetch(behind, i, 0)); count++; } } } return matches; } AV *layers_ahead( SDLx_Layer *layer ) { AV *matches = newAV(); int i; int count = 0; for( i = layer->index + 1; i <= av_len(layer->manager->layers); i++ ) { SV *bag = *av_fetch(layer->manager->layers, i, 0); SDLx_Layer *layer2 = (SDLx_Layer *)bag2obj(bag); if(intersection( layer, layer2 ) || intersection( layer2, layer )) { /* TODO checking transparency */ SvREFCNT_inc(bag); av_store( matches, count, bag ); count++; } } if(count) { AV *ahead = layers_ahead((SDLx_Layer *)bag2obj(*av_fetch(matches, av_len(matches), 0))); if(av_len(ahead) >= 0) { for( i = 0; i <= av_len(ahead); i++ ) { av_store( matches, count, *av_fetch(ahead, i, 0)); count++; } } } return matches; }