OSDN Git Service

リファクタリング
[coroid/inqubus.git] / vhook / comment / shadow.c
1 #include <SDL/SDL.h>
2 #include "surf_util.h"
3 #include "shadow.h"
4
5 /*影なし*/
6 SDL_Surface* noShadow(SDL_Surface* surf,int is_black,int is_fix_size){
7         return surf;
8 }
9 /*右下*/
10 #define SHADOW_SIZE 3
11
12 SDL_Surface* likeNicoNico(SDL_Surface* surf,int is_black,int is_fix_size){
13         /*スライド幅の確定*/
14         int slide = SHADOW_SIZE;
15         if(is_fix_size){
16                 slide <<= 1;
17         }
18         int w = surf->w;
19         int h = surf->h;
20         SDL_Surface* shadow = SDL_CreateRGBSurface(             SDL_SRCALPHA | SDL_HWSURFACE | SDL_HWACCEL,
21                                                                                                 w+(slide<<1),
22                                                                                                 h+(slide<<1),
23                                                                                                 32,
24                                                                                                 #if SDL_BYTEORDER == SDL_BIG_ENDIAN
25                                                                                                     0xff000000,
26                                                                                                     0x00ff0000,
27                                                                                                     0x0000ff00,
28                                                                                                     0x000000ff
29                                                                                                 #else
30                                                                                                     0x000000ff,
31                                                                                                     0x0000ff00,
32                                                                                                     0x00ff0000,
33                                                                                                     0xff000000
34                                                                                                 #endif
35                                                                                         );
36         SDL_Surface* shadow2 = SDL_CreateRGBSurface(    SDL_SRCALPHA | SDL_HWSURFACE | SDL_HWACCEL,
37                                                                                                 w+(slide<<1),
38                                                                                                 h+(slide<<1),
39                                                                                                 32,
40                                                                                                 #if SDL_BYTEORDER == SDL_BIG_ENDIAN
41                                                                                                     0xff000000,
42                                                                                                     0x00ff0000,
43                                                                                                     0x0000ff00,
44                                                                                                     0x000000ff
45                                                                                                 #else
46                                                                                                     0x000000ff,
47                                                                                                     0x0000ff00,
48                                                                                                     0x00ff0000,
49                                                                                                     0xff000000
50                                                                                                 #endif
51                                                                                         );
52         SDL_Rect rect = {slide,slide};
53         SDL_SetAlpha(surf,0,0xff);
54         SDL_BlitSurface(surf,NULL,shadow,&rect);
55         SDL_SetAlpha(surf,SDL_SRCALPHA,0xff);
56         if(is_black){//黒であれば、周りをしろで囲む
57                 setRGB(shadow,0xffffffff);
58         }else{
59                 setRGB(shadow,0);
60         }
61         SDL_SetAlpha(shadow,0,0xff);
62         SDL_BlitSurface(shadow,NULL,shadow2,NULL);
63         SDL_SetAlpha(shadow,SDL_SRCALPHA,0xff);
64         int x,y,z;
65         int nw = shadow->w;
66         int nh = shadow->h;
67         int *pix;
68         int *pix2;
69         int pitch = shadow->pitch;
70         int bps = shadow->format->BytesPerPixel;
71         Uint32 Amask = shadow->format->Amask;
72         Uint32 Mask = (shadow->format->Rmask | shadow->format->Gmask | shadow->format->Bmask);
73         Uint32 Ashift = shadow->format->Ashift;
74         Uint32 Aloss = shadow->format->Aloss;
75         SDL_LockSurface(shadow);
76         SDL_LockSurface(shadow2);
77         //ここは偶数にすること。
78         int zmax = 10;
79         if(is_fix_size){
80                 zmax = 16;
81         }
82         SDL_Surface* tmp;
83         for(z=0;z<zmax;z++){
84                 char *pixels = (char*)shadow->pixels;
85                 char *pixels2 = (char*)shadow2->pixels;
86                 for(y=0;y<nh;y++){
87                         pix = (int*)(&pixels[pitch * y]);
88                         pix2 = (int*)(&pixels2[pitch * y]);
89                         for(x=0;x<nw;x++){
90                                 int right = (x==nw-1) ? 0 : *(int*)((((char*)pix)+bps));
91                                 int left = (x==0) ? 0 : *(int*)((((char*)pix)-bps));
92                                 int up = (y==0) ? 0 : *(int*)((((char*)pix)-pitch));
93                                 int down = (y==nh-1) ? 0 : *(int*)((((char*)pix)+pitch));
94                                 int my = *pix2;
95                                 int new_alpha = (((((my & Amask) >> Ashift) << Aloss) +(((right & Amask) >> Ashift) << Aloss)+(((left & Amask) >> Ashift) << Aloss)+(((up & Amask) >> Ashift) << Aloss)+(((down & Amask) >> Ashift) << Aloss)) / 5) & 0xff;
96                                 new_alpha = (new_alpha * 18) >> 4;
97                                 if(new_alpha > 0xff){
98                                         new_alpha = 0xff;
99                                 }
100                                 *pix2 &= Mask;
101                                 *pix2 |= ((new_alpha >> Aloss) << Ashift) & Amask;
102                                 pix = (int*)(((char*)pix)+bps);
103                                 pix2 = (int*)(((char*)pix2)+bps);
104                         }
105                 }
106                 tmp = shadow2;
107                 shadow2 = shadow;
108                 shadow = tmp;
109         }
110         SDL_UnlockSurface(shadow);
111         SDL_UnlockSurface(shadow2);
112         shadowBlitSurface(surf,NULL,shadow,&rect);
113         SDL_FreeSurface(surf);
114         SDL_FreeSurface(shadow2);
115         return shadow;
116 }
117
118 /*右下*/
119 #define SHADOW_SLIDE 2
120 SDL_Surface* likeNovel(SDL_Surface* surf,int is_black,int is_fix_size){
121         /*スライド幅の確定*/
122         int slide = SHADOW_SLIDE;
123         if(is_fix_size){
124                 slide <<= 1;
125         }
126         /*黒の用意*/
127         SDL_Surface* black = SDL_CreateRGBSurface(      SDL_SRCALPHA | SDL_HWSURFACE | SDL_HWACCEL,
128                                                                                                 surf->w+slide,
129                                                                                                 surf->h+slide,
130                                                                                                 32,
131                                                                                                 #if SDL_BYTEORDER == SDL_BIG_ENDIAN
132                                                                                                     0xff000000,
133                                                                                                     0x00ff0000,
134                                                                                                     0x0000ff00,
135                                                                                                     0x000000ff
136                                                                                                 #else
137                                                                                                     0x000000ff,
138                                                                                                     0x0000ff00,
139                                                                                                     0x00ff0000,
140                                                                                                     0xff000000
141                                                                                                 #endif
142                                                                                                 );
143         SDL_Rect rect = {slide,slide};
144         SDL_SetAlpha(surf,0,0xff);//一回alpha合成を切る
145         SDL_BlitSurface(surf,NULL,black,&rect);
146         SDL_SetAlpha(surf,SDL_SRCALPHA,0xff);
147         if(is_black){//黒であれば、周りをしろで囲む
148                 setRGB(black,0xffffffff);
149         }else{
150                 setRGB(black,0);
151         }
152         setAlpha(black,0.6f);
153         shadowBlitSurface(surf,NULL,black,NULL);
154         SDL_FreeSurface(surf);
155         return black;
156 }
157
158 //散らすのではなく、囲ってしまう。
159 SDL_Surface* likeOld(SDL_Surface* surf,int is_black,int is_fix_size){
160         /*スライド幅の確定*/
161         int slide = SHADOW_SIZE;
162         if(is_fix_size){
163                 slide <<= 1;
164         }
165         int w = surf->w;
166         int h = surf->h;
167         SDL_Surface* shadow = SDL_CreateRGBSurface(             SDL_SRCALPHA | SDL_HWSURFACE | SDL_HWACCEL,
168                                                                                                 w+(slide<<1),
169                                                                                                 h+(slide<<1),
170                                                                                                 32,
171                                                                                                 #if SDL_BYTEORDER == SDL_BIG_ENDIAN
172                                                                                                     0xff000000,
173                                                                                                     0x00ff0000,
174                                                                                                     0x0000ff00,
175                                                                                                     0x000000ff
176                                                                                                 #else
177                                                                                                     0x000000ff,
178                                                                                                     0x0000ff00,
179                                                                                                     0x00ff0000,
180                                                                                                     0xff000000
181                                                                                                 #endif
182                                                                                         );
183         SDL_Surface* shadow2 = SDL_CreateRGBSurface(    SDL_SRCALPHA | SDL_HWSURFACE | SDL_HWACCEL,
184                                                                                                 w+(slide<<1),
185                                                                                                 h+(slide<<1),
186                                                                                                 32,
187                                                                                                 #if SDL_BYTEORDER == SDL_BIG_ENDIAN
188                                                                                                     0xff000000,
189                                                                                                     0x00ff0000,
190                                                                                                     0x0000ff00,
191                                                                                                     0x000000ff
192                                                                                                 #else
193                                                                                                     0x000000ff,
194                                                                                                     0x0000ff00,
195                                                                                                     0x00ff0000,
196                                                                                                     0xff000000
197                                                                                                 #endif
198                                                                                         );
199         SDL_Rect rect = {slide,slide};
200         SDL_SetAlpha(surf,0,0xff);
201         SDL_BlitSurface(surf,NULL,shadow,&rect);
202         SDL_SetAlpha(surf,SDL_SRCALPHA,0xff);
203         if(is_black){//黒であれば、周りをしろで囲む
204                 setRGB(shadow,0xffffffff);
205         }else{
206                 setRGB(shadow,0);
207         }
208         SDL_SetAlpha(shadow,0,0xff);
209         SDL_BlitSurface(shadow,NULL,shadow2,NULL);
210         SDL_SetAlpha(shadow,SDL_SRCALPHA,0xff);
211         int x,y,z;
212         int nw = shadow->w;
213         int nh = shadow->h;
214         int *pix;
215         int *pix2;
216         int pitch = shadow->pitch;
217         int bps = shadow->format->BytesPerPixel;
218         Uint32 Amask = shadow->format->Amask;
219         Uint32 Mask = (shadow->format->Rmask | shadow->format->Gmask | shadow->format->Bmask);
220         Uint32 Ashift = shadow->format->Ashift;
221         Uint32 Aloss = shadow->format->Aloss;
222         SDL_Surface* tmp;
223         SDL_LockSurface(shadow);
224         SDL_LockSurface(shadow2);
225         int zmax = 1;
226         if(is_fix_size){
227                 zmax = 2;
228         }
229         for(z=0;z<zmax;z++){
230                 char *pixels = (char*)shadow->pixels;
231                 char *pixels2 = (char*)shadow2->pixels;
232                 for(y=0;y<nh;y++){
233                         pix = (int*)(&pixels[pitch * y]);
234                         pix2 = (int*)(&pixels2[pitch * y]);
235                         for(x=0;x<nw;x++){
236                                 int right = (x==nw-1) ? 0 : *(int*)((((char*)pix)+bps));
237                                 int left = (x==0) ? 0 : *(int*)((((char*)pix)-bps));
238                                 int up = (y==0) ? 0 : *(int*)((((char*)pix)-pitch));
239                                 int down = (y==nh-1) ? 0 : *(int*)((((char*)pix)+pitch));
240                                 int my = *pix2;
241                                 //周りが空白でない
242                                 if(((right | left | up | down | my) & Amask) != 0){
243                                         *pix2 &= Mask;
244                                         *pix2 |= (((0xff/(z+1)) >> Aloss) << Ashift) & Amask;
245                                 }
246                                 pix = (int*)(((char*)pix)+bps);
247                                 pix2 = (int*)(((char*)pix2)+bps);
248                         }
249                 }
250                 tmp = shadow2;
251                 shadow2 = shadow;
252                 shadow = tmp;
253         }
254         SDL_UnlockSurface(shadow);
255         SDL_UnlockSurface(shadow2);
256         shadowBlitSurface(surf,NULL,shadow,&rect);
257         SDL_FreeSurface(surf);
258         SDL_FreeSurface(shadow2);
259         return shadow;
260 }
261
262
263 //定義
264 SDL_Surface* (*ShadowFunc[SHADOW_MAX])(SDL_Surface* surf,int is_black,int is_fix_size) = {
265         noShadow,
266         likeNicoNico,
267         likeNovel,
268         likeOld
269 };