summaryrefslogtreecommitdiff
path: root/src/fruits
diff options
context:
space:
mode:
Diffstat (limited to 'src/fruits')
-rw-r--r--src/fruits/cap/cap.c22
-rw-r--r--src/fruits/cap/cap.h1
-rw-r--r--src/fruits/cmv/cmv2.c2
3 files changed, 25 insertions, 0 deletions
diff --git a/src/fruits/cap/cap.c b/src/fruits/cap/cap.c
index e1d9e13..317abf4 100644
--- a/src/fruits/cap/cap.c
+++ b/src/fruits/cap/cap.c
@@ -1,3 +1,5 @@
+#include <al/random.h>
+
#include "cap.h"
#if CAP_USE_PYTHON
@@ -219,6 +221,26 @@ bool cap_list_set_completed(struct cap_runner *cap, str *name)
return ret;
}
+// https://benpfaff.org/writings/clc/shuffle.html
+void cap_list_shuffle(struct cap_runner *cap, str *name)
+{
+ struct cap_list *list = list_from_name(cap, name);
+ if (!list) return;
+ aki_mutex_lock(&list->mutex);
+ u32 size = list->entries.size;
+ if (size > 0) {
+ for (u32 i = 0; i < size - 1; i++) {
+ u32 j = i + al_rand() / (AL_RAND_MAX / (size - i) + 1);
+ struct cap_list_entry tmp = al_array_at(list->entries, j);
+ al_array_at(list->entries, j) = al_array_at(list->entries, i);
+ al_array_at(list->entries, i) = tmp;
+ }
+ list->set = -1;
+ list_pump_internal(cap, list, false);
+ }
+ aki_mutex_unlock(&list->mutex);
+}
+
static void list_close_internal(struct cap_list *list)
{
struct cap_list_entry *entry;
diff --git a/src/fruits/cap/cap.h b/src/fruits/cap/cap.h
index 07aa63b..57f6889 100644
--- a/src/fruits/cap/cap.h
+++ b/src/fruits/cap/cap.h
@@ -44,4 +44,5 @@ void cap_list_add(struct cap_runner *cap, str *name, str *unique_id);
bool cap_list_skip(struct cap_runner *cap, str *name, s32 n);
void cap_list_pump(struct cap_runner *cap, str *name, bool buffer);
bool cap_list_set_completed(struct cap_runner *cap, str *name);
+void cap_list_shuffle(struct cap_runner *cap, str *name);
void cap_close(struct cap_runner *cap);
diff --git a/src/fruits/cmv/cmv2.c b/src/fruits/cmv/cmv2.c
index 3c70317..74a4113 100644
--- a/src/fruits/cmv/cmv2.c
+++ b/src/fruits/cmv/cmv2.c
@@ -199,6 +199,8 @@ static u8 line_callback(void *userdata, str *line)
cap_list_skip(&c->cap, default_list, 1);
} else if (al_str_eq(line, al_str_c(";PREV"))) {
cap_list_skip(&c->cap, default_list, -1);
+ } else if (al_str_eq(line, al_str_c(";SHUFFLE"))) {
+ cap_list_shuffle(&c->cap, default_list);
} else {
cap_list_add(&c->cap, default_list, line);
}