root/modules/games/gui_snake.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. draw_element
  2. load_laby
  3. snake_generate_apple
  4. snake_start
  5. game_over
  6. gui_snake_kbd_process
  7. gui_snake_draw
  8. gui_snake_init
  9. basic_module_init

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

/* [<][>][^][v][top][bottom][index][help] */