A modern Music Player Daemon based on Rockbox open source high quality audio player
libadwaita audio rust zig deno mpris rockbox mpd
at master 270 lines 8.0 kB view raw
1/*************************************************************************** 2 * __________ __ ___. 3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___ 4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / 5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < 6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ 7 * \/ \/ \/ \/ \/ 8 * $Id$ 9 * 10 * Copyright (C) 2007 Copyright Kévin Ferrare based on work by Pierre Delore 11 * 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. 16 * 17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 18 * KIND, either express or implied. 19 * 20 ****************************************************************************/ 21 22#include "plugin.h" 23#include "lib/pluginlib_actions.h" 24#include "lib/picture.h" 25#include "lib/pluginlib_exit.h" 26 27 28#if (CONFIG_KEYPAD == IPOD_1G2G_PAD) \ 29 || (CONFIG_KEYPAD == IPOD_3G_PAD) \ 30 || (CONFIG_KEYPAD == IPOD_4G_PAD) 31#define JACKPOT_QUIT PLA_UP 32#else 33#define JACKPOT_QUIT PLA_CANCEL 34#endif 35 36const struct button_mapping* plugin_contexts[]={pla_main_ctx}; 37#define NB_PICTURES 9 38#define NB_SLOTS 3 39 40#define PICTURE_HEIGHT (BMPHEIGHT_jackpot_slots/(NB_PICTURES+1)) 41#if NB_SCREENS==1 42#define PICTURE_ROTATION_STEPS PICTURE_HEIGHT 43#else 44#define REMOTE_PICTURE_HEIGHT (BMPHEIGHT_jackpot_slots_remote/(NB_PICTURES+1)) 45#define PICTURE_ROTATION_STEPS REMOTE_PICTURE_HEIGHT 46#endif 47 48/* FIXME: would be nice to have better graphics ... */ 49#include "pluginbitmaps/jackpot_slots.h" 50#if NB_SCREENS==2 51#include "pluginbitmaps/jackpot_slots_remote.h" 52#endif 53 54const struct picture jackpot_pictures[]={ 55 {jackpot_slots, BMPWIDTH_jackpot_slots, BMPHEIGHT_jackpot_slots, 56 PICTURE_HEIGHT}, 57#if NB_SCREENS==2 58 {jackpot_slots_remote,BMPWIDTH_jackpot_slots_remote, 59 BMPHEIGHT_jackpot_slots_remote, REMOTE_PICTURE_HEIGHT} 60#endif 61}; 62 63#define SLEEP_TIME (HZ/200) 64 65struct jackpot 66{ 67 /* A slot can display "NB_PICTURES" pictures 68 A picture is moving up, it can take PICTURE_ROTATION_STEPS 69 to move a single picture completely. 70 So values in slot_state are comprised between 71 0 and NB_PICTURES*PICTURE_ROTATION_STEPS 72 */ 73 int slot_state[NB_SLOTS]; 74 /* 75 The real state of the picture in pixels on each screen 76 Different from slot_state because of the synchronised 77 rotation between different sized bitmaps on remote and main screen 78 */ 79 int state_y[NB_SCREENS][NB_SLOTS]; 80 int money; 81}; 82 83/*Call when the program exit*/ 84static void jackpot_exit(void) 85{ 86} 87 88static void jackpot_init(struct jackpot* game) 89{ 90 game->money=20; 91 for(int i=0;i<NB_SLOTS;i++){ 92 game->slot_state[i]=(rb->rand()%NB_PICTURES)*PICTURE_ROTATION_STEPS; 93 FOR_NB_SCREENS(j) 94 game->state_y[j][i]=-1; 95 } 96} 97 98static int jackpot_get_result(struct jackpot* game) 99{ 100 int i=NB_SLOTS-1; 101 int multiple=1; 102 int result=0; 103 for(;i>=0;i--) 104 { 105 result+=game->slot_state[i]*multiple/PICTURE_ROTATION_STEPS; 106 multiple*=10; 107 } 108 return(result); 109} 110 111static int jackpot_get_gain(struct jackpot* game) 112{ 113 switch (jackpot_get_result(game)) 114 { 115 case 111 : return(20); 116 case 000 : return(15); 117 case 333 : return(10); 118 case 222 : return(8); 119 case 555 : return(5); 120 case 777 : return(4); 121 case 251 : return(4); 122 case 510 : return(4); 123 case 686 : return(3); 124 case 585 : return(3); 125 case 282 : return(3); 126 case 484 : return(3); 127 case 787 : return(2); 128 case 383 : return(2); 129 case 80 : return(2); 130 } 131 return(0); 132} 133 134static void jackpot_display_slot_machine(struct jackpot* game, struct screen* display) 135{ 136 char str[20]; 137 int i; 138 bool changes=false; 139 const struct picture* picture= &(jackpot_pictures[display->screen_type]); 140 int pos_x=(display->getwidth()-NB_SLOTS*(picture->width+1))/2; 141 int pos_y=(display->getheight()-(picture->slide_height))/2; 142 for(i=0;i<NB_SLOTS;i++) 143 { 144 int state_y= 145 (picture->slide_height*game->slot_state[i])/PICTURE_ROTATION_STEPS; 146 int previous_state_y=game->state_y[display->screen_type][i]; 147 if(state_y==previous_state_y) 148 continue;/*no need to update the picture 149 as it's the same as previous displayed one*/ 150 changes=true; 151 game->state_y[display->screen_type][i]=state_y; 152 vertical_picture_draw_part(display, picture, state_y, pos_x, pos_y); 153 pos_x+=(picture->width+1); 154 } 155 if(changes){ 156 rb->snprintf(str,sizeof(str),"money : $%d", game->money); 157 display->puts(0, 0, str); 158 display->update(); 159 } 160} 161 162 163static void jackpot_info_message(struct screen* display, char* message) 164{ 165 int xpos, ypos; 166 int message_height, message_width; 167 display->getstringsize(message, &message_width, &message_height); 168 xpos=(display->getwidth()-message_width)/2; 169 ypos=display->getheight()-message_height; 170 rb->screen_clear_area(display, 0, ypos, display->getwidth(), 171 message_height); 172 display->putsxy(xpos,ypos,message); 173 display->update(); 174} 175 176static void jackpot_print_turn_result(struct jackpot* game, 177 int gain, struct screen* display) 178{ 179 char str[20]; 180 if (gain==0) 181 { 182 jackpot_info_message(display, "None ..."); 183 if (game->money<=0) 184 jackpot_info_message(display, "You lose...STOP to quit"); 185 } 186 else 187 { 188 rb->snprintf(str,sizeof(str),"You win %d$",gain); 189 jackpot_info_message(display, str); 190 } 191 display->update(); 192} 193 194static void jackpot_play_turn(struct jackpot* game) 195{ 196 /* How many pattern? */ 197 int nb_turns[NB_SLOTS]; 198 int gain,turns_remaining=0; 199 if(game->money<=0) 200 return; 201 game->money--; 202 for(int i=0;i<NB_SLOTS;i++) 203 { 204 nb_turns[i]=(rb->rand()%15+5)*PICTURE_ROTATION_STEPS; 205 turns_remaining+=nb_turns[i]; 206 } 207 FOR_NB_SCREENS(d) 208 { 209 rb->screens[d]->clear_display(); 210 jackpot_info_message(rb->screens[d],"Good luck"); 211 } 212 /* Jackpot Animation */ 213 while(turns_remaining>0) 214 { 215 for(int i=0;i<NB_SLOTS;i++) 216 { 217 if(nb_turns[i]>0) 218 { 219 nb_turns[i]--; 220 game->slot_state[i]++; 221 if(game->slot_state[i]>=PICTURE_ROTATION_STEPS*NB_PICTURES) 222 game->slot_state[i]=0; 223 turns_remaining--; 224 } 225 } 226 FOR_NB_SCREENS(d) 227 jackpot_display_slot_machine(game, rb->screens[d]); 228 rb->sleep(SLEEP_TIME); 229 } 230 gain=jackpot_get_gain(game); 231 if(gain!=0) 232 game->money+=gain; 233 FOR_NB_SCREENS(d) 234 jackpot_print_turn_result(game, gain, rb->screens[d]); 235} 236 237enum plugin_status plugin_start(const void* parameter) 238{ 239 int action; 240 struct jackpot game; 241 (void)parameter; 242 atexit(jackpot_exit); 243 rb->srand(*rb->current_tick); 244 jackpot_init(&game); 245 246 FOR_NB_SCREENS(i){ 247 rb->screens[i]->clear_display(); 248 jackpot_display_slot_machine(&game, rb->screens[i]); 249 } 250 /*Empty the event queue*/ 251 rb->button_clear_queue(); 252 while (true) 253 { 254 action = pluginlib_getaction(TIMEOUT_BLOCK, 255 plugin_contexts, ARRAYLEN(plugin_contexts)); 256 switch ( action ) 257 { 258 case JACKPOT_QUIT: 259 return PLUGIN_OK; 260 case PLA_SELECT: 261 jackpot_play_turn(&game); 262 break; 263 264 default: 265 exit_on_usb(action); 266 break; 267 } 268 } 269 return PLUGIN_OK; 270}