1 /*
2 * Copyright (C) 2004 Tom Bradley
3 * tojabr@shiftygames.com
4 *
5 * initCursor function by Anonymous from man SDL_CreateCursor
6 *
7 * file: pointer.c
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2, or (at your option)
12 * any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software Foundation,
21 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 *
23 */
24
25 #include <stdlib.h>
26
27 #include "SDL_image.h"
28 #include "SDL.h"
29
30 #include "pointer.h"
31
32 static SDL_Cursor * handCursor = 0;
33 static SDL_Cursor * arrowCursor = 0;
34
35 static const char * hand[] = {
36 "32 32 3 1",
37 "x c #000000",
38 ". c #ffffff",
39 " c None",
40 " xx ",
41 " x..x ",
42 " x..x ",
43 " x..x ",
44 " x..xxx x ",
45 " x..x..x.xx ",
46 " xx x..x..x.x.x ",
47 "x..xx.........x ",
48 "x...x.........x ",
49 " x.....x.x.x..x ",
50 " x....x.x.x..x ",
51 " x....x.x.x.x ",
52 " x.........x ",
53 " x.......x ",
54 " x....x.x ",
55 " xxxx x ",
56 " ",
57 " ",
58 " ",
59 " ",
60 " ",
61 " ",
62 " ",
63 " ",
64 " ",
65 " ",
66 " ",
67 " ",
68 " ",
69 " ",
70 " ",
71 " ",
72 "0,0"
73 };
74
75 static const char * arrow[] = {
76 "32 32 3 1",
77 "x c #000000",
78 ". c #ffffff",
79 " c None",
80 ". ",
81 ".. ",
82 ".x. ",
83 ".xx. ",
84 ".xxx. ",
85 ".xxxx. ",
86 ".xxxxx. ",
87 ".xxxxxx. ",
88 ".xxxxxxx. ",
89 ".xxxxxxxx. ",
90 ".xxxxx..... ",
91 ".xx.xx. ",
92 ".x. .xx. ",
93 ".. .xx. ",
94 ". .xx. ",
95 " .xx. ",
96 " .x.. ",
97 " ... ",
98 " ",
99 " ",
100 " ",
101 " ",
102 " ",
103 " ",
104 " ",
105 " ",
106 " ",
107 " ",
108 " ",
109 " ",
110 " ",
111 " ",
112 "0,0"
113 };
114
115 /*****************************************************
116 ****************************************************/
initCursor(const char * image[])117 SDL_Cursor * initCursor(const char * image[])
118 {
119 int i, row, col, hot_x, hot_y;
120 Uint8 data[4 * 32];
121 Uint8 mask[4 * 32];
122
123 i = -1;
124 for (row = 0;row < 32; ++row) {
125 for (col = 0; col < 32; ++col) {
126 if (col % 8) {
127 data[i] <<= 1;
128 mask[i] <<= 1;
129 } else {
130 ++i;
131 data[i] = mask[i] = 0;
132 }
133 switch (image[4 + row][col]) {
134 case 'x':
135 data[i] |= 0x01;
136 mask[i] |= 0x01;
137 break;
138 case '.':
139 mask[i] |= 0x01;
140 break;
141 case ' ':
142 break;
143 }
144 }
145 }
146 sscanf(image[4 + row], "%d,%d", &hot_x, &hot_y);
147 return SDL_CreateCursor(data, mask, 32, 32, hot_x, hot_y);
148 }
149
150
151 /*****************************************************
152 ****************************************************/
getHandCursor()153 SDL_Cursor * getHandCursor()
154 {
155 if(!handCursor)
156 handCursor = initCursor(hand);
157 return handCursor;
158 }
159
160 /*****************************************************
161 ****************************************************/
getArrowCursor()162 SDL_Cursor * getArrowCursor()
163 {
164 if(!arrowCursor)
165 arrowCursor = initCursor(arrow);
166 return arrowCursor;
167 }
168
169
170 /*****************************************************
171 from http://sdldoc.csn.ul.ie/guidevideo.php
172 ****************************************************/
getpixel(SDL_Surface * surface,int x,int y)173 static Uint32 getpixel(SDL_Surface *surface, int x, int y)
174 {
175 int bpp = surface->format->BytesPerPixel;
176 /* Here p is the address to the pixel we want to retrieve */
177 Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp;
178
179 switch(bpp) {
180 case 1:
181 return *p;
182
183 case 2:
184 return *(Uint16 *)p;
185
186 case 3:
187 if(SDL_BYTEORDER == SDL_BIG_ENDIAN)
188 return p[0] << 16 | p[1] << 8 | p[2];
189 else
190 return p[0] | p[1] << 8 | p[2] << 16;
191
192 case 4:
193 return *(Uint32 *)p;
194
195 default:
196 return 0; /* shouldn't happen, but avoids warnings */
197 }
198 }
199
200 /*****************************************************
201 ****************************************************/
putpixel(SDL_Surface * surface,int x,int y,Uint32 pixel)202 static void putpixel(SDL_Surface * surface, int x, int y, Uint32 pixel)
203 {
204 int bpp = surface->format->BytesPerPixel;
205 /* Here p is the address to the pixel we want to set */
206 Uint8 * p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp;
207
208 switch(bpp) {
209 case 1:
210 *p = pixel;
211 break;
212
213 case 2:
214 *(Uint16 *)p = pixel;
215 break;
216
217 case 3:
218 if(SDL_BYTEORDER == SDL_BIG_ENDIAN) {
219 p[0] = (pixel >> 16) & 0xff;
220 p[1] = (pixel >> 8) & 0xff;
221 p[2] = pixel & 0xff;
222 } else {
223 p[0] = pixel & 0xff;
224 p[1] = (pixel >> 8) & 0xff;
225 p[2] = (pixel >> 16) & 0xff;
226 }
227 break;
228
229 case 4:
230 *(Uint32 *)p = pixel;
231 break;
232 }
233 }
234
235 /*****************************************************
236 ****************************************************/
surfaceToCursor(SDL_Surface * image,int hx,int hy)237 SDL_Cursor * surfaceToCursor(SDL_Surface *image, int hx, int hy)
238 {
239 int w, x, y;
240 Uint8 *data, *mask, *d, *m, r, g, b;
241 Uint32 color;
242
243 w = (image->w + 7) / 8;
244 data = (Uint8 *)calloc(w * image->h * 2, 1);
245 if (data == NULL)
246 return NULL;
247
248 mask = data + w * image->h;
249 if (SDL_MUSTLOCK(image))
250 SDL_LockSurface(image);
251 for (y = 0; y < image->h; y++) {
252 d = data + y * w;
253 m = mask + y * w;
254 for (x = 0; x < image->w; x++) {
255 color = getpixel(image, x, y);
256 if ((image->flags & SDL_SRCCOLORKEY) == 0 || color != image->format->colorkey) {
257 SDL_GetRGB(color, image->format, &r, &g, &b);
258 color = (r + g + b) / 3;
259 m[x / 8] |= 128 >> (x & 7);
260 if (color < 128)
261 d[x / 8] |= 128 >> (x & 7);
262 }
263 }
264 }
265 if (SDL_MUSTLOCK(image))
266 SDL_UnlockSurface(image);
267
268 return SDL_CreateCursor(data, mask, w, image->h, hx, hy);
269 }
270