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 "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_SNAKE*/  { 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 /******************** Module Information structure ******************/
 477 
 478 ModuleInfo _module_info =
 479 {
 480     MODULEINFO_V1_MAGICNUM,
 481     sizeof(ModuleInfo),
 482     SIMPLE_MODULE_VERSION,      // Module version
 483 
 484     ANY_CHDK_BRANCH, 0, OPT_ARCHITECTURE,         // Requirements of CHDK version
 485     ANY_PLATFORM_ALLOWED,       // Specify platform dependency
 486 
 487     -LANG_MENU_GAMES_SNAKE,     // Module name
 488     MTYPE_GAME,
 489 
 490     &_librun.base,
 491 
 492     ANY_VERSION,                // CONF version
 493     CAM_SCREEN_VERSION,         // CAM SCREEN version
 494     ANY_VERSION,                // CAM SENSOR version
 495     ANY_VERSION,                // CAM INFO version
 496 
 497     0,
 498 };
 499 
 500 /*************** END OF AUXILARY PART *******************/

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