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_SA9200_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 == COWON_D2_PAD
150 #define CLIX_BUTTON_QUIT BUTTON_POWER
152 #elif (CONFIG_KEYPAD == ONDAVX747_PAD)
153 #define CLIX_BUTTON_QUIT BUTTON_POWER
154 #define CLIX_BUTTON_CLICK BUTTON_MENU
155 #elif (CONFIG_KEYPAD == ONDAVX777_PAD)
156 #define CLIX_BUTTON_QUIT BUTTON_POWER
158 #elif (CONFIG_KEYPAD == MROBE500_PAD)
159 #define CLIX_BUTTON_QUIT BUTTON_POWER
161 #elif (CONFIG_KEYPAD == SAMSUNG_YH_PAD)
162 #define CLIX_BUTTON_QUIT BUTTON_REC
163 #define CLIX_BUTTON_LEFT BUTTON_LEFT
164 #define CLIX_BUTTON_RIGHT BUTTON_RIGHT
165 #define CLIX_BUTTON_CLICK BUTTON_PLAY
166 #define CLIX_BUTTON_UP BUTTON_UP
167 #define CLIX_BUTTON_DOWN BUTTON_DOWN
169 #elif (CONFIG_KEYPAD == PBELL_VIBE500_PAD)
170 #define CLIX_BUTTON_QUIT BUTTON_REC
171 #define CLIX_BUTTON_UP BUTTON_UP
172 #define CLIX_BUTTON_DOWN BUTTON_DOWN
173 #define CLIX_BUTTON_SCROLL_FWD BUTTON_PLAY
174 #define CLIX_BUTTON_SCROLL_BACK BUTTON_MENU
175 #define CLIX_BUTTON_LEFT BUTTON_PREV
176 #define CLIX_BUTTON_RIGHT BUTTON_NEXT
177 #define CLIX_BUTTON_CLICK BUTTON_OK
183 #ifndef CLIX_BUTTON_CLICK
184 #define CLIX_BUTTON_CLICK BUTTON_CENTER
187 #define HIGHSCORE_FILE PLUGIN_GAMES_DIR "/clix.score"
189 struct highscore highest
[NUM_SCORES
];
192 #define BLINK_TICKCOUNT 25
195 #if (LCD_WIDTH >= LCD_HEIGHT)
196 #define BOARD_WIDTH 18
197 #define BOARD_HEIGHT 12
199 #define BOARD_WIDTH 12
200 #define BOARD_HEIGHT 18
204 #if (LCD_WIDTH/BOARD_WIDTH) > (LCD_HEIGHT/BOARD_HEIGHT)
205 #define CELL_SIZE (LCD_HEIGHT/BOARD_HEIGHT)
207 #define CELL_SIZE (LCD_WIDTH/BOARD_WIDTH)
210 #elif (LCD_WIDTH >= 306 && LCD_HEIGHT>= 204)
213 #elif (LCD_WIDTH >= 270 && LCD_HEIGHT>= 180)
216 #elif (LCD_WIDTH >= 234 && LCD_HEIGHT>= 156)
219 #elif (LCD_WIDTH >= 198 && LCD_HEIGHT>= 132)
222 #elif (LCD_WIDTH >= 162 && LCD_HEIGHT>= 108)
225 #elif (LCD_WIDTH >= 126 && LCD_HEIGHT>= 84)
228 #elif (LCD_WIDTH >= 60)
232 #define XYPOS(x,y) ((y) * BOARD_WIDTH + x)
233 #define XOFS LCD_WIDTH/2-(BOARD_WIDTH * (CELL_SIZE + 1)/2)
234 #define YOFS (LCD_HEIGHT+10)/2-(BOARD_HEIGHT * (CELL_SIZE + 1)/2)
237 struct clix_game_state_t
{
238 int level
; /* current level */
239 int score
; /* current game score */
240 int x
,y
; /* current positions of the cursor */
241 int board
[BOARD_WIDTH
* BOARD_HEIGHT
]; /* play board*/
242 /* state of selected fields,maybe we can store this in the play board too */
243 bool board_selected
[ BOARD_WIDTH
* BOARD_HEIGHT
];
246 bool blink
; /* true if selected CELLS are currently white */
249 /* game state enum */
256 /* cell color enum */
271 /* recursive function to check if a neighbour cell is of the same color
272 if so call the function with the neighbours position
274 static void clix_set_selected(struct clix_game_state_t
* state
,
275 const int x
, const int y
)
277 state
->selected_count
++;
278 state
->board_selected
[ XYPOS( x
, y
)] = true;
279 int current_color
= state
->board
[ XYPOS( x
, y
)];
282 state
->board
[ XYPOS( x
- 1, y
)] == current_color
&&
283 state
->board_selected
[ XYPOS(x
- 1, y
)] == false)
284 clix_set_selected( state
, x
- 1, y
);
286 if( (y
+ 1) < BOARD_HEIGHT
&&
287 state
->board
[ XYPOS( x
, y
+ 1)] == current_color
&&
288 state
->board_selected
[ XYPOS(x
, y
+ 1)] == false)
289 clix_set_selected( state
, x
, y
+ 1);
291 if( (x
+ 1) < BOARD_WIDTH
&&
292 state
->board
[ XYPOS( x
+ 1, y
)] == current_color
&&
293 state
->board_selected
[ XYPOS(x
+ 1, y
)] == false)
294 clix_set_selected( state
, x
+ 1, y
);
297 state
->board
[ XYPOS( x
, y
- 1)] == current_color
&&
298 state
->board_selected
[ XYPOS(x
, y
- 1)] == false)
299 clix_set_selected( state
, x
, y
- 1);
302 /* updates "blinking" cells by finding out which one is a valid neighbours */
303 static void clix_update_selected(struct clix_game_state_t
* state
)
307 for( i
= 0; i
< BOARD_WIDTH
* BOARD_HEIGHT
; ++i
)
309 state
->board_selected
[i
] = false;
311 state
->selected_count
= 0;
313 /* recursion starts here */
314 clix_set_selected( state
, state
->x
, state
->y
);
317 /* inits the board with new random colors according to the level */
318 static void clix_init_new_level(struct clix_game_state_t
* state
)
323 state
->y
= BOARD_HEIGHT
/ 2;
324 state
->x
= BOARD_WIDTH
/ 2;
326 rb
->srand( *rb
->current_tick
);
327 /* create a random colored board, according to the current level */
328 for(i
= 0; i
< BOARD_HEIGHT
* BOARD_WIDTH
; ++i
)
330 r
= rb
->rand() % (state
->level
+ 1);
335 /* this inits the game state structure */
336 static void clix_init(struct clix_game_state_t
* state
)
340 state
->blink
= false;
341 state
->status
= CLIX_CONTINUE
;
343 clix_init_new_level(state
);
345 clix_update_selected(state
);
348 /* Function for drawing a cell */
349 static void clix_draw_cell(struct clix_game_state_t
* state
, const int x
, const int y
)
354 realx
+= x
* (CELL_SIZE
+ 1);
355 realy
+= y
* (CELL_SIZE
+ 1);
357 if (state
->blink
&& state
->board_selected
[ XYPOS( x
, y
)]) {
358 rb
->lcd_set_foreground(LCD_WHITE
);
360 switch (state
->board
[ XYPOS( x
, y
)])
363 rb
->lcd_set_foreground( LCD_RGBPACK( 25, 25, 255));
366 rb
->lcd_set_foreground( LCD_RGBPACK( 25, 255, 25));
369 rb
->lcd_set_foreground( LCD_RGBPACK( 255, 25, 25));
372 rb
->lcd_set_foreground( LCD_RGBPACK( 225, 225, 25));
375 rb
->lcd_set_foreground( LCD_RGBPACK( 230, 140, 15));
378 rb
->lcd_set_foreground( LCD_RGBPACK( 25, 245, 230));
381 rb
->lcd_set_foreground( LCD_RGBPACK(139, 69, 19));
384 rb
->lcd_set_foreground( LCD_RGBPACK(255, 105, 180));
387 rb
->lcd_set_foreground( LCD_RGBPACK( 0, 100, 0));
390 rb
->lcd_set_foreground( LCD_RGBPACK( 280, 32, 144));
393 rb
->lcd_set_foreground( LCD_BLACK
);
398 rb
->lcd_fillrect( realx
, realy
, CELL_SIZE
, CELL_SIZE
);
401 if ( x
== state
->x
&& y
== state
->y
) {
402 rb
->lcd_set_foreground( LCD_WHITE
);
403 rb
->lcd_drawrect( realx
- 1, realy
- 1, CELL_SIZE
+ 2, CELL_SIZE
+ 2);
407 /* main function of drawing the whole board and score... */
408 static void clix_draw(struct clix_game_state_t
* state
)
414 rb
->lcd_clear_display();
415 rb
->lcd_set_foreground( LCD_WHITE
);
417 rb
->lcd_putsxy( MARGIN
, MARGIN
, "Score:");
418 rb
->snprintf( str
, sizeof(str
), "%d", state
->score
);
419 rb
->lcd_putsxy( 43, MARGIN
, str
);
421 rb
->lcd_putsxy( 75, MARGIN
, "L:");
422 rb
->snprintf( str
, sizeof(str
), "%d", state
->level
);
423 rb
->lcd_putsxy( 90, MARGIN
, str
);
425 rb
->lcd_putsxy( 75, MARGIN
, "Level:");
426 rb
->snprintf( str
, sizeof(str
), "%d", state
->level
);
427 rb
->lcd_putsxy( 113, MARGIN
, str
);
429 for( i
= 0; i
< BOARD_WIDTH
; ++i
)
431 for( j
= 0; j
< BOARD_HEIGHT
; ++j
)
433 clix_draw_cell( state
, i
, j
);
440 static void clix_move_cursor(struct clix_game_state_t
* state
, const bool left
)
448 while(state
->board
[ XYPOS( x
, y
)] == CC_BLACK
&& y
< BOARD_HEIGHT
) y
++;
449 if (y
< BOARD_HEIGHT
) {
463 if( x
< BOARD_WIDTH
- 1)
469 } while ( y
!= state
->y
);
473 /* returns the color of the given position, if out of bounds return CC_BLACK */
474 static int clix_get_color(struct clix_game_state_t
* state
, const int x
, const int y
)
476 if( x
>= 0 && x
< BOARD_WIDTH
&& y
>= 0 && y
< BOARD_HEIGHT
)
477 return state
->board
[XYPOS( x
, y
)];
482 static int clix_clear_selected(struct clix_game_state_t
* state
)
486 state
->status
= CLIX_CLEARED
;
488 /* clear the selected blocks */
489 for( i
= 0; i
< BOARD_WIDTH
; ++i
)
491 for( j
= 0; j
< BOARD_HEIGHT
; ++j
)
493 if( state
->board_selected
[ XYPOS( i
, j
)] )
495 state
->board_selected
[ XYPOS( i
, j
)] = false;
496 state
->board
[ XYPOS( i
, j
)] = CC_BLACK
;
502 state
->score
+= state
->selected_count
* state
->level
;
503 state
->selected_count
= 0;
505 /* let blocks falling down */
506 for( i
= BOARD_WIDTH
- 1; i
>= 0; --i
)
508 for( j
= BOARD_HEIGHT
- 1; j
>= 0; --j
)
511 while( (y
+ 1) < BOARD_HEIGHT
&&
512 state
->board
[ XYPOS( i
, y
+ 1)] == CC_BLACK
517 state
->board
[ XYPOS( i
, y
)] = state
->board
[ XYPOS( i
, j
)];
518 state
->board
[ XYPOS( i
, j
)] = CC_BLACK
;
523 /* move columns to left side */
524 for( i
= 0; i
< BOARD_WIDTH
; ++i
)
527 while( (x
- 1) >= 0 &&
528 state
->board
[ XYPOS( x
- 1, BOARD_HEIGHT
- 1)] == CC_BLACK
533 for( j
= 0; j
< BOARD_HEIGHT
; ++j
)
535 state
->board
[ XYPOS( x
, j
)] = state
->board
[ XYPOS( i
, j
)];
536 state
->board
[ XYPOS( i
, j
)] = CC_BLACK
;
541 if(state
->board
[ XYPOS( 0, BOARD_HEIGHT
- 1)] != CC_BLACK
)
542 state
->status
= CLIX_CONTINUE
;
544 if (state
->status
!= CLIX_CLEARED
) {
545 /* check if a move is still possible, otherwise the game is over.
546 tart from the left bottom, because there are the last fields
547 at the end of the game.
549 for( i
= 0; i
< BOARD_WIDTH
; ++i
)
551 for( j
= BOARD_HEIGHT
- 1; j
>= 0; --j
)
553 int color
= state
->board
[ XYPOS( i
, j
)];
554 if (color
!= CC_BLACK
) {
555 if (color
== clix_get_color( state
, i
- 1, j
) ||
556 color
== clix_get_color( state
, i
+ 1, j
) ||
557 color
== clix_get_color( state
, i
, j
- 1) ||
558 color
== clix_get_color( state
, i
, j
+ 1)
561 /* end the loop, but in a diffrent way than usually*/
568 /* if the loops ended without a possible move, the game is over */
569 if( i
== BOARD_WIDTH
&& j
== -1)
570 state
->status
= CLIX_GAMEOVER
;
572 /* set cursor to the right position */
573 if (state
->status
== CLIX_CONTINUE
) {
574 clix_move_cursor( state
, true);
575 clix_update_selected( state
);
579 return state
->status
;
582 static bool clix_help(void)
584 #define WORDS (sizeof help_text / sizeof (char*))
585 static char *help_text
[] = {
586 "Clix", "", "Aim", "",
587 "Remove", "all", "blocks", "from", "the", "board", "to", "achieve",
588 "the", "next", "level.", "You", "can", "only", "remove", "blocks,",
589 "if", "at", "least", "two", "blocks", "with", "the", "same", "color",
590 "have", "a", "direct", "connection.", "The", "more", "blocks", "you",
591 "remove", "per", "turn,", "the", "more", "points", "you", "get."
593 static struct style_text formation
[]={
594 { 0, TEXT_CENTER
|TEXT_UNDERLINE
},
600 rb
->lcd_setfont(FONT_UI
);
601 rb
->lcd_set_foreground(LCD_WHITE
);
602 if (display_text(WORDS
, help_text
, formation
, NULL
))
605 button
= rb
->button_get(true);
606 if ( rb
->default_event_handler( button
) == SYS_USB_CONNECTED
)
608 } while( ( button
== BUTTON_NONE
)
609 || ( button
& (BUTTON_REL
|BUTTON_REPEAT
) ) );
610 rb
->lcd_setfont(FONT_SYSFIXED
);
615 static int clix_menu_cb(int action
, const struct menu_item_ex
*this_item
)
617 if(action
== ACTION_REQUEST_MENUITEM
618 && !_ingame
&& ((intptr_t)this_item
)==0)
619 return ACTION_EXIT_MENUITEM
;
623 static int clix_menu(struct clix_game_state_t
* state
, bool ingame
)
625 rb
->button_clear_queue();
627 bool leave_menu
=false;
632 MENUITEM_STRINGLIST (main_menu
, "Clix Menu", clix_menu_cb
,
640 #ifdef HAVE_TOUCHSCREEN
641 /* Entering Menu, set the touchscreen to the global setting */
642 rb
->touchscreen_set_mode(rb
->global_settings
->touch_mode
);
645 while (!leave_menu
) {
647 switch (rb
->do_menu(&main_menu
, &choice
, NULL
, false)) {
664 highscore_show(NUM_SCORES
, highest
, NUM_SCORES
, true);
667 playback_control(NULL
);
670 case MENU_ATTACHED_USB
:
679 #ifdef HAVE_TOUCHSCREEN
680 /* Leaving the menu, set back to pointer mode */
681 rb
->touchscreen_set_mode(TOUCHSCREEN_POINT
);
687 static int clix_handle_game(struct clix_game_state_t
* state
)
689 if (clix_menu(state
, 0))
693 int blink_tick
= *rb
->current_tick
+ BLINK_TICKCOUNT
;
701 int lastbutton
= BUTTON_NONE
;
705 if (TIME_AFTER(*rb
->current_tick
, blink_tick
)) {
706 state
->blink
= !state
->blink
;
707 blink_tick
= *rb
->current_tick
+ BLINK_TICKCOUNT
;
710 time
= 6; /* number of ticks this function will loop reading keys */
711 start
= *rb
->current_tick
;
713 while(TIME_BEFORE(*rb
->current_tick
, end
))
718 button
= rb
->button_get_w_tmo(end
- *rb
->current_tick
);
719 #ifdef HAVE_TOUCHSCREEN
720 if(button
& BUTTON_TOUCHSCREEN
)
722 int x
= rb
->button_get_data() >> 16;
723 int y
= rb
->button_get_data() & 0xffff;
732 if(x
< BOARD_WIDTH
&& y
< BOARD_HEIGHT
733 && state
->board
[XYPOS(x
, y
)] != CC_BLACK
)
735 if(state
->x
== x
&& state
->y
== y
)
736 button
= CLIX_BUTTON_CLICK
;
748 #ifndef HAVE_TOUCHSCREEN
749 #ifdef CLIX_BUTTON_SCROLL_BACK
750 case CLIX_BUTTON_SCROLL_BACK
:
751 case CLIX_BUTTON_SCROLL_BACK
|BUTTON_REPEAT
:
755 state
->board
[ XYPOS( state
->x
, state
->y
- 1)] ==
758 state
->y
= BOARD_HEIGHT
- 1;
762 clix_move_cursor(state
, true);
764 case CLIX_BUTTON_RIGHT
:
765 if( state
->x
== (BOARD_WIDTH
- 1))
770 clix_move_cursor(state
, false);
772 #ifdef CLIX_BUTTON_SCROLL_FWD
773 case CLIX_BUTTON_SCROLL_FWD
:
774 case CLIX_BUTTON_SCROLL_FWD
|BUTTON_REPEAT
:
776 case CLIX_BUTTON_DOWN
:
777 if( state
->y
== (BOARD_HEIGHT
- 1))
782 clix_move_cursor( state
, true);
784 case CLIX_BUTTON_LEFT
:
786 state
->x
= BOARD_WIDTH
- 1;
790 clix_move_cursor(state
, true);
794 case CLIX_BUTTON_CLICK
:
796 if (state
->selected_count
> 1) {
797 switch( clix_clear_selected( state
))
800 state
->score
+= state
->level
* 100;
802 if (state
->level
< NUM_LEVELS
) {
803 rb
->splash(HZ
*2, "Great! Next Level!");
805 clix_init_new_level( state
);
806 clix_update_selected( state
);
809 rb
->splash(HZ
*2, "Congratulation!!!");
810 rb
->lcd_clear_display();
811 rb
->splash(HZ
*2, "You have finished the game.");
812 if (clix_menu(state
, 0))
818 rb
->splash(HZ
*2, "Game Over!");
819 rb
->lcd_clear_display();
820 position
=highscore_update(state
->score
,
824 rb
->splash(HZ
*2, "New High Score");
826 highscore_show(position
, highest
,
828 if (clix_menu(state
, 0))
832 rb
->sleep(10); /* prevent repeating clicks */
838 case CLIX_BUTTON_QUIT
:
839 if (clix_menu(state
, 1) != 0) {
840 rb
->button_clear_queue();
849 if(button
!= BUTTON_NONE
)
852 if( (oldx
!= state
->x
|| oldy
!= state
->y
) &&
853 state
->board_selected
[ XYPOS( oldx
, oldy
)] !=
854 state
->board_selected
[ XYPOS( state
->x
, state
->y
)]
857 clix_update_selected(state
);
865 /* this is the plugin entry point */
866 enum plugin_status
plugin_start(const void* parameter
)
870 rb
->lcd_set_backdrop(NULL
);
871 rb
->lcd_set_foreground(LCD_WHITE
);
872 rb
->lcd_set_background(LCD_BLACK
);
873 rb
->lcd_setfont(FONT_SYSFIXED
);
874 #ifdef HAVE_TOUCHSCREEN
875 rb
->touchscreen_set_mode(TOUCHSCREEN_POINT
);
878 highscore_load(HIGHSCORE_FILE
, highest
, NUM_SCORES
);
880 struct clix_game_state_t state
;
881 clix_handle_game( &state
);
883 highscore_save(HIGHSCORE_FILE
, highest
, NUM_SCORES
);