Prepare new maemo release
[maemo-rb.git] / apps / plugins / jackpot.c
blobb380e85180e945232637931014dd4491fc7e93d1
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2007 Copyright Kévin Ferrare based on work by Pierre Delore
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
22 #include "plugin.h"
23 #include "lib/pluginlib_actions.h"
24 #include "lib/picture.h"
25 #include "lib/pluginlib_exit.h"
29 const struct button_mapping* plugin_contexts[]={pla_main_ctx};
30 #define NB_PICTURES 9
31 #define NB_SLOTS 3
33 #ifdef HAVE_LCD_CHARCELLS
34 #define PICTURE_ROTATION_STEPS 7
35 static unsigned char jackpot_slots_patterns[]={
36 0x00, 0x0A, 0x1F, 0x1F, 0x1F, 0x0e, 0x04, /* (+00)Heart */
37 0x00, 0x04, 0x0E, 0x1F, 0x1F, 0x04, 0x0E, /* (+07)Spade */
38 0x00, 0x04, 0x0E, 0x1F, 0x0E, 0x04, 0x00, /* (+14)Diamond */
39 0x00, 0x15, 0x0E, 0x1F, 0x0E, 0x15, 0x00, /* (+21)Club */
40 0x03, 0x04, 0x0e, 0x1F, 0x1F, 0x1F, 0x0e, /* (+28)Cherry */
41 0x00, 0x04, 0x04, 0x1F, 0x04, 0x0E, 0x1F, /* (+35)Cross */
42 0x04, 0x0E, 0x15, 0x04, 0x0A, 0x0A, 0x11, /* (+42)Man */
43 0x00, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x00, /* (+49)Square */
44 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* (+56)Empty */
45 0x00, 0x0A, 0x1F, 0x1F, 0x1F, 0x0e, 0x04 /* (+63)Heart */
47 static unsigned long char_patterns[NB_SLOTS];
48 #define SLEEP_TIME (HZ/24)
49 #else /* bitmaps LCDs */
51 #define PICTURE_HEIGHT (BMPHEIGHT_jackpot_slots/(NB_PICTURES+1))
52 #if NB_SCREENS==1
53 #define PICTURE_ROTATION_STEPS PICTURE_HEIGHT
54 #else
55 #define REMOTE_PICTURE_HEIGHT (BMPHEIGHT_jackpot_slots_remote/(NB_PICTURES+1))
56 #define PICTURE_ROTATION_STEPS REMOTE_PICTURE_HEIGHT
57 #endif
59 /* FIXME: would be nice to have better graphics ... */
60 #include "pluginbitmaps/jackpot_slots.h"
61 #if NB_SCREENS==2
62 #include "pluginbitmaps/jackpot_slots_remote.h"
63 #endif
65 const struct picture jackpot_pictures[]={
66 {jackpot_slots, BMPWIDTH_jackpot_slots, BMPHEIGHT_jackpot_slots,
67 PICTURE_HEIGHT},
68 #if NB_SCREENS==2
69 {jackpot_slots_remote,BMPWIDTH_jackpot_slots_remote,
70 BMPHEIGHT_jackpot_slots_remote, REMOTE_PICTURE_HEIGHT}
71 #endif
74 #define SLEEP_TIME (HZ/200)
75 #endif /* HAVE_LCD_CHARCELLS */
77 struct jackpot
79 /* A slot can display "NB_PICTURES" pictures
80 A picture is moving up, it can take PICTURE_ROTATION_STEPS
81 to move a single picture completely.
82 So values in slot_state are comprised between
83 0 and NB_PICTURES*PICTURE_ROTATION_STEPS
85 int slot_state[NB_SLOTS];
87 The real state of the picture in pixels on each screen
88 Different from slot_state because of the synchronised
89 rotation between different sized bitmaps on remote and main screen
91 int state_y[NB_SCREENS][NB_SLOTS];
92 int money;
95 #ifdef HAVE_LCD_CHARCELLS
96 static void patterns_init(struct screen* display)
98 int i;
99 for(i=0;i<NB_SLOTS;i++)
100 char_patterns[i]=display->get_locked_pattern();
103 static void patterns_deinit(struct screen* display)
105 /* Restore the old pattern */
106 int i;
107 for(i=0;i<NB_SLOTS;i++)
108 display->unlock_pattern(char_patterns[i]);
110 #endif /* HAVE_LCD_CHARCELLS */
112 /*Call when the program exit*/
113 static void jackpot_exit(void)
115 #ifdef HAVE_LCD_CHARCELLS
116 patterns_deinit(rb->screens[SCREEN_MAIN]);
117 #endif /* HAVE_LCD_CHARCELLS */
120 static void jackpot_init(struct jackpot* game)
122 game->money=20;
123 for(int i=0;i<NB_SLOTS;i++){
124 game->slot_state[i]=(rb->rand()%NB_PICTURES)*PICTURE_ROTATION_STEPS;
125 FOR_NB_SCREENS(j)
126 game->state_y[j][i]=-1;
130 static int jackpot_get_result(struct jackpot* game)
132 int i=NB_SLOTS-1;
133 int multiple=1;
134 int result=0;
135 for(;i>=0;i--)
137 result+=game->slot_state[i]*multiple/PICTURE_ROTATION_STEPS;
138 multiple*=10;
140 return(result);
143 static int jackpot_get_gain(struct jackpot* game)
145 switch (jackpot_get_result(game))
147 case 111 : return(20);
148 case 000 : return(15);
149 case 333 : return(10);
150 case 222 : return(8);
151 case 555 : return(5);
152 case 777 : return(4);
153 case 251 : return(4);
154 case 510 : return(4);
155 case 686 : return(3);
156 case 585 : return(3);
157 case 282 : return(3);
158 case 484 : return(3);
159 case 787 : return(2);
160 case 383 : return(2);
161 case 80 : return(2);
163 return(0);
166 static void jackpot_display_slot_machine(struct jackpot* game, struct screen* display)
168 char str[20];
169 int i;
170 bool changes=false;
171 #ifdef HAVE_LCD_CHARCELLS
172 display->putchar(0, 0, '[');
173 #else
174 const struct picture* picture= &(jackpot_pictures[display->screen_type]);
175 int pos_x=(display->getwidth()-NB_SLOTS*(picture->width+1))/2;
176 int pos_y=(display->getheight()-(picture->slide_height))/2;
177 #endif /* HAVE_LCD_CHARCELLS */
178 for(i=0;i<NB_SLOTS;i++)
180 #ifdef HAVE_LCD_CHARCELLS
181 /* the only charcell lcd is 7 pixel high */
182 int state_y=(game->slot_state[i]*7)/PICTURE_ROTATION_STEPS;
183 #else
184 int state_y=
185 (picture->slide_height*game->slot_state[i])/PICTURE_ROTATION_STEPS;
186 #endif /* HAVE_LCD_CHARCELLS */
187 int previous_state_y=game->state_y[display->screen_type][i];
188 if(state_y==previous_state_y)
189 continue;/*no need to update the picture
190 as it's the same as previous displayed one*/
191 changes=true;
192 game->state_y[display->screen_type][i]=state_y;
193 #ifdef HAVE_LCD_CHARCELLS
194 char* current_pattern=&(jackpot_slots_patterns[state_y]);
195 display->define_pattern(char_patterns[i],
196 current_pattern);
197 display->putchar(i+1, 0, char_patterns[i]);
198 #else
199 vertical_picture_draw_part(display, picture, state_y, pos_x, pos_y);
200 pos_x+=(picture->width+1);
201 #endif
203 if(changes){
204 #ifdef HAVE_LCD_CHARCELLS
205 rb->snprintf(str,sizeof(str),"$%d", game->money);
206 display->putchar(++i, 0, ']');
207 display->puts(++i, 0, str);
208 #else
209 rb->snprintf(str,sizeof(str),"money : $%d", game->money);
210 display->puts(0, 0, str);
211 #endif
212 display->update();
217 static void jackpot_info_message(struct screen* display, char* message)
219 #ifdef HAVE_LCD_CHARCELLS
220 display->puts_scroll(0,1,message);
221 #else
222 int xpos, ypos;
223 int message_height, message_width;
224 display->getstringsize(message, &message_width, &message_height);
225 xpos=(display->getwidth()-message_width)/2;
226 ypos=display->getheight()-message_height;
227 rb->screen_clear_area(display, 0, ypos, display->getwidth(),
228 message_height);
229 display->putsxy(xpos,ypos,message);
230 display->update();
231 #endif /* HAVE_LCD_CHARCELLS */
234 static void jackpot_print_turn_result(struct jackpot* game,
235 int gain, struct screen* display)
237 char str[20];
238 if (gain==0)
240 jackpot_info_message(display, "None ...");
241 if (game->money<=0)
242 jackpot_info_message(display, "You lose...STOP to quit");
244 else
246 rb->snprintf(str,sizeof(str),"You win %d$",gain);
247 jackpot_info_message(display, str);
249 display->update();
252 static void jackpot_play_turn(struct jackpot* game)
254 /* How many pattern? */
255 int nb_turns[NB_SLOTS];
256 int gain,turns_remaining=0;
257 if(game->money<=0)
258 return;
259 game->money--;
260 for(int i=0;i<NB_SLOTS;i++)
262 nb_turns[i]=(rb->rand()%15+5)*PICTURE_ROTATION_STEPS;
263 turns_remaining+=nb_turns[i];
265 FOR_NB_SCREENS(d)
267 rb->screens[d]->clear_display();
268 jackpot_info_message(rb->screens[d],"Good luck");
270 /* Jackpot Animation */
271 while(turns_remaining>0)
273 for(int i=0;i<NB_SLOTS;i++)
275 if(nb_turns[i]>0)
277 nb_turns[i]--;
278 game->slot_state[i]++;
279 if(game->slot_state[i]>=PICTURE_ROTATION_STEPS*NB_PICTURES)
280 game->slot_state[i]=0;
281 turns_remaining--;
284 FOR_NB_SCREENS(d)
285 jackpot_display_slot_machine(game, rb->screens[d]);
286 rb->sleep(SLEEP_TIME);
288 gain=jackpot_get_gain(game);
289 if(gain!=0)
290 game->money+=gain;
291 FOR_NB_SCREENS(d)
292 jackpot_print_turn_result(game, gain, rb->screens[d]);
295 enum plugin_status plugin_start(const void* parameter)
297 int action;
298 struct jackpot game;
299 (void)parameter;
300 atexit(jackpot_exit);
301 rb->srand(*rb->current_tick);
302 #ifdef HAVE_LCD_CHARCELLS
303 patterns_init(rb->screens[SCREEN_MAIN]);
304 #endif /* HAVE_LCD_CHARCELLS */
305 jackpot_init(&game);
307 FOR_NB_SCREENS(i){
308 rb->screens[i]->clear_display();
309 jackpot_display_slot_machine(&game, rb->screens[i]);
311 /*Empty the event queue*/
312 rb->button_clear_queue();
313 while (true)
315 action = pluginlib_getaction(TIMEOUT_BLOCK,
316 plugin_contexts, ARRAYLEN(plugin_contexts));
317 switch ( action )
319 case PLA_CANCEL:
320 return PLUGIN_OK;
321 case PLA_SELECT:
322 jackpot_play_turn(&game);
323 break;
325 default:
326 exit_on_usb(action);
327 break;
330 return PLUGIN_OK;