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 (CONFIG_KEYPAD == SANSA_CONNECT_PAD)
29 #define CLIX_BUTTON_QUIT BUTTON_POWER
30 #define CLIX_BUTTON_UP BUTTON_UP
31 #define CLIX_BUTTON_DOWN BUTTON_DOWN
32 #define CLIX_BUTTON_SCROLL_FWD BUTTON_SCROLL_FWD
33 #define CLIX_BUTTON_SCROLL_BACK BUTTON_SCROLL_BACK
34 #define CLIX_BUTTON_LEFT BUTTON_LEFT
35 #define CLIX_BUTTON_RIGHT BUTTON_RIGHT
36 #define CLIX_BUTTON_CLICK BUTTON_SELECT
38 #elif (CONFIG_KEYPAD == SANSA_CLIP_PAD)
39 #define CLIX_BUTTON_QUIT BUTTON_POWER
40 #define CLIX_BUTTON_UP BUTTON_UP
41 #define CLIX_BUTTON_DOWN BUTTON_DOWN
42 #define CLIX_BUTTON_LEFT BUTTON_LEFT
43 #define CLIX_BUTTON_RIGHT BUTTON_RIGHT
44 #define CLIX_BUTTON_CLICK BUTTON_SELECT
46 #elif (CONFIG_KEYPAD == SANSA_FUZE_PAD)
47 #define CLIX_BUTTON_QUIT BUTTON_HOME
48 #define CLIX_BUTTON_UP BUTTON_UP
49 #define CLIX_BUTTON_DOWN BUTTON_DOWN
50 #define CLIX_BUTTON_SCROLL_FWD BUTTON_SCROLL_FWD
51 #define CLIX_BUTTON_SCROLL_BACK BUTTON_SCROLL_BACK
52 #define CLIX_BUTTON_LEFT BUTTON_LEFT
53 #define CLIX_BUTTON_RIGHT BUTTON_RIGHT
54 #define CLIX_BUTTON_CLICK BUTTON_SELECT
56 #elif (CONFIG_KEYPAD == SANSA_C200_PAD)
57 #define CLIX_BUTTON_QUIT BUTTON_POWER
58 #define CLIX_BUTTON_UP BUTTON_UP
59 #define CLIX_BUTTON_DOWN BUTTON_DOWN
60 #define CLIX_BUTTON_SCROLL_FWD BUTTON_VOL_UP
61 #define CLIX_BUTTON_SCROLL_BACK BUTTON_VOL_DOWN
62 #define CLIX_BUTTON_LEFT BUTTON_LEFT
63 #define CLIX_BUTTON_RIGHT BUTTON_RIGHT
64 #define CLIX_BUTTON_CLICK BUTTON_SELECT
66 #elif (CONFIG_KEYPAD == IPOD_4G_PAD) || \
67 (CONFIG_KEYPAD == IPOD_3G_PAD) || \
68 (CONFIG_KEYPAD == IPOD_1G2G_PAD)
69 #define CLIX_BUTTON_QUIT (BUTTON_SELECT | BUTTON_MENU)
70 #define CLIX_BUTTON_UP BUTTON_MENU
71 #define CLIX_BUTTON_DOWN BUTTON_PLAY
72 #define CLIX_BUTTON_SCROLL_FWD BUTTON_SCROLL_FWD
73 #define CLIX_BUTTON_SCROLL_BACK BUTTON_SCROLL_BACK
74 #define CLIX_BUTTON_CLICK BUTTON_SELECT
75 #define CLIX_BUTTON_RIGHT BUTTON_RIGHT
76 #define CLIX_BUTTON_LEFT BUTTON_LEFT
78 #elif (CONFIG_KEYPAD == GIGABEAT_PAD)
79 #define CLIX_BUTTON_QUIT BUTTON_POWER
80 #define CLIX_BUTTON_LEFT BUTTON_LEFT
81 #define CLIX_BUTTON_RIGHT BUTTON_RIGHT
82 #define CLIX_BUTTON_CLICK BUTTON_SELECT
83 #define CLIX_BUTTON_UP BUTTON_UP
84 #define CLIX_BUTTON_DOWN BUTTON_DOWN
86 #elif (CONFIG_KEYPAD == GIGABEAT_S_PAD) || \
87 (CONFIG_KEYPAD == SAMSUNG_YPR0_PAD)
88 #define CLIX_BUTTON_QUIT BUTTON_BACK
89 #define CLIX_BUTTON_LEFT BUTTON_LEFT
90 #define CLIX_BUTTON_RIGHT BUTTON_RIGHT
91 #define CLIX_BUTTON_CLICK BUTTON_SELECT
92 #define CLIX_BUTTON_UP BUTTON_UP
93 #define CLIX_BUTTON_DOWN BUTTON_DOWN
95 #elif (CONFIG_KEYPAD == IRIVER_H10_PAD)
96 #define CLIX_BUTTON_QUIT BUTTON_POWER
97 #define CLIX_BUTTON_LEFT BUTTON_LEFT
98 #define CLIX_BUTTON_RIGHT BUTTON_RIGHT
99 #define CLIX_BUTTON_CLICK BUTTON_PLAY
100 #define CLIX_BUTTON_UP BUTTON_SCROLL_UP
101 #define CLIX_BUTTON_DOWN BUTTON_SCROLL_DOWN
103 #elif CONFIG_KEYPAD == IAUDIO67_PAD
104 #define CLIX_BUTTON_QUIT BUTTON_POWER
105 #define CLIX_BUTTON_LEFT BUTTON_LEFT
106 #define CLIX_BUTTON_RIGHT BUTTON_RIGHT
107 #define CLIX_BUTTON_CLICK BUTTON_PLAY
108 #define CLIX_BUTTON_UP BUTTON_STOP
109 #define CLIX_BUTTON_DOWN BUTTON_PLAY
111 #elif CONFIG_KEYPAD == IAUDIO_X5M5_PAD
112 #define CLIX_BUTTON_QUIT BUTTON_POWER
113 #define CLIX_BUTTON_LEFT BUTTON_LEFT
114 #define CLIX_BUTTON_RIGHT BUTTON_RIGHT
115 #define CLIX_BUTTON_CLICK BUTTON_SELECT
116 #define CLIX_BUTTON_UP BUTTON_UP
117 #define CLIX_BUTTON_DOWN BUTTON_DOWN
119 #elif (CONFIG_KEYPAD == IRIVER_H300_PAD)
120 #define CLIX_BUTTON_QUIT BUTTON_OFF
121 #define CLIX_BUTTON_LEFT BUTTON_LEFT
122 #define CLIX_BUTTON_RIGHT BUTTON_RIGHT
123 #define CLIX_BUTTON_CLICK BUTTON_SELECT
124 #define CLIX_BUTTON_UP BUTTON_UP
125 #define CLIX_BUTTON_DOWN BUTTON_DOWN
127 #elif CONFIG_KEYPAD == CREATIVEZVM_PAD
128 #define CLIX_BUTTON_QUIT BUTTON_BACK
129 #define CLIX_BUTTON_LEFT BUTTON_LEFT
130 #define CLIX_BUTTON_RIGHT BUTTON_RIGHT
131 #define CLIX_BUTTON_CLICK BUTTON_SELECT
132 #define CLIX_BUTTON_UP BUTTON_UP
133 #define CLIX_BUTTON_DOWN BUTTON_DOWN
135 #elif (CONFIG_KEYPAD == PHILIPS_HDD1630_PAD)
136 #define CLIX_BUTTON_QUIT BUTTON_POWER
137 #define CLIX_BUTTON_LEFT BUTTON_LEFT
138 #define CLIX_BUTTON_RIGHT BUTTON_RIGHT
139 #define CLIX_BUTTON_CLICK BUTTON_SELECT
140 #define CLIX_BUTTON_UP BUTTON_UP
141 #define CLIX_BUTTON_DOWN BUTTON_DOWN
143 #elif (CONFIG_KEYPAD == PHILIPS_HDD6330_PAD)
144 #define CLIX_BUTTON_QUIT BUTTON_POWER
145 #define CLIX_BUTTON_LEFT BUTTON_PREV
146 #define CLIX_BUTTON_RIGHT BUTTON_NEXT
147 #define CLIX_BUTTON_CLICK BUTTON_PLAY
148 #define CLIX_BUTTON_UP BUTTON_UP
149 #define CLIX_BUTTON_DOWN BUTTON_DOWN
151 #elif (CONFIG_KEYPAD == PHILIPS_SA9200_PAD)
152 #define CLIX_BUTTON_QUIT BUTTON_POWER
153 #define CLIX_BUTTON_LEFT BUTTON_PREV
154 #define CLIX_BUTTON_RIGHT BUTTON_NEXT
155 #define CLIX_BUTTON_CLICK BUTTON_PLAY
156 #define CLIX_BUTTON_UP BUTTON_UP
157 #define CLIX_BUTTON_DOWN BUTTON_DOWN
159 #elif CONFIG_KEYPAD == COWON_D2_PAD
160 #define CLIX_BUTTON_QUIT BUTTON_POWER
162 #elif (CONFIG_KEYPAD == ONDAVX747_PAD)
163 #define CLIX_BUTTON_QUIT BUTTON_POWER
164 #define CLIX_BUTTON_CLICK BUTTON_MENU
165 #elif (CONFIG_KEYPAD == ONDAVX777_PAD)
166 #define CLIX_BUTTON_QUIT BUTTON_POWER
168 #elif (CONFIG_KEYPAD == MROBE500_PAD)
169 #define CLIX_BUTTON_QUIT BUTTON_POWER
171 #elif (CONFIG_KEYPAD == SAMSUNG_YH_PAD)
172 #define CLIX_BUTTON_QUIT BUTTON_REC
173 #define CLIX_BUTTON_LEFT BUTTON_LEFT
174 #define CLIX_BUTTON_RIGHT BUTTON_RIGHT
175 #define CLIX_BUTTON_CLICK BUTTON_PLAY
176 #define CLIX_BUTTON_UP BUTTON_UP
177 #define CLIX_BUTTON_DOWN BUTTON_DOWN
179 #elif (CONFIG_KEYPAD == PBELL_VIBE500_PAD)
180 #define CLIX_BUTTON_QUIT BUTTON_REC
181 #define CLIX_BUTTON_UP BUTTON_UP
182 #define CLIX_BUTTON_DOWN BUTTON_DOWN
183 #define CLIX_BUTTON_SCROLL_FWD BUTTON_PLAY
184 #define CLIX_BUTTON_SCROLL_BACK BUTTON_MENU
185 #define CLIX_BUTTON_LEFT BUTTON_PREV
186 #define CLIX_BUTTON_RIGHT BUTTON_NEXT
187 #define CLIX_BUTTON_CLICK BUTTON_OK
189 #elif (CONFIG_KEYPAD == SANSA_FUZEPLUS_PAD)
190 #define CLIX_BUTTON_QUIT BUTTON_POWER
191 #define CLIX_BUTTON_UP BUTTON_UP
192 #define CLIX_BUTTON_DOWN BUTTON_DOWN
193 #define CLIX_BUTTON_SCROLL_FWD BUTTON_BACK
194 #define CLIX_BUTTON_SCROLL_BACK BUTTON_PLAYPAUSE
195 #define CLIX_BUTTON_LEFT BUTTON_LEFT
196 #define CLIX_BUTTON_RIGHT BUTTON_RIGHT
197 #define CLIX_BUTTON_CLICK BUTTON_SELECT
203 #ifndef CLIX_BUTTON_CLICK
204 #define CLIX_BUTTON_CLICK BUTTON_CENTER
207 #define SCORE_FILE PLUGIN_GAMES_DATA_DIR "/clix.score"
209 struct highscore highscores
[NUM_SCORES
];
212 #define BLINK_TICKCOUNT 25
215 #if (LCD_WIDTH >= LCD_HEIGHT)
216 #define BOARD_WIDTH 18
217 #define BOARD_HEIGHT 12
219 #define BOARD_WIDTH 12
220 #define BOARD_HEIGHT 18
224 #if (LCD_WIDTH/BOARD_WIDTH) > (LCD_HEIGHT/BOARD_HEIGHT)
225 #define CELL_SIZE (LCD_HEIGHT/BOARD_HEIGHT)
227 #define CELL_SIZE (LCD_WIDTH/BOARD_WIDTH)
230 #elif (LCD_WIDTH >= 306 && LCD_HEIGHT>= 204)
233 #elif (LCD_WIDTH >= 270 && LCD_HEIGHT>= 180)
236 #elif (LCD_WIDTH >= 234 && LCD_HEIGHT>= 156)
239 #elif (LCD_WIDTH >= 198 && LCD_HEIGHT>= 132)
242 #elif (LCD_WIDTH >= 162 && LCD_HEIGHT>= 108)
245 #elif (LCD_WIDTH >= 126 && LCD_HEIGHT>= 84)
248 #elif (LCD_WIDTH >= 60)
252 #define XYPOS(x,y) ((y) * BOARD_WIDTH + x)
253 #define XOFS LCD_WIDTH/2-(BOARD_WIDTH * (CELL_SIZE + 1)/2)
254 #define YOFS (LCD_HEIGHT+10)/2-(BOARD_HEIGHT * (CELL_SIZE + 1)/2)
257 struct clix_game_state_t
{
258 int level
; /* current level */
259 int score
; /* current game score */
260 int x
,y
; /* current positions of the cursor */
261 int board
[BOARD_WIDTH
* BOARD_HEIGHT
]; /* play board*/
262 /* state of selected fields,maybe we can store this in the play board too */
263 bool board_selected
[ BOARD_WIDTH
* BOARD_HEIGHT
];
266 bool blink
; /* true if selected CELLS are currently white */
269 /* game state enum */
276 /* cell color enum */
291 /* recursive function to check if a neighbour cell is of the same color
292 if so call the function with the neighbours position
294 static void clix_set_selected(struct clix_game_state_t
* state
,
295 const int x
, const int y
)
297 state
->selected_count
++;
298 state
->board_selected
[ XYPOS( x
, y
)] = true;
299 int current_color
= state
->board
[ XYPOS( x
, y
)];
302 state
->board
[ XYPOS( x
- 1, y
)] == current_color
&&
303 state
->board_selected
[ XYPOS(x
- 1, y
)] == false)
304 clix_set_selected( state
, x
- 1, y
);
306 if( (y
+ 1) < BOARD_HEIGHT
&&
307 state
->board
[ XYPOS( x
, y
+ 1)] == current_color
&&
308 state
->board_selected
[ XYPOS(x
, y
+ 1)] == false)
309 clix_set_selected( state
, x
, y
+ 1);
311 if( (x
+ 1) < BOARD_WIDTH
&&
312 state
->board
[ XYPOS( x
+ 1, y
)] == current_color
&&
313 state
->board_selected
[ XYPOS(x
+ 1, y
)] == false)
314 clix_set_selected( state
, x
+ 1, y
);
317 state
->board
[ XYPOS( x
, y
- 1)] == current_color
&&
318 state
->board_selected
[ XYPOS(x
, y
- 1)] == false)
319 clix_set_selected( state
, x
, y
- 1);
322 /* updates "blinking" cells by finding out which one is a valid neighbours */
323 static void clix_update_selected(struct clix_game_state_t
* state
)
327 for( i
= 0; i
< BOARD_WIDTH
* BOARD_HEIGHT
; ++i
)
329 state
->board_selected
[i
] = false;
331 state
->selected_count
= 0;
333 /* recursion starts here */
334 clix_set_selected( state
, state
->x
, state
->y
);
337 /* inits the board with new random colors according to the level */
338 static void clix_init_new_level(struct clix_game_state_t
* state
)
343 state
->y
= BOARD_HEIGHT
/ 2;
344 state
->x
= BOARD_WIDTH
/ 2;
346 rb
->srand( *rb
->current_tick
);
347 /* create a random colored board, according to the current level */
348 for(i
= 0; i
< BOARD_HEIGHT
* BOARD_WIDTH
; ++i
)
350 r
= rb
->rand() % (state
->level
+ 1);
355 /* this inits the game state structure */
356 static void clix_init(struct clix_game_state_t
* state
)
360 state
->blink
= false;
361 state
->status
= CLIX_CONTINUE
;
363 clix_init_new_level(state
);
365 clix_update_selected(state
);
368 /* Function for drawing a cell */
369 static void clix_draw_cell(struct clix_game_state_t
* state
, const int x
, const int y
)
374 realx
+= x
* (CELL_SIZE
+ 1);
375 realy
+= y
* (CELL_SIZE
+ 1);
377 if (state
->blink
&& state
->board_selected
[ XYPOS( x
, y
)]) {
378 rb
->lcd_set_foreground(LCD_WHITE
);
380 switch (state
->board
[ XYPOS( x
, y
)])
383 rb
->lcd_set_foreground( LCD_RGBPACK( 25, 25, 255));
386 rb
->lcd_set_foreground( LCD_RGBPACK( 25, 255, 25));
389 rb
->lcd_set_foreground( LCD_RGBPACK( 255, 25, 25));
392 rb
->lcd_set_foreground( LCD_RGBPACK( 225, 225, 25));
395 rb
->lcd_set_foreground( LCD_RGBPACK( 230, 140, 15));
398 rb
->lcd_set_foreground( LCD_RGBPACK( 25, 245, 230));
401 rb
->lcd_set_foreground( LCD_RGBPACK(139, 69, 19));
404 rb
->lcd_set_foreground( LCD_RGBPACK(255, 105, 180));
407 rb
->lcd_set_foreground( LCD_RGBPACK( 0, 100, 0));
410 rb
->lcd_set_foreground( LCD_RGBPACK( 280, 32, 144));
413 rb
->lcd_set_foreground( LCD_BLACK
);
418 rb
->lcd_fillrect( realx
, realy
, CELL_SIZE
, CELL_SIZE
);
421 if ( x
== state
->x
&& y
== state
->y
) {
422 rb
->lcd_set_foreground( LCD_WHITE
);
423 rb
->lcd_drawrect( realx
- 1, realy
- 1, CELL_SIZE
+ 2, CELL_SIZE
+ 2);
427 /* main function of drawing the whole board and score... */
428 static void clix_draw(struct clix_game_state_t
* state
)
433 rb
->lcd_clear_display();
434 rb
->lcd_set_foreground( LCD_WHITE
);
436 rb
->lcd_putsxy( MARGIN
, MARGIN
, "Score:");
437 rb
->lcd_putsxyf( 43, MARGIN
, "%d", state
->score
);
439 rb
->lcd_putsxy( 75, MARGIN
, "L:");
440 rb
->lcd_putsxyf( 90, MARGIN
, "%d", state
->level
);
442 rb
->lcd_putsxy( 75, MARGIN
, "Level:");
443 rb
->lcd_putsxyf( 113, MARGIN
, "%d", state
->level
);
445 for( i
= 0; i
< BOARD_WIDTH
; ++i
)
447 for( j
= 0; j
< BOARD_HEIGHT
; ++j
)
449 clix_draw_cell( state
, i
, j
);
454 rb
->lcd_set_foreground(LCD_WHITE
);
457 static void clix_move_cursor(struct clix_game_state_t
* state
, const bool left
)
465 while(state
->board
[ XYPOS( x
, y
)] == CC_BLACK
&& y
< BOARD_HEIGHT
) y
++;
466 if (y
< BOARD_HEIGHT
) {
480 if( x
< BOARD_WIDTH
- 1)
486 } while ( y
!= state
->y
);
489 /* returns the color of the given position, if out of bounds return CC_BLACK */
490 static int clix_get_color(struct clix_game_state_t
* state
, const int x
, const int y
)
492 if( x
>= 0 && x
< BOARD_WIDTH
&& y
>= 0 && y
< BOARD_HEIGHT
)
493 return state
->board
[XYPOS( x
, y
)];
498 static int clix_clear_selected(struct clix_game_state_t
* state
)
503 state
->status
= CLIX_CLEARED
;
505 /* clear the selected blocks */
506 for( i
= 0; i
< BOARD_WIDTH
; ++i
)
508 for( j
= 0; j
< BOARD_HEIGHT
; ++j
)
510 if( state
->board_selected
[ XYPOS( i
, j
)] )
512 state
->board_selected
[ XYPOS( i
, j
)] = false;
513 state
->board
[ XYPOS( i
, j
)] = CC_BLACK
;
519 state
->score
+= state
->selected_count
* state
->level
;
520 state
->selected_count
= 0;
522 /* let blocks falling down */
523 for( i
= BOARD_WIDTH
- 1; i
>= 0; --i
)
525 for( j
= BOARD_HEIGHT
- 1; j
>= 0; --j
)
528 while( (y
+ 1) < BOARD_HEIGHT
&&
529 state
->board
[ XYPOS( i
, y
+ 1)] == CC_BLACK
534 state
->board
[ XYPOS( i
, y
)] = state
->board
[ XYPOS( i
, j
)];
535 state
->board
[ XYPOS( i
, j
)] = CC_BLACK
;
540 /* move columns to left side */
541 for( i
= 0; i
< BOARD_WIDTH
; ++i
)
544 while( (x
- 1) >= 0 &&
545 state
->board
[ XYPOS( x
- 1, BOARD_HEIGHT
- 1)] == CC_BLACK
550 for( j
= 0; j
< BOARD_HEIGHT
; ++j
)
552 state
->board
[ XYPOS( x
, j
)] = state
->board
[ XYPOS( i
, j
)];
553 state
->board
[ XYPOS( i
, j
)] = CC_BLACK
;
558 if(state
->board
[ XYPOS( 0, BOARD_HEIGHT
- 1)] != CC_BLACK
)
559 state
->status
= CLIX_CONTINUE
;
561 if (state
->status
!= CLIX_CLEARED
) {
562 /* check if a move is still possible, otherwise the game is over.
563 tart from the left bottom, because there are the last fields
564 at the end of the game.
567 for( i
= 0; !found_move
&& i
< BOARD_WIDTH
; ++i
)
569 for( j
= BOARD_HEIGHT
- 1; !found_move
&& j
>= 0; --j
)
571 int color
= state
->board
[ XYPOS( i
, j
)];
572 if (color
!= CC_BLACK
) {
573 if (color
== clix_get_color( state
, i
- 1, j
) ||
574 color
== clix_get_color( state
, i
+ 1, j
) ||
575 color
== clix_get_color( state
, i
, j
- 1) ||
576 color
== clix_get_color( state
, i
, j
+ 1)
584 /* if the loops ended without a possible move, the game is over */
586 state
->status
= CLIX_GAMEOVER
;
588 /* set cursor to the right position */
589 if (state
->status
== CLIX_CONTINUE
) {
590 clix_move_cursor( state
, true);
591 clix_update_selected( state
);
595 return state
->status
;
598 static bool clix_help(void)
600 static char *help_text
[] = {
601 "Clix", "", "Aim", "",
602 "Remove", "all", "blocks", "from", "the", "board", "to", "achieve",
603 "the", "next", "level.", "You", "can", "only", "remove", "blocks,",
604 "if", "at", "least", "two", "blocks", "with", "the", "same", "color",
605 "have", "a", "direct", "connection.", "The", "more", "blocks", "you",
606 "remove", "per", "turn,", "the", "more", "points", "you", "get."
608 static struct style_text formation
[]={
609 { 0, TEXT_CENTER
|TEXT_UNDERLINE
},
614 rb
->lcd_setfont(FONT_UI
);
615 rb
->lcd_set_foreground(LCD_WHITE
);
616 if (display_text(ARRAYLEN(help_text
), help_text
, formation
, NULL
, true))
618 rb
->lcd_setfont(FONT_SYSFIXED
);
624 static int clix_menu_cb(int action
, const struct menu_item_ex
*this_item
)
626 if(action
== ACTION_REQUEST_MENUITEM
627 && !_ingame
&& ((intptr_t)this_item
)==0)
628 return ACTION_EXIT_MENUITEM
;
632 static int clix_menu(struct clix_game_state_t
* state
, bool ingame
)
634 rb
->button_clear_queue();
636 bool leave_menu
=false;
641 MENUITEM_STRINGLIST (main_menu
, "Clix Menu", clix_menu_cb
,
649 #ifdef HAVE_TOUCHSCREEN
650 /* Entering Menu, set the touchscreen to the global setting */
651 rb
->touchscreen_set_mode(rb
->global_settings
->touch_mode
);
654 while (!leave_menu
) {
656 switch (rb
->do_menu(&main_menu
, &choice
, NULL
, false)) {
673 highscore_show(-1, highscores
, NUM_SCORES
, true);
676 playback_control(NULL
);
679 case MENU_ATTACHED_USB
:
688 #ifdef HAVE_TOUCHSCREEN
689 /* Leaving the menu, set back to pointer mode */
690 rb
->touchscreen_set_mode(TOUCHSCREEN_POINT
);
696 static int clix_click(struct clix_game_state_t
* state
)
699 if (state
->selected_count
<= 1) {
702 switch( clix_clear_selected( state
))
705 state
->score
+= state
->level
* 100;
707 if (state
->level
< NUM_LEVELS
) {
708 rb
->splash(HZ
*2, "Great! Next Level!");
710 clix_init_new_level( state
);
711 clix_update_selected( state
);
714 rb
->splash(HZ
*2, "Congratulation!!!");
715 rb
->splash(HZ
*2, "You have finished the game.");
716 if(clix_menu(state
, 0))
722 rb
->splash(HZ
*2, "Game Over!");
723 rb
->lcd_clear_display();
724 position
= highscore_update(state
->score
, state
->level
, "",
725 highscores
, NUM_SCORES
);
729 rb
->splash(HZ
*2, "New High Score");
730 highscore_show(position
, highscores
, NUM_SCORES
, true);
732 if(clix_menu(state
, 0))
736 rb
->sleep(10); /* prevent repeating clicks */
742 static int clix_handle_game(struct clix_game_state_t
* state
)
745 int blink_tick
= *rb
->current_tick
+ BLINK_TICKCOUNT
;
752 if (clix_menu(state
, 0))
757 if (TIME_AFTER(*rb
->current_tick
, blink_tick
)) {
758 state
->blink
= !state
->blink
;
759 blink_tick
= *rb
->current_tick
+ BLINK_TICKCOUNT
;
762 time
= 6; /* number of ticks this function will loop reading keys */
763 start
= *rb
->current_tick
;
765 while(TIME_BEFORE(*rb
->current_tick
, end
))
770 button
= rb
->button_get_w_tmo(end
- *rb
->current_tick
);
771 #ifdef HAVE_TOUCHSCREEN
772 if(button
& BUTTON_TOUCHSCREEN
)
774 int x
= rb
->button_get_data() >> 16;
775 int y
= rb
->button_get_data() & 0xffff;
784 if(x
< BOARD_WIDTH
&& y
< BOARD_HEIGHT
785 && state
->board
[XYPOS(x
, y
)] != CC_BLACK
)
787 if(state
->x
== x
&& state
->y
== y
)
788 button
= CLIX_BUTTON_CLICK
;
800 #ifndef HAVE_TOUCHSCREEN
801 #ifdef CLIX_BUTTON_SCROLL_BACK
802 case CLIX_BUTTON_SCROLL_BACK
:
803 case CLIX_BUTTON_SCROLL_BACK
|BUTTON_REPEAT
:
806 case CLIX_BUTTON_UP
|BUTTON_REPEAT
:
808 state
->board
[ XYPOS( state
->x
, state
->y
- 1)] ==
811 state
->y
= BOARD_HEIGHT
- 1;
815 clix_move_cursor(state
, true);
818 #ifdef CLIX_BUTTON_SCROLL_FWD
819 case CLIX_BUTTON_SCROLL_FWD
:
820 case CLIX_BUTTON_SCROLL_FWD
|BUTTON_REPEAT
:
822 case CLIX_BUTTON_DOWN
:
823 case CLIX_BUTTON_DOWN
|BUTTON_REPEAT
:
824 if( state
->y
== (BOARD_HEIGHT
- 1))
829 clix_move_cursor( state
, true);
832 case CLIX_BUTTON_RIGHT
:
833 case CLIX_BUTTON_RIGHT
|BUTTON_REPEAT
:
834 if( state
->x
== (BOARD_WIDTH
- 1))
839 clix_move_cursor(state
, false);
842 case CLIX_BUTTON_LEFT
:
843 case CLIX_BUTTON_LEFT
|BUTTON_REPEAT
:
845 state
->x
= BOARD_WIDTH
- 1;
849 clix_move_cursor(state
, true);
852 case CLIX_BUTTON_CLICK
:
853 if (clix_click(state
) == 1)
857 case CLIX_BUTTON_QUIT
:
858 if (clix_menu(state
, 1) != 0) {
859 rb
->button_clear_queue();
868 if( (oldx
!= state
->x
|| oldy
!= state
->y
) &&
869 state
->board_selected
[ XYPOS( oldx
, oldy
)] !=
870 state
->board_selected
[ XYPOS( state
->x
, state
->y
)]
873 clix_update_selected(state
);
881 /* this is the plugin entry point */
882 enum plugin_status
plugin_start(const void* parameter
)
886 rb
->lcd_set_backdrop(NULL
);
887 rb
->lcd_set_foreground(LCD_WHITE
);
888 rb
->lcd_set_background(LCD_BLACK
);
889 rb
->lcd_setfont(FONT_SYSFIXED
);
890 #ifdef HAVE_TOUCHSCREEN
891 rb
->touchscreen_set_mode(TOUCHSCREEN_POINT
);
894 highscore_load(SCORE_FILE
, highscores
, NUM_SCORES
);
896 struct clix_game_state_t state
;
897 clix_handle_game( &state
);
899 highscore_save(SCORE_FILE
, highscores
, NUM_SCORES
);