Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/ClusterM/flipperzero-firmware.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlbert Kharisov <albkharisov@gmail.com>2021-11-24 19:21:12 +0300
committerGitHub <noreply@github.com>2021-11-24 19:21:12 +0300
commit9b8a139e2b026d373166ab89b865f83003afc03b (patch)
tree155592c4a6d22491f5612f5bd3c3945f4ef23646 /applications/dolphin
parent92c499b41b72c1c516527a5d72ec46867dccdbfd (diff)
[FL-1995] New dolphin animations (part 1) (#835)
* Desktop Animation (part 1): Ugly naked ohmygod architecture * fix butthurt, fix locked scene * Change SD icons, fixes * Fix level update animation * Fixes, correct butthurt * Clean up code * furi_assert(0) -> furi_crash("msg") * Gui: rename none layer to desktop, update docs. Co-authored-by: あく <alleteam@gmail.com>
Diffstat (limited to 'applications/dolphin')
-rw-r--r--applications/dolphin/dolphin.c31
-rw-r--r--applications/dolphin/dolphin.h14
-rw-r--r--applications/dolphin/dolphin_i.h2
-rw-r--r--applications/dolphin/helpers/dolphin_deed.c10
-rw-r--r--applications/dolphin/helpers/dolphin_state.c97
-rw-r--r--applications/dolphin/helpers/dolphin_state.h28
6 files changed, 124 insertions, 58 deletions
diff --git a/applications/dolphin/dolphin.c b/applications/dolphin/dolphin.c
index 09bdb982..f6871c04 100644
--- a/applications/dolphin/dolphin.c
+++ b/applications/dolphin/dolphin.c
@@ -1,4 +1,9 @@
+#include "dolphin/dolphin.h"
+#include "desktop/desktop.h"
+#include "dolphin/helpers/dolphin_state.h"
#include "dolphin_i.h"
+#include "furi/pubsub.h"
+#include "sys/_stdint.h"
#include <furi.h>
#define DOLPHIN_TIMEGATE 86400 // one day
#define DOLPHIN_LOCK_EVENT_FLAG (0x1)
@@ -39,6 +44,7 @@ Dolphin* dolphin_alloc() {
dolphin->state = dolphin_state_alloc();
dolphin->event_queue = osMessageQueueNew(8, sizeof(DolphinEvent), NULL);
+ dolphin->pubsub = furi_pubsub_alloc();
return dolphin;
}
@@ -79,7 +85,7 @@ void dolphin_event_release(Dolphin* dolphin, DolphinEvent* event) {
static void dolphin_check_butthurt(DolphinState* state) {
furi_assert(state);
- float diff_time = difftime(dolphin_state_get_timestamp(state), dolphin_state_timestamp());
+ float diff_time = difftime(state->data.timestamp, dolphin_state_timestamp());
if((fabs(diff_time)) > DOLPHIN_TIMEGATE) {
FURI_LOG_I("DolphinState", "Increasing butthurt");
@@ -87,6 +93,10 @@ static void dolphin_check_butthurt(DolphinState* state) {
}
}
+FuriPubSub* dolphin_get_pubsub(Dolphin* dolphin) {
+ return dolphin->pubsub;
+}
+
int32_t dolphin_srv(void* p) {
Dolphin* dolphin = dolphin_alloc();
furi_record_create("dolphin", dolphin);
@@ -97,11 +107,17 @@ int32_t dolphin_srv(void* p) {
while(1) {
if(osMessageQueueGet(dolphin->event_queue, &event, NULL, 60000) == osOK) {
if(event.type == DolphinEventTypeDeed) {
- dolphin_state_on_deed(dolphin->state, event.deed);
+ if(dolphin_state_on_deed(dolphin->state, event.deed)) {
+ DolphinPubsubEvent event = DolphinPubsubEventUpdate;
+ furi_pubsub_publish(dolphin->pubsub, &event);
+ }
} else if(event.type == DolphinEventTypeStats) {
- event.stats->icounter = dolphin_state_get_icounter(dolphin->state);
- event.stats->butthurt = dolphin_state_get_butthurt(dolphin->state);
- event.stats->timestamp = dolphin_state_get_timestamp(dolphin->state);
+ event.stats->icounter = dolphin->state->data.icounter;
+ event.stats->butthurt = dolphin->state->data.butthurt;
+ event.stats->timestamp = dolphin->state->data.timestamp;
+ event.stats->level = dolphin_get_level(dolphin->state->data.icounter);
+ event.stats->level_up_is_pending =
+ !dolphin_state_xp_to_levelup(dolphin->state->data.icounter);
} else if(event.type == DolphinEventTypeFlush) {
dolphin_state_save(dolphin->state);
}
@@ -116,3 +132,8 @@ int32_t dolphin_srv(void* p) {
return 0;
}
+
+void dolphin_upgrade_level(Dolphin* dolphin) {
+ dolphin_state_increase_level(dolphin->state);
+ dolphin_flush(dolphin);
+}
diff --git a/applications/dolphin/dolphin.h b/applications/dolphin/dolphin.h
index c8edca61..97858996 100644
--- a/applications/dolphin/dolphin.h
+++ b/applications/dolphin/dolphin.h
@@ -1,6 +1,8 @@
#pragma once
+#include "furi/pubsub.h"
#include "helpers/dolphin_deed.h"
+#include <stdbool.h>
typedef struct Dolphin Dolphin;
@@ -8,8 +10,14 @@ typedef struct {
uint32_t icounter;
uint32_t butthurt;
uint64_t timestamp;
+ uint8_t level;
+ bool level_up_is_pending;
} DolphinStats;
+typedef enum {
+ DolphinPubsubEventUpdate,
+} DolphinPubsubEvent;
+
/** Deed complete notification. Call it on deed completion.
* See dolphin_deed.h for available deeds. In futures it will become part of assets.
* Thread safe, async
@@ -24,4 +32,8 @@ DolphinStats dolphin_stats(Dolphin* dolphin);
/** Flush dolphin queue and save state
* Thread safe, blocking
*/
-void dolphin_flush(Dolphin* dolphin); \ No newline at end of file
+void dolphin_flush(Dolphin* dolphin);
+
+void dolphin_upgrade_level(Dolphin* dolphin);
+
+FuriPubSub* dolphin_get_pubsub(Dolphin* dolphin);
diff --git a/applications/dolphin/dolphin_i.h b/applications/dolphin/dolphin_i.h
index 5edba30e..85c96c19 100644
--- a/applications/dolphin/dolphin_i.h
+++ b/applications/dolphin/dolphin_i.h
@@ -1,5 +1,6 @@
#pragma once
+#include "furi/pubsub.h"
#include <furi.h>
#include <furi-hal.h>
@@ -26,6 +27,7 @@ struct Dolphin {
DolphinState* state;
// Queue
osMessageQueueId_t event_queue;
+ FuriPubSub* pubsub;
};
Dolphin* dolphin_alloc();
diff --git a/applications/dolphin/helpers/dolphin_deed.c b/applications/dolphin/helpers/dolphin_deed.c
index d589ac23..c7b2305e 100644
--- a/applications/dolphin/helpers/dolphin_deed.c
+++ b/applications/dolphin/helpers/dolphin_deed.c
@@ -1,12 +1,14 @@
#include "dolphin_deed.h"
+#include <furi.h>
static const DolphinDeedWeight dolphin_deed_weights[DolphinDeedMax] = {
- {1, 2, 60},
- {1, 2, 60},
- {1, 2, 60},
- {-1, 2, 60},
+ {1, -1, 60},
+ {1, -1, 60},
+ {1, -1, 60},
+ {-1, 1, 60},
};
const DolphinDeedWeight* dolphin_deed_weight(DolphinDeed deed) {
+ furi_assert(deed < DolphinDeedMax);
return &dolphin_deed_weights[deed];
}
diff --git a/applications/dolphin/helpers/dolphin_state.c b/applications/dolphin/helpers/dolphin_state.c
index 31066534..13b8ca95 100644
--- a/applications/dolphin/helpers/dolphin_state.c
+++ b/applications/dolphin/helpers/dolphin_state.c
@@ -1,4 +1,5 @@
#include "dolphin_state.h"
+#include <stdint.h>
#include <storage/storage.h>
#include <furi.h>
#include <math.h>
@@ -9,23 +10,8 @@
#define DOLPHIN_STATE_HEADER_MAGIC 0xD0
#define DOLPHIN_STATE_HEADER_VERSION 0x01
#define DOLPHIN_LVL_THRESHOLD 20.0f
-
-typedef struct {
- uint32_t limit_ibutton;
- uint32_t limit_nfc;
- uint32_t limit_ir;
- uint32_t limit_rfid;
-
- uint32_t flags;
- uint32_t icounter;
- uint32_t butthurt;
- uint64_t timestamp;
-} DolphinStoreData;
-
-struct DolphinState {
- DolphinStoreData data;
- bool dirty;
-};
+#define LEVEL2_THRESHOLD 20
+#define LEVEL3_THRESHOLD 100
DolphinState* dolphin_state_alloc() {
return furi_alloc(sizeof(DolphinState));
@@ -93,18 +79,62 @@ uint64_t dolphin_state_timestamp() {
return mktime(&current);
}
-void dolphin_state_on_deed(DolphinState* dolphin_state, DolphinDeed deed) {
+bool dolphin_state_is_levelup(uint32_t icounter) {
+ return (icounter == LEVEL2_THRESHOLD) || (icounter == LEVEL3_THRESHOLD);
+}
+
+uint8_t dolphin_get_level(uint32_t icounter) {
+ if(icounter <= LEVEL2_THRESHOLD) {
+ return 1;
+ } else if(icounter <= LEVEL3_THRESHOLD) {
+ return 2;
+ } else {
+ return 3;
+ }
+}
+
+uint32_t dolphin_state_xp_to_levelup(uint32_t icounter) {
+ uint32_t threshold = 0;
+ if(icounter <= LEVEL2_THRESHOLD) {
+ threshold = LEVEL2_THRESHOLD;
+ } else if(icounter <= LEVEL3_THRESHOLD) {
+ threshold = LEVEL3_THRESHOLD;
+ } else {
+ threshold = (uint32_t)-1;
+ }
+ return threshold - icounter;
+}
+
+bool dolphin_state_on_deed(DolphinState* dolphin_state, DolphinDeed deed) {
const DolphinDeedWeight* deed_weight = dolphin_deed_weight(deed);
int32_t icounter = dolphin_state->data.icounter + deed_weight->icounter;
- int32_t butthurt = dolphin_state->data.butthurt;
+ bool level_up = false;
+ bool mood_changed = false;
+
+ if(icounter <= 0) {
+ icounter = 0;
+ if(dolphin_state->data.icounter == 0) {
+ return false;
+ }
+ }
- if(icounter >= 0) {
- dolphin_state->data.icounter = icounter;
- dolphin_state->data.butthurt = MAX(butthurt - deed_weight->icounter, 0);
- dolphin_state->data.timestamp = dolphin_state_timestamp();
+ uint8_t xp_to_levelup = dolphin_state_xp_to_levelup(dolphin_state->data.icounter);
+ if(xp_to_levelup) {
+ level_up = true;
+ dolphin_state->data.icounter += MIN(xp_to_levelup, deed_weight->icounter);
}
+ uint32_t new_butthurt =
+ CLAMP(((int32_t)dolphin_state->data.butthurt) + deed_weight->butthurt, 14, 0);
+
+ if(!!dolphin_state->data.butthurt != !!new_butthurt) {
+ mood_changed = true;
+ }
+ dolphin_state->data.butthurt = new_butthurt;
+ dolphin_state->data.timestamp = dolphin_state_timestamp();
dolphin_state->dirty = true;
+
+ return level_up || mood_changed;
}
void dolphin_state_butthurted(DolphinState* dolphin_state) {
@@ -113,22 +143,7 @@ void dolphin_state_butthurted(DolphinState* dolphin_state) {
dolphin_state->dirty = true;
}
-uint32_t dolphin_state_get_icounter(DolphinState* dolphin_state) {
- return dolphin_state->data.icounter;
-}
-
-uint32_t dolphin_state_get_butthurt(DolphinState* dolphin_state) {
- return dolphin_state->data.butthurt;
-}
-
-uint64_t dolphin_state_get_timestamp(DolphinState* dolphin_state) {
- return dolphin_state->data.timestamp;
-}
-
-uint32_t dolphin_state_get_level(uint32_t icounter) {
- return 0.5f + sqrtf(1.0f + 8.0f * ((float)icounter / DOLPHIN_LVL_THRESHOLD)) / 2.0f;
-}
-
-uint32_t dolphin_state_xp_to_levelup(uint32_t icounter, uint32_t level, bool remaining) {
- return (DOLPHIN_LVL_THRESHOLD * level * (level + 1) / 2) - (remaining ? icounter : 0);
+void dolphin_state_increase_level(DolphinState* dolphin_state) {
+ ++dolphin_state->data.icounter;
+ dolphin_state->dirty = true;
}
diff --git a/applications/dolphin/helpers/dolphin_state.h b/applications/dolphin/helpers/dolphin_state.h
index 7c4a33cd..25d2d9d2 100644
--- a/applications/dolphin/helpers/dolphin_state.h
+++ b/applications/dolphin/helpers/dolphin_state.h
@@ -7,6 +7,22 @@
#include <time.h>
typedef struct DolphinState DolphinState;
+typedef struct {
+ uint32_t limit_ibutton;
+ uint32_t limit_nfc;
+ uint32_t limit_ir;
+ uint32_t limit_rfid;
+
+ uint32_t flags;
+ uint32_t icounter;
+ uint32_t butthurt;
+ uint64_t timestamp;
+} DolphinStoreData;
+
+struct DolphinState {
+ DolphinStoreData data;
+ bool dirty;
+};
DolphinState* dolphin_state_alloc();
@@ -20,16 +36,14 @@ void dolphin_state_clear(DolphinState* dolphin_state);
uint64_t dolphin_state_timestamp();
-void dolphin_state_on_deed(DolphinState* dolphin_state, DolphinDeed deed);
+bool dolphin_state_on_deed(DolphinState* dolphin_state, DolphinDeed deed);
void dolphin_state_butthurted(DolphinState* dolphin_state);
-uint32_t dolphin_state_get_icounter(DolphinState* dolphin_state);
+uint32_t dolphin_state_xp_to_levelup(uint32_t icounter);
-uint32_t dolphin_state_get_butthurt(DolphinState* dolphin_state);
+bool dolphin_state_is_levelup(uint32_t icounter);
-uint64_t dolphin_state_get_timestamp(DolphinState* dolphin_state);
+void dolphin_state_increase_level(DolphinState* dolphin_state);
-uint32_t dolphin_state_get_level(uint32_t icounter);
-
-uint32_t dolphin_state_xp_to_levelup(uint32_t icounter, uint32_t level, bool remaining); \ No newline at end of file
+uint8_t dolphin_get_level(uint32_t icounter);