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) 2005 by Brandon Low
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/configfile.h"
25#include "lib/playback_control.h"
26
27#define MAX_DICES 12
28#define INITIAL_NB_DICES 1
29#define INITIAL_NB_SIDES 2 /* corresponds to 6 sides in the array */
30
31
32#if (CONFIG_KEYPAD == IPOD_1G2G_PAD) \
33 || (CONFIG_KEYPAD == IPOD_3G_PAD) \
34 || (CONFIG_KEYPAD == IPOD_4G_PAD)
35#define DICE_QUIT PLA_UP
36#else
37#define DICE_QUIT PLA_CANCEL
38#endif
39#define DICE_ROLL PLA_SELECT
40
41
42#define CFG_FILE "dice.cfg"
43
44const struct button_mapping* plugin_contexts[]={pla_main_ctx};
45
46struct dices
47{
48 int values[MAX_DICES];
49 int total;
50 int nb_dices;
51 int nb_sides;
52};
53
54#define PRINT_BUFFER_LENGTH MAX_DICES*4
55
56
57static struct dices dice;
58static int sides_index;
59
60static struct opt_items nb_sides_option[8] = {
61 { "3", TALK_ID(3, UNIT_INT) },
62 { "4", TALK_ID(4, UNIT_INT) },
63 { "6", TALK_ID(6, UNIT_INT) },
64 { "8", TALK_ID(8, UNIT_INT) },
65 { "10", TALK_ID(10, UNIT_INT) },
66 { "12", TALK_ID(12, UNIT_INT) },
67 { "20", TALK_ID(20, UNIT_INT) },
68 { "100", TALK_ID(100, UNIT_INT) }
69};
70static int nb_sides_values[] = { 3, 4, 6, 8, 10, 12, 20, 100 };
71static char *sides_conf[] = {"3", "4", "6", "8", "10", "12", "20", "100" };
72static struct configdata config[] =
73{
74 {TYPE_INT, 0, MAX_DICES, { .int_p = &dice.nb_dices}, "dice count", NULL},
75 {TYPE_ENUM, 0, 8, { .int_p = &sides_index }, "side count", sides_conf}
76};
77
78static void dice_init(struct dices* dice);
79static void dice_roll(struct dices* dice);
80static void dice_print(struct dices* dice, struct screen* display);
81static bool dice_menu(struct dices* dice);
82
83/* plugin entry point */
84enum plugin_status plugin_start(const void* parameter) {
85 (void)parameter;
86 int action;
87
88 dice_init(&dice);
89 rb->srand(*rb->current_tick);
90
91 configfile_load(CFG_FILE, config, 2, 0);
92 dice.nb_sides = nb_sides_values[sides_index];
93 if(!dice_menu(&dice))
94 {
95 configfile_save(CFG_FILE, config, 2, 0);
96 return PLUGIN_OK;
97 }
98 configfile_save(CFG_FILE, config, 2, 0);
99 dice_roll(&dice);
100 FOR_NB_SCREENS(i)
101 dice_print( &dice, rb->screens[i] );
102 while(true) {
103 action = pluginlib_getaction(TIMEOUT_BLOCK,
104 plugin_contexts, ARRAYLEN(plugin_contexts));
105 switch(action) {
106 case DICE_ROLL:
107 dice_roll(&dice);
108 FOR_NB_SCREENS(i)
109 dice_print( &dice, rb->screens[i] );
110 break;
111 case DICE_QUIT:
112 return PLUGIN_OK;
113 }
114 }
115}
116
117static void dice_init(struct dices* dice){
118 dice->nb_dices=INITIAL_NB_DICES;
119 sides_index=INITIAL_NB_SIDES;
120
121}
122
123static void dice_roll(struct dices* dice) {
124 int i;
125 dice->total = 0;
126 for (i=0; i<dice->nb_dices; i++) {
127 dice->values[i] = rb->rand()%dice->nb_sides + 1;
128 dice->total+=dice->values[i];
129 }
130}
131
132static void dice_print_string_buffer(struct dices* dice, char* buffer,
133 int start, int end){
134 int i, written;
135 for (i=start; i<end; i++) {
136 written=rb->snprintf(buffer, PRINT_BUFFER_LENGTH,
137 " %3d", dice->values[i]);
138 buffer=&(buffer[written]);
139 }
140}
141
142static void dice_print(struct dices* dice, struct screen* display){
143 char buffer[PRINT_BUFFER_LENGTH];
144 /* display characteristics */
145 int char_height, char_width;
146 display->getstringsize("M", &char_width, &char_height);
147 int display_nb_row=display->getheight()/char_height;
148 int display_nb_col=display->getwidth()/char_width;
149
150 int nb_dices_per_line=display_nb_col/4;/* 4 char per dice displayed*/
151 if(!nb_dices_per_line)
152 nb_dices_per_line++;
153
154 int nb_lines_required=dice->nb_dices/nb_dices_per_line;
155 int current_row=0;
156 if(dice->nb_dices%nb_dices_per_line!=0)
157 nb_lines_required++;
158 display->clear_display();
159 if(display_nb_row<nb_lines_required){
160 /* Put everything on the same scrolling line */
161 dice_print_string_buffer(dice, buffer, 0, dice->nb_dices);
162 display->puts_scroll(0, current_row, buffer);
163 current_row++;
164 }else{
165 int start=0;
166 int end=0;
167 for(;current_row<nb_lines_required;current_row++){
168 end=start+nb_dices_per_line;
169 if(end>dice->nb_dices)
170 end=dice->nb_dices;
171 dice_print_string_buffer(dice, buffer, start, end);
172 display->puts(0, current_row, buffer);
173 start=end;
174 }
175 }
176 rb->snprintf(buffer, PRINT_BUFFER_LENGTH, "Total: %d", dice->total);
177 display->puts_scroll(0, current_row, buffer);
178 display->update();
179}
180
181static bool dice_menu(struct dices * dice) {
182 int selection;
183 bool menu_quit = false, result = false;
184
185 MENUITEM_STRINGLIST(menu, "Dice Menu", NULL,
186 "Roll Dice",
187 "Number of Dice", "Number of Sides",
188 "Playback Control", "Quit");
189
190
191 while (!menu_quit) {
192 switch(rb->do_menu(&menu, &selection, NULL, false)){
193 case 0:
194 menu_quit = true;
195 result = true;
196 break;
197
198 case 1:
199 rb->set_int("Number of Dice", "", UNIT_INT, &(dice->nb_dices),
200 NULL, 1, 1, MAX_DICES, NULL );
201 break;
202
203 case 2:
204 rb->set_option("Number of Sides", &sides_index, RB_INT,
205 nb_sides_option,
206 sizeof(nb_sides_values)/sizeof(int), NULL);
207 dice->nb_sides=nb_sides_values[sides_index];
208 break;
209
210 case 3:
211 playback_control(NULL);
212 break;
213
214 default:
215 menu_quit = true;
216 result = false;
217 break;
218 }
219 }
220 return result;
221}