diff options
author | Albert Kharisov <albkharisov@gmail.com> | 2021-11-24 19:21:12 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-11-24 19:21:12 +0300 |
commit | 9b8a139e2b026d373166ab89b865f83003afc03b (patch) | |
tree | 155592c4a6d22491f5612f5bd3c3945f4ef23646 /applications/dolphin | |
parent | 92c499b41b72c1c516527a5d72ec46867dccdbfd (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.c | 31 | ||||
-rw-r--r-- | applications/dolphin/dolphin.h | 14 | ||||
-rw-r--r-- | applications/dolphin/dolphin_i.h | 2 | ||||
-rw-r--r-- | applications/dolphin/helpers/dolphin_deed.c | 10 | ||||
-rw-r--r-- | applications/dolphin/helpers/dolphin_state.c | 97 | ||||
-rw-r--r-- | applications/dolphin/helpers/dolphin_state.h | 28 |
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(¤t); } -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); |