A modern Music Player Daemon based on Rockbox open source high quality audio player
libadwaita
audio
rust
zig
deno
mpris
rockbox
mpd
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}