This source file includes following definitions.
- draw_element
- load_laby
- snake_generate_apple
- snake_start
- game_over
- gui_snake_kbd_process
- gui_snake_draw
- gui_snake_init
- basic_module_init
1 #include "camera_info.h"
2 #include "keyboard.h"
3 #include "lang.h"
4 #include "conf.h"
5 #include "gui.h"
6 #include "gui_draw.h"
7 #include "gui_lang.h"
8 #include "gui_batt.h"
9 #include "gui_mbox.h"
10 #include "modes.h"
11
12 #include "module_def.h"
13
14 void gui_game_menu_kbd_process();
15 int gui_snake_kbd_process();
16 void gui_snake_draw();
17
18 gui_handler GUI_MODE_SNAKE =
19 { GUI_MODE_MODULE, gui_snake_draw, gui_snake_kbd_process, gui_game_menu_kbd_process, 0, GUI_MODE_FLAG_NODRAWRESTORE };
20
21
22 int snake_scale;
23 int snake_screen_size;
24 int screen_left;
25 int screen_top;
26
27 #define SNAKE_MAX_LENGTH 0xF0
28 #define SNAKE_ELEMENT_SIZE 8
29 #define RING_WIDTH 40
30 #define RING_HEIGHT 24
31 enum{
32 DIR_LEFT = 0,
33 DIR_DOWN,
34 DIR_UP,
35 DIR_RIGHT,
36 };
37 unsigned char ring[RING_WIDTH][RING_HEIGHT];
38 unsigned short snake_head;
39 unsigned short snake_tail;
40 unsigned char snake[SNAKE_MAX_LENGTH][2];
41 unsigned int points;
42 unsigned char level;
43 unsigned char direction;
44 char str_buf[40];
45
46 const unsigned char labyrinth[4][RING_HEIGHT][RING_WIDTH] = {
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 " # ",
130 " # ",
131 " # ",
132 " ########################## ",
133 " # ",
134 " # ",
135 " ########## # ",
136 " # #### ",
137 " # ",
138 " # ",
139 " # ",
140 " # ",
141 " # ",
142 " ################# # ",
143 " # ",
144 " # # ",
145 " ######## # ",
146 " # ",
147 " ########################## ",
148 " # ",
149 " # ",
150 " # ",
151 " ",
152 },
153 };
154
155 const char head[8][8] = {
156 " GG ",
157 " GBBG",
158 " G BG",
159 " GGGGGGG",
160 "RGGGGGGG",
161 " GGGGGGG",
162 " ",
163 " ",
164 };
165
166 const char tail[8][8] = {
167 " ",
168 " ",
169 " ",
170 "G GGG GG",
171 "GGGGGGGG",
172 "GGG GGG ",
173 " ",
174 " ",
175 };
176
177 const char tail2[8][8] = {
178 " ",
179 " ",
180 " ",
181 " GG ",
182 "GGGG ",
183 "GGGGG ",
184 " GGG ",
185 " GG ",
186 };
187
188 const char apple[8][8] = {
189 " ",
190 " GGGB ",
191 "GGG B ",
192 " G RRR ",
193 " RRRRR ",
194 " RRRRR ",
195 " RRRRR ",
196 " RRR ",
197 };
198
199 const char wall[8][8] = {
200 "OOOOO OO",
201 "OOOOO OO",
202 " ",
203 "OO OOOOO",
204 "OO OOOOO",
205 " ",
206 "OOOOO OO",
207 "OOOOO OO",
208 };
209
210 static void draw_element(int x,int y,const char element[8][8],char angle){
211 x = screen_left + x * snake_screen_size;
212 y = screen_top + y * snake_screen_size;
213 int xx,yy,px,py;
214 for(xx=0;xx<SNAKE_ELEMENT_SIZE;xx++)
215 for(yy=0;yy<SNAKE_ELEMENT_SIZE;yy++){
216 char c = COLOR_RED;
217 char col = 0;
218
219 if(angle == 0) col = element[yy][xx];
220 if(angle == 1) col = element[xx][7-yy];
221 if(angle == 2) col = element[xx][yy];
222 if(angle == 3) col = element[yy][7-xx];
223 if(angle == 4) col = element[7-xx][yy];
224 switch(col){
225 case 'R': c = COLOR_RED; break;
226 case 'G': c = COLOR_GREEN; break;
227 case 'B': c = COLOR_BLACK; break;
228 case 'b': c = COLOR_BLUE; break;
229 case 'Y': c = COLOR_YELLOW; break;
230 case 'O': c = 0x28; break;
231 default: c = COLOR_WHITE; break;
232 };
233 for (px=xx*snake_scale; px<(xx+1)*snake_scale; px+=1)
234 for (py=yy*snake_scale; py<(yy+1)*snake_scale; py+=1)
235 draw_pixel( x+px, y+py, c );
236 }
237 }
238
239
240
241 static void load_laby(int num){
242 int x,y;
243 for(x=0;x<RING_WIDTH;x++)
244 for(y=0;y<RING_HEIGHT;y++){
245 ring[x][y] = labyrinth[num][y][x];
246 if(ring[x][y] != ' '){
247 draw_element(x,y,wall,0);
248 }else{
249 draw_rectangle(screen_left + x * snake_screen_size,
250 screen_top + y * snake_screen_size,
251 screen_left + x * snake_screen_size+snake_screen_size-1,
252 screen_top + y * snake_screen_size+snake_screen_size-1, MAKE_COLOR(COLOR_WHITE,COLOR_WHITE), RECT_BORDER0|DRAW_FILLED);
253 }
254 }
255 }
256
257 static void snake_generate_apple()
258 {
259 int x,y,i;
260 while(1)
261 {
262 randomagain:
263 x = rand() % RING_WIDTH;
264 y = rand() % RING_HEIGHT;
265 if(ring[x][y] != ' ') continue;
266 i = snake_tail;
267 while(1){
268 if(snake[i][0] == x && snake[i][1] == y) goto randomagain;
269 if(i == snake_head) break;
270 i = (i+1)%SNAKE_MAX_LENGTH;
271 }
272 draw_element(x,y,apple,0);
273 ring[x][y] = 1;
274 break;
275 }
276 }
277
278 static void snake_start()
279 {
280 int i;
281 load_laby(rand()%4);
282 snake_head = 2;
283 snake_tail = 0;
284 level = 5;
285 points = 0;
286 for(i=snake_tail;i<=snake_head;i++){
287 snake[i][0] = 2+i;
288 snake[i][1] = 2;
289 draw_rectangle(screen_left + snake[i][0] * snake_screen_size,
290 screen_top + snake[i][1] * snake_screen_size,
291 screen_left + snake[i][0] * snake_screen_size+snake_screen_size-1,
292 screen_top + snake[i][1] * snake_screen_size+snake_screen_size-1, MAKE_COLOR(COLOR_WHITE,COLOR_RED), RECT_BORDER1|DRAW_FILLED);
293 }
294 direction = DIR_RIGHT;
295 for(i=0;i<10;i++)
296 snake_generate_apple();
297 }
298
299 static void game_over()
300 {
301 draw_rectangle(camera_screen.disp_left,0,camera_screen.disp_right,camera_screen.height-1, MAKE_COLOR(COLOR_GREY,COLOR_GREY), RECT_BORDER0|DRAW_FILLED);
302 sprintf(str_buf,lang_str(LANG_SNAKE_POINTS),points);
303 draw_string(camera_screen.disp_width / 2 - strlen(str_buf)*FONT_WIDTH/2,camera_screen.height/2-FONT_HEIGHT/2,str_buf, MAKE_COLOR(COLOR_GREY, COLOR_BLUE));
304 msleep(3000);
305 snake_start();
306 }
307
308 int gui_snake_kbd_process()
309 {
310 switch (kbd_get_autoclicked_key()) {
311 case KEY_UP:
312 if(direction != DIR_DOWN) direction = DIR_UP;
313 break;
314 case KEY_DOWN:
315 if(direction != DIR_UP) direction = DIR_DOWN;
316 break;
317 case KEY_LEFT:
318 if(direction != DIR_RIGHT) direction = DIR_LEFT;
319 break;
320 case KEY_RIGHT:
321 if(direction != DIR_LEFT) direction = DIR_RIGHT;
322 break;
323 case KEY_SET:
324
325
326 break;
327 case KEY_ERASE:
328 case KEY_DISPLAY:
329 break;
330 }
331 return 0;
332 }
333
334 void gui_snake_draw()
335 {
336 unsigned short new_head;
337 unsigned short new_tail;
338 unsigned short new_cord;
339 char game_over_flag = 0, draw_head, clear_tail, draw_points = 1;
340 unsigned char prevdir = direction;
341 unsigned int i;
342 new_head = (snake_head + 1) % SNAKE_MAX_LENGTH;
343 new_tail = (snake_tail + 1) % SNAKE_MAX_LENGTH;
344 draw_head = 1;
345 clear_tail = 1;
346 if (direction == DIR_RIGHT)
347 {
348 new_cord = (snake[snake_head][0] + 1) % RING_WIDTH;
349 snake[new_head][0] = new_cord;
350 snake[new_head][1] = snake[snake_head][1];
351 }
352 else if (direction == DIR_LEFT)
353 {
354 new_cord = snake[snake_head][0] - 1;
355 if (new_cord == 0xFFFF)
356 new_cord = RING_WIDTH - 1;
357 snake[new_head][0] = new_cord;
358 snake[new_head][1] = snake[snake_head][1];
359 }
360 else if (direction == DIR_UP)
361 {
362 new_cord = snake[snake_head][1] - 1;
363 if (new_cord == 0xFFFF)
364 new_cord = RING_HEIGHT - 1;
365 snake[new_head][0] = snake[snake_head][0];
366 snake[new_head][1] = new_cord;
367 }
368 else if (direction == DIR_DOWN)
369 {
370 new_cord = (snake[snake_head][1] + 1) % RING_HEIGHT;
371 snake[new_head][0] = snake[snake_head][0];
372 snake[new_head][1] = new_cord;
373 }
374
375 i = snake_tail;
376 while (1)
377 {
378 if (snake[i][0] == snake[new_head][0] && snake[i][1] == snake[new_head][1])
379 {
380 game_over_flag = 1;
381 break;
382 }
383 if (i == snake_head)
384 break;
385 i = (i + 1) % SNAKE_MAX_LENGTH;
386 }
387
388 if (ring[snake[new_head][0]][snake[new_head][1]] == 1)
389 {
390 ring[snake[new_head][0]][snake[new_head][1]] = ' ';
391 snake_generate_apple();
392 points += level;
393 draw_points = 1;
394 if ((new_head + 1) % SNAKE_MAX_LENGTH != snake_tail)
395 {
396 new_tail = snake_tail;
397 clear_tail = 0;
398 }
399 }
400 else if (ring[snake[new_head][0]][snake[new_head][1]] != ' ')
401 {
402 game_over_flag = 1;
403 }
404 if (draw_head)
405 {
406 draw_element(snake[new_head][0], snake[new_head][1], head, direction);
407
408 new_cord = snake_head - 1;
409 if (new_cord == 0xFFFF)
410 new_cord = SNAKE_MAX_LENGTH - 1;
411 if (snake[new_cord][0] > snake[new_head][0] && snake[new_cord][1] > snake[new_head][1] && direction == DIR_UP)
412 draw_element(snake[snake_head][0], snake[snake_head][1], tail2, 2);
413 else if (snake[new_cord][0] > snake[new_head][0] && snake[new_cord][1] > snake[new_head][1] && direction == DIR_LEFT)
414 draw_element(snake[snake_head][0], snake[snake_head][1], tail2, 0);
415 else if (snake[new_cord][0] < snake[new_head][0] && snake[new_cord][1] > snake[new_head][1] && direction == DIR_UP)
416 draw_element(snake[snake_head][0], snake[snake_head][1], tail2, 4);
417 else if (snake[new_cord][0] < snake[new_head][0] && snake[new_cord][1] > snake[new_head][1] && direction == DIR_RIGHT)
418 draw_element(snake[snake_head][0], snake[snake_head][1], tail2, 3);
419 else if (snake[new_cord][0] < snake[new_head][0] && snake[new_cord][1] < snake[new_head][1] && direction == DIR_RIGHT)
420 draw_element(snake[snake_head][0], snake[snake_head][1], tail2, 2);
421 else if (snake[new_cord][0] < snake[new_head][0] && snake[new_cord][1] < snake[new_head][1] && direction == DIR_DOWN)
422 draw_element(snake[snake_head][0], snake[snake_head][1], tail2, 0);
423 else if (snake[new_cord][0] > snake[new_head][0] && snake[new_cord][1] < snake[new_head][1] && direction == DIR_LEFT)
424 draw_element(snake[snake_head][0], snake[snake_head][1], tail2, 4);
425 else if (snake[new_cord][0] > snake[new_head][0] && snake[new_cord][1] < snake[new_head][1] && direction == DIR_DOWN)
426 draw_element(snake[snake_head][0], snake[snake_head][1], tail2, 3);
427 else if (prevdir == direction && (direction == DIR_RIGHT || direction == DIR_LEFT))
428 draw_element(snake[snake_head][0], snake[snake_head][1], tail, 0);
429 else if (prevdir == direction && (direction == DIR_UP || direction == DIR_DOWN))
430 draw_element(snake[snake_head][0], snake[snake_head][1], tail, 1);
431 }
432 prevdir = direction;
433 if (clear_tail)
434 {
435 draw_rectangle(screen_left + snake[snake_tail][0] * snake_screen_size,
436 screen_top + snake[snake_tail][1] * snake_screen_size,
437 screen_left + snake[snake_tail][0] * snake_screen_size + snake_screen_size - 1,
438 screen_top + snake[snake_tail][1] * snake_screen_size + snake_screen_size - 1, MAKE_COLOR(COLOR_WHITE, COLOR_WHITE), RECT_BORDER0 | DRAW_FILLED);
439 }
440 snake_head = new_head;
441 snake_tail = new_tail;
442 msleep(100);
443 if (game_over_flag)
444 {
445 game_over();
446 game_over_flag = 0;
447 }
448 if (draw_points)
449 {
450 draw_points = 0;
451 sprintf(str_buf, lang_str(LANG_SNAKE_POINTS), points);
452 draw_string(camera_screen.disp_width/2 - strlen(str_buf)*FONT_WIDTH/2, camera_screen.height-FONT_HEIGHT-4, str_buf, MAKE_COLOR(COLOR_GREY, COLOR_BLUE));
453 }
454 }
455
456 int gui_snake_init()
457 {
458 snake_scale = camera_screen.height / 240;
459 if (snake_scale < 1) snake_scale = 1;
460 snake_screen_size = SNAKE_ELEMENT_SIZE * snake_scale;
461 screen_left = camera_screen.disp_left + (camera_screen.disp_width - RING_WIDTH * snake_screen_size)/2;
462 screen_top = (camera_screen.height - FONT_HEIGHT - 4 - RING_HEIGHT * snake_screen_size)/2;
463
464 draw_rectangle(camera_screen.disp_left,0,camera_screen.disp_right,camera_screen.height-1, MAKE_COLOR(COLOR_GREY,COLOR_GREY), RECT_BORDER0|DRAW_FILLED);
465 snake_start();
466 gui_set_mode(&GUI_MODE_SNAKE);
467 return 1;
468 }
469
470 int basic_module_init() {
471 return gui_snake_init();
472 }
473
474 #include "simple_game.c"
475
476
477
478 ModuleInfo _module_info =
479 {
480 MODULEINFO_V1_MAGICNUM,
481 sizeof(ModuleInfo),
482 SIMPLE_MODULE_VERSION,
483
484 ANY_CHDK_BRANCH, 0, OPT_ARCHITECTURE,
485 ANY_PLATFORM_ALLOWED,
486
487 -LANG_MENU_GAMES_SNAKE,
488 MTYPE_GAME,
489
490 &_librun.base,
491
492 ANY_VERSION,
493 CAM_SCREEN_VERSION,
494 ANY_VERSION,
495 ANY_VERSION,
496
497 0,
498 };
499
500