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 SCORE_FILE PLUGIN_GAMES_DIR "/clix.score"
189 struct highscore highscores
[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
);
438 rb
->lcd_set_foreground(LCD_WHITE
);
441 static void clix_move_cursor(struct clix_game_state_t
* state
, const bool left
)
449 while(state
->board
[ XYPOS( x
, y
)] == CC_BLACK
&& y
< BOARD_HEIGHT
) y
++;
450 if (y
< BOARD_HEIGHT
) {
464 if( x
< BOARD_WIDTH
- 1)
470 } 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
)
487 state
->status
= CLIX_CLEARED
;
489 /* clear the selected blocks */
490 for( i
= 0; i
< BOARD_WIDTH
; ++i
)
492 for( j
= 0; j
< BOARD_HEIGHT
; ++j
)
494 if( state
->board_selected
[ XYPOS( i
, j
)] )
496 state
->board_selected
[ XYPOS( i
, j
)] = false;
497 state
->board
[ XYPOS( i
, j
)] = CC_BLACK
;
503 state
->score
+= state
->selected_count
* state
->level
;
504 state
->selected_count
= 0;
506 /* let blocks falling down */
507 for( i
= BOARD_WIDTH
- 1; i
>= 0; --i
)
509 for( j
= BOARD_HEIGHT
- 1; j
>= 0; --j
)
512 while( (y
+ 1) < BOARD_HEIGHT
&&
513 state
->board
[ XYPOS( i
, y
+ 1)] == CC_BLACK
518 state
->board
[ XYPOS( i
, y
)] = state
->board
[ XYPOS( i
, j
)];
519 state
->board
[ XYPOS( i
, j
)] = CC_BLACK
;
524 /* move columns to left side */
525 for( i
= 0; i
< BOARD_WIDTH
; ++i
)
528 while( (x
- 1) >= 0 &&
529 state
->board
[ XYPOS( x
- 1, BOARD_HEIGHT
- 1)] == CC_BLACK
534 for( j
= 0; j
< BOARD_HEIGHT
; ++j
)
536 state
->board
[ XYPOS( x
, j
)] = state
->board
[ XYPOS( i
, j
)];
537 state
->board
[ XYPOS( i
, j
)] = CC_BLACK
;
542 if(state
->board
[ XYPOS( 0, BOARD_HEIGHT
- 1)] != CC_BLACK
)
543 state
->status
= CLIX_CONTINUE
;
545 if (state
->status
!= CLIX_CLEARED
) {
546 /* check if a move is still possible, otherwise the game is over.
547 tart from the left bottom, because there are the last fields
548 at the end of the game.
551 for( i
= 0; !found_move
&& i
< BOARD_WIDTH
; ++i
)
553 for( j
= BOARD_HEIGHT
- 1; !found_move
&& j
>= 0; --j
)
555 int color
= state
->board
[ XYPOS( i
, j
)];
556 if (color
!= CC_BLACK
) {
557 if (color
== clix_get_color( state
, i
- 1, j
) ||
558 color
== clix_get_color( state
, i
+ 1, j
) ||
559 color
== clix_get_color( state
, i
, j
- 1) ||
560 color
== clix_get_color( state
, i
, j
+ 1)
568 /* if the loops ended without a possible move, the game is over */
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 static char *help_text
[] = {
585 "Clix", "", "Aim", "",
586 "Remove", "all", "blocks", "from", "the", "board", "to", "achieve",
587 "the", "next", "level.", "You", "can", "only", "remove", "blocks,",
588 "if", "at", "least", "two", "blocks", "with", "the", "same", "color",
589 "have", "a", "direct", "connection.", "The", "more", "blocks", "you",
590 "remove", "per", "turn,", "the", "more", "points", "you", "get."
592 static struct style_text formation
[]={
593 { 0, TEXT_CENTER
|TEXT_UNDERLINE
},
598 rb
->lcd_setfont(FONT_UI
);
599 rb
->lcd_set_foreground(LCD_WHITE
);
600 if (display_text(ARRAYLEN(help_text
), help_text
, formation
, NULL
, true))
602 rb
->lcd_setfont(FONT_SYSFIXED
);
608 static int clix_menu_cb(int action
, const struct menu_item_ex
*this_item
)
610 if(action
== ACTION_REQUEST_MENUITEM
611 && !_ingame
&& ((intptr_t)this_item
)==0)
612 return ACTION_EXIT_MENUITEM
;
616 static int clix_menu(struct clix_game_state_t
* state
, bool ingame
)
618 rb
->button_clear_queue();
620 bool leave_menu
=false;
625 MENUITEM_STRINGLIST (main_menu
, "Clix Menu", clix_menu_cb
,
633 #ifdef HAVE_TOUCHSCREEN
634 /* Entering Menu, set the touchscreen to the global setting */
635 rb
->touchscreen_set_mode(rb
->global_settings
->touch_mode
);
638 while (!leave_menu
) {
640 switch (rb
->do_menu(&main_menu
, &choice
, NULL
, false)) {
657 highscore_show(-1, highscores
, NUM_SCORES
, true);
660 playback_control(NULL
);
663 case MENU_ATTACHED_USB
:
672 #ifdef HAVE_TOUCHSCREEN
673 /* Leaving the menu, set back to pointer mode */
674 rb
->touchscreen_set_mode(TOUCHSCREEN_POINT
);
680 static int clix_click(struct clix_game_state_t
* state
)
683 if (state
->selected_count
<= 1) {
686 switch( clix_clear_selected( state
))
689 state
->score
+= state
->level
* 100;
691 if (state
->level
< NUM_LEVELS
) {
692 rb
->splash(HZ
*2, "Great! Next Level!");
694 clix_init_new_level( state
);
695 clix_update_selected( state
);
698 rb
->splash(HZ
*2, "Congratulation!!!");
699 rb
->splash(HZ
*2, "You have finished the game.");
700 if(clix_menu(state
, 0))
706 rb
->splash(HZ
*2, "Game Over!");
707 rb
->lcd_clear_display();
708 position
= highscore_update(state
->score
, state
->level
, "",
709 highscores
, NUM_SCORES
);
713 rb
->splash(HZ
*2, "New High Score");
714 highscore_show(position
, highscores
, NUM_SCORES
, true);
716 if(clix_menu(state
, 0))
720 rb
->sleep(10); /* prevent repeating clicks */
726 static int clix_handle_game(struct clix_game_state_t
* state
)
729 int blink_tick
= *rb
->current_tick
+ BLINK_TICKCOUNT
;
736 if (clix_menu(state
, 0))
741 if (TIME_AFTER(*rb
->current_tick
, blink_tick
)) {
742 state
->blink
= !state
->blink
;
743 blink_tick
= *rb
->current_tick
+ BLINK_TICKCOUNT
;
746 time
= 6; /* number of ticks this function will loop reading keys */
747 start
= *rb
->current_tick
;
749 while(TIME_BEFORE(*rb
->current_tick
, end
))
754 button
= rb
->button_get_w_tmo(end
- *rb
->current_tick
);
755 #ifdef HAVE_TOUCHSCREEN
756 if(button
& BUTTON_TOUCHSCREEN
)
758 int x
= rb
->button_get_data() >> 16;
759 int y
= rb
->button_get_data() & 0xffff;
768 if(x
< BOARD_WIDTH
&& y
< BOARD_HEIGHT
769 && state
->board
[XYPOS(x
, y
)] != CC_BLACK
)
771 if(state
->x
== x
&& state
->y
== y
)
772 button
= CLIX_BUTTON_CLICK
;
784 #ifndef HAVE_TOUCHSCREEN
785 #ifdef CLIX_BUTTON_SCROLL_BACK
786 case CLIX_BUTTON_SCROLL_BACK
:
787 case CLIX_BUTTON_SCROLL_BACK
|BUTTON_REPEAT
:
790 case CLIX_BUTTON_UP
|BUTTON_REPEAT
:
792 state
->board
[ XYPOS( state
->x
, state
->y
- 1)] ==
795 state
->y
= BOARD_HEIGHT
- 1;
799 clix_move_cursor(state
, true);
802 #ifdef CLIX_BUTTON_SCROLL_FWD
803 case CLIX_BUTTON_SCROLL_FWD
:
804 case CLIX_BUTTON_SCROLL_FWD
|BUTTON_REPEAT
:
806 case CLIX_BUTTON_DOWN
:
807 case CLIX_BUTTON_DOWN
|BUTTON_REPEAT
:
808 if( state
->y
== (BOARD_HEIGHT
- 1))
813 clix_move_cursor( state
, true);
816 case CLIX_BUTTON_RIGHT
:
817 case CLIX_BUTTON_RIGHT
|BUTTON_REPEAT
:
818 if( state
->x
== (BOARD_WIDTH
- 1))
823 clix_move_cursor(state
, false);
826 case CLIX_BUTTON_LEFT
:
827 case CLIX_BUTTON_LEFT
|BUTTON_REPEAT
:
829 state
->x
= BOARD_WIDTH
- 1;
833 clix_move_cursor(state
, true);
836 case CLIX_BUTTON_CLICK
:
837 if (clix_click(state
) == 1)
841 case CLIX_BUTTON_QUIT
:
842 if (clix_menu(state
, 1) != 0) {
843 rb
->button_clear_queue();
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(SCORE_FILE
, highscores
, NUM_SCORES
);
880 struct clix_game_state_t state
;
881 clix_handle_game( &state
);
883 highscore_save(SCORE_FILE
, highscores
, NUM_SCORES
);