Daniel Stenberg | 611e359 | 2003-07-24 09:40:15 +0000 | [diff] [blame] | 1 | /*************************************************************************** |
Kevin Ferrare | ac01778 | 2007-07-25 09:38:55 +0000 | [diff] [blame] | 2 | * __________ __ ___. |
Daniel Stenberg | 611e359 | 2003-07-24 09:40:15 +0000 | [diff] [blame] | 3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ |
| 4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / |
| 5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < |
| 6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ |
Kevin Ferrare | ac01778 | 2007-07-25 09:38:55 +0000 | [diff] [blame] | 7 | * \/ \/ \/ \/ \/ |
Daniel Stenberg | 611e359 | 2003-07-24 09:40:15 +0000 | [diff] [blame] | 8 | * $Id$ |
| 9 | * |
Kevin Ferrare | ac01778 | 2007-07-25 09:38:55 +0000 | [diff] [blame] | 10 | * Copyright (C) 2007 Copyright Kévin Ferrare based on work by Pierre Delore |
Daniel Stenberg | 611e359 | 2003-07-24 09:40:15 +0000 | [diff] [blame] | 11 | * |
| 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 Stenberg | 611e359 | 2003-07-24 09:40:15 +0000 | [diff] [blame] | 19 | |
Kevin Ferrare | ac01778 | 2007-07-25 09:38:55 +0000 | [diff] [blame] | 20 | #include "plugin.h" |
| 21 | #include "pluginlib_actions.h" |
Daniel Stenberg | 611e359 | 2003-07-24 09:40:15 +0000 | [diff] [blame] | 22 | |
Jens Arnold | a36b1d4 | 2006-01-15 18:20:18 +0000 | [diff] [blame] | 23 | PLUGIN_HEADER |
| 24 | |
Kevin Ferrare | ac01778 | 2007-07-25 09:38:55 +0000 | [diff] [blame] | 25 | const struct button_mapping* plugin_contexts[]={generic_actions}; |
| 26 | #define NB_PICTURES 9 |
| 27 | #define NB_SLOTS 3 |
Daniel Stenberg | 611e359 | 2003-07-24 09:40:15 +0000 | [diff] [blame] | 28 | |
Kevin Ferrare | ac01778 | 2007-07-25 09:38:55 +0000 | [diff] [blame] | 29 | #ifdef HAVE_LCD_CHARCELLS |
| 30 | #define PICTURE_ROTATION_STEPS 7 |
| 31 | static 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 Stenberg | 611e359 | 2003-07-24 09:40:15 +0000 | [diff] [blame] | 40 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* (+56)Empty */ |
Kevin Ferrare | ac01778 | 2007-07-25 09:38:55 +0000 | [diff] [blame] | 41 | 0x00, 0x0A, 0x1F, 0x1F, 0x1F, 0x0e, 0x04 /* (+63)Heart */ |
| 42 | }; |
| 43 | static 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 | |
| 54 | struct jackpot_picture{ |
Kevin Ferrare | a55a436 | 2007-07-25 10:08:51 +0000 | [diff] [blame] | 55 | const void* data; |
Kevin Ferrare | ac01778 | 2007-07-25 09:38:55 +0000 | [diff] [blame] | 56 | int width; |
| 57 | int height; |
Daniel Stenberg | 611e359 | 2003-07-24 09:40:15 +0000 | [diff] [blame] | 58 | }; |
| 59 | |
Kevin Ferrare | ac01778 | 2007-07-25 09:38:55 +0000 | [diff] [blame] | 60 | /* 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 Stenberg | 611e359 | 2003-07-24 09:40:15 +0000 | [diff] [blame] | 65 | |
Kevin Ferrare | ac01778 | 2007-07-25 09:38:55 +0000 | [diff] [blame] | 66 | const 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 Stenberg | 611e359 | 2003-07-24 09:40:15 +0000 | [diff] [blame] | 83 | static struct plugin_api* rb; |
| 84 | |
Kevin Ferrare | ac01778 | 2007-07-25 09:38:55 +0000 | [diff] [blame] | 85 | struct jackpot |
Daniel Stenberg | 611e359 | 2003-07-24 09:40:15 +0000 | [diff] [blame] | 86 | { |
Kevin Ferrare | ac01778 | 2007-07-25 09:38:55 +0000 | [diff] [blame] | 87 | /* 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 Stenberg | 611e359 | 2003-07-24 09:40:15 +0000 | [diff] [blame] | 102 | |
Kevin Ferrare | ac01778 | 2007-07-25 09:38:55 +0000 | [diff] [blame] | 103 | #ifdef HAVE_LCD_CHARCELLS |
| 104 | void 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 Stenberg | 611e359 | 2003-07-24 09:40:15 +0000 | [diff] [blame] | 109 | } |
| 110 | |
Kevin Ferrare | ac01778 | 2007-07-25 09:38:55 +0000 | [diff] [blame] | 111 | void 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 Stenberg | 611e359 | 2003-07-24 09:40:15 +0000 | [diff] [blame] | 120 | /*Call when the program exit*/ |
Kevin Ferrare | ac01778 | 2007-07-25 09:38:55 +0000 | [diff] [blame] | 121 | void jackpot_exit(void *parameter) |
Daniel Stenberg | 611e359 | 2003-07-24 09:40:15 +0000 | [diff] [blame] | 122 | { |
Jens Arnold | 2afdf95 | 2004-10-22 00:22:07 +0000 | [diff] [blame] | 123 | (void)parameter; |
Kevin Ferrare | ac01778 | 2007-07-25 09:38:55 +0000 | [diff] [blame] | 124 | #ifdef HAVE_LCD_CHARCELLS |
| 125 | patterns_deinit(rb->screens[SCREEN_MAIN]); |
| 126 | #endif /* HAVE_LCD_CHARCELLS */ |
| 127 | } |
Daniel Stenberg | 611e359 | 2003-07-24 09:40:15 +0000 | [diff] [blame] | 128 | |
Kevin Ferrare | ac01778 | 2007-07-25 09:38:55 +0000 | [diff] [blame] | 129 | void 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 | |
| 140 | int 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 | |
| 153 | int 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 | |
| 176 | void 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 Stenberg | 611e359 | 2003-07-24 09:40:15 +0000 | [diff] [blame] | 232 | } |
| 233 | |
| 234 | |
Kevin Ferrare | ac01778 | 2007-07-25 09:38:55 +0000 | [diff] [blame] | 235 | void 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 | |
| 251 | void 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 | |
| 269 | void 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 Stenberg | 611e359 | 2003-07-24 09:40:15 +0000 | [diff] [blame] | 312 | enum plugin_status plugin_start(struct plugin_api* api, void* parameter) |
| 313 | { |
Daniel Stenberg | 611e359 | 2003-07-24 09:40:15 +0000 | [diff] [blame] | 314 | rb = api; |
Kevin Ferrare | ac01778 | 2007-07-25 09:38:55 +0000 | [diff] [blame] | 315 | int action, i; |
| 316 | struct jackpot game; |
| 317 | (void)parameter; |
Daniel Stenberg | 611e359 | 2003-07-24 09:40:15 +0000 | [diff] [blame] | 318 | rb->srand(*rb->current_tick); |
Kevin Ferrare | ac01778 | 2007-07-25 09:38:55 +0000 | [diff] [blame] | 319 | #ifdef HAVE_LCD_CHARCELLS |
| 320 | patterns_init(rb->screens[SCREEN_MAIN]); |
| 321 | #endif /* HAVE_LCD_CHARCELLS */ |
| 322 | jackpot_init(&game); |
Daniel Stenberg | 611e359 | 2003-07-24 09:40:15 +0000 | [diff] [blame] | 323 | |
Kevin Ferrare | ac01778 | 2007-07-25 09:38:55 +0000 | [diff] [blame] | 324 | FOR_NB_SCREENS(i){ |
| 325 | rb->screens[i]->clear_display(); |
| 326 | jackpot_display_slot_machine(&game, rb->screens[i]); |
| 327 | } |
Daniel Stenberg | 611e359 | 2003-07-24 09:40:15 +0000 | [diff] [blame] | 328 | /*Empty the event queue*/ |
Jens Arnold | 3c348df | 2005-01-26 22:48:25 +0000 | [diff] [blame] | 329 | rb->button_clear_queue(); |
Kevin Ferrare | ac01778 | 2007-07-25 09:38:55 +0000 | [diff] [blame] | 330 | while (true) |
Daniel Stenberg | 611e359 | 2003-07-24 09:40:15 +0000 | [diff] [blame] | 331 | { |
Kevin Ferrare | ac01778 | 2007-07-25 09:38:55 +0000 | [diff] [blame] | 332 | action = pluginlib_getaction(rb, TIMEOUT_BLOCK, |
| 333 | plugin_contexts, 1); |
| 334 | switch ( action ) |
Daniel Stenberg | 611e359 | 2003-07-24 09:40:15 +0000 | [diff] [blame] | 335 | { |
Kevin Ferrare | ac01778 | 2007-07-25 09:38:55 +0000 | [diff] [blame] | 336 | case PLA_QUIT: |
| 337 | return PLUGIN_OK; |
| 338 | case PLA_FIRE: |
| 339 | jackpot_play_turn(&game); |
| 340 | break; |
Daniel Stenberg | 611e359 | 2003-07-24 09:40:15 +0000 | [diff] [blame] | 341 | |
Kevin Ferrare | ac01778 | 2007-07-25 09:38:55 +0000 | [diff] [blame] | 342 | default: |
| 343 | if (rb->default_event_handler_ex(action, jackpot_exit, NULL) |
| 344 | == SYS_USB_CONNECTED) |
| 345 | return PLUGIN_USB_CONNECTED; |
| 346 | break; |
Daniel Stenberg | 611e359 | 2003-07-24 09:40:15 +0000 | [diff] [blame] | 347 | } |
| 348 | } |
Jens Arnold | 2afdf95 | 2004-10-22 00:22:07 +0000 | [diff] [blame] | 349 | jackpot_exit(NULL); |
Daniel Stenberg | 611e359 | 2003-07-24 09:40:15 +0000 | [diff] [blame] | 350 | return PLUGIN_OK; |
| 351 | } |