Skip to content

Commit e47b58e

Browse files
authored
Merge pull request #3 from Ka3u6y6a/2-history
2 history
2 parents 159eaa1 + 6ebbef5 commit e47b58e

8 files changed

+141
-26
lines changed

.flipcorg/gallery/history-screen.png

2.17 KB
Loading

.flipcorg/gallery/main-screen.png

-13 Bytes
Loading

CHANGELOG.md

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# Changelog
2+
3+
## 1.1
4+
- Add history of dice rolls
5+
- UI fixes
6+
7+
## 1
8+
- Initial release

README.md

+5-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
# Flipper Zero DnD Dice
1+
# Flipper Zero DnD Dice
2+
Version: 1.1 ([Changelog](https://github.com/Ka3u6y6a/flipper-zero-dice/blob/main/CHANGELOG.md))
23

34
<div style="text-align:center"><img src=".flipcorg/banner.png"/></div>
45
<br />
@@ -10,8 +11,10 @@ Dice types: Coin, d4, d6, d8, d10, d12, d20, d100
1011
## Screenshots
1112

1213
<div style="text-align:center"><img src=".flipcorg/gallery/main-screen.png"/></div>
13-
<br />
14+
<br />
1415
<div style="text-align:center"><img src=".flipcorg/gallery/roll-screen.png"/></div>
16+
<br />
17+
<div style="text-align:center"><img src=".flipcorg/gallery/history-screen.png"/></div>
1518

1619
## Compiling
1720

assets/ui_button_exit.png

40 Bytes
Loading

assets/ui_button_history.png

221 Bytes
Loading

constants.h

+47-4
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,14 @@
55

66
#define DICE_TYPES 8
77

8+
#define HISTORY_SIZE 10
9+
#define HISTORY_COL HISTORY_SIZE / 2
10+
#define HISTORY_START_POST_X 2
11+
#define HISTORY_START_POST_Y 10
12+
#define HISTORY_STEP_X 66
13+
#define HISTORY_STEP_Y 10
14+
#define HISTORY_X_GAP 11
15+
816
#define MAX_DICE_COUNT 10
917
#define MAX_COIN_FRAMES 9
1018
#define MAX_DICE_FRAMES 4
@@ -47,14 +55,20 @@ const Icon* dice_frames[] = {
4755
&I_d100_1, &I_d100_2, &I_d100_3, &I_d100_4, // d100
4856
};
4957

58+
const uint8_t screen_pos[] = {};
59+
5060
typedef struct {
5161
uint8_t type;
5262
int x;
5363
int y;
5464
char* name;
5565
} Dice;
5666

57-
const uint8_t screen_pos[] = {};
67+
typedef struct {
68+
int8_t index;
69+
uint8_t count;
70+
uint8_t result;
71+
} History;
5872

5973
static const Dice dice_types[] = {
6074
{2, 0, 0, "Coin"},
@@ -74,7 +88,8 @@ typedef enum {
7488
SwipeRightState,
7589
AnimState,
7690
AnimResultState,
77-
ResultState
91+
ResultState,
92+
HistoryState,
7893
} AppState;
7994

8095
typedef struct {
@@ -91,6 +106,7 @@ typedef struct {
91106
uint8_t dice_count;
92107
int8_t result_pos;
93108
Dice dices[DICE_TYPES];
109+
History history[HISTORY_SIZE];
94110
FuriMutex* mutex;
95111
} State;
96112

@@ -106,6 +122,33 @@ void init(State* const state) {
106122
state->dices[i].x = DICE_X + (i * DICE_GAP);
107123
state->dices[i].y = i == 0 ? DICE_Y_T : DICE_Y;
108124
}
125+
126+
for(uint8_t i = 0; i < HISTORY_SIZE; i++) {
127+
state->history[i].index = -1;
128+
}
129+
}
130+
131+
void add_to_history(State* const state, uint8_t index, uint8_t count, uint8_t result) {
132+
uint8_t last = HISTORY_SIZE - 1;
133+
if (state->history[last].index >= 0){
134+
for(uint8_t i = 1; i < HISTORY_SIZE; i++) {
135+
state->history[i - 1] = state->history[i];
136+
}
137+
138+
state->history[last].index = index;
139+
state->history[last].count = count;
140+
state->history[last].result = result;
141+
return;
142+
}
143+
144+
for(uint8_t i = 0; i < HISTORY_SIZE; i++) {
145+
if (state->history[i].index < 0){
146+
state->history[i].index = index;
147+
state->history[i].count = count;
148+
state->history[i].result = result;
149+
return;
150+
}
151+
}
109152
}
110153

111154
void coin_set_start(uint16_t type) {
@@ -138,7 +181,7 @@ bool isDiceNameVisible(AppState state) {
138181

139182
bool isDiceButtonsVisible(AppState state) {
140183
return isDiceNameVisible(state) && state != AnimResultState && state != ResultState &&
141-
state != AnimState;
184+
state != AnimState && state != HistoryState;
142185
}
143186

144187
bool isOneDice(uint8_t dice_index) {
@@ -147,7 +190,7 @@ bool isOneDice(uint8_t dice_index) {
147190

148191
bool isDiceSettingsDisabled(AppState state, uint8_t dice_index) {
149192
return isOneDice(dice_index) || state == ResultState || state == AnimResultState ||
150-
state == AnimState;
193+
state == AnimState || state == HistoryState;
151194
}
152195

153196
bool isAnimState(AppState state) {

dice_app.c

+81-20
Original file line numberDiff line numberDiff line change
@@ -76,10 +76,11 @@ static void roll(State* const state) {
7676

7777
if(state->dice_index == 0) coin_set_end(state->roll_result); // change coin anim
7878

79+
add_to_history(state, state->dice_index, state->dice_count, state->roll_result);
7980
state->app_state = AnimState;
8081
}
8182

82-
static void draw_ui(const State* state, Canvas* canvas) {
83+
static void draw_main_menu(const State* state, Canvas* canvas) {
8384
canvas_set_font(canvas, FontSecondary);
8485

8586
FuriString* count = furi_string_alloc();
@@ -92,7 +93,7 @@ static void draw_ui(const State* state, Canvas* canvas) {
9293
}
9394
// dice arrow buttons
9495
if(isDiceButtonsVisible(state->app_state)) {
95-
if(state->dice_index > 0) canvas_draw_icon(canvas, 45, 44, &I_ui_button_left);
96+
if(state->dice_index > 0) canvas_draw_icon(canvas, 44, 44, &I_ui_button_left);
9697
if(state->dice_index < DICE_TYPES - 1)
9798
canvas_draw_icon(canvas, 78, 44, &I_ui_button_right);
9899
}
@@ -105,17 +106,62 @@ static void draw_ui(const State* state, Canvas* canvas) {
105106
canvas_draw_str_aligned(canvas, 58, 61, AlignCenter, AlignBottom, furi_string_get_cstr(count));
106107

107108
// buttons
108-
if(isAnimState(state->app_state) == false) canvas_draw_icon(canvas, 92, 54, &I_ui_button_roll);
109+
if(isAnimState(state->app_state) == false) {
110+
canvas_draw_icon(canvas, 92, 54, &I_ui_button_roll);
111+
canvas_draw_icon(canvas, 0, 54, &I_ui_button_history);
112+
}
109113

110-
if(state->app_state != AnimResultState && state->app_state != ResultState) {
111-
canvas_draw_icon(canvas, 0, 54, &I_ui_button_exit);
112-
} else {
114+
if(state->app_state == AnimResultState || state->app_state == ResultState) {
113115
canvas_draw_icon(canvas, 0, 54, &I_ui_button_back);
114116
}
115117

116118
furi_string_free(count);
117119
}
118120

121+
static void draw_history(const State* state, Canvas* canvas) {
122+
canvas_set_font(canvas, FontSecondary);
123+
FuriString* hist = furi_string_alloc();
124+
125+
uint8_t x = HISTORY_START_POST_X;
126+
uint8_t y = HISTORY_START_POST_Y;
127+
for(uint8_t i = 0; i < HISTORY_COL; i++) {
128+
// left side
129+
furi_string_printf(hist, "%01d.", i + 1);
130+
canvas_draw_str_aligned(canvas, x, y, AlignLeft, AlignBottom, furi_string_get_cstr(hist));
131+
if (state->history[i].index < 0) {
132+
furi_string_printf(hist, "--------");
133+
} else {
134+
if (state->history[i].index == 0){
135+
furi_string_printf(hist, state->history[i].result == 1 ? "Heads" : "Tails");
136+
} else {
137+
furi_string_printf(hist, "%01d%s: %01d", state->history[i].count, dice_types[state->history[i].index].name, state->history[i].result);
138+
}
139+
}
140+
canvas_draw_str_aligned(canvas, x + HISTORY_X_GAP, y, AlignLeft, AlignBottom, furi_string_get_cstr(hist));
141+
142+
// right side
143+
uint8_t r_index = i + HISTORY_COL;
144+
furi_string_printf(hist, "%01d.", r_index + 1);
145+
canvas_draw_str_aligned(canvas, x + HISTORY_STEP_X, y, AlignLeft, AlignBottom, furi_string_get_cstr(hist));
146+
if (state->history[r_index].index < 0){
147+
furi_string_printf(hist, "--------");
148+
} else {
149+
if (state->history[r_index].index == 0){
150+
furi_string_printf(hist, state->history[r_index].result == 1 ? "Heads" : "Tails");
151+
} else {
152+
furi_string_printf(hist, "%01d%s: %01d", state->history[r_index].count, dice_types[state->history[r_index].index].name, state->history[r_index].result);
153+
}
154+
}
155+
canvas_draw_str_aligned(canvas, x + HISTORY_STEP_X + HISTORY_X_GAP, y, AlignLeft, AlignBottom, furi_string_get_cstr(hist));
156+
157+
y += HISTORY_STEP_Y;
158+
}
159+
160+
canvas_draw_icon(canvas, 0, 54, &I_ui_button_back);
161+
canvas_draw_icon(canvas, 75, 54, &I_ui_button_exit);
162+
furi_string_free(hist);
163+
}
164+
119165
static void draw_dice(const State* state, Canvas* canvas) {
120166
if(isMenuState(state->app_state) == false) { // draw only selected dice
121167
if(state->dice_index == 0) { // coin
@@ -200,12 +246,16 @@ static void draw_callback(Canvas* canvas, void* ctx) {
200246

201247
canvas_clear(canvas);
202248

203-
draw_ui(state, canvas);
204-
205-
if(isResultVisible(state->app_state, state->dice_index)) {
206-
draw_results(state, canvas);
249+
if (state->app_state == HistoryState) {
250+
draw_history(state, canvas);
207251
} else {
208-
draw_dice(state, canvas);
252+
draw_main_menu(state, canvas);
253+
254+
if(isResultVisible(state->app_state, state->dice_index)) {
255+
draw_results(state, canvas);
256+
} else {
257+
draw_dice(state, canvas);
258+
}
209259
}
210260

211261
furi_mutex_release(state->mutex);
@@ -289,31 +339,42 @@ int32_t dice_dnd_app(void* p) {
289339
if(state->dice_index != 0) {
290340
state->dice_count += 1;
291341
if(state->dice_count > MAX_DICE_COUNT) {
292-
state->dice_count = MAX_DICE_COUNT;
342+
state->dice_count = 1;
293343
}
294344
}
295345
} else if(event.input.key == InputKeyDown) {
296346
state->dice_count -= 1;
297347
if(state->dice_count < 1) {
298-
state->dice_count = 1;
348+
state->dice_count = MAX_DICE_COUNT;
299349
}
300350
}
301351
}
302352
// roll
303353
if(event.input.key == InputKeyOk && isAnimState(state->app_state) == false) {
304354
roll(state);
305355
}
306-
// back to dice select state or quit from app
307-
if(event.input.key == InputKeyBack) {
308-
if(state->app_state == ResultState ||
309-
state->app_state == AnimResultState) {
356+
}
357+
358+
// back button handlers
359+
if(event.input.key == InputKeyBack){
360+
// switch states
361+
if(event.input.type == InputTypeShort) {
362+
if(state->app_state == SelectState){
363+
state->app_state = HistoryState;
364+
}
365+
else if(state->app_state == HistoryState) {
366+
state->app_state = SelectState;
367+
}
368+
else if(state->app_state == ResultState || state->app_state == AnimResultState) {
310369
state->anim_frame = 0;
311370
state->app_state = SelectState;
312-
} else {
313-
processing = false;
314371
}
315372
}
316-
}
373+
// exit
374+
else if(event.input.type == InputTypeLong) {
375+
processing = false;
376+
}
377+
}
317378
}
318379
} else {
319380
FURI_LOG_D(TAG, "osMessageQueue: event timeout");

0 commit comments

Comments
 (0)