OSDN Git Service

リファクタリング
[coroid/inqubus.git] / vhook / comment / surf_util.c
1 #include <SDL/SDL.h>
2 #include "surf_util.h"
3 #include "../mydef.h"
4
5 SDL_Surface* connectSurface(SDL_Surface* top,SDL_Surface* bottom){
6         SDL_Surface* ret = SDL_CreateRGBSurface( SDL_SRCALPHA,
7                                                                                         MAX(top->w,bottom->w),
8                                                                                         top->h+bottom->h,
9                                                                                         32,
10                                                                                         #if SDL_BYTEORDER == SDL_BIG_ENDIAN
11                                                                                             0xff000000,
12                                                                                             0x00ff0000,
13                                                                                             0x0000ff00,
14                                                                                             0x000000ff
15                                                                                         #else
16                                                                                             0x000000ff,
17                                                                                             0x0000ff00,
18                                                                                             0x00ff0000,
19                                                                                                 0xff000000
20                                                                                         #endif
21                                                                                         );
22         SDL_SetAlpha(top,SDL_SRCALPHA | SDL_RLEACCEL,0xff);
23         SDL_SetAlpha(bottom,SDL_SRCALPHA | SDL_RLEACCEL,0xff);
24
25         SDL_BlitSurface(top,NULL,ret,NULL);
26
27         SDL_Rect rect2 = {0,top->h};
28         SDL_BlitSurface(bottom,NULL,ret,&rect2);
29         SDL_FreeSurface(top);
30         SDL_FreeSurface(bottom);
31         return ret;
32 }
33
34 void setAlpha(SDL_Surface* surf,double alpha_t){
35         int x,y;
36         int h = surf->h;
37         int w = surf->w;
38         Uint32 mask,shift,bytesp,pitch,loss;
39         Uint8 alpha;
40         Uint8* pixels;
41         Uint32* pix;
42         SDL_PixelFormat* format = surf->format;
43         /*変数の設定*/
44         mask = format->Amask;
45         shift = format->Ashift;
46         loss = format->Aloss;
47         bytesp = format->BytesPerPixel;
48         pitch = surf->pitch;
49         pixels = surf->pixels;
50         SDL_LockSurface(surf);//サーフェイスをロック
51         for(y=0;y<h;y++){
52                 for(x=0;x<w;x++){
53                         pix = (Uint32*)(&pixels[y*pitch + x*bytesp]);
54                         alpha = (Uint8)((((*pix) & mask) >> shift) << loss);
55                         alpha *= alpha_t;
56                         (*pix) &= ~((0xff >> loss) << shift);
57                         (*pix) |= (alpha >> loss) << shift;
58                 }
59         }
60         SDL_UnlockSurface(surf);//アンロック
61 }
62
63 /**
64  * srcの不透明度を上書きしてしまう。
65  * srcの方が不透明なら、それを上書き。
66  */
67
68 void overrideAlpha(SDL_Surface *src, SDL_Rect *srcrect, SDL_Surface *dst, SDL_Rect *dstrect){
69         SDL_LockSurface(src);//サーフェイスをロック
70         SDL_LockSurface(dst);//サーフェイスをロック
71         //範囲の確定
72         int sw = src->w;
73         int sh = src->h;
74         int sx = 0;
75         int sy = 0;
76         if(srcrect != NULL){
77                 sx = srcrect->x;
78                 sy = srcrect->y;
79                 if(sx >= sw || sy > sh){
80                         return;
81                 }
82                 sw = MIN(sw-sx,srcrect->w);
83                 sh = MIN(sh-sy,srcrect->h);
84         }
85         int dw = dst->w;
86         int dh = dst->h;
87         int dx = 0;
88         int dy = 0;
89         if(dstrect != NULL){
90                 dx = dstrect->x;
91                 dy = dstrect->y;
92                 if(dx >= dw || dy > dh){
93                         return;
94                 }
95                 dw = MIN(dw-dx,dstrect->w);
96                 dh = MIN(dh-dy,dstrect->h);
97         }
98         //小さいほうにあわせる
99         if(dw > sw){
100                 dw = sw;
101         }else{
102                 sw = dw;
103         }
104         if(dh > sh){
105                 dh = sh;
106         }else{
107                 sh = dh;
108         }
109         //やっとこさ描画。。
110         int sbytesp = src->format->BytesPerPixel;
111         int dbytesp = dst->format->BytesPerPixel;
112         int spitch = src->pitch;
113         int dpitch = dst->pitch;
114         int sAmask = src->format->Amask;
115         int dAmask = dst->format->Amask;
116         int sAshift = src->format->Ashift;
117         int dAshift = dst->format->Ashift;
118         int sAloss = src->format->Aloss;
119         int dAloss = dst->format->Aloss;
120         Uint8* spix = (Uint8*)src->pixels;
121         Uint8* dpix = (Uint8*)dst->pixels;
122         Uint32* spt;
123         Uint32* dpt;
124         Uint32 salpha;
125         Uint32 dalpha;
126         int x,y;
127         for(y=0;y<sh;y++){
128                 for(x=0;x<sw;x++){
129                         spt = (Uint32*)(&spix[(sy+y)*spitch+(sx+x)*sbytesp]);
130                         dpt = (Uint32*)(&dpix[(dy+y)*dpitch+(dx+x)*dbytesp]);
131                         salpha = ((*spt & sAmask)>>sAshift)<<sAloss;
132                         dalpha = ((*dpt & dAmask)>>dAshift)<<dAloss;
133                         if(salpha > dalpha){
134                                 *dpt &= ~dAmask;
135                                 *dpt |= (salpha>>dAloss)<<dAshift;
136                         }
137                 }
138         }
139         SDL_UnlockSurface(dst);//アンロック
140         SDL_UnlockSurface(src);//アンロック
141 }
142
143 void inline shadowBlitSurface(SDL_Surface *src, SDL_Rect *srcrect, SDL_Surface *dst, SDL_Rect *dstrect){
144         SDL_BlitSurface(src,srcrect,dst,dstrect);
145         overrideAlpha(src,srcrect,dst,dstrect);
146 }
147
148 void setRGB(SDL_Surface* surf,Uint32 color){
149         int x,y;
150         int h = surf->h;
151         int w = surf->w;
152         int bytesp = surf->format->BytesPerPixel;
153         int pitch = surf->pitch;
154         Uint32 Amask = surf->format->Amask;
155         color &= surf->format->Rmask | surf->format->Gmask | surf->format->Bmask;
156         Uint8* pix = (Uint8*)surf->pixels;
157         Uint32* pt;
158         SDL_LockSurface(surf);//サーフェイスをロック
159         for(y=0;y<h;y++){
160                 for(x=0;x<w;x++){
161                         pt = (Uint32*)(&pix[y*pitch + x*bytesp]);
162                         *pt &= Amask;
163                         *pt |= color;
164                 }
165         }
166         SDL_UnlockSurface(surf);//サーフェイスをアンロック
167 }
168
169 void getRGBA(SDL_Surface* surf,int x,int y,char* r,char* g,char* b,char* a){
170         int pix_index = y * surf->pitch + x * surf->format->BytesPerPixel;
171         char* pix = (char*)surf->pixels;
172         SDL_GetRGBA(*(Uint32*)(&pix[pix_index]),surf->format,(Uint8*)r,(Uint8*)g,(Uint8*)b,(Uint8*)a);
173 }
174