diff --git a/applications/plugins/asteroids/LICENSE b/applications/plugins/asteroids/LICENSE new file mode 100644 index 000000000..2d8a8a74d --- /dev/null +++ b/applications/plugins/asteroids/LICENSE @@ -0,0 +1,24 @@ +Copyright (c) 2022-2023 Salvatore Sanfilippo + +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/applications/plugins/asteroids/app.c b/applications/plugins/asteroids/app.c index 9aee8e9f0..495542a24 100644 --- a/applications/plugins/asteroids/app.c +++ b/applications/plugins/asteroids/app.c @@ -13,23 +13,51 @@ #include #include #include +#include #define TAG "Asteroids" // Used for logging -#define DEBUG_MSG 1 +#define DEBUG_MSG 0 #define SCREEN_XRES 128 #define SCREEN_YRES 64 #define GAME_START_LIVES 3 +#define MAXLIVES 5 /* Max bonus lives allowed. */ #define TTLBUL 30 /* Bullet time to live, in ticks. */ -#define MAXBUL 5 /* Max bullets on the screen. */ +#define MAXBUL 50 /* Max bullets on the screen. */ +//@todo MAX Asteroids #define MAXAST 32 /* Max asteroids on the screen. */ +#define MAXPOWERUPS 3 /* Max powerups allowed on screen */ +#define POWERUPSTTL 400 /* Max powerup time to live, in ticks. */ #define SHIP_HIT_ANIMATION_LEN 15 -#define SAVING_DIRECTORY "/ext/apps_data/asteroids" +#define SAVING_DIRECTORY "/ext/apps/Games" #define SAVING_FILENAME SAVING_DIRECTORY "/game_asteroids.save" #ifndef PI #define PI 3.14159265358979f #endif /* ============================ Data structures ============================= */ +typedef enum PowerUpType { + PowerUpTypeShield, // Shield + PowerUpTypeLife, // Extra life + PowerUpTypeFirePower, // Burst Fire power + // PowerUpTypeRadialFire, // Radial Fire power + PowerUpTypeNuke, // Nuke power + // PowerUpTypeClone, // Clone ship + // PowerUpTypeAssist, // Secondary ship + Number_of_PowerUps // Used to count the number of powerups +} PowerUpType; + +// struct PowerUp +typedef struct PowerUp { + float x, y, vx, vy; /* Fields like in ship. */ + // rot, /* Fields like ship. */ + // rot_speed, /* Angular velocity (rot speed and sense). */ + float size; /* Power Up size */ + + uint32_t ttl; /* Time to live, in ticks. */ + uint32_t display_ttl; /* How long to display the powerup before it disappears */ + enum PowerUpType powerUpType; /* PowerUp type */ + bool isPowerUpActive; /* Is the powerup active? */ +} PowerUp; typedef struct Ship { float x, /* Ship x position. */ @@ -51,6 +79,7 @@ typedef struct Asteroid { uint8_t shape_seed; /* Seed to give random shape. */ } Asteroid; +// @todo AsteroidsApp typedef struct AsteroidsApp { /* GUI */ Gui* gui; @@ -61,6 +90,7 @@ typedef struct AsteroidsApp { /* Game state. */ int running; /* Once false exists the app. */ bool gameover; /* Gameover status. */ + bool paused; /* Game paused status. */ uint32_t ticks; /* Game ticks. Increments at each refresh. */ uint32_t score; /* Game score. */ uint32_t highscore; /* Highscore. Shown on Game Over Screen */ @@ -73,11 +103,14 @@ typedef struct AsteroidsApp { /* Ship state. */ struct Ship ship; + struct PowerUp powerUps[MAXPOWERUPS]; /* Each powerup state. */ + int powerUps_num; /* Active powerups. */ /* Bullets state. */ struct Bullet bullets[MAXBUL]; /* Each bullet state. */ int bullets_num; /* Active bullets. */ uint32_t last_bullet_tick; /* Tick the last bullet was fired. */ + uint32_t bullet_min_period; /* Minimum time between bullets in ms. */ /* Asteroids state. */ Asteroid asteroids[MAXAST]; /* Each asteroid state. */ @@ -133,9 +166,63 @@ const NotificationSequence sequence_bullet_fired = { NULL, }; +const NotificationSequence sequence_powerup_collected = { + &message_vibro_on, + &message_delay_1, + &message_delay_1, + &message_delay_1, + &message_delay_1, + &message_delay_1, + &message_vibro_off, + NULL, +}; + +const NotificationSequence sequence_nuke = { + &message_blink_set_color_red, + &message_blink_start_100, + + &message_vibro_on, + &message_delay_10, + &message_vibro_off, + + &message_vibro_on, + &message_delay_10, + &message_vibro_off, + + &message_vibro_on, + &message_delay_10, + &message_vibro_off, + &message_red_0, + + &message_vibro_on, + &message_delay_10, + &message_delay_1, + &message_delay_1, + &message_vibro_off, + + &message_vibro_on, + &message_delay_10, + &message_delay_1, + &message_delay_1, + &message_vibro_off, + + &message_vibro_on, + &message_delay_10, + &message_delay_1, + &message_delay_1, + &message_vibro_off, + + &message_blink_stop, + &message_vibro_off, + &message_sound_off, + NULL, +}; + /* ============================== Prototyeps ================================ */ // Only functions called before their definition are here. +bool isPowerUpActive(AsteroidsApp* app, enum PowerUpType powerUpType); +bool isPowerUpAlreadyExists(AsteroidsApp* app, enum PowerUpType powerUpType); bool load_game(AsteroidsApp* app); void save_game(AsteroidsApp* app); void restart_game_after_gameover(AsteroidsApp* app); @@ -183,6 +270,8 @@ void lfsr_next(unsigned char* prev) { *prev ^= *prev << 7; /* Mix things a bit more. */ } +/* ================================ Render ================================ */ + /* Render the polygon 'poly' at x,y, rotated by the specified angle. */ void draw_poly(Canvas* const canvas, Poly* poly, uint8_t x, uint8_t y, float a) { Poly rot; @@ -249,20 +338,127 @@ void draw_left_lives(Canvas* const canvas, AsteroidsApp* app) { } } -/* Given the current position, update it according to the velocity and - * wrap it back to the other side if the object went over the screen. */ -void update_pos_by_velocity(float* x, float* y, float vx, float vy) { - /* Return back from one side to the other of the screen. */ - *x += vx; - *y += vy; - if(*x >= SCREEN_XRES) - *x = 0; - else if(*x < 0) - *x = SCREEN_XRES - 1; - if(*y >= SCREEN_YRES) - *y = 0; - else if(*y < 0) - *y = SCREEN_YRES - 1; +bool should_draw_powerUp(PowerUp* const p) { + // Just return if power up has already been picked up + if(p->display_ttl == 0) return false; + + // Begin flashing power up when it is about to expire + if(p->display_ttl < 100) { + return p->display_ttl % 8 > 0; + } + + return true; +} + +void draw_powerUp_RemainingLife(Canvas* canvas, PowerUp* const p, int y_offset) { + if(!p->isPowerUpActive) return; + + /* + Here we generate a reverse progress bar. The bar is 24 pixels wide and 1 pixel tall. + Calculate the percentage of hitpoints left: hitpoints / total hitpoints + Multiply the percentage by the width of the bar (in pixels): percentage * bar width + Subtract the result from the width of the bar to get the filled portion of the bar: bar width - (percentage * bar width) + Round the result to the nearest integer to get the final result. + + 400 / 400 = 1.0 + 1.0 * 24 = 24 + 24 - 24 = 0 + Round(0) = 0 + */ + int progress_bar_width = SCREEN_XRES / 4; + + if(p->ttl > 0) { + canvas_set_color(canvas, ColorBlack); + int remaining = ceil(((float)p->ttl / (float)POWERUPSTTL) * (float)progress_bar_width); + + if(remaining > 0) { + canvas_draw_line( + canvas, + (SCREEN_XRES / 2) - remaining, // x1 + 3 + y_offset, //y1 + (SCREEN_XRES / 2) + remaining, //x2 + 3 + y_offset); // y2 + } + } +} + +void draw_powerUps(Canvas* const canvas, PowerUp* const p) { + /* + + * * * * * * * * * * + * * + * * + * * + * F * + * * + * * + * * + * * + * * * * * * * * * * + + BOX_SIZE = 10 + Box_Width = BOX_SIZE + BOX_HEIGHT = BOX_SIZE + BOX_X_POS = x - BOX_WIDTH/2 + BOX_Y_POS = y - BOX_HEIGHT/2 + POS_F_X = WIDTH/2 + POS_F_Y = HEIGHT/2 + + */ + + //@todo render_callback + + // Just return if power up has already been picked up + // FURI_LOG_I(TAG, "[draw_powerUps] Display TTL: %lu", p->display_ttl); + if(p->display_ttl == 0) return; + if(!should_draw_powerUp(p)) return; + + canvas_set_color(canvas, ColorXOR); + + // Display power up to be picked up + switch(p->powerUpType) { + case PowerUpTypeFirePower: + canvas_draw_icon(canvas, p->x, p->y, &I_firepower_shifted_9x10); + break; + case PowerUpTypeShield: + canvas_draw_icon(canvas, p->x, p->y, &I_shield_frame); + break; + case PowerUpTypeLife: + // Draw a heart + canvas_draw_icon(canvas, p->x, p->y, &I_heart_10x10); + break; + case PowerUpTypeNuke: + // canvas_draw_disc(canvas, p->x, p->y, p->size); + // canvas_draw_str(canvas, p->x, p->y, "N"); + canvas_draw_icon(canvas, p->x, p->y, &I_nuke_10x10); + break; + // case PowerUpTypeRadialFire: + // // Draw box with letter R inside + // canvas_draw_str(canvas, p->x, p->y, "R"); + // break; + // case PowerUpTypeAssist: + // // Draw box with letter A inside + // canvas_draw_str(canvas, p->x, p->y, "A"); + // break; + // case PowerUpTypeClone: + // // Draw box with letter C inside + // canvas_draw_str(canvas, p->x, p->y, "C"); + // break; + default: + //@todo Uknown Power Up Type Detected + // Draw box with letter U inside + canvas_draw_str(canvas, p->x, p->y, "?"); + FURI_LOG_E(TAG, "Unexpected Power Up Type Detected: %i", p->powerUpType); + break; + } +} + +void draw_shield(Canvas* const canvas, AsteroidsApp* app) { + if(isPowerUpActive(app, PowerUpTypeShield) == false) return; + + canvas_set_color(canvas, ColorXOR); + // canvas_draw_disc(canvas, app->ship.x, app->ship.y, 4); + canvas_draw_circle(canvas, app->ship.x, app->ship.y, 8); } /* Render the current game screen. */ @@ -286,6 +482,9 @@ void render_callback(Canvas* const canvas, void* ctx) { /* Draw ship, asteroids, bullets. */ draw_poly(canvas, &ShipPoly, app->ship.x, app->ship.y, app->ship.rot); + /* Draw shield if active. */ + draw_shield(canvas, app); + if(key_pressed_time(app, InputKeyUp) > 0) { notification_message(furi_record_open(RECORD_NOTIFICATION), &sequence_thrusters); draw_poly(canvas, &ShipFirePoly, app->ship.x, app->ship.y, app->ship.rot); @@ -295,6 +494,20 @@ void render_callback(Canvas* const canvas, void* ctx) { for(int j = 0; j < app->asteroids_num; j++) draw_asteroid(canvas, &app->asteroids[j]); + for(int j = 0; j < app->powerUps_num; j++) { + draw_powerUps(canvas, &app->powerUps[j]); + draw_powerUp_RemainingLife(canvas, &app->powerUps[j], j); + } + + if(app->paused) { + canvas_set_color(canvas, ColorXOR); + canvas_set_font(canvas, FontPrimary); + canvas_draw_rbox(canvas, 0, 0, SCREEN_XRES, SCREEN_YRES, 4); + canvas_draw_str_aligned( + canvas, SCREEN_XRES / 2, SCREEN_YRES / 2, AlignCenter, AlignCenter, "Paused"); + return; + } + /* Game over text. */ if(app->gameover) { canvas_set_color(canvas, ColorBlack); @@ -331,6 +544,22 @@ void render_callback(Canvas* const canvas, void* ctx) { /* ============================ Game logic ================================== */ +/* Given the current position, update it according to the velocity and + * wrap it back to the other side if the object went over the screen. */ +void update_pos_by_velocity(float* x, float* y, float vx, float vy) { + /* Return back from one side to the other of the screen. */ + *x += vx; + *y += vy; + if(*x >= SCREEN_XRES) + *x = 0; + else if(*x < 0) + *x = SCREEN_XRES - 1; + if(*y >= SCREEN_YRES) + *y = 0; + else if(*y < 0) + *y = SCREEN_YRES - 1; +} + float distance(float x1, float y1, float x2, float y2) { float dx = x1 - x2; float dy = y1 - y2; @@ -363,9 +592,16 @@ bool objects_are_colliding(float x1, float y1, float r1, float x2, float y2, flo return dx * dx + dy * dy < rsum * rsum; } +/* ================================ Bullets ================================ */ +//@todo ship_fire_bullet /* Create a new bullet headed in the same direction of the ship. */ void ship_fire_bullet(AsteroidsApp* app) { - if(app->bullets_num == MAXBUL) return; + // No power ups, only 5 bullets allowed + if(isPowerUpActive(app, PowerUpTypeFirePower) == false && app->bullets_num >= 5) return; + + // Double the Fire Power + if(isPowerUpActive(app, PowerUpTypeFirePower) && (app->bullets_num >= (MAXBUL))) return; + notification_message(furi_record_open(RECORD_NOTIFICATION), &sequence_bullet_fired); Bullet* b = &app->bullets[app->bullets_num]; b->x = app->ship.x; @@ -401,6 +637,7 @@ void remove_bullet(AsteroidsApp* app, int bid) { if(n && bid != n) app->bullets[bid] = app->bullets[n]; } +/* ================================ Asteroids ================================ */ /* Create a new asteroid, away from the ship. Return the * pointer to the asteroid object, so that the caller can change * certain things of the asteroid if needed. */ @@ -466,6 +703,159 @@ void asteroid_was_hit(AsteroidsApp* app, int id) { } } +/* ================================ Power Up ================================ */ +bool isPowerUpCollidingWithEachOther(AsteroidsApp* app, float x, float y, float size) { + for(int i = 0; i < app->powerUps_num; i++) { + PowerUp* p2 = &app->powerUps[i]; + if(objects_are_colliding(x, y, size, p2->x, p2->y, p2->size, 1)) return true; + } + return false; +} + +bool should_trigger_rare_powerUp(PowerUpType selected_powerUpType) { + switch(selected_powerUpType) { + case PowerUpTypeLife: // Make extra life power up more rare + return rand() % 10 != 0; + case PowerUpTypeShield: // Make shield power up more rare + return rand() % 4 != 0; + default: + return true; + } +} + +//@todo Add PowerUp +PowerUp* add_powerUp(AsteroidsApp* app) { + FURI_LOG_I(TAG, "add_powerUp: %i", app->powerUps_num); + if(app->powerUps_num == MAXPOWERUPS) return NULL; // Max Power Ups reached + if(app->lives == MAXLIVES) return NULL; // Max Lives reached + + // Randomly select power up for display + PowerUpType selected_powerUpType = rand() % Number_of_PowerUps; + FURI_LOG_I(TAG, "[add_powerUp] Power Up Selected: %i", selected_powerUpType); + + // Don't add already existing power ups + if(isPowerUpAlreadyExists(app, selected_powerUpType)) { + FURI_LOG_D(TAG, "[add_powerUp] Power Up %i already active", selected_powerUpType); + return NULL; + } + + // Make some power ups more rare + if(!should_trigger_rare_powerUp(selected_powerUpType)) { + FURI_LOG_D(TAG, "[add_powerUp] Power Up %i not triggered", selected_powerUpType); + return NULL; + } + + float size = 10; + float min_distance = 20; + float x, y; + do { + //Make sure power up is not spawned on the edge of the screen + x = rand() % (SCREEN_XRES - (int)size); + y = rand() % (SCREEN_YRES - (int)size); + + //Also keep it away from the lives and score at the top of screen + if(y < size) y = size; + } while( + ((distance(app->ship.x, app->ship.y, x, y) < min_distance + size) || + isPowerUpCollidingWithEachOther(app, x, y, size))); + + PowerUp* p = &app->powerUps[app->powerUps_num++]; + p->x = x; + p->y = y; + //@todo Disable Velocity + p->vx = 0; //2 * (-.5 + ((float)rand() / RAND_MAX)); + p->vy = 0; //2 * (-.5 + ((float)rand() / RAND_MAX)); + p->display_ttl = 200; + p->ttl = POWERUPSTTL; + p->size = size; + // p->size = size; + // p->rot = 0; + // p->rot_speed = ((float)rand() / RAND_MAX) / 10; + // if(app->ticks & 1) p->rot_speed = -(p->rot_speed); + + //@todo add powerup type, for now hardcoding to firepower + p->powerUpType = selected_powerUpType; + p->isPowerUpActive = false; + FURI_LOG_I(TAG, "[add_powerUp] Power Up Added: %i", p->powerUpType); + return p; +} + +bool isPowerUpActive(AsteroidsApp* const app, PowerUpType const powerUpType) { + for(int i = 0; i < app->powerUps_num; i++) { + // PowerUp* p = &app->powerUps[i]; + // if(p->powerUpType == powerUpType && p->ttl > 0 && p->display_ttl == 0) return true; + if(app->powerUps[i].isPowerUpActive && app->powerUps[i].powerUpType == powerUpType) { + return true; + } + } + return false; +} + +bool isPowerUpAlreadyExists(AsteroidsApp* const app, PowerUpType const powerUpType) { + for(int i = 0; i < app->powerUps_num; i++) { + if(app->powerUps[i].powerUpType == powerUpType) return true; + } + return false; +} + +//@todo remove_powerUp +void remove_powerUp(AsteroidsApp* app, int id) { + FURI_LOG_I(TAG, "remove_powerUp: %i", id); + // Invalid ID, ignore + if(id < 0) { + FURI_LOG_E(TAG, "remove_powerUp: Invalid ID: %i", id); + return; + } + // TODO: Break this out into object types that set the game state + // Return the bullet period to normal + if(app->powerUps[id].powerUpType == PowerUpTypeFirePower) { + app->bullet_min_period = 200; + } + + /* Replace the top powerUp with the empty space left + * by the removal of this one. This way we always take the + * array dense, which is an advantage when looping. */ + int n = --app->powerUps_num; + if(n && id != n) app->powerUps[id] = app->powerUps[n]; +} + +void remove_all_astroids_and_bullets(AsteroidsApp* app) { + app->score += app->asteroids_num; + app->asteroids_num = 0; + app->bullets_num = 0; +} + +//@todo powerUp_was_hit +void powerUp_was_hit(AsteroidsApp* app, int id) { + PowerUp* p = &app->powerUps[id]; + if(p->display_ttl == 0) return; // Don't collect if already collected or expired + + // Vibrate to indicate power up was collected + notification_message(furi_record_open(RECORD_NOTIFICATION), &sequence_powerup_collected); + + switch(p->powerUpType) { + case PowerUpTypeLife: + if(app->lives < MAXLIVES) app->lives++; + remove_powerUp(app, id); + break; + case PowerUpTypeFirePower: + p->ttl = POWERUPSTTL / 2; + app->bullet_min_period = 100; + break; + case PowerUpTypeNuke: + //TODO: Animate explosion + notification_message(furi_record_open(RECORD_NOTIFICATION), &sequence_nuke); + // Simulate nuke explosion + remove_all_astroids_and_bullets(app); + break; + default: + break; + } + p->display_ttl = 0; + p->isPowerUpActive = true; +} + +/* ================================ Game States ================================ */ /* Set gameover state. When in game-over mode, the game displays a gameover * text with a background of many asteroids floating around. */ void game_over(AsteroidsApp* app) { @@ -494,7 +884,9 @@ void restart_game(AsteroidsApp* app) { app->ship.vx = 0; app->ship.vy = 0; app->bullets_num = 0; + app->powerUps_num = 0; app->last_bullet_tick = 0; + app->bullet_min_period = 200; app->asteroids_num = 0; app->ship_hit = 0; } @@ -510,6 +902,7 @@ void restart_game_after_gameover(AsteroidsApp* app) { restart_game(app); } +/* ================================ Position & Status ================================ */ /* Move bullets. */ void update_bullets_position(AsteroidsApp* app) { for(int j = 0; j < app->bullets_num; j++) { @@ -536,6 +929,68 @@ void update_asteroids_position(AsteroidsApp* app) { } } +bool should_add_powerUp(AsteroidsApp* app) { + srand(furi_get_tick()); + int random_number = rand() % 100 + 1; + + // The chance of spawning a power-up decreases as the game goes on + int threshold = 100 - (app->score * 5); + + // Make sure the threshold doesn't go below 10 + threshold = (threshold < 10) ? 10 : threshold; + // FURI_LOG_I( + // TAG, + // "Random number: %d, threshold: %d Bool: %d", + // random_number, + // threshold, + // random_number <= threshold); + return random_number <= threshold; +} + +void update_powerUps_position(AsteroidsApp* app) { + for(int j = 0; j < app->powerUps_num; j++) { + // @todo update_powerUps_position + if(app->powerUps[j].display_ttl > 0) { + update_pos_by_velocity( + &app->powerUps[j].x, &app->powerUps[j].y, app->powerUps[j].vx, app->powerUps[j].vy); + } + } +} + +// @todo update_powerUp_status +/* This updates the state of each power up collected and removes them if they have expired. */ +void update_powerUp_status(AsteroidsApp* app) { + for(int j = 0; j < app->powerUps_num; j++) { + if(app->powerUps[j].ttl > 0 && app->powerUps[j].isPowerUpActive) { + // Only decrement ttl if we actually picked up power up + app->powerUps[j].ttl--; + } else if(app->powerUps[j].display_ttl > 0) { + app->powerUps[j].display_ttl--; + } else if(app->powerUps[j].ttl == 0 || app->powerUps[j].display_ttl == 0) { + FURI_LOG_I( + TAG, + "[update_powerUp_status] Power up expired!, ttl: %lu, display_ttl: %lu id: %d", + app->powerUps[j].ttl, + app->powerUps[j].display_ttl, + j); + // we've reached the end of life of the power up + // Time to remove it + app->powerUps[j].isPowerUpActive = false; + remove_powerUp(app, j); + j--; /* Process this power up index again: the removal will + fill it with the top power up to take the array dense. */ + } else { + FURI_LOG_E( + TAG, + "[update_powerUp_status] Power up error! Invalid Index: %d ttl: %lu display_ttl: %lu PowerUp_Num: %d", + j, + app->powerUps[j].ttl, + app->powerUps[j].display_ttl, + app->powerUps_num); + } + } +} + /* Collision detection and game state update based on collisions. */ void detect_collisions(AsteroidsApp* app) { /* Detect collision between bullet and asteroid. */ @@ -560,8 +1015,26 @@ void detect_collisions(AsteroidsApp* app) { for(int j = 0; j < app->asteroids_num; j++) { Asteroid* a = &app->asteroids[j]; if(objects_are_colliding(a->x, a->y, a->size, app->ship.x, app->ship.y, 4, 1)) { - ship_was_hit(app); - break; + if(isPowerUpActive(app, PowerUpTypeShield)) { + // Asteroid was hit with shield + notification_message( + furi_record_open(RECORD_NOTIFICATION), &sequence_bullet_fired); + asteroid_was_hit(app, j); + j--; /* Scan this j value again. */ + } else { + // No sheild active, take damage + ship_was_hit(app); + break; + } + } + } + + /* Detect collision between ship and powerUp. */ + for(int j = 0; j < app->powerUps_num; j++) { + PowerUp* p = &app->powerUps[j]; + if(objects_are_colliding(p->x, p->y, p->size, app->ship.x, app->ship.y, 4, 1)) { + powerUp_was_hit(app, j); + // break; } } } @@ -599,6 +1072,12 @@ void game_tick(void* ctx) { update_asteroids_position(app); view_port_update(app->view_port); return; + } else if(app->paused) { + if(key_pressed_time(app, InputKeyBack) > 100 || key_pressed_time(app, InputKeyOk) > 100) { + app->paused = false; + } + view_port_update(app->view_port); + return; } /* Handle keypresses. */ @@ -617,19 +1096,32 @@ void game_tick(void* ctx) { * asteroids_update_keypress_state() since depends on exact * pressure timing. */ if(app->fire) { - uint32_t bullet_min_period = 200; // In milliseconds uint32_t now = furi_get_tick(); - if(now - app->last_bullet_tick >= bullet_min_period) { + if(now - app->last_bullet_tick >= app->bullet_min_period) { ship_fire_bullet(app); app->last_bullet_tick = now; } app->fire = false; } + // DEBUG: Show Power Up Status + // for(int j = 0; j < app->powerUps_num; j++) { + // PowerUp* p = &app->powerUps[j]; + // FURI_LOG_I( + // TAG, + // "Power Up Type: %d TTL: %lu Display_TTL: %lu PowerUpNum: %i", + // p->powerUpType, + // p->ttl, + // p->display_ttl, + // app->powerUps_num); + // } + /* Update positions and detect collisions. */ update_pos_by_velocity(&app->ship.x, &app->ship.y, app->ship.vx, app->ship.vy); update_bullets_position(app); update_asteroids_position(app); + update_powerUp_status(app); //@todo update_powerUp_status + update_powerUps_position(app); detect_collisions(app); /* From time to time, create a new asteroid. The more asteroids @@ -639,6 +1131,13 @@ void game_tick(void* ctx) { add_asteroid(app); } + /* From time to time add a random power up */ + //@todo game tick + // if(app->powerUps_num == 0 || random() % (500 + (100 * (int)app->score)) <= app->powerUps_num) { + if(should_add_powerUp(app)) { + add_powerUp(app); + } + app->ticks++; view_port_update(app->view_port); } @@ -760,8 +1259,17 @@ int32_t asteroids_app_entry(void* p) { while(app->running) { FuriStatus qstat = furi_message_queue_get(app->event_queue, &input, 100); if(qstat == FuriStatusOk) { - if(DEBUG_MSG) - FURI_LOG_E(TAG, "Main Loop - Input: type %d key %u", input.type, input.key); + // if(DEBUG_MSG) + // FURI_LOG_E(TAG, "Main Loop - Input: type %d key %u", input.type, input.key); + /* Handle Pause */ + if(input.type == InputTypeShort && input.key == InputKeyBack) { + app->paused = !app->paused; + if(app->paused) { + furi_timer_stop(timer); + } else { + furi_timer_start(timer, furi_kernel_get_tick_frequency() / 10); + } + } /* Handle navigation here. Then handle view-specific inputs * in the view specific handling function. */ @@ -775,11 +1283,11 @@ int32_t asteroids_app_entry(void* p) { } else { /* Useful to understand if the app is still alive when it * does not respond because of bugs. */ - if(DEBUG_MSG) { - static int c = 0; - c++; - if(!(c % 20)) FURI_LOG_E(TAG, "Loop timeout"); - } + // if(DEBUG_MSG) { + // static int c = 0; + // c++; + // if(!(c % 20)) FURI_LOG_E(TAG, "Loop timeout"); + // } } } diff --git a/applications/plugins/asteroids/application.fam b/applications/plugins/asteroids/application.fam index f5ad2cdb9..5eb43a6e5 100644 --- a/applications/plugins/asteroids/application.fam +++ b/applications/plugins/asteroids/application.fam @@ -3,10 +3,14 @@ App( name="Asteroids", apptype=FlipperAppType.EXTERNAL, entry_point="asteroids_app_entry", - cdefines=["APP_PROTOVIEW"], + cdefines=["APP_ASTEROIDS"], requires=["gui"], stack_size=8 * 1024, order=50, fap_icon="appicon.png", fap_category="Games", + fap_icon_assets="assets", # Image assets to compile for this application + fap_description="An implementation of the classic arcade game Asteroids", + fap_author="antirez, SimplyMinimal", + fap_weburl="https://github.com/SimplyMinimal/FlipperZero-Asteroids", ) diff --git a/applications/plugins/asteroids/assets/ammo_10x10.png b/applications/plugins/asteroids/assets/ammo_10x10.png new file mode 100644 index 000000000..b112a1a7f Binary files /dev/null and b/applications/plugins/asteroids/assets/ammo_10x10.png differ diff --git a/applications/plugins/asteroids/assets/ammo_11x11.png b/applications/plugins/asteroids/assets/ammo_11x11.png new file mode 100644 index 000000000..55e59f858 Binary files /dev/null and b/applications/plugins/asteroids/assets/ammo_11x11.png differ diff --git a/applications/plugins/asteroids/assets/firepower_12x12.png b/applications/plugins/asteroids/assets/firepower_12x12.png new file mode 100644 index 000000000..711a29200 Binary files /dev/null and b/applications/plugins/asteroids/assets/firepower_12x12.png differ diff --git a/applications/plugins/asteroids/assets/firepower_9x10.png b/applications/plugins/asteroids/assets/firepower_9x10.png new file mode 100644 index 000000000..4070b6c88 Binary files /dev/null and b/applications/plugins/asteroids/assets/firepower_9x10.png differ diff --git a/applications/plugins/asteroids/assets/firepower_shifted_9x10.png b/applications/plugins/asteroids/assets/firepower_shifted_9x10.png new file mode 100644 index 000000000..9c8506d18 Binary files /dev/null and b/applications/plugins/asteroids/assets/firepower_shifted_9x10.png differ diff --git a/applications/plugins/asteroids/assets/heart_10x10.png b/applications/plugins/asteroids/assets/heart_10x10.png new file mode 100644 index 000000000..0d66b49ee Binary files /dev/null and b/applications/plugins/asteroids/assets/heart_10x10.png differ diff --git a/applications/plugins/asteroids/assets/heart_12x12.png b/applications/plugins/asteroids/assets/heart_12x12.png new file mode 100644 index 000000000..b1cfdcdfe Binary files /dev/null and b/applications/plugins/asteroids/assets/heart_12x12.png differ diff --git a/applications/plugins/asteroids/assets/nuke_10x10.png b/applications/plugins/asteroids/assets/nuke_10x10.png new file mode 100644 index 000000000..8b49fc98e Binary files /dev/null and b/applications/plugins/asteroids/assets/nuke_10x10.png differ diff --git a/applications/plugins/asteroids/assets/shield-frame.png b/applications/plugins/asteroids/assets/shield-frame.png new file mode 100644 index 000000000..60a670f0e Binary files /dev/null and b/applications/plugins/asteroids/assets/shield-frame.png differ diff --git a/applications/plugins/asteroids/assets/shield_clean.png b/applications/plugins/asteroids/assets/shield_clean.png new file mode 100644 index 000000000..59eefb717 Binary files /dev/null and b/applications/plugins/asteroids/assets/shield_clean.png differ diff --git a/applications/plugins/asteroids/assets/split_shield_10x10.png b/applications/plugins/asteroids/assets/split_shield_10x10.png new file mode 100644 index 000000000..bff879ca1 Binary files /dev/null and b/applications/plugins/asteroids/assets/split_shield_10x10.png differ diff --git a/applications/plugins/cli_bridge/README.md b/applications/plugins/cli_bridge/README.md index 446f3b8a9..b6d35fa7f 100644 --- a/applications/plugins/cli_bridge/README.md +++ b/applications/plugins/cli_bridge/README.md @@ -13,12 +13,12 @@ git clone https://github.com/ranchordo/flipperzero-cli-bridge ./applications_use # If everything went well, the built .fap file can be found in ./dist/f7-D/apps/apps/Tools/cli_gui.fap ``` # Usage -On the flipperzero, you should be able to find a new application (CLI-GUI Bridge) under Applications->Tools. Opening it will result in a text prompt - the prompt for the command line. Enter a suitable command (quickly pressing the back button will input a space) such as `subghz chat [freq in hz, e.g. 310000000]`, etc, then navigate to and press the SAVE key. You should then see the command window. Use Up and Down to scroll, and use Left or Center to get back to the text input prompt. A quick tap of the back key while viewing the console output sends a Ctrl-C to the console. +On the flipperzero, you should be able to find a new application (CLI-GUI Bridge) under Applications->Tools. Opening it will result in a text prompt - the prompt for the command line. Enter a suitable command (quickly pressing the back button or holding `_` on the keyboard will input a space) such as `subghz chat [freq in hz, e.g. 310000000]`, etc, then navigate to and press the SAVE key. You should then see the command window. Use Up and Down to scroll, and use Left or Center to get back to the text input prompt. A quick tap of the back key while viewing the console output sends a Ctrl-C to the console, and a long press of the left or right keys during text input will navigate back to the console output without executing. ## Exiting the app Holding and then releasing the back key for at least a second or so (long press) will exit the app normally, meaning that the inner terminal will send Ctrl-C and close. Any sessions will be disconnected. -Holding and then releasing the OK key for at least a second or so (long press) will exit the app while keeping the terminal open. Terminal output will be cleared the next time you launch the app, but whatever command or session was running previously will be resumed. This is especially handy with subghz chat - exiting the app while keeping the terminal open will not disconnect you from the chat, and the flipper will still vibrate briefly whenever a new message comes in (even if the app is closed). +Holding and then releasing the OK key while focusing on the console output for at least a second or so (long press) will exit the app while keeping the terminal open. Terminal output will be cleared the next time you launch the app, but whatever command or session was running previously will be resumed. This is especially handy with subghz chat - exiting the app while keeping the terminal open will not disconnect you from the chat, and the flipper will still vibrate briefly whenever a new message comes in (even if the app is closed). NOTE: USB functionality (qFlipper, normal USB CLI) may not work after running the app (especially after exiting without closing the terminal), simply restart your flipper and all USB functionality will return to normal. diff --git a/applications/plugins/cli_bridge/cligui_main.c b/applications/plugins/cli_bridge/cligui_main.c index 137b4a08b..4e7987c89 100644 --- a/applications/plugins/cli_bridge/cligui_main.c +++ b/applications/plugins/cli_bridge/cligui_main.c @@ -50,8 +50,10 @@ static void input_callback_wrapper(InputEvent* event, void* context) { view_dispatcher_stop(app->view_dispatcher); } if(event->type == InputTypeLong && event->key == InputKeyOk) { - persistent_exit = true; - view_dispatcher_stop(app->view_dispatcher); + if(app->data->state == ViewConsoleOutput) { + persistent_exit = true; + view_dispatcher_stop(app->view_dispatcher); + } } if(app->data->state == ViewTextInput) { text_input_input_handler(app, event); diff --git a/applications/plugins/cli_bridge/text_input.c b/applications/plugins/cli_bridge/text_input.c index 295e7629d..568b8ebcd 100644 --- a/applications/plugins/cli_bridge/text_input.c +++ b/applications/plugins/cli_bridge/text_input.c @@ -19,8 +19,6 @@ void text_input_result_callback(void* ctx) { } void text_input_input_handler(CliguiApp* app, InputEvent* event) { - UNUSED(app); - UNUSED(event); if(event->type == InputTypeShort && event->key == InputKeyBack) { // view_dispatcher_switch_to_view(app->view_dispatcher, ViewConsoleOutput); // app->data->state = ViewConsoleOutput; @@ -28,4 +26,9 @@ void text_input_input_handler(CliguiApp* app, InputEvent* event) { app->text_input_store[len] = ' '; app->text_input_store[len + 1] = 0; } + if(event->type == InputTypeLong && + (event->key == InputKeyLeft || event->key == InputKeyRight)) { + view_dispatcher_switch_to_view(app->view_dispatcher, ViewConsoleOutput); + app->data->state = ViewConsoleOutput; + } } \ No newline at end of file diff --git a/applications/plugins/cntdown_timer/application.fam b/applications/plugins/cntdown_timer/application.fam index e2c950907..ba22fd4bd 100644 --- a/applications/plugins/cntdown_timer/application.fam +++ b/applications/plugins/cntdown_timer/application.fam @@ -1,5 +1,7 @@ +# qv. https://github.com/flipperdevices/flipperzero-firmware/blob/dev/documentation/AppManifests.md + App( - appid="Count_Down_Timer", + appid="cntdown_tim", name="Count Down Timer", apptype=FlipperAppType.EXTERNAL, entry_point="app_main", diff --git a/applications/plugins/flashlight/application.fam b/applications/plugins/flashlight/application.fam index 6d70a036f..ea8eb03d1 100644 --- a/applications/plugins/flashlight/application.fam +++ b/applications/plugins/flashlight/application.fam @@ -1,5 +1,5 @@ App( - appid="Flashlight", + appid="flashlight", name="[GPIO] Flashlight", apptype=FlipperAppType.EXTERNAL, entry_point="flashlight_app", diff --git a/applications/plugins/flashlight/flashlight.c b/applications/plugins/flashlight/flashlight.c index 534d48fdb..251c596ef 100644 --- a/applications/plugins/flashlight/flashlight.c +++ b/applications/plugins/flashlight/flashlight.c @@ -18,14 +18,14 @@ typedef struct { } PluginEvent; typedef struct { + FuriMutex* mutex; bool is_on; } PluginState; static void render_callback(Canvas* const canvas, void* ctx) { - const PluginState* plugin_state = acquire_mutex((ValueMutex*)ctx, 25); - if(plugin_state == NULL) { - return; - } + furi_assert(ctx); + const PluginState* plugin_state = ctx; + furi_mutex_acquire(plugin_state->mutex, FuriWaitForever); canvas_set_font(canvas, FontPrimary); elements_multiline_text_aligned(canvas, 64, 2, AlignCenter, AlignTop, "Flashlight"); @@ -41,7 +41,7 @@ static void render_callback(Canvas* const canvas, void* ctx) { canvas, 64, 40, AlignCenter, AlignTop, "Press OK button to off"); } - release_mutex((ValueMutex*)ctx, plugin_state); + furi_mutex_release(plugin_state->mutex); } static void input_callback(InputEvent* input_event, FuriMessageQueue* event_queue) { @@ -69,8 +69,8 @@ int32_t flashlight_app() { PluginState* plugin_state = malloc(sizeof(PluginState)); - ValueMutex state_mutex; - if(!init_mutex(&state_mutex, plugin_state, sizeof(PluginState))) { + plugin_state->mutex = furi_mutex_alloc(FuriMutexTypeNormal); + if(!plugin_state->mutex) { FURI_LOG_E("flashlight", "cannot create mutex\r\n"); furi_message_queue_free(event_queue); free(plugin_state); @@ -79,7 +79,7 @@ int32_t flashlight_app() { // Set system callbacks ViewPort* view_port = view_port_alloc(); - view_port_draw_callback_set(view_port, render_callback, &state_mutex); + view_port_draw_callback_set(view_port, render_callback, plugin_state); view_port_input_callback_set(view_port, input_callback, event_queue); // Open GUI and register view_port @@ -90,7 +90,7 @@ int32_t flashlight_app() { for(bool processing = true; processing;) { FuriStatus event_status = furi_message_queue_get(event_queue, &event, 100); - PluginState* plugin_state = (PluginState*)acquire_mutex_block(&state_mutex); + furi_mutex_acquire(plugin_state->mutex, FuriWaitForever); if(event_status == FuriStatusOk) { // press events @@ -116,7 +116,7 @@ int32_t flashlight_app() { } view_port_update(view_port); - release_mutex(&state_mutex, plugin_state); + furi_mutex_release(plugin_state->mutex); } view_port_enabled_set(view_port, false); @@ -124,7 +124,7 @@ int32_t flashlight_app() { furi_record_close(RECORD_GUI); view_port_free(view_port); furi_message_queue_free(event_queue); - delete_mutex(&state_mutex); + furi_mutex_free(plugin_state->mutex); return 0; } diff --git a/applications/plugins/geigercounter/application.fam b/applications/plugins/geigercounter/application.fam index 71be5a161..ea5e1fa85 100644 --- a/applications/plugins/geigercounter/application.fam +++ b/applications/plugins/geigercounter/application.fam @@ -1,5 +1,5 @@ App( - appid="Geiger_Coutner", + appid="flipper_geiger", name="[GPIO] Geiger Counter", apptype=FlipperAppType.EXTERNAL, entry_point="flipper_geiger_app", diff --git a/applications/plugins/geigercounter/flipper_geiger.c b/applications/plugins/geigercounter/flipper_geiger.c index 709db9a26..a5503eb90 100644 --- a/applications/plugins/geigercounter/flipper_geiger.c +++ b/applications/plugins/geigercounter/flipper_geiger.c @@ -29,6 +29,7 @@ typedef struct { } EventApp; typedef struct { + FuriMutex* mutex; uint32_t cps, cpm; uint32_t line[SCREEN_SIZE_X / 2]; float coef; @@ -36,12 +37,13 @@ typedef struct { } mutexStruct; static void draw_callback(Canvas* canvas, void* ctx) { - UNUSED(ctx); + furi_assert(ctx); mutexStruct displayStruct; - mutexStruct* geigerMutex = (mutexStruct*)acquire_mutex_block((ValueMutex*)ctx); + mutexStruct* geigerMutex = ctx; + furi_mutex_acquire(geigerMutex->mutex, FuriWaitForever); memcpy(&displayStruct, geigerMutex, sizeof(mutexStruct)); - release_mutex((ValueMutex*)ctx, geigerMutex); + furi_mutex_release(geigerMutex->mutex); char buffer[32]; if(displayStruct.data == 0) @@ -101,7 +103,8 @@ static void gpiocallback(void* ctx) { furi_message_queue_put(queue, &event, 0); } -int32_t flipper_geiger_app() { +int32_t flipper_geiger_app(void* p) { + UNUSED(p); EventApp event; FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(EventApp)); @@ -117,11 +120,14 @@ int32_t flipper_geiger_app() { uint32_t counter = 0; - ValueMutex state_mutex; - init_mutex(&state_mutex, &mutexVal, sizeof(mutexVal)); + mutexVal.mutex = furi_mutex_alloc(FuriMutexTypeNormal); + if(!mutexVal.mutex) { + furi_message_queue_free(event_queue); + return 255; + } ViewPort* view_port = view_port_alloc(); - view_port_draw_callback_set(view_port, draw_callback, &state_mutex); + view_port_draw_callback_set(view_port, draw_callback, &mutexVal); view_port_input_callback_set(view_port, input_callback, event_queue); furi_hal_gpio_add_int_callback(&gpio_ext_pa7, gpiocallback, event_queue); @@ -146,62 +152,62 @@ int32_t flipper_geiger_app() { break; } else if(event.input.key == InputKeyOk && event.input.type == InputTypeShort) { counter = 0; - mutexStruct* geigerMutex = (mutexStruct*)acquire_mutex_block(&state_mutex); + furi_mutex_acquire(mutexVal.mutex, FuriWaitForever); - geigerMutex->cps = 0; - geigerMutex->cpm = 0; - for(int i = 0; i < SCREEN_SIZE_X / 2; i++) geigerMutex->line[i] = 0; + mutexVal.cps = 0; + mutexVal.cpm = 0; + for(int i = 0; i < SCREEN_SIZE_X / 2; i++) mutexVal.line[i] = 0; screenRefresh = 1; - release_mutex(&state_mutex, geigerMutex); + furi_mutex_release(mutexVal.mutex); } else if((event.input.key == InputKeyLeft && event.input.type == InputTypeShort)) { - mutexStruct* geigerMutex = (mutexStruct*)acquire_mutex_block(&state_mutex); + furi_mutex_acquire(mutexVal.mutex, FuriWaitForever); - if(geigerMutex->data != 0) - geigerMutex->data--; + if(mutexVal.data != 0) + mutexVal.data--; else - geigerMutex->data = 2; + mutexVal.data = 2; screenRefresh = 1; - release_mutex(&state_mutex, geigerMutex); + furi_mutex_release(mutexVal.mutex); } else if((event.input.key == InputKeyRight && event.input.type == InputTypeShort)) { - mutexStruct* geigerMutex = (mutexStruct*)acquire_mutex_block(&state_mutex); + furi_mutex_acquire(mutexVal.mutex, FuriWaitForever); - if(geigerMutex->data != 2) - geigerMutex->data++; + if(mutexVal.data != 2) + mutexVal.data++; else - geigerMutex->data = 0; + mutexVal.data = 0; screenRefresh = 1; - release_mutex(&state_mutex, geigerMutex); + furi_mutex_release(mutexVal.mutex); } } else if(event.type == ClockEventTypeTick) { - mutexStruct* geigerMutex = (mutexStruct*)acquire_mutex_block(&state_mutex); + furi_mutex_acquire(mutexVal.mutex, FuriWaitForever); for(int i = 0; i < SCREEN_SIZE_X / 2 - 1; i++) - geigerMutex->line[SCREEN_SIZE_X / 2 - 1 - i] = - geigerMutex->line[SCREEN_SIZE_X / 2 - 2 - i]; + mutexVal.line[SCREEN_SIZE_X / 2 - 1 - i] = + mutexVal.line[SCREEN_SIZE_X / 2 - 2 - i]; - geigerMutex->line[0] = counter; - geigerMutex->cps = counter; + mutexVal.line[0] = counter; + mutexVal.cps = counter; counter = 0; - geigerMutex->cpm = geigerMutex->line[0]; - uint32_t max = geigerMutex->line[0]; + mutexVal.cpm = mutexVal.line[0]; + uint32_t max = mutexVal.line[0]; for(int i = 1; i < SCREEN_SIZE_X / 2; i++) { - if(i < 60) geigerMutex->cpm += geigerMutex->line[i]; - if(geigerMutex->line[i] > max) max = geigerMutex->line[i]; + if(i < 60) mutexVal.cpm += mutexVal.line[i]; + if(mutexVal.line[i] > max) max = mutexVal.line[i]; } if(max > 0) - geigerMutex->coef = ((float)(SCREEN_SIZE_Y - 15)) / ((float)max); + mutexVal.coef = ((float)(SCREEN_SIZE_Y - 15)) / ((float)max); else - geigerMutex->coef = 1; + mutexVal.coef = 1; screenRefresh = 1; - release_mutex(&state_mutex, geigerMutex); + furi_mutex_release(mutexVal.mutex); } else if(event.type == EventGPIO) { counter++; } @@ -217,7 +223,7 @@ int32_t flipper_geiger_app() { furi_hal_pwm_stop(FuriHalPwmOutputIdLptim2PA4); furi_message_queue_free(event_queue); - delete_mutex(&state_mutex); + furi_mutex_free(mutexVal.mutex); gui_remove_view_port(gui, view_port); view_port_free(view_port); furi_timer_free(timer); diff --git a/applications/plugins/gpioreader2/GPIO_reader.c b/applications/plugins/gpio_reader_a/GPIO_reader.c similarity index 88% rename from applications/plugins/gpioreader2/GPIO_reader.c rename to applications/plugins/gpio_reader_a/GPIO_reader.c index be333cd7e..eb5f95e67 100644 --- a/applications/plugins/gpioreader2/GPIO_reader.c +++ b/applications/plugins/gpio_reader_a/GPIO_reader.c @@ -17,10 +17,13 @@ typedef struct { typedef struct { int pin; int pullMode; + FuriMutex* mutex; } PluginState; static void render_callback(Canvas* const canvas, void* ctx) { - const PluginState* plugin_state = acquire_mutex((ValueMutex*)ctx, 25); + furi_assert(ctx); + const PluginState* plugin_state = ctx; + furi_mutex_acquire(plugin_state->mutex, FuriWaitForever); canvas_set_font(canvas, FontPrimary); canvas_draw_str_aligned( @@ -57,7 +60,7 @@ static void render_callback(Canvas* const canvas, void* ctx) { AlignCenter, gpio_item_get_pin_level(plugin_state->pin)); - release_mutex((ValueMutex*)ctx, plugin_state); + furi_mutex_release(plugin_state->mutex); } static void input_callback(InputEvent* input_event, FuriMessageQueue* event_queue) { @@ -79,8 +82,8 @@ int32_t GPIO_reader_app(void* p) { PluginState* plugin_state = malloc(sizeof(PluginState)); GPIO_reader_state_init(plugin_state); - ValueMutex state_mutex; - if(!init_mutex(&state_mutex, plugin_state, sizeof(PluginState))) { + plugin_state->mutex = furi_mutex_alloc(FuriMutexTypeNormal); + if(!plugin_state->mutex) { FURI_LOG_E("GPIO_reader", "cannot create mutex\r\n"); free(plugin_state); return 255; @@ -88,7 +91,7 @@ int32_t GPIO_reader_app(void* p) { // Set system callbacks ViewPort* view_port = view_port_alloc(); - view_port_draw_callback_set(view_port, render_callback, &state_mutex); + view_port_draw_callback_set(view_port, render_callback, plugin_state); view_port_input_callback_set(view_port, input_callback, event_queue); // Open GUI and register view_port @@ -98,7 +101,7 @@ int32_t GPIO_reader_app(void* p) { PluginEvent event; for(bool processing = true; processing;) { FuriStatus event_status = furi_message_queue_get(event_queue, &event, 100); - PluginState* plugin_state = (PluginState*)acquire_mutex_block(&state_mutex); + furi_mutex_acquire(plugin_state->mutex, FuriWaitForever); if(event_status == FuriStatusOk) { // press events @@ -131,20 +134,19 @@ int32_t GPIO_reader_app(void* p) { } } } - } else { - FURI_LOG_D("GPIO_reader", "FuriMessageQueue: event timeout"); - // event timeout } view_port_update(view_port); - release_mutex(&state_mutex, plugin_state); + furi_mutex_release(plugin_state->mutex); } view_port_enabled_set(view_port, false); gui_remove_view_port(gui, view_port); furi_record_close("gui"); view_port_free(view_port); + furi_mutex_free(plugin_state->mutex); furi_message_queue_free(event_queue); + free(plugin_state); return 0; } \ No newline at end of file diff --git a/applications/plugins/gpioreader2/GPIO_reader_item.c b/applications/plugins/gpio_reader_a/GPIO_reader_item.c similarity index 100% rename from applications/plugins/gpioreader2/GPIO_reader_item.c rename to applications/plugins/gpio_reader_a/GPIO_reader_item.c diff --git a/applications/plugins/gpioreader2/GPIO_reader_item.h b/applications/plugins/gpio_reader_a/GPIO_reader_item.h similarity index 100% rename from applications/plugins/gpioreader2/GPIO_reader_item.h rename to applications/plugins/gpio_reader_a/GPIO_reader_item.h diff --git a/applications/plugins/gpioreader2/README.md b/applications/plugins/gpio_reader_a/README.md similarity index 100% rename from applications/plugins/gpioreader2/README.md rename to applications/plugins/gpio_reader_a/README.md diff --git a/applications/plugins/gpioreader2/application.fam b/applications/plugins/gpio_reader_a/application.fam similarity index 89% rename from applications/plugins/gpioreader2/application.fam rename to applications/plugins/gpio_reader_a/application.fam index bf25c323d..4ec90df6a 100644 --- a/applications/plugins/gpioreader2/application.fam +++ b/applications/plugins/gpio_reader_a/application.fam @@ -1,5 +1,5 @@ App( - appid="GPIO_Reader_A", + appid="gpio_reader_a", name="[GPIO] Reader (Aurelilc)", apptype=FlipperAppType.EXTERNAL, entry_point="GPIO_reader_app", diff --git a/applications/plugins/gpioreader/icon.png b/applications/plugins/gpio_reader_a/icon.png similarity index 100% rename from applications/plugins/gpioreader/icon.png rename to applications/plugins/gpio_reader_a/icon.png diff --git a/applications/plugins/gpioreader/LICENSE b/applications/plugins/gpio_reader_b/LICENSE similarity index 100% rename from applications/plugins/gpioreader/LICENSE rename to applications/plugins/gpio_reader_b/LICENSE diff --git a/applications/plugins/gpioreader/README.md b/applications/plugins/gpio_reader_b/README.md similarity index 100% rename from applications/plugins/gpioreader/README.md rename to applications/plugins/gpio_reader_b/README.md diff --git a/applications/plugins/gpioreader/application.fam b/applications/plugins/gpio_reader_b/application.fam similarity index 91% rename from applications/plugins/gpioreader/application.fam rename to applications/plugins/gpio_reader_b/application.fam index a7f297d47..aa26060aa 100644 --- a/applications/plugins/gpioreader/application.fam +++ b/applications/plugins/gpio_reader_b/application.fam @@ -1,5 +1,5 @@ App( - appid="GPIO_Reader_B", + appid="gpio_reader_b", name="[GPIO] Reader (biotinker)", apptype=FlipperAppType.EXTERNAL, entry_point="gpio_app", diff --git a/applications/plugins/gpioreader/gpio_app.c b/applications/plugins/gpio_reader_b/gpio_app.c similarity index 100% rename from applications/plugins/gpioreader/gpio_app.c rename to applications/plugins/gpio_reader_b/gpio_app.c diff --git a/applications/plugins/gpioreader/gpio_app.h b/applications/plugins/gpio_reader_b/gpio_app.h similarity index 100% rename from applications/plugins/gpioreader/gpio_app.h rename to applications/plugins/gpio_reader_b/gpio_app.h diff --git a/applications/plugins/gpioreader/gpio_app_i.h b/applications/plugins/gpio_reader_b/gpio_app_i.h similarity index 100% rename from applications/plugins/gpioreader/gpio_app_i.h rename to applications/plugins/gpio_reader_b/gpio_app_i.h diff --git a/applications/plugins/gpioreader/gpio_custom_event.h b/applications/plugins/gpio_reader_b/gpio_custom_event.h similarity index 100% rename from applications/plugins/gpioreader/gpio_custom_event.h rename to applications/plugins/gpio_reader_b/gpio_custom_event.h diff --git a/applications/plugins/gpioreader/gpio_item.c b/applications/plugins/gpio_reader_b/gpio_item.c similarity index 100% rename from applications/plugins/gpioreader/gpio_item.c rename to applications/plugins/gpio_reader_b/gpio_item.c diff --git a/applications/plugins/gpioreader/gpio_item.h b/applications/plugins/gpio_reader_b/gpio_item.h similarity index 100% rename from applications/plugins/gpioreader/gpio_item.h rename to applications/plugins/gpio_reader_b/gpio_item.h diff --git a/applications/plugins/gpioreader/gpioreader.png b/applications/plugins/gpio_reader_b/gpioreader.png similarity index 100% rename from applications/plugins/gpioreader/gpioreader.png rename to applications/plugins/gpio_reader_b/gpioreader.png diff --git a/applications/plugins/gpioreader2/icon.png b/applications/plugins/gpio_reader_b/icon.png similarity index 100% rename from applications/plugins/gpioreader2/icon.png rename to applications/plugins/gpio_reader_b/icon.png diff --git a/applications/plugins/gpioreader/scenes/gpio_scene.c b/applications/plugins/gpio_reader_b/scenes/gpio_scene.c similarity index 100% rename from applications/plugins/gpioreader/scenes/gpio_scene.c rename to applications/plugins/gpio_reader_b/scenes/gpio_scene.c diff --git a/applications/plugins/gpioreader/scenes/gpio_scene.h b/applications/plugins/gpio_reader_b/scenes/gpio_scene.h similarity index 100% rename from applications/plugins/gpioreader/scenes/gpio_scene.h rename to applications/plugins/gpio_reader_b/scenes/gpio_scene.h diff --git a/applications/plugins/gpioreader/scenes/gpio_scene_config.h b/applications/plugins/gpio_reader_b/scenes/gpio_scene_config.h similarity index 100% rename from applications/plugins/gpioreader/scenes/gpio_scene_config.h rename to applications/plugins/gpio_reader_b/scenes/gpio_scene_config.h diff --git a/applications/plugins/gpioreader/scenes/gpio_scene_reader.c b/applications/plugins/gpio_reader_b/scenes/gpio_scene_reader.c similarity index 100% rename from applications/plugins/gpioreader/scenes/gpio_scene_reader.c rename to applications/plugins/gpio_reader_b/scenes/gpio_scene_reader.c diff --git a/applications/plugins/gpioreader/scenes/gpio_scene_start.c b/applications/plugins/gpio_reader_b/scenes/gpio_scene_start.c similarity index 100% rename from applications/plugins/gpioreader/scenes/gpio_scene_start.c rename to applications/plugins/gpio_reader_b/scenes/gpio_scene_start.c diff --git a/applications/plugins/gpioreader/scenes/gpio_scene_test.c b/applications/plugins/gpio_reader_b/scenes/gpio_scene_test.c similarity index 100% rename from applications/plugins/gpioreader/scenes/gpio_scene_test.c rename to applications/plugins/gpio_reader_b/scenes/gpio_scene_test.c diff --git a/applications/plugins/gpioreader/scenes/gpio_scene_usb_uart.c b/applications/plugins/gpio_reader_b/scenes/gpio_scene_usb_uart.c similarity index 100% rename from applications/plugins/gpioreader/scenes/gpio_scene_usb_uart.c rename to applications/plugins/gpio_reader_b/scenes/gpio_scene_usb_uart.c diff --git a/applications/plugins/gpioreader/scenes/gpio_scene_usb_uart_close_rpc.c b/applications/plugins/gpio_reader_b/scenes/gpio_scene_usb_uart_close_rpc.c similarity index 100% rename from applications/plugins/gpioreader/scenes/gpio_scene_usb_uart_close_rpc.c rename to applications/plugins/gpio_reader_b/scenes/gpio_scene_usb_uart_close_rpc.c diff --git a/applications/plugins/gpioreader/scenes/gpio_scene_usb_uart_config.c b/applications/plugins/gpio_reader_b/scenes/gpio_scene_usb_uart_config.c similarity index 100% rename from applications/plugins/gpioreader/scenes/gpio_scene_usb_uart_config.c rename to applications/plugins/gpio_reader_b/scenes/gpio_scene_usb_uart_config.c diff --git a/applications/plugins/gpioreader/usb_uart_bridge.c b/applications/plugins/gpio_reader_b/usb_uart_bridge.c similarity index 100% rename from applications/plugins/gpioreader/usb_uart_bridge.c rename to applications/plugins/gpio_reader_b/usb_uart_bridge.c diff --git a/applications/plugins/gpioreader/usb_uart_bridge.h b/applications/plugins/gpio_reader_b/usb_uart_bridge.h similarity index 100% rename from applications/plugins/gpioreader/usb_uart_bridge.h rename to applications/plugins/gpio_reader_b/usb_uart_bridge.h diff --git a/applications/plugins/gpioreader/views/gpio_reader.c b/applications/plugins/gpio_reader_b/views/gpio_reader.c similarity index 100% rename from applications/plugins/gpioreader/views/gpio_reader.c rename to applications/plugins/gpio_reader_b/views/gpio_reader.c diff --git a/applications/plugins/gpioreader/views/gpio_reader.h b/applications/plugins/gpio_reader_b/views/gpio_reader.h similarity index 100% rename from applications/plugins/gpioreader/views/gpio_reader.h rename to applications/plugins/gpio_reader_b/views/gpio_reader.h diff --git a/applications/plugins/gpioreader/views/gpio_test.c b/applications/plugins/gpio_reader_b/views/gpio_test.c similarity index 100% rename from applications/plugins/gpioreader/views/gpio_test.c rename to applications/plugins/gpio_reader_b/views/gpio_test.c diff --git a/applications/plugins/gpioreader/views/gpio_test.h b/applications/plugins/gpio_reader_b/views/gpio_test.h similarity index 100% rename from applications/plugins/gpioreader/views/gpio_test.h rename to applications/plugins/gpio_reader_b/views/gpio_test.h diff --git a/applications/plugins/gpioreader/views/gpio_usb_uart.c b/applications/plugins/gpio_reader_b/views/gpio_usb_uart.c similarity index 100% rename from applications/plugins/gpioreader/views/gpio_usb_uart.c rename to applications/plugins/gpio_reader_b/views/gpio_usb_uart.c diff --git a/applications/plugins/gpioreader/views/gpio_usb_uart.h b/applications/plugins/gpio_reader_b/views/gpio_usb_uart.h similarity index 100% rename from applications/plugins/gpioreader/views/gpio_usb_uart.h rename to applications/plugins/gpio_reader_b/views/gpio_usb_uart.h diff --git a/applications/plugins/passgen/application.fam b/applications/plugins/passgen/application.fam index 94005e716..b6c1ae8e0 100644 --- a/applications/plugins/passgen/application.fam +++ b/applications/plugins/passgen/application.fam @@ -1,7 +1,7 @@ App( - appid="Password_Generator", + appid="passgen", name="Password Generator", - apptype=FlipperAppType.EXTERNAL, + apptype=FlipperAppType.PLUGIN, entry_point="passgenapp", requires=[ "gui", diff --git a/applications/plugins/passgen/passgen.c b/applications/plugins/passgen/passgen.c index c0f9c6e59..12cdc10fb 100644 --- a/applications/plugins/passgen/passgen.c +++ b/applications/plugins/passgen/passgen.c @@ -4,7 +4,7 @@ #include #include #include -#include +#include #define PASSGEN_MAX_LENGTH 16 #define PASSGEN_CHARACTERS_LENGTH (26 * 4) diff --git a/applications/plugins/pong/flipper_pong.c b/applications/plugins/pong/flipper_pong.c index 0e80e6ff3..55b371ad5 100644 --- a/applications/plugins/pong/flipper_pong.c +++ b/applications/plugins/pong/flipper_pong.c @@ -6,6 +6,7 @@ #include #include #include +#include #include #define SCREEN_SIZE_X 128 @@ -14,7 +15,8 @@ #define PAD_SIZE_X 3 #define PAD_SIZE_Y 8 -#define PLAYER1_PAD_SPEED 2 +#define PLAYER1_PAD_SPEED 4 + #define PLAYER2_PAD_SPEED 2 #define BALL_SIZE 4 @@ -29,14 +31,16 @@ typedef struct { } EventApp; typedef struct Players { + FuriMutex* mutex; uint8_t player1_X, player1_Y, player2_X, player2_Y; uint16_t player1_score, player2_score; uint8_t ball_X, ball_Y, ball_X_speed, ball_Y_speed, ball_X_direction, ball_Y_direction; } Players; static void draw_callback(Canvas* canvas, void* ctx) { - UNUSED(ctx); - Players* playersMutex = (Players*)acquire_mutex_block((ValueMutex*)ctx); + furi_assert(ctx); + Players* playersMutex = ctx; + furi_mutex_acquire(playersMutex->mutex, FuriWaitForever); canvas_draw_frame(canvas, 0, 0, 128, 64); canvas_draw_box( @@ -57,7 +61,7 @@ static void draw_callback(Canvas* canvas, void* ctx) { canvas_draw_str_aligned( canvas, SCREEN_SIZE_X / 2 + 15, SCREEN_SIZE_Y / 2 + 2, AlignCenter, AlignTop, buffer); - release_mutex((ValueMutex*)ctx, playersMutex); + furi_mutex_release(playersMutex->mutex); } static void input_callback(InputEvent* input_event, void* ctx) { @@ -97,7 +101,8 @@ uint8_t changeDirection() { return randomuint8[0]; } -int32_t flipper_pong_app() { +int32_t flipper_pong_app(void* p) { + UNUSED(p); EventApp event; FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(EventApp)); @@ -117,78 +122,83 @@ int32_t flipper_pong_app() { players.ball_X_direction = changeDirection(); players.ball_Y_direction = changeDirection(); - ValueMutex state_mutex; - init_mutex(&state_mutex, &players, sizeof(Players)); + players.mutex = furi_mutex_alloc(FuriMutexTypeNormal); + if(!players.mutex) { + furi_message_queue_free(event_queue); + return 255; + } ViewPort* view_port = view_port_alloc(); - view_port_draw_callback_set(view_port, draw_callback, &state_mutex); + view_port_draw_callback_set(view_port, draw_callback, &players); view_port_input_callback_set(view_port, input_callback, event_queue); Gui* gui = furi_record_open(RECORD_GUI); gui_add_view_port(gui, view_port, GuiLayerFullscreen); + NotificationApp* notification = furi_record_open(RECORD_NOTIFICATION); + if(players.ball_X_direction == 0) + notification_message(notification, &sequence_set_only_red_255); + else + notification_message(notification, &sequence_set_only_blue_255); + FuriTimer* timer = furi_timer_alloc(clock_tick, FuriTimerTypePeriodic, event_queue); furi_timer_start(timer, 1000 / FPS); while(1) { FuriStatus event_status = furi_message_queue_get(event_queue, &event, FuriWaitForever); - Players* playersMutex = (Players*)acquire_mutex_block(&state_mutex); + furi_mutex_acquire(players.mutex, FuriWaitForever); if(event_status == FuriStatusOk) { if(event.type == EventTypeInput) { if(event.input.key == InputKeyBack) { - release_mutex(&state_mutex, playersMutex); + furi_mutex_release(players.mutex); + notification_message(notification, &sequence_set_only_green_255); break; } else if(event.input.key == InputKeyUp) { - if(playersMutex->player1_Y >= 1 + PLAYER1_PAD_SPEED) - playersMutex->player1_Y -= PLAYER1_PAD_SPEED; + if(players.player1_Y >= 1 + PLAYER1_PAD_SPEED) + players.player1_Y -= PLAYER1_PAD_SPEED; else - playersMutex->player1_Y = 1; + players.player1_Y = 1; } else if(event.input.key == InputKeyDown) { - if(playersMutex->player1_Y <= - SCREEN_SIZE_Y - PAD_SIZE_Y - PLAYER1_PAD_SPEED - 1) - playersMutex->player1_Y += PLAYER1_PAD_SPEED; + if(players.player1_Y <= SCREEN_SIZE_Y - PAD_SIZE_Y - PLAYER1_PAD_SPEED - 1) + players.player1_Y += PLAYER1_PAD_SPEED; else - playersMutex->player1_Y = SCREEN_SIZE_Y - PAD_SIZE_Y - 1; + players.player1_Y = SCREEN_SIZE_Y - PAD_SIZE_Y - 1; } } else if(event.type == ClockEventTypeTick) { - if(playersMutex->ball_X + BALL_SIZE / 2 <= SCREEN_SIZE_X * 0.35 && - playersMutex->ball_X_direction == 0) { - if(playersMutex->ball_Y + BALL_SIZE / 2 < - playersMutex->player2_Y + PAD_SIZE_Y / 2) { - if(playersMutex->player2_Y >= 1 + PLAYER2_PAD_SPEED) - playersMutex->player2_Y -= PLAYER2_PAD_SPEED; + if(players.ball_X + BALL_SIZE / 2 <= SCREEN_SIZE_X * 0.35 && + players.ball_X_direction == 0) { + if(players.ball_Y + BALL_SIZE / 2 < players.player2_Y + PAD_SIZE_Y / 2) { + if(players.player2_Y >= 1 + PLAYER2_PAD_SPEED) + players.player2_Y -= PLAYER2_PAD_SPEED; else - playersMutex->player2_Y = 1; - } else if( - playersMutex->ball_Y + BALL_SIZE / 2 > - playersMutex->player2_Y + PAD_SIZE_Y / 2) { - if(playersMutex->player2_Y <= - SCREEN_SIZE_Y - PAD_SIZE_Y - PLAYER2_PAD_SPEED - 1) - playersMutex->player2_Y += PLAYER2_PAD_SPEED; + players.player2_Y = 1; + } else if(players.ball_Y + BALL_SIZE / 2 > players.player2_Y + PAD_SIZE_Y / 2) { + if(players.player2_Y <= SCREEN_SIZE_Y - PAD_SIZE_Y - PLAYER2_PAD_SPEED - 1) + players.player2_Y += PLAYER2_PAD_SPEED; else - playersMutex->player2_Y = SCREEN_SIZE_Y - PAD_SIZE_Y - 1; + players.player2_Y = SCREEN_SIZE_Y - PAD_SIZE_Y - 1; } } uint8_t ball_corner_X[4] = { - playersMutex->ball_X, - playersMutex->ball_X + BALL_SIZE, - playersMutex->ball_X + BALL_SIZE, - playersMutex->ball_X}; + players.ball_X, + players.ball_X + BALL_SIZE, + players.ball_X + BALL_SIZE, + players.ball_X}; uint8_t ball_corner_Y[4] = { - playersMutex->ball_Y, - playersMutex->ball_Y, - playersMutex->ball_Y + BALL_SIZE, - playersMutex->ball_Y + BALL_SIZE}; + players.ball_Y, + players.ball_Y, + players.ball_Y + BALL_SIZE, + players.ball_Y + BALL_SIZE}; bool insidePlayer1 = false, insidePlayer2 = false; for(int i = 0; i < 4; i++) { if(insidePad( ball_corner_X[i], ball_corner_Y[i], - playersMutex->player1_X, - playersMutex->player1_Y) == true) { + players.player1_X, + players.player1_Y) == true) { insidePlayer1 = true; break; } @@ -196,83 +206,88 @@ int32_t flipper_pong_app() { if(insidePad( ball_corner_X[i], ball_corner_Y[i], - playersMutex->player2_X, - playersMutex->player2_Y) == true) { + players.player2_X, + players.player2_Y) == true) { insidePlayer2 = true; break; } } if(insidePlayer1 == true) { - playersMutex->ball_X_direction = 0; - playersMutex->ball_X -= playersMutex->ball_X_speed; - playersMutex->ball_X_speed = changeSpeed(); - playersMutex->ball_Y_speed = changeSpeed(); + players.ball_X_direction = 0; + players.ball_X -= players.ball_X_speed; + players.ball_X_speed = changeSpeed(); + players.ball_Y_speed = changeSpeed(); + notification_message(notification, &sequence_set_only_red_255); } else if(insidePlayer2 == true) { - playersMutex->ball_X_direction = 1; - playersMutex->ball_X += playersMutex->ball_X_speed; - playersMutex->ball_X_speed = changeSpeed(); - playersMutex->ball_Y_speed = changeSpeed(); + players.ball_X_direction = 1; + players.ball_X += players.ball_X_speed; + players.ball_X_speed = changeSpeed(); + players.ball_Y_speed = changeSpeed(); + notification_message(notification, &sequence_set_only_blue_255); } else { - if(playersMutex->ball_X_direction == 1) { - if(playersMutex->ball_X <= - SCREEN_SIZE_X - BALL_SIZE - 1 - playersMutex->ball_X_speed) { - playersMutex->ball_X += playersMutex->ball_X_speed; + if(players.ball_X_direction == 1) { + if(players.ball_X <= + SCREEN_SIZE_X - BALL_SIZE - 1 - players.ball_X_speed) { + players.ball_X += players.ball_X_speed; } else { - playersMutex->ball_X = SCREEN_SIZE_X / 2 - BALL_SIZE / 2; - playersMutex->ball_Y = SCREEN_SIZE_Y / 2 - BALL_SIZE / 2; - playersMutex->ball_X_speed = 1; - playersMutex->ball_Y_speed = 1; - playersMutex->ball_X_direction = 0; - playersMutex->player2_score++; + players.ball_X = SCREEN_SIZE_X / 2 - BALL_SIZE / 2; + players.ball_Y = SCREEN_SIZE_Y / 2 - BALL_SIZE / 2; + players.ball_X_speed = 1; + players.ball_Y_speed = 1; + players.ball_X_direction = 0; + players.player2_score++; + notification_message(notification, &sequence_set_only_red_255); } } else { - if(playersMutex->ball_X >= 1 + playersMutex->ball_X_speed) { - playersMutex->ball_X -= playersMutex->ball_X_speed; + if(players.ball_X >= 1 + players.ball_X_speed) { + players.ball_X -= players.ball_X_speed; } else { - playersMutex->ball_X = SCREEN_SIZE_X / 2 - BALL_SIZE / 2; - playersMutex->ball_Y = SCREEN_SIZE_Y / 2 - BALL_SIZE / 2; - playersMutex->ball_X_speed = 1; - playersMutex->ball_Y_speed = 1; - playersMutex->ball_X_direction = 1; - playersMutex->player1_score++; + players.ball_X = SCREEN_SIZE_X / 2 - BALL_SIZE / 2; + players.ball_Y = SCREEN_SIZE_Y / 2 - BALL_SIZE / 2; + players.ball_X_speed = 1; + players.ball_Y_speed = 1; + players.ball_X_direction = 1; + players.player1_score++; + notification_message(notification, &sequence_set_only_blue_255); } } } - if(playersMutex->ball_Y_direction == 1) { - if(playersMutex->ball_Y <= - SCREEN_SIZE_Y - BALL_SIZE - 1 - playersMutex->ball_Y_speed) { - playersMutex->ball_Y += playersMutex->ball_Y_speed; + if(players.ball_Y_direction == 1) { + if(players.ball_Y <= SCREEN_SIZE_Y - BALL_SIZE - 1 - players.ball_Y_speed) { + players.ball_Y += players.ball_Y_speed; } else { - playersMutex->ball_Y = SCREEN_SIZE_Y - BALL_SIZE - 1; - playersMutex->ball_X_speed = changeSpeed(); - playersMutex->ball_Y_speed = changeSpeed(); - playersMutex->ball_Y_direction = 0; + players.ball_Y = SCREEN_SIZE_Y - BALL_SIZE - 1; + players.ball_X_speed = changeSpeed(); + players.ball_Y_speed = changeSpeed(); + players.ball_Y_direction = 0; } } else { - if(playersMutex->ball_Y >= 1 + playersMutex->ball_Y_speed) { - playersMutex->ball_Y -= playersMutex->ball_Y_speed; + if(players.ball_Y >= 1 + players.ball_Y_speed) { + players.ball_Y -= players.ball_Y_speed; } else { - playersMutex->ball_Y = 1; - playersMutex->ball_X_speed = changeSpeed(); - playersMutex->ball_Y_speed = changeSpeed(); - playersMutex->ball_Y_direction = 1; + players.ball_Y = 1; + players.ball_X_speed = changeSpeed(); + players.ball_Y_speed = changeSpeed(); + players.ball_Y_direction = 1; } } } } - release_mutex(&state_mutex, playersMutex); + furi_mutex_release(players.mutex); view_port_update(view_port); } + notification_message(notification, &sequence_reset_rgb); furi_message_queue_free(event_queue); - delete_mutex(&state_mutex); + furi_mutex_free(players.mutex); gui_remove_view_port(gui, view_port); view_port_free(view_port); furi_timer_free(timer); furi_record_close(RECORD_GUI); + furi_record_close(RECORD_NOTIFICATION); return 0; -} +} \ No newline at end of file diff --git a/applications/plugins/qrcode/application.fam b/applications/plugins/qrcode/application.fam index 68a378fa4..3aac3f18d 100644 --- a/applications/plugins/qrcode/application.fam +++ b/applications/plugins/qrcode/application.fam @@ -1,7 +1,7 @@ App( - appid="QRCode", + appid="qrcode", name="QR Code", - fap_version=(1, 0), + fap_version=(1, 1), fap_description="Display qrcodes", fap_author="Bob Matcuk", fap_weburl="https://github.com/bmatcuk/flipperzero-qrcode", @@ -16,5 +16,4 @@ App( fap_category="Tools", fap_icon="icons/qrcode_10px.png", fap_icon_assets="icons", - fap_icon_assets_symbol="qrcode", ) diff --git a/applications/plugins/scrambler/LICENSE b/applications/plugins/rubiks_cube_scrambler/LICENSE similarity index 100% rename from applications/plugins/scrambler/LICENSE rename to applications/plugins/rubiks_cube_scrambler/LICENSE diff --git a/applications/plugins/rubiks_cube_scrambler/README.md b/applications/plugins/rubiks_cube_scrambler/README.md new file mode 100644 index 000000000..feddf06d6 --- /dev/null +++ b/applications/plugins/rubiks_cube_scrambler/README.md @@ -0,0 +1,13 @@ +# Rubik's Cube Scrambler FAP + +## Where to start? +Install the .fap file and put it in your apps folder + +## What does what? +The On/Off button toggles the vibration notification on and off. The "New" button generates a new scramble. The scramble letters correspond with the following moves: R = Right, L = Left, U = Up, D = Down, F = Front, B = Back. The number after the letter indicates how many times to turn that face. For example, R2 means to turn the right face twice. The ' symbol indicates a counter-clockwise turn. For example, R' means to turn the right face counter-clockwise once. + + + +# A special thanks to Tanish for their c scrambler example 🙏 +https://github.com/TanishBhongade/RubiksCubeScrambler-C/ + diff --git a/applications/plugins/scrambler/application.fam b/applications/plugins/rubiks_cube_scrambler/application.fam similarity index 80% rename from applications/plugins/scrambler/application.fam rename to applications/plugins/rubiks_cube_scrambler/application.fam index 4d48d7bb5..7200f3e9c 100644 --- a/applications/plugins/scrambler/application.fam +++ b/applications/plugins/rubiks_cube_scrambler/application.fam @@ -1,6 +1,6 @@ # COMPILE ISTRUCTIONS: -# Clean the code and remove old binaries/compilation artefact +# Clean the code and remove old binaries/compilation artefact # ./fbt -c fap_rubiks_cube_scrambler # Compile FAP @@ -10,7 +10,7 @@ # ./fbt launch_app APPSRC=rubiks_cube_scrambler App( - appid="Rubiks_Cube_Scrambler", + appid="rubiks_cube_scrambler", name="Rubik's Cube Scrambler", apptype=FlipperAppType.EXTERNAL, entry_point="rubiks_cube_scrambler_main", diff --git a/applications/plugins/scrambler/cube.png b/applications/plugins/rubiks_cube_scrambler/cube.png similarity index 100% rename from applications/plugins/scrambler/cube.png rename to applications/plugins/rubiks_cube_scrambler/cube.png diff --git a/applications/plugins/scrambler/rubiks_cube_scrambler.c b/applications/plugins/rubiks_cube_scrambler/rubiks_cube_scrambler.c similarity index 100% rename from applications/plugins/scrambler/rubiks_cube_scrambler.c rename to applications/plugins/rubiks_cube_scrambler/rubiks_cube_scrambler.c diff --git a/applications/plugins/scrambler/scrambler.c b/applications/plugins/rubiks_cube_scrambler/scrambler.c similarity index 100% rename from applications/plugins/scrambler/scrambler.c rename to applications/plugins/rubiks_cube_scrambler/scrambler.c diff --git a/applications/plugins/scrambler/scrambler.h b/applications/plugins/rubiks_cube_scrambler/scrambler.h similarity index 100% rename from applications/plugins/scrambler/scrambler.h rename to applications/plugins/rubiks_cube_scrambler/scrambler.h diff --git a/applications/plugins/scrambler/README.md b/applications/plugins/scrambler/README.md deleted file mode 100644 index 7e4700bcd..000000000 --- a/applications/plugins/scrambler/README.md +++ /dev/null @@ -1,16 +0,0 @@ -# Setting up the Rubik's Cube Scrambler - -## Installation -To install the Rubik's Cube Scrambler, simply add the `rubiks_cube_scrambler` folder to your `application_users` folder. - -## Cleaning the code and removing old files -Run `./fbt -c fap_rubiks_cube_scrambler` to clean the code and remove any old binaries or compilation artifacts. - -## Compiling the FAP -To compile the FAP, run `./fbt fap_rubiks_cube_scrambler`. - -## Launching the app -To run the Rubik's Cube Scrambler directly from the Flip.x0, use `./fbt launch_app APPSRC=rubiks_cube_scrambler`. - -# A special thanks to Tanish for their c scrambler example 🙏 -https://github.com/TanishBhongade/RubiksCubeScrambler-C/ diff --git a/applications/plugins/scrambler/assets/1.png b/applications/plugins/scrambler/assets/1.png deleted file mode 100644 index d2099ea34..000000000 Binary files a/applications/plugins/scrambler/assets/1.png and /dev/null differ diff --git a/applications/plugins/tuning_fork/application.fam b/applications/plugins/tuning_fork/application.fam index 47cef5364..5979ddb2a 100644 --- a/applications/plugins/tuning_fork/application.fam +++ b/applications/plugins/tuning_fork/application.fam @@ -1,5 +1,5 @@ App( - appid="Tuning_Fork", + appid="tuning_fork", name="Tuning Fork", apptype=FlipperAppType.EXTERNAL, entry_point="tuning_fork_app", diff --git a/applications/plugins/tuning_fork/tuning_fork.c b/applications/plugins/tuning_fork/tuning_fork.c index 69a76029f..6912d1780 100644 --- a/applications/plugins/tuning_fork/tuning_fork.c +++ b/applications/plugins/tuning_fork/tuning_fork.c @@ -28,6 +28,7 @@ typedef struct { enum Page { Tunings, Notes }; typedef struct { + FuriMutex* mutex; bool playing; enum Page page; int current_tuning_note_index; @@ -114,7 +115,7 @@ static void decrease_volume(TuningForkState* tuning_fork_state) { } static void play(TuningForkState* tuning_fork_state) { - if(furi_hal_speaker_is_mine() || furi_hal_speaker_acquire(30)) { + if(furi_hal_speaker_is_mine() || furi_hal_speaker_acquire(1000)) { furi_hal_speaker_start( current_tuning_note_freq(tuning_fork_state), tuning_fork_state->volume); } @@ -133,10 +134,9 @@ static void replay(TuningForkState* tuning_fork_state) { } static void render_callback(Canvas* const canvas, void* ctx) { - TuningForkState* tuning_fork_state = acquire_mutex((ValueMutex*)ctx, 25); - if(tuning_fork_state == NULL) { - return; - } + furi_assert(ctx); + TuningForkState* tuning_fork_state = ctx; + furi_mutex_acquire(tuning_fork_state->mutex, FuriWaitForever); string_t tempStr; string_init(tempStr); @@ -185,7 +185,7 @@ static void render_callback(Canvas* const canvas, void* ctx) { } string_clear(tempStr); - release_mutex((ValueMutex*)ctx, tuning_fork_state); + furi_mutex_release(tuning_fork_state->mutex); } static void input_callback(InputEvent* input_event, FuriMessageQueue* event_queue) { @@ -210,8 +210,8 @@ int32_t tuning_fork_app() { TuningForkState* tuning_fork_state = malloc(sizeof(TuningForkState)); tuning_fork_state_init(tuning_fork_state); - ValueMutex state_mutex; - if(!init_mutex(&state_mutex, tuning_fork_state, sizeof(TuningForkState))) { + tuning_fork_state->mutex = furi_mutex_alloc(FuriMutexTypeNormal); + if(!tuning_fork_state->mutex) { FURI_LOG_E("TuningFork", "cannot create mutex\r\n"); free(tuning_fork_state); return 255; @@ -219,7 +219,7 @@ int32_t tuning_fork_app() { // Set system callbacks ViewPort* view_port = view_port_alloc(); - view_port_draw_callback_set(view_port, render_callback, &state_mutex); + view_port_draw_callback_set(view_port, render_callback, tuning_fork_state); view_port_input_callback_set(view_port, input_callback, event_queue); Gui* gui = furi_record_open("gui"); @@ -229,7 +229,7 @@ int32_t tuning_fork_app() { for(bool processing = true; processing;) { FuriStatus event_status = furi_message_queue_get(event_queue, &event, 100); - TuningForkState* tuning_fork_state = (TuningForkState*)acquire_mutex_block(&state_mutex); + furi_mutex_acquire(tuning_fork_state->mutex, FuriWaitForever); if(event_status == FuriStatusOk) { if(event.type == EventTypeKey) { @@ -387,12 +387,10 @@ int32_t tuning_fork_app() { } } } - } else { - FURI_LOG_D("TuningFork", "FuriMessageQueue: event timeout"); } view_port_update(view_port); - release_mutex(&state_mutex, tuning_fork_state); + furi_mutex_release(tuning_fork_state->mutex); } view_port_enabled_set(view_port, false); @@ -400,7 +398,7 @@ int32_t tuning_fork_app() { furi_record_close("gui"); view_port_free(view_port); furi_message_queue_free(event_queue); - delete_mutex(&state_mutex); + furi_mutex_free(tuning_fork_state->mutex); furi_record_close(RECORD_NOTIFICATION); free(tuning_fork_state); diff --git a/applications/plugins/wifi_deauther_v2/LICENSE b/applications/plugins/wifi_deauther/LICENSE similarity index 100% rename from applications/plugins/wifi_deauther_v2/LICENSE rename to applications/plugins/wifi_deauther/LICENSE diff --git a/applications/plugins/wifi_deauther_v2/README.md b/applications/plugins/wifi_deauther/README.md similarity index 79% rename from applications/plugins/wifi_deauther_v2/README.md rename to applications/plugins/wifi_deauther/README.md index 40fff1324..87a419f90 100644 --- a/applications/plugins/wifi_deauther_v2/README.md +++ b/applications/plugins/wifi_deauther/README.md @@ -4,10 +4,6 @@ Flipper Zero esp8266 deauther app. Based off the WiFi Marauder App from 0xchocolate. -Thanks to Roguemaster for fixing some issues I had with the code and didnt get a chance to get to. I have now uploaded these changes into the source. - -I have also successfully built this with unleashed souce as well and included the FAP file here. unleashed version unlshd-020. - https://github.com/0xchocolate/flipperzero-firmware-with-wifi-marauder-companion https://github.com/RogueMaster/flipperzero-firmware-wPlugins/tree/unleashed/applications/wifi_marauder_companion @@ -36,13 +32,10 @@ TX--------U_RX -Video in action (old version). +Video in action. https://youtu.be/_RFzZyPkeR0 -New video and install instructions. -https://youtu.be/CKK7t0TaRVQ - -If you want to disable the built in WiFi access and web interface (only use flipper to send serial commands) then select "set webinterface false", "save settings" and "reboot". When it starts back up you wont see the pwned AP any more. +If you want to disable the built in WiFi access and web interface (only use flipper to serial send commands) then select "set webinterface false", "save settings" and "reboot". When it starts back up you wont see the pwned AP any more. I installed this into Roguemaster to test. diff --git a/applications/plugins/wifi_deauther_v2/application.fam b/applications/plugins/wifi_deauther/application.fam similarity index 75% rename from applications/plugins/wifi_deauther_v2/application.fam rename to applications/plugins/wifi_deauther/application.fam index e7c1dec5d..07ceb543b 100644 --- a/applications/plugins/wifi_deauther_v2/application.fam +++ b/applications/plugins/wifi_deauther/application.fam @@ -1,6 +1,6 @@ App( - appid="ESP8266_Wifi_Deauther", - name="[ESP8266] WiFi (Deauther) v2", + appid="ESP8266_Wifi_Deauther_v2", + name="[ESP8266] Deauther v2", apptype=FlipperAppType.EXTERNAL, entry_point="wifi_deauther_app", cdefines=["APP_WIFI_deauther"], diff --git a/applications/plugins/wifi_deauther_v2/scenes/wifi_deauther_scene.c b/applications/plugins/wifi_deauther/scenes/wifi_deauther_scene.c similarity index 100% rename from applications/plugins/wifi_deauther_v2/scenes/wifi_deauther_scene.c rename to applications/plugins/wifi_deauther/scenes/wifi_deauther_scene.c diff --git a/applications/plugins/wifi_deauther_v2/scenes/wifi_deauther_scene.h b/applications/plugins/wifi_deauther/scenes/wifi_deauther_scene.h similarity index 100% rename from applications/plugins/wifi_deauther_v2/scenes/wifi_deauther_scene.h rename to applications/plugins/wifi_deauther/scenes/wifi_deauther_scene.h diff --git a/applications/plugins/wifi_deauther_v2/scenes/wifi_deauther_scene_config.h b/applications/plugins/wifi_deauther/scenes/wifi_deauther_scene_config.h similarity index 100% rename from applications/plugins/wifi_deauther_v2/scenes/wifi_deauther_scene_config.h rename to applications/plugins/wifi_deauther/scenes/wifi_deauther_scene_config.h diff --git a/applications/plugins/wifi_deauther_v2/scenes/wifi_deauther_scene_console_output.c b/applications/plugins/wifi_deauther/scenes/wifi_deauther_scene_console_output.c similarity index 84% rename from applications/plugins/wifi_deauther_v2/scenes/wifi_deauther_scene_console_output.c rename to applications/plugins/wifi_deauther/scenes/wifi_deauther_scene_console_output.c index a9b738b06..a3d03a0d1 100644 --- a/applications/plugins/wifi_deauther_v2/scenes/wifi_deauther_scene_console_output.c +++ b/applications/plugins/wifi_deauther/scenes/wifi_deauther_scene_console_output.c @@ -21,13 +21,6 @@ void wifi_deauther_console_output_handle_rx_data_cb(uint8_t* buf, size_t len, vo void wifi_deauther_scene_console_output_on_enter(void* context) { WifideautherApp* app = context; - // Register callback to receive data - wifi_deauther_uart_set_handle_rx_data_cb( - app->uart, wifi_deauther_console_output_handle_rx_data_cb); // setup callback for rx thread - - // Give a small delay to allow UART to settle. - furi_delay_ms(600); - TextBox* text_box = app->text_box; text_box_reset(app->text_box); text_box_set_font(text_box, TextBoxFontText); @@ -39,7 +32,17 @@ void wifi_deauther_scene_console_output_on_enter(void* context) { if(app->is_command) { furi_string_reset(app->text_box_store); app->text_box_store_strlen = 0; + if(0 == strncmp("help", app->selected_tx_string, strlen("help"))) { + const char* help_msg = "For app support/feedback,\nreach out to\n"; + furi_string_cat_str(app->text_box_store, help_msg); + app->text_box_store_strlen += strlen(help_msg); + } + if(app->show_stopscan_tip) { + const char* help_msg = "Press BACK to send stopscan\n"; + furi_string_cat_str(app->text_box_store, help_msg); + app->text_box_store_strlen += strlen(help_msg); + } } else { // "View Log" menu action text_box_set_text(app->text_box, furi_string_get_cstr(app->text_box_store)); } @@ -47,6 +50,10 @@ void wifi_deauther_scene_console_output_on_enter(void* context) { scene_manager_set_scene_state(app->scene_manager, WifideautherSceneConsoleOutput, 0); view_dispatcher_switch_to_view(app->view_dispatcher, WifideautherAppViewConsoleOutput); + // Register callback to receive data + wifi_deauther_uart_set_handle_rx_data_cb( + app->uart, wifi_deauther_console_output_handle_rx_data_cb); // setup callback for rx thread + // Send command with newline '\n' if(app->is_command && app->selected_tx_string) { wifi_deauther_uart_tx( diff --git a/applications/plugins/wifi_deauther_v2/scenes/wifi_deauther_scene_start.c b/applications/plugins/wifi_deauther/scenes/wifi_deauther_scene_start.c similarity index 100% rename from applications/plugins/wifi_deauther_v2/scenes/wifi_deauther_scene_start.c rename to applications/plugins/wifi_deauther/scenes/wifi_deauther_scene_start.c index 2519c9a07..92b80b2cf 100644 --- a/applications/plugins/wifi_deauther_v2/scenes/wifi_deauther_scene_start.c +++ b/applications/plugins/wifi_deauther/scenes/wifi_deauther_scene_start.c @@ -33,13 +33,6 @@ const WifideautherItem MenuItems[NUM_MENU_ITEMS] = { NO_ARGS, FOCUS_CONSOLE_END, NO_TIP}, - {"Show", - {"SSIDs", "Stations", "All", "Selected"}, - 4, - {"show ap", "show station", "show all", "show selected"}, - NO_ARGS, - FOCUS_CONSOLE_END, - NO_TIP}, {"Select", {"All", "SSIDs", "Stations"}, 3, @@ -54,6 +47,13 @@ const WifideautherItem MenuItems[NUM_MENU_ITEMS] = { INPUT_ARGS, FOCUS_CONSOLE_END, NO_TIP}, + {"Show", + {"SSIDs", "Stations", "All", "Selected"}, + 4, + {"show ap", "show station", "show all", "show selected"}, + NO_ARGS, + FOCUS_CONSOLE_END, + NO_TIP}, {"Attack", {"deauth", "deauthall", "beacon", "probe"}, 4, diff --git a/applications/plugins/wifi_deauther_v2/scenes/wifi_deauther_scene_text_input.c b/applications/plugins/wifi_deauther/scenes/wifi_deauther_scene_text_input.c similarity index 55% rename from applications/plugins/wifi_deauther_v2/scenes/wifi_deauther_scene_text_input.c rename to applications/plugins/wifi_deauther/scenes/wifi_deauther_scene_text_input.c index 2968f4de1..339b2f2a3 100644 --- a/applications/plugins/wifi_deauther_v2/scenes/wifi_deauther_scene_text_input.c +++ b/applications/plugins/wifi_deauther/scenes/wifi_deauther_scene_text_input.c @@ -25,32 +25,16 @@ void wifi_deauther_scene_text_input_on_enter(void* context) { // Setup view TextInput* text_input = app->text_input; // Add help message to header - if(0 == strncmp("select aps", app->selected_tx_string, strlen("select aps"))) { - text_input_set_header_text(text_input, "Enter SSID ID to attack"); - } else if(0 == strncmp("select stations", app->selected_tx_string, strlen("select stations"))) { - text_input_set_header_text(text_input, "Enter Station ID to attack"); - } - if(0 == strncmp("deselect aps", app->selected_tx_string, strlen("deselect aps"))) { - text_input_set_header_text(text_input, "Enter SSID ID to remove"); - } else if( - 0 == strncmp("deselect stations", app->selected_tx_string, strlen("deselect stations"))) { - text_input_set_header_text(text_input, "Enter Station ID to remove"); - } else if(0 == strncmp("get settings", app->selected_tx_string, strlen("get settings"))) { - text_input_set_header_text(text_input, "Get setting. Enter for all"); - } else if( - 0 == - strncmp( - "set webinterface false", app->selected_tx_string, strlen("set webinterface false"))) { - text_input_set_header_text(text_input, "Disable PWNED management AP"); - } else if(0 == strncmp("set ssid: pwned", app->selected_tx_string, strlen("set ssid: pwned"))) { - text_input_set_header_text(text_input, "Change management SSID"); - } else if( - 0 == - strncmp( - "set password: deauther", app->selected_tx_string, strlen("set password: deauther"))) { - text_input_set_header_text(text_input, "Change management PWD"); - } else if(0 == strncmp("save settings", app->selected_tx_string, strlen("save settings"))) { - text_input_set_header_text(text_input, "Save Settings"); + if(0 == strncmp("ssid -a -g", app->selected_tx_string, strlen("ssid -a -g"))) { + text_input_set_header_text(text_input, "Enter # SSIDs to generate"); + } else if(0 == strncmp("ssid -a -n", app->selected_tx_string, strlen("ssid -a -n"))) { + text_input_set_header_text(text_input, "Enter SSID name to add"); + } else if(0 == strncmp("ssid -r", app->selected_tx_string, strlen("ssid -r"))) { + text_input_set_header_text(text_input, "Remove target from SSID list"); + } else if(0 == strncmp("select -a", app->selected_tx_string, strlen("select -a"))) { + text_input_set_header_text(text_input, "Add target from AP list"); + } else if(0 == strncmp("select -s", app->selected_tx_string, strlen("select -s"))) { + text_input_set_header_text(text_input, "Add target from SSID list"); } else { text_input_set_header_text(text_input, "Add command arguments"); } @@ -65,7 +49,6 @@ void wifi_deauther_scene_text_input_on_enter(void* context) { view_dispatcher_switch_to_view(app->view_dispatcher, WifideautherAppViewTextInput); } -///* bool wifi_deauther_scene_text_input_on_event(void* context, SceneManagerEvent event) { WifideautherApp* app = context; bool consumed = false; @@ -87,4 +70,3 @@ void wifi_deauther_scene_text_input_on_exit(void* context) { text_input_reset(app->text_input); } -//*/ \ No newline at end of file diff --git a/applications/plugins/wifi_deauther_v2/wifi_10px.png b/applications/plugins/wifi_deauther/wifi_10px.png similarity index 100% rename from applications/plugins/wifi_deauther_v2/wifi_10px.png rename to applications/plugins/wifi_deauther/wifi_10px.png diff --git a/applications/plugins/wifi_deauther_v2/wifi_deauther_app.c b/applications/plugins/wifi_deauther/wifi_deauther_app.c similarity index 100% rename from applications/plugins/wifi_deauther_v2/wifi_deauther_app.c rename to applications/plugins/wifi_deauther/wifi_deauther_app.c diff --git a/applications/plugins/wifi_deauther_v2/wifi_deauther_app.h b/applications/plugins/wifi_deauther/wifi_deauther_app.h similarity index 100% rename from applications/plugins/wifi_deauther_v2/wifi_deauther_app.h rename to applications/plugins/wifi_deauther/wifi_deauther_app.h diff --git a/applications/plugins/wifi_deauther_v2/wifi_deauther_app_i.h b/applications/plugins/wifi_deauther/wifi_deauther_app_i.h similarity index 100% rename from applications/plugins/wifi_deauther_v2/wifi_deauther_app_i.h rename to applications/plugins/wifi_deauther/wifi_deauther_app_i.h diff --git a/applications/plugins/wifi_deauther_v2/wifi_deauther_custom_event.h b/applications/plugins/wifi_deauther/wifi_deauther_custom_event.h similarity index 100% rename from applications/plugins/wifi_deauther_v2/wifi_deauther_custom_event.h rename to applications/plugins/wifi_deauther/wifi_deauther_custom_event.h diff --git a/applications/plugins/wifi_deauther_v2/wifi_deauther_uart.c b/applications/plugins/wifi_deauther/wifi_deauther_uart.c similarity index 100% rename from applications/plugins/wifi_deauther_v2/wifi_deauther_uart.c rename to applications/plugins/wifi_deauther/wifi_deauther_uart.c index 10e73c323..434ccfd97 100644 --- a/applications/plugins/wifi_deauther_v2/wifi_deauther_uart.c +++ b/applications/plugins/wifi_deauther/wifi_deauther_uart.c @@ -42,8 +42,6 @@ void wifi_deauther_uart_on_irq_cb(UartIrqEvent ev, uint8_t data, void* context) static int32_t uart_worker(void* context) { WifideautherUart* uart = (void*)context; - uart->rx_stream = xStreamBufferCreate(RX_BUF_SIZE, 1); - while(1) { uint32_t events = furi_thread_flags_wait(WORKER_ALL_RX_EVENTS, FuriFlagWaitAny, FuriWaitForever); @@ -69,11 +67,8 @@ void wifi_deauther_uart_tx(uint8_t* data, size_t len) { WifideautherUart* wifi_deauther_uart_init(WifideautherApp* app) { WifideautherUart* uart = malloc(sizeof(WifideautherUart)); - furi_hal_console_disable(); - furi_hal_uart_set_br(UART_CH, BAUDRATE); - furi_hal_uart_set_irq_cb(UART_CH, wifi_deauther_uart_on_irq_cb, uart); - uart->app = app; + uart->rx_stream = xStreamBufferCreate(RX_BUF_SIZE, 1); uart->rx_thread = furi_thread_alloc(); furi_thread_set_name(uart->rx_thread, "WifideautherUartRxThread"); furi_thread_set_stack_size(uart->rx_thread, 1024); @@ -81,6 +76,11 @@ WifideautherUart* wifi_deauther_uart_init(WifideautherApp* app) { furi_thread_set_callback(uart->rx_thread, uart_worker); furi_thread_start(uart->rx_thread); + + furi_hal_console_disable(); + furi_hal_uart_set_br(UART_CH, BAUDRATE); + furi_hal_uart_set_irq_cb(UART_CH, wifi_deauther_uart_on_irq_cb, uart); + return uart; } diff --git a/applications/plugins/wifi_deauther_v2/wifi_deauther_uart.h b/applications/plugins/wifi_deauther/wifi_deauther_uart.h similarity index 100% rename from applications/plugins/wifi_deauther_v2/wifi_deauther_uart.h rename to applications/plugins/wifi_deauther/wifi_deauther_uart.h diff --git a/applications/plugins/yatzee/application.fam b/applications/plugins/yatzee/application.fam index b30e90d23..1c59d634b 100644 --- a/applications/plugins/yatzee/application.fam +++ b/applications/plugins/yatzee/application.fam @@ -1,5 +1,5 @@ App( - appid="Yatzee", + appid="yatzee", name="Yatzee", apptype=FlipperAppType.EXTERNAL, entry_point="yatzee_main", diff --git a/applications/plugins/yatzee/yatzee.c b/applications/plugins/yatzee/yatzee.c index 304a604c1..fa114fde4 100644 --- a/applications/plugins/yatzee/yatzee.c +++ b/applications/plugins/yatzee/yatzee.c @@ -1,4 +1,4 @@ -#include "Yatzee_icons.h" +#include "yatzee_icons.h" #include #include