Dolphin_srv timestamp and butthurt; Desktop_srv refactoring (#750)
* dolphin_srv: save timestamp on deed; desktop_srv minor refactoring * dolphin_srv timegated butthurt increse, desktop refactoring * desktop app: update debug screen * remove debug logging * increasing icounter affects butthurt value * Dolphin: correct error message on DolphinStore load Co-authored-by: Aleksandr Kutuzov <alleteam@gmail.com>
This commit is contained in:
parent
1dd96419ab
commit
5dbfe3d90a
@ -19,7 +19,7 @@
|
||||
#include "views/desktop_debug.h"
|
||||
|
||||
#include "scenes/desktop_scene.h"
|
||||
|
||||
#include "helpers/desktop_animation.h"
|
||||
#include "desktop/desktop_settings/desktop_settings.h"
|
||||
|
||||
typedef enum {
|
||||
|
26
applications/desktop/helpers/desktop_animation.c
Normal file
26
applications/desktop/helpers/desktop_animation.c
Normal file
@ -0,0 +1,26 @@
|
||||
#include "desktop_animation.h"
|
||||
|
||||
static const Icon* idle_scenes[] = {&A_Wink_128x64, &A_WatchingTV_128x64};
|
||||
|
||||
const Icon* desktop_get_icon() {
|
||||
uint8_t new = 0;
|
||||
|
||||
#if 0
|
||||
// checking dolphin state here to choose appropriate animation
|
||||
|
||||
Dolphin* dolphin = furi_record_open("dolphin");
|
||||
DolphinStats stats = dolphin_stats(dolphin);
|
||||
float timediff = fabs(difftime(stats.timestamp, dolphin_state_timestamp()));
|
||||
|
||||
FURI_LOG_I("desktop-animation", "background change");
|
||||
FURI_LOG_I("desktop-animation", "icounter: %d", stats.icounter);
|
||||
FURI_LOG_I("desktop-animation", "butthurt: %d", stats.butthurt);
|
||||
FURI_LOG_I("desktop-animation", "time since deeed: %.0f", timediff);
|
||||
#endif
|
||||
|
||||
if((random() % 100) > 50) { // temp rnd selection
|
||||
new = random() % COUNT_OF(idle_scenes);
|
||||
}
|
||||
|
||||
return idle_scenes[new];
|
||||
}
|
10
applications/desktop/helpers/desktop_animation.h
Normal file
10
applications/desktop/helpers/desktop_animation.h
Normal file
@ -0,0 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#include <furi.h>
|
||||
#include <math.h>
|
||||
#include <assets_icons.h>
|
||||
#include "dolphin/dolphin.h"
|
||||
#include "dolphin/helpers/dolphin_state.h"
|
||||
#include "time.h"
|
||||
|
||||
const Icon* desktop_get_icon();
|
@ -13,6 +13,7 @@ void desktop_scene_locked_on_enter(void* context) {
|
||||
desktop_locked_set_callback(locked_view, desktop_scene_locked_callback, desktop);
|
||||
desktop_locked_reset_door_pos(locked_view);
|
||||
desktop_locked_update_hint_timeout(locked_view);
|
||||
desktop_locked_set_dolphin_animation(locked_view);
|
||||
|
||||
view_port_enabled_set(desktop->lock_viewport, true);
|
||||
osTimerStart(locked_view->timer, 63);
|
||||
|
@ -39,6 +39,7 @@ void desktop_scene_main_on_enter(void* context) {
|
||||
desktop_main_unlocked(desktop->main_view);
|
||||
}
|
||||
|
||||
desktop_main_switch_dolphin_animation(desktop->main_view);
|
||||
view_dispatcher_switch_to_view(desktop->view_dispatcher, DesktopViewMain);
|
||||
}
|
||||
|
||||
|
@ -2,8 +2,8 @@
|
||||
#include "../desktop_i.h"
|
||||
#include "desktop_debug.h"
|
||||
|
||||
#include "applications/dolphin/helpers/dolphin_state.h"
|
||||
#include "applications/dolphin/dolphin.h"
|
||||
#include "dolphin/helpers/dolphin_state.h"
|
||||
#include "dolphin/dolphin.h"
|
||||
|
||||
void desktop_debug_set_callback(
|
||||
DesktopDebugView* debug_view,
|
||||
@ -21,7 +21,7 @@ void desktop_debug_render(Canvas* canvas, void* model) {
|
||||
const Version* ver;
|
||||
char buffer[64];
|
||||
|
||||
static const char* headers[] = {"FW Version info:", "Boot Version info:", "Desktop info:"};
|
||||
static const char* headers[] = {"FW Version info:", "Boot Version info:", "Dolphin info:"};
|
||||
|
||||
canvas_set_color(canvas, ColorBlack);
|
||||
canvas_set_font(canvas, FontPrimary);
|
||||
@ -56,7 +56,7 @@ void desktop_debug_render(Canvas* canvas, void* model) {
|
||||
"%s [%s]",
|
||||
version_get_version(ver),
|
||||
version_get_builddate(ver));
|
||||
canvas_draw_str(canvas, 5, 33, buffer);
|
||||
canvas_draw_str(canvas, 5, 32, buffer);
|
||||
|
||||
snprintf(
|
||||
buffer,
|
||||
@ -68,16 +68,22 @@ void desktop_debug_render(Canvas* canvas, void* model) {
|
||||
|
||||
snprintf(
|
||||
buffer, sizeof(buffer), "[%s] %s", version_get_target(ver), version_get_gitbranch(ver));
|
||||
canvas_draw_str(canvas, 5, 53, buffer);
|
||||
canvas_draw_str(canvas, 5, 54, buffer);
|
||||
|
||||
} else {
|
||||
char buffer[64];
|
||||
uint32_t current_lvl = dolphin_state_get_level(m->icounter);
|
||||
uint32_t remaining = dolphin_state_xp_to_levelup(m->icounter, current_lvl, true);
|
||||
|
||||
canvas_set_font(canvas, FontSecondary);
|
||||
snprintf(buffer, 64, "Icounter: %ld", m->icounter);
|
||||
canvas_draw_str(canvas, 5, 30, buffer);
|
||||
snprintf(buffer, 64, "Butthurt: %ld", m->butthurt);
|
||||
canvas_draw_str(canvas, 5, 40, buffer);
|
||||
snprintf(buffer, 64, "Icounter: %ld Butthurt %ld", m->icounter, m->butthurt);
|
||||
canvas_draw_str(canvas, 5, 23, buffer);
|
||||
|
||||
snprintf(buffer, 64, "Level: %ld To level up: %ld", current_lvl, remaining);
|
||||
canvas_draw_str(canvas, 5, 33, buffer);
|
||||
|
||||
snprintf(buffer, 64, "%s", asctime(localtime((const time_t*)&m->timestamp)));
|
||||
canvas_draw_str(canvas, 5, 43, buffer);
|
||||
canvas_draw_str(canvas, 0, 53, "[< >] icounter value [ok] save");
|
||||
}
|
||||
}
|
||||
@ -151,6 +157,7 @@ void desktop_debug_get_dolphin_data(DesktopDebugView* debug_view) {
|
||||
debug_view->view, (DesktopDebugViewModel * model) {
|
||||
model->icounter = stats.icounter;
|
||||
model->butthurt = stats.butthurt;
|
||||
model->timestamp = stats.timestamp;
|
||||
return true;
|
||||
});
|
||||
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include <gui/elements.h>
|
||||
#include <furi.h>
|
||||
#include <storage/storage.h>
|
||||
#include <time.h>
|
||||
|
||||
typedef enum {
|
||||
DesktopDebugEventDeed,
|
||||
@ -35,6 +36,7 @@ struct DesktopDebugView {
|
||||
typedef struct {
|
||||
uint32_t icounter;
|
||||
uint32_t butthurt;
|
||||
uint64_t timestamp;
|
||||
DesktopViewStatsScreens screen;
|
||||
} DesktopDebugViewModel;
|
||||
|
||||
|
@ -2,8 +2,6 @@
|
||||
#include "../desktop_i.h"
|
||||
#include "desktop_locked.h"
|
||||
|
||||
static const Icon* idle_scenes[] = {&A_Wink_128x64, &A_WatchingTV_128x64};
|
||||
|
||||
void desktop_locked_set_callback(
|
||||
DesktopLockedView* locked_view,
|
||||
DesktopLockedViewCallback callback,
|
||||
@ -20,11 +18,11 @@ void locked_view_timer_callback(void* context) {
|
||||
}
|
||||
|
||||
// temporary locked screen animation managment
|
||||
static void desktop_locked_set_scene(DesktopLockedView* locked_view, const Icon* icon_data) {
|
||||
void desktop_locked_set_dolphin_animation(DesktopLockedView* locked_view) {
|
||||
with_view_model(
|
||||
locked_view->view, (DesktopLockedViewModel * model) {
|
||||
if(model->animation) icon_animation_free(model->animation);
|
||||
model->animation = icon_animation_alloc(icon_data);
|
||||
model->animation = icon_animation_alloc(desktop_get_icon());
|
||||
view_tie_icon_animation(locked_view->view, model->animation);
|
||||
return true;
|
||||
});
|
||||
@ -42,8 +40,8 @@ void desktop_locked_reset_door_pos(DesktopLockedView* locked_view) {
|
||||
with_view_model(
|
||||
locked_view->view, (DesktopLockedViewModel * model) {
|
||||
model->animation_seq_end = false;
|
||||
model->door_left_x = -57;
|
||||
model->door_right_x = 115;
|
||||
model->door_left_x = DOOR_L_POS;
|
||||
model->door_right_x = DOOR_R_POS;
|
||||
return true;
|
||||
});
|
||||
}
|
||||
@ -57,10 +55,10 @@ void desktop_locked_manage_redraw(DesktopLockedView* locked_view) {
|
||||
animation_seq_end = model->animation_seq_end;
|
||||
|
||||
if(!model->animation_seq_end) {
|
||||
model->door_left_x = CLAMP(model->door_left_x + 5, 0, -57);
|
||||
model->door_right_x = CLAMP(model->door_right_x - 5, 115, 60);
|
||||
model->door_left_x = CLAMP(model->door_left_x + 5, DOOR_L_POS_MAX, DOOR_L_POS);
|
||||
model->door_right_x = CLAMP(model->door_right_x - 5, DOOR_R_POS, DOOR_R_POS_MIN);
|
||||
} else {
|
||||
model->hint_expire_at = 0;
|
||||
model->hint_expire_at = !model->hint_expire_at;
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -84,7 +82,7 @@ void desktop_locked_reset_counter(DesktopLockedView* locked_view) {
|
||||
|
||||
void desktop_locked_render(Canvas* canvas, void* model) {
|
||||
DesktopLockedViewModel* m = model;
|
||||
|
||||
uint32_t now = osKernelGetTickCount();
|
||||
canvas_clear(canvas);
|
||||
canvas_set_color(canvas, ColorBlack);
|
||||
|
||||
@ -97,7 +95,7 @@ void desktop_locked_render(Canvas* canvas, void* model) {
|
||||
canvas_draw_icon_animation(canvas, 0, -3, m->animation);
|
||||
}
|
||||
|
||||
if(osKernelGetTickCount() < m->hint_expire_at) {
|
||||
if(now < m->hint_expire_at) {
|
||||
if(!m->animation_seq_end) {
|
||||
canvas_set_font(canvas, FontPrimary);
|
||||
elements_multiline_text_framed(canvas, 42, 30, "Locked");
|
||||
@ -125,7 +123,6 @@ bool desktop_locked_input(InputEvent* event, void* context) {
|
||||
|
||||
if(event->key == InputKeyBack) {
|
||||
uint32_t press_time = osKernelGetTickCount();
|
||||
|
||||
// check if pressed sequentially
|
||||
if(press_time - locked_view->lock_lastpress > UNLOCK_RST_TIMEOUT) {
|
||||
locked_view->lock_lastpress = press_time;
|
||||
@ -178,7 +175,6 @@ DesktopLockedView* desktop_locked_alloc() {
|
||||
view_set_enter_callback(locked_view->view, desktop_locked_enter);
|
||||
view_set_exit_callback(locked_view->view, desktop_locked_exit);
|
||||
|
||||
desktop_locked_set_scene(locked_view, idle_scenes[random() % COUNT_OF(idle_scenes)]);
|
||||
return locked_view;
|
||||
}
|
||||
|
||||
|
@ -9,6 +9,11 @@
|
||||
#define UNLOCK_RST_TIMEOUT 300
|
||||
#define UNLOCK_CNT 2 // 3 actually
|
||||
|
||||
#define DOOR_L_POS -57
|
||||
#define DOOR_L_POS_MAX 0
|
||||
#define DOOR_R_POS 115
|
||||
#define DOOR_R_POS_MIN 60
|
||||
|
||||
typedef enum {
|
||||
DesktopLockedEventUnlock,
|
||||
DesktopLockedEventUpdate,
|
||||
@ -44,6 +49,7 @@ void desktop_locked_set_callback(
|
||||
DesktopLockedViewCallback callback,
|
||||
void* context);
|
||||
|
||||
void desktop_locked_set_dolphin_animation(DesktopLockedView* locked_view);
|
||||
void desktop_locked_update_hint_timeout(DesktopLockedView* locked_view);
|
||||
void desktop_locked_reset_counter(DesktopLockedView* locked_view);
|
||||
void desktop_locked_reset_door_pos(DesktopLockedView* locked_view);
|
||||
|
@ -2,8 +2,6 @@
|
||||
#include "../desktop_i.h"
|
||||
#include "desktop_main.h"
|
||||
|
||||
static const Icon* idle_scenes[] = {&A_Wink_128x64, &A_WatchingTV_128x64};
|
||||
|
||||
void desktop_main_set_callback(
|
||||
DesktopMainView* main_view,
|
||||
DesktopMainViewCallback callback,
|
||||
@ -22,38 +20,26 @@ void desktop_main_reset_hint(DesktopMainView* main_view) {
|
||||
});
|
||||
}
|
||||
|
||||
// temporary main screen animation managment
|
||||
static void desktop_main_set_scene(DesktopMainView* main_view, const Icon* icon_data) {
|
||||
void desktop_main_switch_dolphin_animation(DesktopMainView* main_view) {
|
||||
with_view_model(
|
||||
main_view->view, (DesktopMainViewModel * model) {
|
||||
if(model->animation) icon_animation_free(model->animation);
|
||||
model->animation = icon_animation_alloc(icon_data);
|
||||
model->animation = icon_animation_alloc(desktop_get_icon());
|
||||
view_tie_icon_animation(main_view->view, model->animation);
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
void desktop_scene_handler_switch_scene(DesktopMainView* main_view) {
|
||||
with_view_model(
|
||||
main_view->view, (DesktopMainViewModel * model) {
|
||||
if(icon_animation_is_last_frame(model->animation)) {
|
||||
if(model->animation) icon_animation_free(model->animation);
|
||||
model->animation = icon_animation_alloc(idle_scenes[model->scene_num]);
|
||||
model->scene_num = random() % COUNT_OF(idle_scenes);
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
void desktop_main_render(Canvas* canvas, void* model) {
|
||||
canvas_clear(canvas);
|
||||
DesktopMainViewModel* m = model;
|
||||
uint32_t now = osKernelGetTickCount();
|
||||
|
||||
if(m->animation) {
|
||||
canvas_draw_icon_animation(canvas, 0, -3, m->animation);
|
||||
}
|
||||
|
||||
if(osKernelGetTickCount() < m->hint_expire_at) {
|
||||
if(now < m->hint_expire_at) {
|
||||
canvas_set_font(canvas, FontPrimary);
|
||||
elements_multiline_text_framed(canvas, 42, 30, "Unlocked");
|
||||
}
|
||||
@ -115,8 +101,6 @@ DesktopMainView* desktop_main_alloc() {
|
||||
view_set_enter_callback(main_view->view, desktop_main_enter);
|
||||
view_set_exit_callback(main_view->view, desktop_main_exit);
|
||||
|
||||
desktop_main_set_scene(main_view, idle_scenes[random() % COUNT_OF(idle_scenes)]);
|
||||
|
||||
return main_view;
|
||||
}
|
||||
|
||||
|
@ -41,3 +41,5 @@ View* desktop_main_get_view(DesktopMainView* main_view);
|
||||
DesktopMainView* desktop_main_alloc();
|
||||
|
||||
void desktop_main_free(DesktopMainView* main_view);
|
||||
|
||||
void desktop_main_switch_dolphin_animation(DesktopMainView* main_view);
|
||||
|
@ -1,6 +1,6 @@
|
||||
#include "dolphin_i.h"
|
||||
#include <furi.h>
|
||||
|
||||
#define DOLPHIN_TIMEGATE 86400 // one day
|
||||
#define DOLPHIN_LOCK_EVENT_FLAG (0x1)
|
||||
|
||||
void dolphin_deed(Dolphin* dolphin, DolphinDeed deed) {
|
||||
@ -77,6 +77,21 @@ 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());
|
||||
|
||||
#if 0
|
||||
FURI_LOG_I("dolphin-state", "Butthurt check, time since deed %.0f", fabs(diff_time));
|
||||
#endif
|
||||
|
||||
if((fabs(diff_time)) > DOLPHIN_TIMEGATE) {
|
||||
// increase butthurt
|
||||
FURI_LOG_I("dolphin-state", "Increasing butthurt");
|
||||
dolphin_state_butthurted(state);
|
||||
}
|
||||
}
|
||||
|
||||
int32_t dolphin_srv(void* p) {
|
||||
Dolphin* dolphin = dolphin_alloc();
|
||||
furi_record_create("dolphin", dolphin);
|
||||
@ -91,11 +106,13 @@ int32_t dolphin_srv(void* p) {
|
||||
} 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);
|
||||
} else if(event.type == DolphinEventTypeFlush) {
|
||||
dolphin_state_save(dolphin->state);
|
||||
}
|
||||
dolphin_event_release(dolphin, &event);
|
||||
} else {
|
||||
dolphin_check_butthurt(dolphin->state);
|
||||
dolphin_state_save(dolphin->state);
|
||||
}
|
||||
}
|
||||
|
@ -7,6 +7,7 @@ typedef struct Dolphin Dolphin;
|
||||
typedef struct {
|
||||
uint32_t icounter;
|
||||
uint32_t butthurt;
|
||||
uint64_t timestamp;
|
||||
} DolphinStats;
|
||||
|
||||
/** Deed complete notification. Call it on deed completion.
|
||||
|
@ -25,6 +25,7 @@ typedef struct {
|
||||
uint32_t flags;
|
||||
uint32_t icounter;
|
||||
uint32_t butthurt;
|
||||
uint64_t timestamp;
|
||||
} DolphinStoreData;
|
||||
|
||||
typedef struct {
|
||||
@ -107,8 +108,12 @@ bool dolphin_state_load(DolphinState* dolphin_state) {
|
||||
|
||||
File* file = storage_file_alloc(dolphin_state->fs_api);
|
||||
bool load_result = storage_file_open(file, DOLPHIN_STORE_KEY, FSAM_READ, FSOM_OPEN_EXISTING);
|
||||
|
||||
if(load_result) {
|
||||
if(!load_result) {
|
||||
FURI_LOG_E(
|
||||
"dolphin-state",
|
||||
"Load failed. Storage returned: %s",
|
||||
storage_file_get_error_desc(file));
|
||||
} else {
|
||||
uint16_t bytes_count = storage_file_read(file, &store, sizeof(DolphinStore));
|
||||
|
||||
if(bytes_count != sizeof(DolphinStore)) {
|
||||
@ -117,12 +122,8 @@ bool dolphin_state_load(DolphinState* dolphin_state) {
|
||||
}
|
||||
|
||||
if(!load_result) {
|
||||
FURI_LOG_E(
|
||||
"dolphin-state",
|
||||
"Load failed. Storage returned: %s",
|
||||
storage_file_get_error_desc(file));
|
||||
FURI_LOG_E("dolphin-state", "DolphinStore size mismatch");
|
||||
} else {
|
||||
FURI_LOG_I("dolphin-state", "State loaded, verifying header");
|
||||
if(store.header.magic == DOLPHIN_STORE_HEADER_MAGIC &&
|
||||
store.header.version == DOLPHIN_STORE_HEADER_VERSION) {
|
||||
FURI_LOG_I(
|
||||
@ -150,7 +151,7 @@ bool dolphin_state_load(DolphinState* dolphin_state) {
|
||||
} else {
|
||||
FURI_LOG_E(
|
||||
"dolphin-state",
|
||||
"Magic(%d != %d) and Version(%d != %d) mismatch",
|
||||
"Magic(%d != %d) or Version(%d != %d) mismatch",
|
||||
store.header.magic,
|
||||
DOLPHIN_STORE_HEADER_MAGIC,
|
||||
store.header.version,
|
||||
@ -171,17 +172,45 @@ void dolphin_state_clear(DolphinState* dolphin_state) {
|
||||
memset(&dolphin_state->data, 0, sizeof(DolphinStoreData));
|
||||
}
|
||||
|
||||
uint64_t dolphin_state_timestamp() {
|
||||
RTC_TimeTypeDef time;
|
||||
RTC_DateTypeDef date;
|
||||
struct tm current;
|
||||
|
||||
HAL_RTC_GetTime(&hrtc, &time, RTC_FORMAT_BIN);
|
||||
HAL_RTC_GetDate(&hrtc, &date, RTC_FORMAT_BIN);
|
||||
|
||||
current.tm_year = date.Year + 100;
|
||||
current.tm_mday = date.Date;
|
||||
current.tm_mon = date.Month - 1;
|
||||
|
||||
current.tm_hour = time.Hours;
|
||||
current.tm_min = time.Minutes;
|
||||
current.tm_sec = time.Seconds;
|
||||
|
||||
return mktime(¤t);
|
||||
}
|
||||
|
||||
void 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;
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
dolphin_state->dirty = true;
|
||||
}
|
||||
|
||||
void dolphin_state_butthurted(DolphinState* dolphin_state) {
|
||||
dolphin_state->data.butthurt++;
|
||||
dolphin_state->data.timestamp = dolphin_state_timestamp();
|
||||
dolphin_state->dirty = true;
|
||||
}
|
||||
|
||||
uint32_t dolphin_state_get_icounter(DolphinState* dolphin_state) {
|
||||
return dolphin_state->data.icounter;
|
||||
}
|
||||
@ -190,13 +219,14 @@ uint32_t dolphin_state_get_butthurt(DolphinState* dolphin_state) {
|
||||
return dolphin_state->data.butthurt;
|
||||
}
|
||||
|
||||
uint32_t dolphin_state_get_level(DolphinState* dolphin_state) {
|
||||
return 0.5f +
|
||||
sqrtf(1.0f + 8.0f * ((float)dolphin_state->data.icounter / DOLPHIN_LVL_THRESHOLD)) /
|
||||
2.0f;
|
||||
uint64_t dolphin_state_get_timestamp(DolphinState* dolphin_state) {
|
||||
return dolphin_state->data.timestamp;
|
||||
}
|
||||
|
||||
uint32_t dolphin_state_xp_to_levelup(DolphinState* dolphin_state, uint32_t level, bool remaining) {
|
||||
return (DOLPHIN_LVL_THRESHOLD * level * (level + 1) / 2) -
|
||||
(remaining ? dolphin_state->data.icounter : 0);
|
||||
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);
|
||||
}
|
@ -3,6 +3,8 @@
|
||||
#include "dolphin_deed.h"
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <rtc.h>
|
||||
#include <time.h>
|
||||
|
||||
typedef struct DolphinState DolphinState;
|
||||
|
||||
@ -16,12 +18,18 @@ bool dolphin_state_load(DolphinState* dolphin_state);
|
||||
|
||||
void dolphin_state_clear(DolphinState* dolphin_state);
|
||||
|
||||
uint64_t dolphin_state_timestamp();
|
||||
|
||||
void 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_get_butthurt(DolphinState* dolphin_state);
|
||||
|
||||
uint32_t dolphin_state_get_level(DolphinState* dolphin_state);
|
||||
uint64_t dolphin_state_get_timestamp(DolphinState* dolphin_state);
|
||||
|
||||
uint32_t dolphin_state_xp_to_levelup(DolphinState* dolphin_state, uint32_t level, bool remaining);
|
||||
uint32_t dolphin_state_get_level(uint32_t icounter);
|
||||
|
||||
uint32_t dolphin_state_xp_to_levelup(uint32_t icounter, uint32_t level, bool remaining);
|
Loading…
Reference in New Issue
Block a user