unleashed-firmware/applications/flipfrid/flipfrid.c

238 lines
8.2 KiB
C
Raw Normal View History

2022-08-24 16:14:03 +00:00
#include "flipfrid.h"
2022-09-01 15:03:18 +00:00
#include "scene/flipfrid_scene_entrypoint.h"
#include "scene/flipfrid_scene_load_file.h"
#include "scene/flipfrid_scene_select_field.h"
#include "scene/flipfrid_scene_run_attack.h"
2022-08-24 16:14:03 +00:00
static void flipfrid_draw_callback(Canvas* const canvas, void* ctx) {
2022-09-01 15:03:18 +00:00
FlipFridState* flipfrid_state = (FlipFridState*)acquire_mutex((ValueMutex*)ctx, 100);
2022-08-24 16:14:03 +00:00
if(flipfrid_state == NULL) {
return;
}
2022-09-01 15:03:18 +00:00
// Draw correct Canvas
switch(flipfrid_state->current_scene) {
case NoneScene:
case SceneEntryPoint:
flipfrid_scene_entrypoint_on_draw(canvas, flipfrid_state);
2022-08-24 16:14:03 +00:00
break;
2022-09-01 15:03:18 +00:00
case SceneSelectFile:
flipfrid_scene_load_file_on_draw(canvas, flipfrid_state);
2022-08-24 16:14:03 +00:00
break;
2022-09-01 15:03:18 +00:00
case SceneSelectField:
flipfrid_scene_select_field_on_draw(canvas, flipfrid_state);
2022-08-24 16:14:03 +00:00
break;
2022-09-01 15:03:18 +00:00
case SceneAttack:
flipfrid_scene_run_attack_on_draw(canvas, flipfrid_state);
2022-08-24 16:14:03 +00:00
break;
}
release_mutex((ValueMutex*)ctx, flipfrid_state);
}
void flipfrid_input_callback(InputEvent* input_event, FuriMessageQueue* event_queue) {
furi_assert(event_queue);
FlipFridEvent event = {
.evt_type = EventTypeKey, .key = input_event->key, .input_type = input_event->type};
furi_message_queue_put(event_queue, &event, 25);
}
static void flipfrid_timer_callback(FuriMessageQueue* event_queue) {
furi_assert(event_queue);
FlipFridEvent event = {
.evt_type = EventTypeTick, .key = InputKeyUp, .input_type = InputTypeRelease};
furi_message_queue_put(event_queue, &event, 25);
}
2022-09-01 15:03:18 +00:00
FlipFridState* flipfrid_alloc() {
FlipFridState* flipfrid = malloc(sizeof(FlipFridState));
string_init(flipfrid->file_path);
string_init(flipfrid->file_path_tmp);
string_init(flipfrid->notification_msg);
string_init(flipfrid->attack_name);
flipfrid->previous_scene = NoneScene;
flipfrid->current_scene = SceneEntryPoint;
flipfrid->is_running = true;
flipfrid->is_attacking = false;
flipfrid->key_index = 0;
flipfrid->menu_index = 0;
flipfrid->attack = FlipFridAttackDefaultValues;
flipfrid->notify = furi_record_open(RECORD_NOTIFICATION);
flipfrid->data[0] = 0x00;
flipfrid->data[1] = 0x00;
flipfrid->data[2] = 0x00;
flipfrid->data[3] = 0x00;
flipfrid->data[4] = 0x00;
flipfrid->payload[0] = 0x00;
flipfrid->payload[1] = 0x00;
flipfrid->payload[2] = 0x00;
flipfrid->payload[3] = 0x00;
flipfrid->payload[4] = 0x00;
//Dialog
flipfrid->dialogs = furi_record_open(RECORD_DIALOGS);
return flipfrid;
}
void flipfrid_free(FlipFridState* flipfrid) {
//Dialog
furi_record_close(RECORD_DIALOGS);
notification_message(flipfrid->notify, &sequence_blink_stop);
// Path strings
string_clear(flipfrid->file_path);
string_clear(flipfrid->file_path_tmp);
string_clear(flipfrid->notification_msg);
string_clear(flipfrid->attack_name);
free(flipfrid->data);
free(flipfrid->payload);
// The rest
free(flipfrid);
}
2022-08-24 16:14:03 +00:00
// ENTRYPOINT
int32_t flipfrid_start(void* p) {
2022-09-01 15:46:08 +00:00
UNUSED(p);
2022-08-24 16:14:03 +00:00
// Input
2022-09-01 15:03:18 +00:00
FURI_LOG_I(TAG, "Initializing input");
2022-08-24 16:14:03 +00:00
FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(FlipFridEvent));
2022-09-01 15:03:18 +00:00
FlipFridState* flipfrid_state = flipfrid_alloc();
2022-08-24 16:14:03 +00:00
ValueMutex flipfrid_state_mutex;
// Mutex
2022-09-01 15:03:18 +00:00
FURI_LOG_I(TAG, "Initializing flipfrid mutex");
2022-08-24 16:14:03 +00:00
if(!init_mutex(&flipfrid_state_mutex, flipfrid_state, sizeof(FlipFridState))) {
2022-09-01 15:03:18 +00:00
FURI_LOG_E(TAG, "cannot create mutex\r\n");
2022-08-24 16:14:03 +00:00
furi_message_queue_free(event_queue);
furi_record_close(RECORD_NOTIFICATION);
furi_record_close(RECORD_DIALOGS);
2022-08-24 16:14:03 +00:00
free(flipfrid_state);
return 255;
2022-08-24 16:14:03 +00:00
}
// Configure view port
2022-09-01 15:03:18 +00:00
FURI_LOG_I(TAG, "Initializing viewport");
2022-08-24 16:14:03 +00:00
ViewPort* view_port = view_port_alloc();
view_port_draw_callback_set(view_port, flipfrid_draw_callback, &flipfrid_state_mutex);
view_port_input_callback_set(view_port, flipfrid_input_callback, event_queue);
// Configure timer
2022-09-01 15:03:18 +00:00
FURI_LOG_I(TAG, "Initializing timer");
2022-08-24 16:14:03 +00:00
FuriTimer* timer =
furi_timer_alloc(flipfrid_timer_callback, FuriTimerTypePeriodic, event_queue);
2022-09-01 15:03:18 +00:00
furi_timer_start(timer, furi_kernel_get_tick_frequency() / 10); // 10 times per second
2022-08-24 16:14:03 +00:00
// Register view port in GUI
2022-09-01 15:03:18 +00:00
FURI_LOG_I(TAG, "Initializing gui");
2022-08-24 16:14:03 +00:00
Gui* gui = (Gui*)furi_record_open(RECORD_GUI);
gui_add_view_port(gui, view_port, GuiLayerFullscreen);
// Init values
FlipFridEvent event;
2022-09-01 15:03:18 +00:00
while(flipfrid_state->is_running) {
2022-08-24 16:14:03 +00:00
// Get next event
FuriStatus event_status = furi_message_queue_get(event_queue, &event, 25);
if(event_status == FuriStatusOk) {
if(event.evt_type == EventTypeKey) {
2022-09-01 15:03:18 +00:00
//Handle event key
switch(flipfrid_state->current_scene) {
case NoneScene:
case SceneEntryPoint:
flipfrid_scene_entrypoint_on_event(event, flipfrid_state);
break;
case SceneSelectFile:
flipfrid_scene_load_file_on_event(event, flipfrid_state);
break;
case SceneSelectField:
flipfrid_scene_select_field_on_event(event, flipfrid_state);
break;
case SceneAttack:
flipfrid_scene_run_attack_on_event(event, flipfrid_state);
break;
}
} else if(event.evt_type == EventTypeTick) {
//Handle event tick
if(flipfrid_state->current_scene != flipfrid_state->previous_scene) {
// Trigger Exit Scene
switch(flipfrid_state->previous_scene) {
case SceneEntryPoint:
flipfrid_scene_entrypoint_on_exit(flipfrid_state);
2022-08-24 16:14:03 +00:00
break;
2022-09-01 15:03:18 +00:00
case SceneSelectFile:
flipfrid_scene_load_file_on_exit(flipfrid_state);
2022-08-24 16:14:03 +00:00
break;
2022-09-01 15:03:18 +00:00
case SceneSelectField:
flipfrid_scene_select_field_on_exit(flipfrid_state);
2022-08-24 16:14:03 +00:00
break;
2022-09-01 15:03:18 +00:00
case SceneAttack:
flipfrid_scene_run_attack_on_exit(flipfrid_state);
2022-08-24 16:14:03 +00:00
break;
2022-09-01 15:03:18 +00:00
case NoneScene:
2022-08-24 16:14:03 +00:00
break;
}
2022-09-01 15:03:18 +00:00
// Trigger Entry Scene
switch(flipfrid_state->current_scene) {
case NoneScene:
case SceneEntryPoint:
flipfrid_scene_entrypoint_on_enter(flipfrid_state);
break;
case SceneSelectFile:
flipfrid_scene_load_file_on_enter(flipfrid_state);
break;
case SceneSelectField:
flipfrid_scene_select_field_on_enter(flipfrid_state);
break;
case SceneAttack:
flipfrid_scene_run_attack_on_enter(flipfrid_state);
break;
2022-08-24 16:14:03 +00:00
}
2022-09-01 15:03:18 +00:00
flipfrid_state->previous_scene = flipfrid_state->current_scene;
}
// Trigger Tick Scene
switch(flipfrid_state->current_scene) {
case NoneScene:
case SceneEntryPoint:
flipfrid_scene_entrypoint_on_tick(flipfrid_state);
break;
case SceneSelectFile:
flipfrid_scene_load_file_on_tick(flipfrid_state);
break;
case SceneSelectField:
flipfrid_scene_select_field_on_tick(flipfrid_state);
break;
case SceneAttack:
flipfrid_scene_run_attack_on_tick(flipfrid_state);
break;
2022-08-24 16:14:03 +00:00
}
view_port_update(view_port);
}
}
}
// Cleanup
furi_timer_stop(timer);
furi_timer_free(timer);
2022-09-01 15:03:18 +00:00
FURI_LOG_I(TAG, "Cleaning up");
2022-08-24 16:14:03 +00:00
gui_remove_view_port(gui, view_port);
view_port_free(view_port);
furi_message_queue_free(event_queue);
furi_record_close(RECORD_GUI);
furi_record_close(RECORD_NOTIFICATION);
2022-09-01 15:03:18 +00:00
flipfrid_free(flipfrid_state);
2022-08-24 16:14:03 +00:00
return 0;
}