Introduce __attribute__((unused)) (#defined to UNUSED_ATTR) to mark possibly unused...
[kugel-rb.git] / apps / plugins / dice.c
blob7810b5e7ef8d37a26a959475a834a82e8ecaf6d0
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2005 by Brandon Low
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.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
22 #include "plugin.h"
23 #include "lib/pluginlib_actions.h"
24 #include "lib/configfile.h"
25 #include "lib/playback_control.h"
27 #define MAX_DICES 12
28 #define INITIAL_NB_DICES 1
29 #define INITIAL_NB_SIDES 2 /* corresponds to 6 sides in the array */
31 #define DICE_QUIT PLA_QUIT
32 #define DICE_ROLL PLA_START
35 #define CFG_FILE "dice.cfg"
37 const struct button_mapping* plugin_contexts[]={generic_actions};
39 struct dices
41 int values[MAX_DICES];
42 int total;
43 int nb_dices;
44 int nb_sides;
47 #define PRINT_BUFFER_LENGTH MAX_DICES*4
48 PLUGIN_HEADER
50 static struct dices dice;
51 static int sides_index;
53 static struct opt_items nb_sides_option[8] = {
54 { "3", -1 },
55 { "4", -1 },
56 { "6", -1 },
57 { "8", -1 },
58 { "10", -1 },
59 { "12", -1 },
60 { "20", -1 },
61 { "100", -1 }
63 static int nb_sides_values[] = { 3, 4, 6, 8, 10, 12, 20, 100 };
64 static char *sides_conf[] = {"3", "4", "6", "8", "10", "12", "20", "100" };
65 static struct configdata config[] =
67 {TYPE_INT, 0, MAX_DICES, { .int_p = &dice.nb_dices}, "dice count", NULL},
68 {TYPE_ENUM, 0, 8, { .int_p = &sides_index }, "side count", sides_conf}
71 void dice_init(struct dices* dice);
72 void dice_roll(struct dices* dice);
73 void dice_print(struct dices* dice, struct screen* display);
74 bool dice_menu(struct dices* dice);
76 /* plugin entry point */
77 enum plugin_status plugin_start(UNUSED_ATTR const void* parameter) {
78 int i, action;
80 dice_init(&dice);
81 rb->srand(*rb->current_tick);
83 configfile_load(CFG_FILE, config, 2, 0);
84 dice.nb_sides = nb_sides_values[sides_index];
85 if(!dice_menu(&dice))
87 configfile_save(CFG_FILE, config, 2, 0);
88 return PLUGIN_OK;
90 configfile_save(CFG_FILE, config, 2, 0);
91 dice_roll(&dice);
92 FOR_NB_SCREENS(i)
93 dice_print( &dice, rb->screens[i] );
94 while(true) {
95 action = pluginlib_getaction(TIMEOUT_BLOCK,
96 plugin_contexts, 1);
97 switch(action) {
98 case DICE_ROLL:
99 dice_roll(&dice);
100 FOR_NB_SCREENS(i)
101 dice_print( &dice, rb->screens[i] );
102 break;
103 case DICE_QUIT:
104 return PLUGIN_OK;
109 void dice_init(struct dices* dice){
110 dice->nb_dices=INITIAL_NB_DICES;
111 sides_index=INITIAL_NB_SIDES;
115 void dice_roll(struct dices* dice) {
116 int i;
117 dice->total = 0;
118 for (i=0; i<dice->nb_dices; i++) {
119 dice->values[i] = rb->rand()%dice->nb_sides + 1;
120 dice->total+=dice->values[i];
124 void dice_print_string_buffer(struct dices* dice, char* buffer,
125 int start, int end){
126 int i, written;
127 for (i=start; i<end; i++) {
128 written=rb->snprintf(buffer, PRINT_BUFFER_LENGTH,
129 " %3d", dice->values[i]);
130 buffer=&(buffer[written]);
134 void dice_print(struct dices* dice, struct screen* display){
135 char buffer[PRINT_BUFFER_LENGTH];
136 /* display characteristics */
137 int char_height, char_width;
138 display->getstringsize("M", &char_width, &char_height);
139 int display_nb_row=display->getheight()/char_height;
140 int display_nb_col=display->getwidth()/char_width;
142 int nb_dices_per_line=display_nb_col/4;/* 4 char per dice displayed*/
143 int nb_lines_required=dice->nb_dices/nb_dices_per_line;
144 int current_row=0;
145 if(dice->nb_dices%nb_dices_per_line!=0)
146 nb_lines_required++;
147 display->clear_display();
148 if(display_nb_row<nb_lines_required){
149 /* Put everything on the same scrolling line */
150 dice_print_string_buffer(dice, buffer, 0, dice->nb_dices);
151 display->puts_scroll(0, current_row, buffer);
152 current_row++;
153 }else{
154 int start=0;
155 int end=0;
156 for(;current_row<nb_lines_required;current_row++){
157 end=start+nb_dices_per_line;
158 if(end>dice->nb_dices)
159 end=dice->nb_dices;
160 dice_print_string_buffer(dice, buffer, start, end);
161 display->puts(0, current_row, buffer);
162 start=end;
165 rb->snprintf(buffer, PRINT_BUFFER_LENGTH, "Total: %d", dice->total);
166 display->puts_scroll(0, current_row, buffer);
167 display->update();
170 bool dice_menu(struct dices * dice) {
171 int selection;
172 bool menu_quit = false, result = false;
174 MENUITEM_STRINGLIST(menu, "Dice Menu", NULL,
175 "Roll Dice",
176 "Number of Dice", "Number of Sides",
177 "Playback Control", "Quit");
180 while (!menu_quit) {
181 switch(rb->do_menu(&menu, &selection, NULL, false)){
182 case 0:
183 menu_quit = true;
184 result = true;
185 break;
187 case 1:
188 rb->set_int("Number of Dice", "", UNIT_INT, &(dice->nb_dices),
189 NULL, 1, 1, MAX_DICES, NULL );
190 break;
192 case 2:
193 rb->set_option("Number of Sides", &sides_index, INT,
194 nb_sides_option,
195 sizeof(nb_sides_values)/sizeof(int), NULL);
196 dice->nb_sides=nb_sides_values[sides_index];
197 break;
199 case 3:
200 playback_control(NULL);
201 break;
203 default:
204 menu_quit = true;
205 result = false;
206 break;
209 return result;