blob: bcb12f1a336a5be98f8d68220fca65013fee7229 [file] [log] [blame]
Daniel Stenberg611e3592003-07-24 09:40:15 +00001/***************************************************************************
Kevin Ferrareac017782007-07-25 09:38:55 +00002 * __________ __ ___.
Daniel Stenberg611e3592003-07-24 09:40:15 +00003 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
Kevin Ferrareac017782007-07-25 09:38:55 +00007 * \/ \/ \/ \/ \/
Daniel Stenberg611e3592003-07-24 09:40:15 +00008 * $Id$
9 *
Kevin Ferrareac017782007-07-25 09:38:55 +000010 * Copyright (C) 2007 Copyright Kévin Ferrare based on work by Pierre Delore
Daniel Stenberg611e3592003-07-24 09:40:15 +000011 *
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
Daniel Stenberg611e3592003-07-24 09:40:15 +000019
Kevin Ferrareac017782007-07-25 09:38:55 +000020#include "plugin.h"
21#include "pluginlib_actions.h"
Daniel Stenberg611e3592003-07-24 09:40:15 +000022
Jens Arnolda36b1d42006-01-15 18:20:18 +000023PLUGIN_HEADER
24
Kevin Ferrareac017782007-07-25 09:38:55 +000025const struct button_mapping* plugin_contexts[]={generic_actions};
26#define NB_PICTURES 9
27#define NB_SLOTS 3
Daniel Stenberg611e3592003-07-24 09:40:15 +000028
Kevin Ferrareac017782007-07-25 09:38:55 +000029#ifdef HAVE_LCD_CHARCELLS
30#define PICTURE_ROTATION_STEPS 7
31static unsigned char jackpot_slots_patterns[]={
32 0x00, 0x0A, 0x1F, 0x1F, 0x1F, 0x0e, 0x04, /* (+00)Heart */
33 0x00, 0x04, 0x0E, 0x1F, 0x1F, 0x04, 0x0E, /* (+07)Spade */
34 0x00, 0x04, 0x0E, 0x1F, 0x0E, 0x04, 0x00, /* (+14)Diamond */
35 0x00, 0x15, 0x0E, 0x1F, 0x0E, 0x15, 0x00, /* (+21)Club */
36 0x03, 0x04, 0x0e, 0x1F, 0x1F, 0x1F, 0x0e, /* (+28)Cherry */
37 0x00, 0x04, 0x04, 0x1F, 0x04, 0x0E, 0x1F, /* (+35)Cross */
38 0x04, 0x0E, 0x15, 0x04, 0x0A, 0x0A, 0x11, /* (+42)Man */
39 0x00, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x00, /* (+49)Square */
Daniel Stenberg611e3592003-07-24 09:40:15 +000040 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* (+56)Empty */
Kevin Ferrareac017782007-07-25 09:38:55 +000041 0x00, 0x0A, 0x1F, 0x1F, 0x1F, 0x0e, 0x04 /* (+63)Heart */
42};
43static unsigned long char_patterns[NB_SLOTS];
44#else /* bitmaps LCDs */
45
46#define PICTURE_HEIGHT (BMPHEIGHT_jackpot_slots/(NB_PICTURES+1))
47#if NB_SCREENS==1
48#define PICTURE_ROTATION_STEPS PICTURE_HEIGHT
49#else
50#define REMOTE_PICTURE_HEIGHT (BMPHEIGHT_jackpot_slots_remote/(NB_PICTURES+1))
51#define PICTURE_ROTATION_STEPS (REMOTE_PICTURE_HEIGHT*PICTURE_HEIGHT)
52#endif
53
54struct jackpot_picture{
Kevin Ferrarea55a4362007-07-25 10:08:51 +000055 const void* data;
Kevin Ferrareac017782007-07-25 09:38:55 +000056 int width;
57 int height;
Daniel Stenberg611e3592003-07-24 09:40:15 +000058};
59
Kevin Ferrareac017782007-07-25 09:38:55 +000060/* FIXME: would be nice to have better graphics ... */
61#include "jackpot_slots.h"
62#if NB_SCREENS==2
63#include "jackpot_slots_remote.h"
64#endif
Daniel Stenberg611e3592003-07-24 09:40:15 +000065
Kevin Ferrareac017782007-07-25 09:38:55 +000066const struct jackpot_picture jackpot_pictures[]={
67 {
68 jackpot_slots,
69 BMPWIDTH_jackpot_slots,
70 PICTURE_HEIGHT
71 },
72#if NB_SCREENS==2
73 {
74 jackpot_slots_remote,
75 BMPWIDTH_jackpot_slots_remote,
76 REMOTE_PICTURE_HEIGHT
77 }
78#endif
79};
80
81#endif /* HAVE_LCD_CHARCELLS */
82
Daniel Stenberg611e3592003-07-24 09:40:15 +000083static struct plugin_api* rb;
84
Kevin Ferrareac017782007-07-25 09:38:55 +000085struct jackpot
Daniel Stenberg611e3592003-07-24 09:40:15 +000086{
Kevin Ferrareac017782007-07-25 09:38:55 +000087 /* A slot can display "NB_PICTURES" pictures
88 A picture is moving up, it can take PICTURE_ROTATION_STEPS
89 to move a single picture completely.
90 So values in slot_state are comprised between
91 0 and NB_PICTURES*PICTURE_ROTATION_STEPS
92 */
93 int slot_state[NB_SLOTS];
94 /*
95 The real state of the picture in pixels on each screen
96 Different from slot_state because of the synchronised
97 rotation between different sized bitmaps on remote and main screen
98 */
99 int state_y[NB_SCREENS][NB_SLOTS];
100 int money;
101};
Daniel Stenberg611e3592003-07-24 09:40:15 +0000102
Kevin Ferrareac017782007-07-25 09:38:55 +0000103#ifdef HAVE_LCD_CHARCELLS
104void patterns_init(struct screen* display)
105{
106 int i;
107 for(i=0;i<NB_SLOTS;i++)
108 char_patterns[i]=display->get_locked_pattern();
Daniel Stenberg611e3592003-07-24 09:40:15 +0000109}
110
Kevin Ferrareac017782007-07-25 09:38:55 +0000111void patterns_deinit(struct screen* display)
112{
113 /* Restore the old pattern */
114 int i;
115 for(i=0;i<NB_SLOTS;i++)
116 display->unlock_pattern(char_patterns[i]);
117}
118#endif /* HAVE_LCD_CHARCELLS */
119
Daniel Stenberg611e3592003-07-24 09:40:15 +0000120/*Call when the program exit*/
Kevin Ferrareac017782007-07-25 09:38:55 +0000121void jackpot_exit(void *parameter)
Daniel Stenberg611e3592003-07-24 09:40:15 +0000122{
Jens Arnold2afdf952004-10-22 00:22:07 +0000123 (void)parameter;
Kevin Ferrareac017782007-07-25 09:38:55 +0000124#ifdef HAVE_LCD_CHARCELLS
125 patterns_deinit(rb->screens[SCREEN_MAIN]);
126#endif /* HAVE_LCD_CHARCELLS */
127}
Daniel Stenberg611e3592003-07-24 09:40:15 +0000128
Kevin Ferrareac017782007-07-25 09:38:55 +0000129void jackpot_init(struct jackpot* game)
130{
131 int i,j;
132 game->money=20;
133 for(i=0;i<NB_SLOTS;i++){
134 game->slot_state[i]=(rb->rand()%NB_PICTURES)*PICTURE_ROTATION_STEPS;
135 FOR_NB_SCREENS(j)
136 game->state_y[j][i]=-1;
137 }
138}
139
140int jackpot_get_result(struct jackpot* game)
141{
142 int i=NB_SLOTS-1;
143 int multiple=1;
144 int result=0;
145 for(;i>=0;i--)
146 {
147 result+=game->slot_state[i]*multiple/PICTURE_ROTATION_STEPS;
148 multiple*=10;
149 }
150 return(result);
151}
152
153int jackpot_get_gain(struct jackpot* game)
154{
155 switch (jackpot_get_result(game))
156 {
157 case 111 : return(20);
158 case 000 : return(15);
159 case 333 : return(10);
160 case 222 : return(8);
161 case 555 : return(5);
162 case 777 : return(4);
163 case 251 : return(4);
164 case 510 : return(4);
165 case 686 : return(3);
166 case 585 : return(3);
167 case 282 : return(3);
168 case 484 : return(3);
169 case 787 : return(2);
170 case 383 : return(2);
171 case 80 : return(2);
172 }
173 return(0);
174}
175
176void jackpot_display_slot_machine(struct jackpot* game, struct screen* display)
177{
178 char str[20];
179 int i;
180 bool changes=false;
181#ifdef HAVE_LCD_CHARCELLS
182 display->putc(0, 0, '[');
183#else
184 const struct jackpot_picture* picture=
185 &(jackpot_pictures[display->screen_type]);
186 int pos_x=(display->width-NB_SLOTS*(picture->width+1))/2;
187 int pos_y=(display->height-(picture->height))/2;
188#endif /* HAVE_LCD_CHARCELLS */
189 for(i=0;i<NB_SLOTS;i++)
190 {
191#ifdef HAVE_LCD_CHARCELLS
192 /* the only charcell lcd is 7 pixel high */
193 int state_y=(game->slot_state[i]*7)/PICTURE_ROTATION_STEPS;
194#else
195 int state_y=
196 (picture->height*game->slot_state[i])/PICTURE_ROTATION_STEPS;
197#endif /* HAVE_LCD_CHARCELLS */
198 int previous_state_y=game->state_y[display->screen_type][i];
199 if(state_y==previous_state_y)
200 continue;/*no need to update the picture
201 as it's the same as previous displayed one*/
202 changes=true;
203 game->state_y[display->screen_type][i]=state_y;
204#ifdef HAVE_LCD_CHARCELLS
205 char* current_pattern=&(jackpot_slots_patterns[state_y]);
206 display->define_pattern(char_patterns[i],
207 current_pattern);
208 display->putc(i+1, 0, char_patterns[i]);
209#else
210 display->bitmap_part(
211 picture->data,
212 /*slice into picture->data */
213 0, state_y,
214 picture->width,
215 /* Position on the screen */
216 pos_x, pos_y, picture->width, picture->height
217 );
218 pos_x+=(picture->width+1);
219#endif
220 }
221 if(changes){
222#ifdef HAVE_LCD_CHARCELLS
223 rb->snprintf(str,sizeof(str),"$%d", game->money);
224 display->putc(++i, 0, ']');
225 display->puts(++i, 0, str);
226#else
227 rb->snprintf(str,sizeof(str),"money : $%d", game->money);
228 display->puts(0, 0, str);
229#endif
230 display->update();
231 }
Daniel Stenberg611e3592003-07-24 09:40:15 +0000232}
233
234
Kevin Ferrareac017782007-07-25 09:38:55 +0000235void jackpot_info_message(struct screen* display, char* message)
236{
237#ifdef HAVE_LCD_CHARCELLS
238 display->puts_scroll(0,1,message);
239#else
240 int xpos, ypos;
241 int message_height, message_width;
242 display->getstringsize(message, &message_width, &message_height);
243 xpos=(display->width-message_width)/2;
244 ypos=display->height-message_height;
245 rb->screen_clear_area(display, 0, ypos, display->width, message_height);
246 display->putsxy(xpos,ypos,message);
247 display->update();
248#endif /* HAVE_LCD_CHARCELLS */
249}
250
251void jackpot_print_turn_result(struct jackpot* game,
252 int gain, struct screen* display)
253{
254 char str[20];
255 if (gain==0)
256 {
257 jackpot_info_message(display, "None ...");
258 if (game->money<=0)
259 jackpot_info_message(display, "You lose...STOP to quit");
260 }
261 else
262 {
263 rb->snprintf(str,sizeof(str),"You win %d$",gain);
264 jackpot_info_message(display, str);
265 }
266 display->update();
267}
268
269void jackpot_play_turn(struct jackpot* game)
270{
271 /* How many pattern? */
272 int nb_turns[NB_SLOTS];
273 int i,d,gain,turns_remaining=0;
274 if(game->money<=0)
275 return;
276 game->money--;
277 for(i=0;i<NB_SLOTS;i++)
278 {
279 nb_turns[i]=(rb->rand()%15+5)*PICTURE_ROTATION_STEPS;
280 turns_remaining+=nb_turns[i];
281 }
282 FOR_NB_SCREENS(d)
283 {
284 rb->screens[d]->clear_display();
285 jackpot_info_message(rb->screens[d],"Good luck");
286 }
287 /* Jackpot Animation */
288 while(turns_remaining>0)
289 {
290 for(i=0;i<NB_SLOTS;i++)
291 {
292 if(nb_turns[i]>0)
293 {
294 nb_turns[i]--;
295 game->slot_state[i]++;
296 if(game->slot_state[i]>=PICTURE_ROTATION_STEPS*NB_PICTURES)
297 game->slot_state[i]=0;
298 turns_remaining--;
299 }
300 }
301 FOR_NB_SCREENS(d)
302 jackpot_display_slot_machine(game, rb->screens[d]);
303 rb->sleep(7*HZ/(24*PICTURE_ROTATION_STEPS));
304 }
305 gain=jackpot_get_gain(game);
306 if(gain!=0)
307 game->money+=gain;
308 FOR_NB_SCREENS(d)
309 jackpot_print_turn_result(game, gain, rb->screens[d]);
310}
311
Daniel Stenberg611e3592003-07-24 09:40:15 +0000312enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
313{
Daniel Stenberg611e3592003-07-24 09:40:15 +0000314 rb = api;
Kevin Ferrareac017782007-07-25 09:38:55 +0000315 int action, i;
316 struct jackpot game;
317 (void)parameter;
Daniel Stenberg611e3592003-07-24 09:40:15 +0000318 rb->srand(*rb->current_tick);
Kevin Ferrareac017782007-07-25 09:38:55 +0000319#ifdef HAVE_LCD_CHARCELLS
320 patterns_init(rb->screens[SCREEN_MAIN]);
321#endif /* HAVE_LCD_CHARCELLS */
322 jackpot_init(&game);
Daniel Stenberg611e3592003-07-24 09:40:15 +0000323
Kevin Ferrareac017782007-07-25 09:38:55 +0000324 FOR_NB_SCREENS(i){
325 rb->screens[i]->clear_display();
326 jackpot_display_slot_machine(&game, rb->screens[i]);
327 }
Daniel Stenberg611e3592003-07-24 09:40:15 +0000328 /*Empty the event queue*/
Jens Arnold3c348df2005-01-26 22:48:25 +0000329 rb->button_clear_queue();
Kevin Ferrareac017782007-07-25 09:38:55 +0000330 while (true)
Daniel Stenberg611e3592003-07-24 09:40:15 +0000331 {
Kevin Ferrareac017782007-07-25 09:38:55 +0000332 action = pluginlib_getaction(rb, TIMEOUT_BLOCK,
333 plugin_contexts, 1);
334 switch ( action )
Daniel Stenberg611e3592003-07-24 09:40:15 +0000335 {
Kevin Ferrareac017782007-07-25 09:38:55 +0000336 case PLA_QUIT:
337 return PLUGIN_OK;
338 case PLA_FIRE:
339 jackpot_play_turn(&game);
340 break;
Daniel Stenberg611e3592003-07-24 09:40:15 +0000341
Kevin Ferrareac017782007-07-25 09:38:55 +0000342 default:
343 if (rb->default_event_handler_ex(action, jackpot_exit, NULL)
344 == SYS_USB_CONNECTED)
345 return PLUGIN_USB_CONNECTED;
346 break;
Daniel Stenberg611e3592003-07-24 09:40:15 +0000347 }
348 }
Jens Arnold2afdf952004-10-22 00:22:07 +0000349 jackpot_exit(NULL);
Daniel Stenberg611e3592003-07-24 09:40:15 +0000350 return PLUGIN_OK;
351}