-
Notifications
You must be signed in to change notification settings - Fork 28
/
LayerManager.h
130 lines (113 loc) · 3.7 KB
/
LayerManager.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
#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;
static inline 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;
}
static inline 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;
}
static inline 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;
}