1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2008-2009 Rene Peinthor
11 * Contribution from Johannes Schwarz (new menu system, use of highscore lib)
13 * All files in this archive are subject to the GNU General Public License.
14 * See the file COPYING in the source tree root for full license agreement.
16 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
17 * KIND, either express or implied.
19 ****************************************************************************/
21 #include "lib/highscore.h"
22 #include "lib/playback_control.h"
23 #include "lib/display_text.h"
27 #if (CONFIG_KEYPAD == SANSA_E200_PAD)
28 #define CLIX_BUTTON_QUIT BUTTON_POWER
29 #define CLIX_BUTTON_UP BUTTON_UP
30 #define CLIX_BUTTON_DOWN BUTTON_DOWN
31 #define CLIX_BUTTON_SCROLL_FWD BUTTON_SCROLL_FWD
32 #define CLIX_BUTTON_SCROLL_BACK BUTTON_SCROLL_BACK
33 #define CLIX_BUTTON_LEFT BUTTON_LEFT
34 #define CLIX_BUTTON_RIGHT BUTTON_RIGHT
35 #define CLIX_BUTTON_CLICK BUTTON_SELECT
37 #elif (CONFIG_KEYPAD == SANSA_CLIP_PAD)
38 #define CLIX_BUTTON_QUIT BUTTON_POWER
39 #define CLIX_BUTTON_UP BUTTON_UP
40 #define CLIX_BUTTON_DOWN BUTTON_DOWN
41 #define CLIX_BUTTON_LEFT BUTTON_LEFT
42 #define CLIX_BUTTON_RIGHT BUTTON_RIGHT
43 #define CLIX_BUTTON_CLICK BUTTON_SELECT
45 #elif (CONFIG_KEYPAD == SANSA_FUZE_PAD)
46 #define CLIX_BUTTON_QUIT BUTTON_HOME
47 #define CLIX_BUTTON_UP BUTTON_UP
48 #define CLIX_BUTTON_DOWN BUTTON_DOWN
49 #define CLIX_BUTTON_SCROLL_FWD BUTTON_SCROLL_FWD
50 #define CLIX_BUTTON_SCROLL_BACK BUTTON_SCROLL_BACK
51 #define CLIX_BUTTON_LEFT BUTTON_LEFT
52 #define CLIX_BUTTON_RIGHT BUTTON_RIGHT
53 #define CLIX_BUTTON_CLICK BUTTON_SELECT
55 #elif (CONFIG_KEYPAD == SANSA_C200_PAD)
56 #define CLIX_BUTTON_QUIT BUTTON_POWER
57 #define CLIX_BUTTON_UP BUTTON_UP
58 #define CLIX_BUTTON_DOWN BUTTON_DOWN
59 #define CLIX_BUTTON_SCROLL_FWD BUTTON_VOL_UP
60 #define CLIX_BUTTON_SCROLL_BACK BUTTON_VOL_DOWN
61 #define CLIX_BUTTON_LEFT BUTTON_LEFT
62 #define CLIX_BUTTON_RIGHT BUTTON_RIGHT
63 #define CLIX_BUTTON_CLICK BUTTON_SELECT
65 #elif (CONFIG_KEYPAD == IPOD_4G_PAD) || \
66 (CONFIG_KEYPAD == IPOD_3G_PAD) || \
67 (CONFIG_KEYPAD == IPOD_1G2G_PAD)
68 #define CLIX_BUTTON_QUIT (BUTTON_SELECT | BUTTON_MENU)
69 #define CLIX_BUTTON_UP BUTTON_MENU
70 #define CLIX_BUTTON_DOWN BUTTON_PLAY
71 #define CLIX_BUTTON_SCROLL_FWD BUTTON_SCROLL_FWD
72 #define CLIX_BUTTON_SCROLL_BACK BUTTON_SCROLL_BACK
73 #define CLIX_BUTTON_CLICK BUTTON_SELECT
74 #define CLIX_BUTTON_RIGHT BUTTON_RIGHT
75 #define CLIX_BUTTON_LEFT BUTTON_LEFT
77 #elif (CONFIG_KEYPAD == GIGABEAT_PAD)
78 #define CLIX_BUTTON_QUIT BUTTON_POWER
79 #define CLIX_BUTTON_LEFT BUTTON_LEFT
80 #define CLIX_BUTTON_RIGHT BUTTON_RIGHT
81 #define CLIX_BUTTON_CLICK BUTTON_SELECT
82 #define CLIX_BUTTON_UP BUTTON_UP
83 #define CLIX_BUTTON_DOWN BUTTON_DOWN
85 #elif (CONFIG_KEYPAD == GIGABEAT_S_PAD)
86 #define CLIX_BUTTON_QUIT BUTTON_BACK
87 #define CLIX_BUTTON_LEFT BUTTON_LEFT
88 #define CLIX_BUTTON_RIGHT BUTTON_RIGHT
89 #define CLIX_BUTTON_CLICK BUTTON_SELECT
90 #define CLIX_BUTTON_UP BUTTON_UP
91 #define CLIX_BUTTON_DOWN BUTTON_DOWN
93 #elif (CONFIG_KEYPAD == IRIVER_H10_PAD)
94 #define CLIX_BUTTON_QUIT BUTTON_POWER
95 #define CLIX_BUTTON_LEFT BUTTON_LEFT
96 #define CLIX_BUTTON_RIGHT BUTTON_RIGHT
97 #define CLIX_BUTTON_CLICK BUTTON_PLAY
98 #define CLIX_BUTTON_UP BUTTON_SCROLL_UP
99 #define CLIX_BUTTON_DOWN BUTTON_SCROLL_DOWN
101 #elif CONFIG_KEYPAD == IAUDIO67_PAD
102 #define CLIX_BUTTON_QUIT BUTTON_POWER
103 #define CLIX_BUTTON_LEFT BUTTON_LEFT
104 #define CLIX_BUTTON_RIGHT BUTTON_RIGHT
105 #define CLIX_BUTTON_CLICK BUTTON_PLAY
106 #define CLIX_BUTTON_UP BUTTON_STOP
107 #define CLIX_BUTTON_DOWN BUTTON_PLAY
109 #elif CONFIG_KEYPAD == IAUDIO_X5M5_PAD
110 #define CLIX_BUTTON_QUIT BUTTON_POWER
111 #define CLIX_BUTTON_LEFT BUTTON_LEFT
112 #define CLIX_BUTTON_RIGHT BUTTON_RIGHT
113 #define CLIX_BUTTON_CLICK BUTTON_SELECT
114 #define CLIX_BUTTON_UP BUTTON_UP
115 #define CLIX_BUTTON_DOWN BUTTON_DOWN
117 #elif (CONFIG_KEYPAD == IRIVER_H300_PAD)
118 #define CLIX_BUTTON_QUIT BUTTON_OFF
119 #define CLIX_BUTTON_LEFT BUTTON_LEFT
120 #define CLIX_BUTTON_RIGHT BUTTON_RIGHT
121 #define CLIX_BUTTON_CLICK BUTTON_SELECT
122 #define CLIX_BUTTON_UP BUTTON_UP
123 #define CLIX_BUTTON_DOWN BUTTON_DOWN
125 #elif CONFIG_KEYPAD == CREATIVEZVM_PAD
126 #define CLIX_BUTTON_QUIT BUTTON_BACK
127 #define CLIX_BUTTON_LEFT BUTTON_LEFT
128 #define CLIX_BUTTON_RIGHT BUTTON_RIGHT
129 #define CLIX_BUTTON_CLICK BUTTON_SELECT
130 #define CLIX_BUTTON_UP BUTTON_UP
131 #define CLIX_BUTTON_DOWN BUTTON_DOWN
133 #elif (CONFIG_KEYPAD == PHILIPS_HDD1630_PAD)
134 #define CLIX_BUTTON_QUIT BUTTON_POWER
135 #define CLIX_BUTTON_LEFT BUTTON_LEFT
136 #define CLIX_BUTTON_RIGHT BUTTON_RIGHT
137 #define CLIX_BUTTON_CLICK BUTTON_SELECT
138 #define CLIX_BUTTON_UP BUTTON_UP
139 #define CLIX_BUTTON_DOWN BUTTON_DOWN
141 #elif (CONFIG_KEYPAD == PHILIPS_HDD6330_PAD)
142 #define CLIX_BUTTON_QUIT BUTTON_POWER
143 #define CLIX_BUTTON_LEFT BUTTON_PREV
144 #define CLIX_BUTTON_RIGHT BUTTON_NEXT
145 #define CLIX_BUTTON_CLICK BUTTON_PLAY
146 #define CLIX_BUTTON_UP BUTTON_UP
147 #define CLIX_BUTTON_DOWN BUTTON_DOWN
149 #elif (CONFIG_KEYPAD == PHILIPS_SA9200_PAD)
150 #define CLIX_BUTTON_QUIT BUTTON_POWER
151 #define CLIX_BUTTON_LEFT BUTTON_PREV
152 #define CLIX_BUTTON_RIGHT BUTTON_NEXT
153 #define CLIX_BUTTON_CLICK BUTTON_PLAY
154 #define CLIX_BUTTON_UP BUTTON_UP
155 #define CLIX_BUTTON_DOWN BUTTON_DOWN
157 #elif CONFIG_KEYPAD == COWON_D2_PAD
158 #define CLIX_BUTTON_QUIT BUTTON_POWER
160 #elif (CONFIG_KEYPAD == ONDAVX747_PAD)
161 #define CLIX_BUTTON_QUIT BUTTON_POWER
162 #define CLIX_BUTTON_CLICK BUTTON_MENU
163 #elif (CONFIG_KEYPAD == ONDAVX777_PAD)
164 #define CLIX_BUTTON_QUIT BUTTON_POWER
166 #elif (CONFIG_KEYPAD == MROBE500_PAD)
167 #define CLIX_BUTTON_QUIT BUTTON_POWER
169 #elif (CONFIG_KEYPAD == SAMSUNG_YH_PAD)
170 #define CLIX_BUTTON_QUIT BUTTON_REC
171 #define CLIX_BUTTON_LEFT BUTTON_LEFT
172 #define CLIX_BUTTON_RIGHT BUTTON_RIGHT
173 #define CLIX_BUTTON_CLICK BUTTON_PLAY
174 #define CLIX_BUTTON_UP BUTTON_UP
175 #define CLIX_BUTTON_DOWN BUTTON_DOWN
177 #elif (CONFIG_KEYPAD == PBELL_VIBE500_PAD)
178 #define CLIX_BUTTON_QUIT BUTTON_REC
179 #define CLIX_BUTTON_UP BUTTON_UP
180 #define CLIX_BUTTON_DOWN BUTTON_DOWN
181 #define CLIX_BUTTON_SCROLL_FWD BUTTON_PLAY
182 #define CLIX_BUTTON_SCROLL_BACK BUTTON_MENU
183 #define CLIX_BUTTON_LEFT BUTTON_PREV
184 #define CLIX_BUTTON_RIGHT BUTTON_NEXT
185 #define CLIX_BUTTON_CLICK BUTTON_OK
191 #ifndef CLIX_BUTTON_CLICK
192 #define CLIX_BUTTON_CLICK BUTTON_CENTER
195 #define SCORE_FILE PLUGIN_GAMES_DATA_DIR "/clix.score"
197 struct highscore highscores
[NUM_SCORES
];
200 #define BLINK_TICKCOUNT 25
203 #if (LCD_WIDTH >= LCD_HEIGHT)
204 #define BOARD_WIDTH 18
205 #define BOARD_HEIGHT 12
207 #define BOARD_WIDTH 12
208 #define BOARD_HEIGHT 18
212 #if (LCD_WIDTH/BOARD_WIDTH) > (LCD_HEIGHT/BOARD_HEIGHT)
213 #define CELL_SIZE (LCD_HEIGHT/BOARD_HEIGHT)
215 #define CELL_SIZE (LCD_WIDTH/BOARD_WIDTH)
218 #elif (LCD_WIDTH >= 306 && LCD_HEIGHT>= 204)
221 #elif (LCD_WIDTH >= 270 && LCD_HEIGHT>= 180)
224 #elif (LCD_WIDTH >= 234 && LCD_HEIGHT>= 156)
227 #elif (LCD_WIDTH >= 198 && LCD_HEIGHT>= 132)
230 #elif (LCD_WIDTH >= 162 && LCD_HEIGHT>= 108)
233 #elif (LCD_WIDTH >= 126 && LCD_HEIGHT>= 84)
236 #elif (LCD_WIDTH >= 60)
240 #define XYPOS(x,y) ((y) * BOARD_WIDTH + x)
241 #define XOFS LCD_WIDTH/2-(BOARD_WIDTH * (CELL_SIZE + 1)/2)
242 #define YOFS (LCD_HEIGHT+10)/2-(BOARD_HEIGHT * (CELL_SIZE + 1)/2)
245 struct clix_game_state_t
{
246 int level
; /* current level */
247 int score
; /* current game score */
248 int x
,y
; /* current positions of the cursor */
249 int board
[BOARD_WIDTH
* BOARD_HEIGHT
]; /* play board*/
250 /* state of selected fields,maybe we can store this in the play board too */
251 bool board_selected
[ BOARD_WIDTH
* BOARD_HEIGHT
];
254 bool blink
; /* true if selected CELLS are currently white */
257 /* game state enum */
264 /* cell color enum */
279 /* recursive function to check if a neighbour cell is of the same color
280 if so call the function with the neighbours position
282 static void clix_set_selected(struct clix_game_state_t
* state
,
283 const int x
, const int y
)
285 state
->selected_count
++;
286 state
->board_selected
[ XYPOS( x
, y
)] = true;
287 int current_color
= state
->board
[ XYPOS( x
, y
)];
290 state
->board
[ XYPOS( x
- 1, y
)] == current_color
&&
291 state
->board_selected
[ XYPOS(x
- 1, y
)] == false)
292 clix_set_selected( state
, x
- 1, y
);
294 if( (y
+ 1) < BOARD_HEIGHT
&&
295 state
->board
[ XYPOS( x
, y
+ 1)] == current_color
&&
296 state
->board_selected
[ XYPOS(x
, y
+ 1)] == false)
297 clix_set_selected( state
, x
, y
+ 1);
299 if( (x
+ 1) < BOARD_WIDTH
&&
300 state
->board
[ XYPOS( x
+ 1, y
)] == current_color
&&
301 state
->board_selected
[ XYPOS(x
+ 1, y
)] == false)
302 clix_set_selected( state
, x
+ 1, y
);
305 state
->board
[ XYPOS( x
, y
- 1)] == current_color
&&
306 state
->board_selected
[ XYPOS(x
, y
- 1)] == false)
307 clix_set_selected( state
, x
, y
- 1);
310 /* updates "blinking" cells by finding out which one is a valid neighbours */
311 static void clix_update_selected(struct clix_game_state_t
* state
)
315 for( i
= 0; i
< BOARD_WIDTH
* BOARD_HEIGHT
; ++i
)
317 state
->board_selected
[i
] = false;
319 state
->selected_count
= 0;
321 /* recursion starts here */
322 clix_set_selected( state
, state
->x
, state
->y
);
325 /* inits the board with new random colors according to the level */
326 static void clix_init_new_level(struct clix_game_state_t
* state
)
331 state
->y
= BOARD_HEIGHT
/ 2;
332 state
->x
= BOARD_WIDTH
/ 2;
334 rb
->srand( *rb
->current_tick
);
335 /* create a random colored board, according to the current level */
336 for(i
= 0; i
< BOARD_HEIGHT
* BOARD_WIDTH
; ++i
)
338 r
= rb
->rand() % (state
->level
+ 1);
343 /* this inits the game state structure */
344 static void clix_init(struct clix_game_state_t
* state
)
348 state
->blink
= false;
349 state
->status
= CLIX_CONTINUE
;
351 clix_init_new_level(state
);
353 clix_update_selected(state
);
356 /* Function for drawing a cell */
357 static void clix_draw_cell(struct clix_game_state_t
* state
, const int x
, const int y
)
362 realx
+= x
* (CELL_SIZE
+ 1);
363 realy
+= y
* (CELL_SIZE
+ 1);
365 if (state
->blink
&& state
->board_selected
[ XYPOS( x
, y
)]) {
366 rb
->lcd_set_foreground(LCD_WHITE
);
368 switch (state
->board
[ XYPOS( x
, y
)])
371 rb
->lcd_set_foreground( LCD_RGBPACK( 25, 25, 255));
374 rb
->lcd_set_foreground( LCD_RGBPACK( 25, 255, 25));
377 rb
->lcd_set_foreground( LCD_RGBPACK( 255, 25, 25));
380 rb
->lcd_set_foreground( LCD_RGBPACK( 225, 225, 25));
383 rb
->lcd_set_foreground( LCD_RGBPACK( 230, 140, 15));
386 rb
->lcd_set_foreground( LCD_RGBPACK( 25, 245, 230));
389 rb
->lcd_set_foreground( LCD_RGBPACK(139, 69, 19));
392 rb
->lcd_set_foreground( LCD_RGBPACK(255, 105, 180));
395 rb
->lcd_set_foreground( LCD_RGBPACK( 0, 100, 0));
398 rb
->lcd_set_foreground( LCD_RGBPACK( 280, 32, 144));
401 rb
->lcd_set_foreground( LCD_BLACK
);
406 rb
->lcd_fillrect( realx
, realy
, CELL_SIZE
, CELL_SIZE
);
409 if ( x
== state
->x
&& y
== state
->y
) {
410 rb
->lcd_set_foreground( LCD_WHITE
);
411 rb
->lcd_drawrect( realx
- 1, realy
- 1, CELL_SIZE
+ 2, CELL_SIZE
+ 2);
415 /* main function of drawing the whole board and score... */
416 static void clix_draw(struct clix_game_state_t
* state
)
421 rb
->lcd_clear_display();
422 rb
->lcd_set_foreground( LCD_WHITE
);
424 rb
->lcd_putsxy( MARGIN
, MARGIN
, "Score:");
425 rb
->lcd_putsxyf( 43, MARGIN
, "%d", state
->score
);
427 rb
->lcd_putsxy( 75, MARGIN
, "L:");
428 rb
->lcd_putsxyf( 90, MARGIN
, "%d", state
->level
);
430 rb
->lcd_putsxy( 75, MARGIN
, "Level:");
431 rb
->lcd_putsxyf( 113, MARGIN
, "%d", state
->level
);
433 for( i
= 0; i
< BOARD_WIDTH
; ++i
)
435 for( j
= 0; j
< BOARD_HEIGHT
; ++j
)
437 clix_draw_cell( state
, i
, j
);
442 rb
->lcd_set_foreground(LCD_WHITE
);
445 static void clix_move_cursor(struct clix_game_state_t
* state
, const bool left
)
453 while(state
->board
[ XYPOS( x
, y
)] == CC_BLACK
&& y
< BOARD_HEIGHT
) y
++;
454 if (y
< BOARD_HEIGHT
) {
468 if( x
< BOARD_WIDTH
- 1)
474 } while ( y
!= state
->y
);
477 /* returns the color of the given position, if out of bounds return CC_BLACK */
478 static int clix_get_color(struct clix_game_state_t
* state
, const int x
, const int y
)
480 if( x
>= 0 && x
< BOARD_WIDTH
&& y
>= 0 && y
< BOARD_HEIGHT
)
481 return state
->board
[XYPOS( x
, y
)];
486 static int clix_clear_selected(struct clix_game_state_t
* state
)
491 state
->status
= CLIX_CLEARED
;
493 /* clear the selected blocks */
494 for( i
= 0; i
< BOARD_WIDTH
; ++i
)
496 for( j
= 0; j
< BOARD_HEIGHT
; ++j
)
498 if( state
->board_selected
[ XYPOS( i
, j
)] )
500 state
->board_selected
[ XYPOS( i
, j
)] = false;
501 state
->board
[ XYPOS( i
, j
)] = CC_BLACK
;
507 state
->score
+= state
->selected_count
* state
->level
;
508 state
->selected_count
= 0;
510 /* let blocks falling down */
511 for( i
= BOARD_WIDTH
- 1; i
>= 0; --i
)
513 for( j
= BOARD_HEIGHT
- 1; j
>= 0; --j
)
516 while( (y
+ 1) < BOARD_HEIGHT
&&
517 state
->board
[ XYPOS( i
, y
+ 1)] == CC_BLACK
522 state
->board
[ XYPOS( i
, y
)] = state
->board
[ XYPOS( i
, j
)];
523 state
->board
[ XYPOS( i
, j
)] = CC_BLACK
;
528 /* move columns to left side */
529 for( i
= 0; i
< BOARD_WIDTH
; ++i
)
532 while( (x
- 1) >= 0 &&
533 state
->board
[ XYPOS( x
- 1, BOARD_HEIGHT
- 1)] == CC_BLACK
538 for( j
= 0; j
< BOARD_HEIGHT
; ++j
)
540 state
->board
[ XYPOS( x
, j
)] = state
->board
[ XYPOS( i
, j
)];
541 state
->board
[ XYPOS( i
, j
)] = CC_BLACK
;
546 if(state
->board
[ XYPOS( 0, BOARD_HEIGHT
- 1)] != CC_BLACK
)
547 state
->status
= CLIX_CONTINUE
;
549 if (state
->status
!= CLIX_CLEARED
) {
550 /* check if a move is still possible, otherwise the game is over.
551 tart from the left bottom, because there are the last fields
552 at the end of the game.
555 for( i
= 0; !found_move
&& i
< BOARD_WIDTH
; ++i
)
557 for( j
= BOARD_HEIGHT
- 1; !found_move
&& j
>= 0; --j
)
559 int color
= state
->board
[ XYPOS( i
, j
)];
560 if (color
!= CC_BLACK
) {
561 if (color
== clix_get_color( state
, i
- 1, j
) ||
562 color
== clix_get_color( state
, i
+ 1, j
) ||
563 color
== clix_get_color( state
, i
, j
- 1) ||
564 color
== clix_get_color( state
, i
, j
+ 1)
572 /* if the loops ended without a possible move, the game is over */
574 state
->status
= CLIX_GAMEOVER
;
576 /* set cursor to the right position */
577 if (state
->status
== CLIX_CONTINUE
) {
578 clix_move_cursor( state
, true);
579 clix_update_selected( state
);
583 return state
->status
;
586 static bool clix_help(void)
588 static char *help_text
[] = {
589 "Clix", "", "Aim", "",
590 "Remove", "all", "blocks", "from", "the", "board", "to", "achieve",
591 "the", "next", "level.", "You", "can", "only", "remove", "blocks,",
592 "if", "at", "least", "two", "blocks", "with", "the", "same", "color",
593 "have", "a", "direct", "connection.", "The", "more", "blocks", "you",
594 "remove", "per", "turn,", "the", "more", "points", "you", "get."
596 static struct style_text formation
[]={
597 { 0, TEXT_CENTER
|TEXT_UNDERLINE
},
602 rb
->lcd_setfont(FONT_UI
);
603 rb
->lcd_set_foreground(LCD_WHITE
);
604 if (display_text(ARRAYLEN(help_text
), help_text
, formation
, NULL
, true))
606 rb
->lcd_setfont(FONT_SYSFIXED
);
612 static int clix_menu_cb(int action
, const struct menu_item_ex
*this_item
)
614 if(action
== ACTION_REQUEST_MENUITEM
615 && !_ingame
&& ((intptr_t)this_item
)==0)
616 return ACTION_EXIT_MENUITEM
;
620 static int clix_menu(struct clix_game_state_t
* state
, bool ingame
)
622 rb
->button_clear_queue();
624 bool leave_menu
=false;
629 MENUITEM_STRINGLIST (main_menu
, "Clix Menu", clix_menu_cb
,
637 #ifdef HAVE_TOUCHSCREEN
638 /* Entering Menu, set the touchscreen to the global setting */
639 rb
->touchscreen_set_mode(rb
->global_settings
->touch_mode
);
642 while (!leave_menu
) {
644 switch (rb
->do_menu(&main_menu
, &choice
, NULL
, false)) {
661 highscore_show(-1, highscores
, NUM_SCORES
, true);
664 playback_control(NULL
);
667 case MENU_ATTACHED_USB
:
676 #ifdef HAVE_TOUCHSCREEN
677 /* Leaving the menu, set back to pointer mode */
678 rb
->touchscreen_set_mode(TOUCHSCREEN_POINT
);
684 static int clix_click(struct clix_game_state_t
* state
)
687 if (state
->selected_count
<= 1) {
690 switch( clix_clear_selected( state
))
693 state
->score
+= state
->level
* 100;
695 if (state
->level
< NUM_LEVELS
) {
696 rb
->splash(HZ
*2, "Great! Next Level!");
698 clix_init_new_level( state
);
699 clix_update_selected( state
);
702 rb
->splash(HZ
*2, "Congratulation!!!");
703 rb
->splash(HZ
*2, "You have finished the game.");
704 if(clix_menu(state
, 0))
710 rb
->splash(HZ
*2, "Game Over!");
711 rb
->lcd_clear_display();
712 position
= highscore_update(state
->score
, state
->level
, "",
713 highscores
, NUM_SCORES
);
717 rb
->splash(HZ
*2, "New High Score");
718 highscore_show(position
, highscores
, NUM_SCORES
, true);
720 if(clix_menu(state
, 0))
724 rb
->sleep(10); /* prevent repeating clicks */
730 static int clix_handle_game(struct clix_game_state_t
* state
)
733 int blink_tick
= *rb
->current_tick
+ BLINK_TICKCOUNT
;
740 if (clix_menu(state
, 0))
745 if (TIME_AFTER(*rb
->current_tick
, blink_tick
)) {
746 state
->blink
= !state
->blink
;
747 blink_tick
= *rb
->current_tick
+ BLINK_TICKCOUNT
;
750 time
= 6; /* number of ticks this function will loop reading keys */
751 start
= *rb
->current_tick
;
753 while(TIME_BEFORE(*rb
->current_tick
, end
))
758 button
= rb
->button_get_w_tmo(end
- *rb
->current_tick
);
759 #ifdef HAVE_TOUCHSCREEN
760 if(button
& BUTTON_TOUCHSCREEN
)
762 int x
= rb
->button_get_data() >> 16;
763 int y
= rb
->button_get_data() & 0xffff;
772 if(x
< BOARD_WIDTH
&& y
< BOARD_HEIGHT
773 && state
->board
[XYPOS(x
, y
)] != CC_BLACK
)
775 if(state
->x
== x
&& state
->y
== y
)
776 button
= CLIX_BUTTON_CLICK
;
788 #ifndef HAVE_TOUCHSCREEN
789 #ifdef CLIX_BUTTON_SCROLL_BACK
790 case CLIX_BUTTON_SCROLL_BACK
:
791 case CLIX_BUTTON_SCROLL_BACK
|BUTTON_REPEAT
:
794 case CLIX_BUTTON_UP
|BUTTON_REPEAT
:
796 state
->board
[ XYPOS( state
->x
, state
->y
- 1)] ==
799 state
->y
= BOARD_HEIGHT
- 1;
803 clix_move_cursor(state
, true);
806 #ifdef CLIX_BUTTON_SCROLL_FWD
807 case CLIX_BUTTON_SCROLL_FWD
:
808 case CLIX_BUTTON_SCROLL_FWD
|BUTTON_REPEAT
:
810 case CLIX_BUTTON_DOWN
:
811 case CLIX_BUTTON_DOWN
|BUTTON_REPEAT
:
812 if( state
->y
== (BOARD_HEIGHT
- 1))
817 clix_move_cursor( state
, true);
820 case CLIX_BUTTON_RIGHT
:
821 case CLIX_BUTTON_RIGHT
|BUTTON_REPEAT
:
822 if( state
->x
== (BOARD_WIDTH
- 1))
827 clix_move_cursor(state
, false);
830 case CLIX_BUTTON_LEFT
:
831 case CLIX_BUTTON_LEFT
|BUTTON_REPEAT
:
833 state
->x
= BOARD_WIDTH
- 1;
837 clix_move_cursor(state
, true);
840 case CLIX_BUTTON_CLICK
:
841 if (clix_click(state
) == 1)
845 case CLIX_BUTTON_QUIT
:
846 if (clix_menu(state
, 1) != 0) {
847 rb
->button_clear_queue();
856 if( (oldx
!= state
->x
|| oldy
!= state
->y
) &&
857 state
->board_selected
[ XYPOS( oldx
, oldy
)] !=
858 state
->board_selected
[ XYPOS( state
->x
, state
->y
)]
861 clix_update_selected(state
);
869 /* this is the plugin entry point */
870 enum plugin_status
plugin_start(const void* parameter
)
874 rb
->lcd_set_backdrop(NULL
);
875 rb
->lcd_set_foreground(LCD_WHITE
);
876 rb
->lcd_set_background(LCD_BLACK
);
877 rb
->lcd_setfont(FONT_SYSFIXED
);
878 #ifdef HAVE_TOUCHSCREEN
879 rb
->touchscreen_set_mode(TOUCHSCREEN_POINT
);
882 highscore_load(SCORE_FILE
, highscores
, NUM_SCORES
);
884 struct clix_game_state_t state
;
885 clix_handle_game( &state
);
887 highscore_save(SCORE_FILE
, highscores
, NUM_SCORES
);