|
|
@@ -14,6 +14,8 @@
|
|
|
/* generated by fbt from .png files in images folder */
|
|
|
#include <simon_says_icons.h>
|
|
|
|
|
|
+#include <assets_icons.h>
|
|
|
+
|
|
|
#define TAG "Simon" // Used for logging
|
|
|
#define DEBUG_MSG 1
|
|
|
#define SCREEN_XRES 128
|
|
|
@@ -21,7 +23,7 @@
|
|
|
#define BOARD_X 72 // Used for board placement
|
|
|
#define BOARD_Y 8
|
|
|
#define GAME_START_LIVES 3
|
|
|
-#define SAVING_DIRECTORY "/ext/apps/Games"
|
|
|
+#define SAVING_DIRECTORY STORAGE_APP_DATA_PATH_PREFIX
|
|
|
#define SAVING_FILENAME SAVING_DIRECTORY "/game_simon_says.save"
|
|
|
|
|
|
// Define Notes
|
|
|
@@ -69,6 +71,7 @@ typedef struct {
|
|
|
|
|
|
uint32_t last_button_press_tick;
|
|
|
NotificationApp* notification;
|
|
|
+ FuriMutex* mutex;
|
|
|
} SimonData;
|
|
|
|
|
|
/* ============================== Sequences ============================== */
|
|
|
@@ -189,25 +192,25 @@ void draw_current_score(Canvas* canvas, const SimonData* simon_data) {
|
|
|
canvas_draw_str_aligned(canvas, SCREEN_XRES / 2 + 4, 2, AlignCenter, AlignTop, str_score);
|
|
|
}
|
|
|
|
|
|
-void play_sound_up(SimonData* const app) {
|
|
|
+void play_sound_up(const SimonData* app) {
|
|
|
if(furi_hal_speaker_is_mine() || furi_hal_speaker_acquire(30)) {
|
|
|
furi_hal_speaker_start(NOTE_UP, app->volume);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-void play_sound_down(SimonData* const app) {
|
|
|
+void play_sound_down(const SimonData* app) {
|
|
|
if(furi_hal_speaker_is_mine() || furi_hal_speaker_acquire(30)) {
|
|
|
furi_hal_speaker_start(NOTE_DOWN, app->volume);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-void play_sound_left(SimonData* const app) {
|
|
|
+void play_sound_left(const SimonData* app) {
|
|
|
if(furi_hal_speaker_is_mine() || furi_hal_speaker_acquire(30)) {
|
|
|
furi_hal_speaker_start(NOTE_LEFT, app->volume);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-void play_sound_right(SimonData* const app) {
|
|
|
+void play_sound_right(const SimonData* app) {
|
|
|
if(furi_hal_speaker_is_mine() || furi_hal_speaker_acquire(30)) {
|
|
|
furi_hal_speaker_start(NOTE_RIGHT, app->volume);
|
|
|
}
|
|
|
@@ -222,13 +225,9 @@ void stop_sound() {
|
|
|
|
|
|
/* Main Render Function */
|
|
|
void simon_draw_callback(Canvas* canvas, void* ctx) {
|
|
|
- SimonData* const simon_state = acquire_mutex((ValueMutex*)ctx, 25);
|
|
|
- if(simon_state == NULL) {
|
|
|
- if(DEBUG_MSG) FURI_LOG_E(TAG, "[simon_draw_callback] Null simon state");
|
|
|
- return;
|
|
|
- }
|
|
|
+ const SimonData* simon_state = ctx;
|
|
|
+ furi_mutex_acquire(simon_state->mutex, FuriWaitForever);
|
|
|
|
|
|
- UNUSED(ctx);
|
|
|
canvas_clear(canvas);
|
|
|
|
|
|
// ######################### Main Menu #########################
|
|
|
@@ -358,7 +357,7 @@ void simon_draw_callback(Canvas* canvas, void* ctx) {
|
|
|
//TODO
|
|
|
|
|
|
//release the mutex
|
|
|
- release_mutex((ValueMutex*)ctx, simon_state);
|
|
|
+ furi_mutex_release(simon_state->mutex);
|
|
|
}
|
|
|
|
|
|
/* ======================== Input Handling ============================== */
|
|
|
@@ -373,6 +372,7 @@ void simon_input_callback(InputEvent* input_event, void* ctx) {
|
|
|
|
|
|
bool load_game(SimonData* app) {
|
|
|
Storage* storage = furi_record_open(RECORD_STORAGE);
|
|
|
+ storage_common_migrate(storage, EXT_PATH("apps/Games/game_simon_says.save"), SAVING_FILENAME);
|
|
|
|
|
|
File* file = storage_file_alloc(storage);
|
|
|
|
|
|
@@ -396,12 +396,6 @@ bool load_game(SimonData* app) {
|
|
|
void save_game(SimonData* app) {
|
|
|
Storage* storage = furi_record_open(RECORD_STORAGE);
|
|
|
|
|
|
- if(storage_common_stat(storage, SAVING_DIRECTORY, NULL) == FSE_NOT_EXIST) {
|
|
|
- if(!storage_simply_mkdir(storage, SAVING_DIRECTORY)) {
|
|
|
- return;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
File* file = storage_file_alloc(storage);
|
|
|
if(storage_file_open(file, SAVING_FILENAME, FSAM_WRITE, FSOM_CREATE_ALWAYS)) {
|
|
|
storage_file_write(file, app, sizeof(SimonData));
|
|
|
@@ -556,8 +550,8 @@ int32_t simon_says_app_entry(void* p) {
|
|
|
FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(InputEvent));
|
|
|
|
|
|
SimonData* simon_state = malloc(sizeof(SimonData));
|
|
|
- ValueMutex simon_state_value_mutex;
|
|
|
- if(!init_mutex(&simon_state_value_mutex, simon_state, sizeof(SimonData))) {
|
|
|
+ simon_state->mutex = furi_mutex_alloc(FuriMutexTypeNormal);
|
|
|
+ if(!simon_state->mutex) {
|
|
|
FURI_LOG_E(TAG, "cannot create mutex\r\n");
|
|
|
free(simon_state);
|
|
|
return -1;
|
|
|
@@ -565,7 +559,7 @@ int32_t simon_says_app_entry(void* p) {
|
|
|
|
|
|
// Configure view port
|
|
|
ViewPort* view_port = view_port_alloc();
|
|
|
- view_port_draw_callback_set(view_port, simon_draw_callback, &simon_state_value_mutex);
|
|
|
+ view_port_draw_callback_set(view_port, simon_draw_callback, simon_state);
|
|
|
view_port_input_callback_set(view_port, simon_input_callback, event_queue);
|
|
|
|
|
|
// Register view port in GUI
|
|
|
@@ -578,7 +572,7 @@ int32_t simon_says_app_entry(void* p) {
|
|
|
InputEvent input;
|
|
|
|
|
|
// Show Main Menu Screen
|
|
|
- load_game(simon_state);
|
|
|
+ //load_game(simon_state);
|
|
|
restart_game_after_gameover(simon_state);
|
|
|
simon_state->gameState = mainMenu;
|
|
|
|
|
|
@@ -587,15 +581,16 @@ int32_t simon_says_app_entry(void* p) {
|
|
|
|
|
|
FuriStatus q_status = furi_message_queue_get(
|
|
|
event_queue, &input, simon_state->numberOfMillisecondsBeforeShapeDisappears);
|
|
|
+ furi_mutex_acquire(simon_state->mutex, FuriWaitForever);
|
|
|
|
|
|
if(q_status == FuriStatusOk) {
|
|
|
- FURI_LOG_D(TAG, "Got input event: %d", input.key);
|
|
|
+ //FURI_LOG_D(TAG, "Got input event: %d", input.key);
|
|
|
//break out of the loop if the back key is pressed
|
|
|
if(input.key == InputKeyBack && input.type == InputTypeLong) {
|
|
|
// Save high score before quitting
|
|
|
- if(simon_state->is_new_highscore) {
|
|
|
- save_game(simon_state);
|
|
|
- }
|
|
|
+ //if(simon_state->is_new_highscore) {
|
|
|
+ // save_game(simon_state);
|
|
|
+ //}
|
|
|
break;
|
|
|
}
|
|
|
|
|
|
@@ -636,12 +631,12 @@ int32_t simon_says_app_entry(void* p) {
|
|
|
break;
|
|
|
}
|
|
|
} else {
|
|
|
- FURI_LOG_D(TAG, "Input type is not short");
|
|
|
+ //FURI_LOG_D(TAG, "Input type is not short");
|
|
|
simon_state->set_board_neutral = true;
|
|
|
}
|
|
|
}
|
|
|
- } else {
|
|
|
- FURI_LOG_E(TAG, "cannot get message from queue\r\n");
|
|
|
+ // } else {
|
|
|
+ // FURI_LOG_E(TAG, "cannot get message from queue\r\n");
|
|
|
}
|
|
|
|
|
|
// @todo Animation Loop for debug
|
|
|
@@ -651,6 +646,7 @@ int32_t simon_says_app_entry(void* p) {
|
|
|
// }
|
|
|
|
|
|
view_port_update(view_port);
|
|
|
+ furi_mutex_release(simon_state->mutex);
|
|
|
}
|
|
|
|
|
|
stop_sound();
|
|
|
@@ -658,9 +654,10 @@ int32_t simon_says_app_entry(void* p) {
|
|
|
gui_remove_view_port(gui, view_port);
|
|
|
view_port_free(view_port);
|
|
|
furi_message_queue_free(event_queue);
|
|
|
- free(simon_state);
|
|
|
+ furi_mutex_free(simon_state->mutex);
|
|
|
furi_record_close(RECORD_NOTIFICATION);
|
|
|
furi_record_close(RECORD_GUI);
|
|
|
+ free(simon_state);
|
|
|
|
|
|
return 0;
|
|
|
}
|