1 /*
2 * IceBreaker
3 * Copyright (c) 2000-2002 Matthew Miller <mattdm@mattdm.org>
4 * except the init_system_cursor function, which was lovingly stolen from
5 * the SDL documentation
6 *
7 * <http://www.mattdm.org/icebreaker/>
8 *
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the Free
11 * Software Foundation; either version 2 of the License, or (at your option)
12 * any later version.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
17 * for more details.
18 *
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, write to the Free Software Foundation, Inc., 59
21 * Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 *
23 */
24 
25 
26 
27 #include <SDL.h>
28 #include "cursor.h"
29 #include "icebreaker.h"
30 
31 static SDL_Cursor* createcursor(const char *image[]);
32 
33 static SDL_Cursor* cursorarrow;
34 static SDL_Cursor* cursorhorizontal;
35 static SDL_Cursor* cursorvertical;
36 static SDL_Cursor* cursorclick;
37 
38 
39 /* XPM */
40 static const char *cursorarrowxpm[] = {
41 /* width height num_colors chars_per_pixel */
42 "    32    32        3            1",
43 /* colors */
44 "X c #000000",
45 ". c #ffffff",
46 "  c None",
47 /* pixels */
48 "X                               ",
49 "XX                              ",
50 "X.X                             ",
51 "X..X                            ",
52 "X...X                           ",
53 "X....X                          ",
54 "X.....X                         ",
55 "X......X                        ",
56 "X.......X                       ",
57 "X........X                      ",
58 "X.....XXXXX                     ",
59 "X..X..X                         ",
60 "X.X X..X                        ",
61 "XX  X..X                        ",
62 "X    X..X                       ",
63 "     X..X                       ",
64 "      X..X                      ",
65 "      X..X                      ",
66 "       XX                       ",
67 "                                ",
68 "                                ",
69 "                                ",
70 "                                ",
71 "                                ",
72 "                                ",
73 "                                ",
74 "                                ",
75 "                                ",
76 "                                ",
77 "                                ",
78 "                                ",
79 "                                ",
80 "0,0"
81 };
82 
83 
84 /* XPM */
85 static const char *cursorhorizontalxpm[] = {
86 /* width height num_colors chars_per_pixel */
87 "    32    32        3            1",
88 /* colors */
89 "X c #000000",
90 ". c #ffffff",
91 "  c None",
92 /* pixels */
93 "        X X                     ",
94 "       XX XX                    ",
95 "      X.X X.X                   ",
96 "     X..X X..X                  ",
97 "    X...X X...X                 ",
98 "   X....X X....X                ",
99 "  X.....XXX.....X               ",
100 " X...............X              ",
101 "X.................X             ",
102 " X...............X              ",
103 "  X.....XXX.....X               ",
104 "   X....X X....X                ",
105 "    X...X X...X                 ",
106 "     X..X X..X                  ",
107 "      X.X X.X                   ",
108 "       XX XX                    ",
109 "        X X                     ",
110 "                                ",
111 "                                ",
112 "                                ",
113 "                                ",
114 "                                ",
115 "                                ",
116 "                                ",
117 "                                ",
118 "                                ",
119 "                                ",
120 "                                ",
121 "                                ",
122 "                                ",
123 "                                ",
124 "                                ",
125 "9,8"
126 };
127 
128 /* XPM */
129 static const char *cursorverticalxpm[] = {
130 /* width height num_colors chars_per_pixel */
131 "    32    32        3            1",
132 /* colors */
133 "X c #000000",
134 ". c #ffffff",
135 "  c None",
136 /* pixels */
137 "        X                       ",
138 "       X.X                      ",
139 "      X...X                     ",
140 "     X.....X                    ",
141 "    X.......X                   ",
142 "   X.........X                  ",
143 "  X...........X                 ",
144 " X.............X                ",
145 "XXXXXXX...XXXXXXX               ",
146 "      X...X                     ",
147 "XXXXXXX...XXXXXXX               ",
148 " X.............X                ",
149 "  X...........X                 ",
150 "   X.........X                  ",
151 "    X.......X                   ",
152 "     X.....X                    ",
153 "      X...X                     ",
154 "       X.X                      ",
155 "        X                       ",
156 "                                ",
157 "                                ",
158 "                                ",
159 "                                ",
160 "                                ",
161 "                                ",
162 "                                ",
163 "                                ",
164 "                                ",
165 "                                ",
166 "                                ",
167 "                                ",
168 "                                ",
169 "8,9"
170 };
171 
172 /* XPM */
173 static const char *cursorclickxpm[] = {
174 /* width height num_colors chars_per_pixel */
175 "    32    32        3            1",
176 /* colors */
177 "X c #000000",
178 ". c #ffffff",
179 "  c None",
180 /* pixels */
181 " XXXX  XXX   XXX  XXXX  XXX  XX ",
182 "X....X X.X   X.X X....X X.X X.X ",
183 "X.XXX  X.X   X.X X.XXX  X.XX.X  ",
184 "X.X    X.X   X.X X.X    X...X   ",
185 "X.X    X.X   X.X X.X    X.XX.X  ",
186 "X.XXX  X.XXX X.X X.XXX  X.X X.X ",
187 "X....X X...X X.X X....X X.X X.X ",
188 " XXXX  XXXXX XXX  XXXX  XXX XXX ",
189 "                                ",
190 "                                ",
191 "        XXXXXXX  XXXXX          ",
192 "        X.....X X.....X         ",
193 "        XXX.XXX X.XXX.X         ",
194 "          X.X   X.X X.X         ",
195 "          X.X   X.X X.X         ",
196 "          X.X   X.XXX.X         ",
197 "          X.X   X.....X         ",
198 "          XXX    XXXXX          ",
199 "                                ",
200 "                                ",
201 " XXXX  XXXXXX  X    XXXX  XXXXXX",
202 "X....X X....X X.X   X...X X....X",
203 "X.XXX  XX.XXX X..X  X.XX.X X.XXX",
204 "X....X  X.X  X.XX.X X...X  X.X  ",
205 " XXX.X  X.X X.....X X.X.X  X.X  ",
206 " XXX.X  X.X X.XXX.X X.XX.X X.X  ",
207 "X....X  X.X X.X X.X X.XX.X X.X  ",
208 " XXXX   XXX XXX XXX XXX XX XXX  ",
209 "                                ",
210 "                                ",
211 "                                ",
212 "                                ",
213 "15,15"
214 };
215 
216 
createcursor(const char * image[])217 static SDL_Cursor* createcursor(const char *image[])
218 {
219 	int i, row, col;
220 	Uint8 data[4*32];
221 	Uint8 mask[4*32];
222 	int hot_x, hot_y;
223 
224 	i = -1;
225 	for ( row=0; row<32; ++row )
226 	{
227 		for ( col=0; col<32; ++col )
228 		{
229 			if ( col % 8 )
230 			{
231 		        	data[i] <<= 1;
232 				mask[i] <<= 1;
233 			}
234 			else
235 			{
236 				++i;
237 				data[i] = mask[i] = 0;
238 			}
239 			switch (image[4+row][col])
240 			{
241 				case '.':
242 					data[i] |= 0x01;
243 					mask[i] |= 0x01;
244 				break;
245 				case 'X':
246 					mask[i] |= 0x01;
247 				break;
248 				case ' ':
249 				break;
250 			}
251 		}
252 	}
253 	sscanf(image[4+row], "%d,%d", &hot_x, &hot_y);
254 	return SDL_CreateCursor(data, mask, 32, 32, hot_x, hot_y);
255 }
256 
setcursor(CursorType c)257 void setcursor(CursorType c)
258 {
259 	static CursorType current=CURSORDEFAULT;
260 	if (c != current)
261 	{
262 		switch (c)
263 		{
264 			case CURSORDEFAULT: //falls through
265 			case CURSORARROW:
266 				SDL_SetCursor(cursorarrow);
267 			break;
268 			case CURSORHORIZONTAL:
269 				SDL_SetCursor(cursorhorizontal);
270 			break;
271 			case CURSORVERTICAL:
272 				SDL_SetCursor(cursorvertical);
273 			break;
274 			case CURSORCLICK:
275 				SDL_SetCursor(cursorclick);
276 			break;
277 		}
278 		current=c;
279 	}
280 }
281 
initcursors(void)282 void initcursors(void)
283 {
284 	// fix -- add error checking
285 	cursorarrow=createcursor(cursorarrowxpm);
286 	cursorhorizontal=createcursor(cursorhorizontalxpm);
287 	cursorvertical=createcursor(cursorverticalxpm);
288 	cursorclick=createcursor(cursorclickxpm);
289 }
290 
291 
quitcursors(void)292 void quitcursors(void)
293 {
294 	SDL_FreeCursor(cursorarrow);
295 	SDL_FreeCursor(cursorhorizontal);
296 	SDL_FreeCursor(cursorvertical);
297 	SDL_FreeCursor(cursorclick);
298 }
299