Skip to content

Commit

Permalink
Fixed some stuff. Added tons of logging for cli log, but ir still cra…
Browse files Browse the repository at this point in the history
…shes.
  • Loading branch information
RocketGod-git committed Aug 22, 2024
1 parent 3cca0c7 commit e1d90b0
Show file tree
Hide file tree
Showing 12 changed files with 439 additions and 173 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
dist/*
.vscode
.clang-format
.clangd
.editorconfig
.env
.ufbt
4 changes: 2 additions & 2 deletions docs/README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
# Flipper Zero - Laser Tag
# Flipper Zero - Development Toolkit

Not working, yet.
Short description.
36 changes: 26 additions & 10 deletions game_state.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@

#include "game_state.h"
#include <furi.h>
#include <stdlib.h>

struct GameState {
LaserTagTeam team;
Expand All @@ -12,36 +14,39 @@ struct GameState {

GameState* game_state_alloc() {
GameState* state = malloc(sizeof(GameState));
if(!state) {
return NULL;
}
state->team = TeamRed;
state->health = 100;
state->health = INITIAL_HEALTH;
state->score = 0;
state->ammo = 100;
state->ammo = INITIAL_AMMO;
state->game_time = 0;
state->game_over = false;
return state;
}

void game_state_free(GameState* state) {
free(state);
}

void game_state_reset(GameState* state) {
state->health = 100;
furi_assert(state);
state->health = INITIAL_HEALTH;
state->score = 0;
state->ammo = 100;
state->ammo = INITIAL_AMMO;
state->game_time = 0;
state->game_over = false;
}

void game_state_set_team(GameState* state, LaserTagTeam team) {
furi_assert(state);
state->team = team;
}

LaserTagTeam game_state_get_team(GameState* state) {
furi_assert(state);
return state->team;
}

void game_state_decrease_health(GameState* state, uint8_t amount) {
furi_assert(state);
if(state->health > amount) {
state->health -= amount;
} else {
Expand All @@ -51,22 +56,27 @@ void game_state_decrease_health(GameState* state, uint8_t amount) {
}

void game_state_increase_health(GameState* state, uint8_t amount) {
state->health = (state->health + amount > 100) ? 100 : state->health + amount;
furi_assert(state);
state->health = (state->health + amount > MAX_HEALTH) ? MAX_HEALTH : state->health + amount;
}

uint8_t game_state_get_health(GameState* state) {
furi_assert(state);
return state->health;
}

void game_state_increase_score(GameState* state, uint16_t points) {
furi_assert(state);
state->score += points;
}

uint16_t game_state_get_score(GameState* state) {
furi_assert(state);
return state->score;
}

void game_state_decrease_ammo(GameState* state, uint16_t amount) {
furi_assert(state);
if(state->ammo > amount) {
state->ammo -= amount;
} else {
Expand All @@ -75,25 +85,31 @@ void game_state_decrease_ammo(GameState* state, uint16_t amount) {
}

void game_state_increase_ammo(GameState* state, uint16_t amount) {
furi_assert(state);
state->ammo += amount;
}

uint16_t game_state_get_ammo(GameState* state) {
furi_assert(state);
return state->ammo;
}

void game_state_update_time(GameState* state, uint32_t delta_time) {
furi_assert(state);
state->game_time += delta_time;
}

uint32_t game_state_get_time(GameState* state) {
furi_assert(state);
return state->game_time;
}

bool game_state_is_game_over(GameState* state) {
furi_assert(state);
return state->game_over;
}

void game_state_set_game_over(GameState* state, bool game_over) {
furi_assert(state);
state->game_over = game_over;
}
}
6 changes: 3 additions & 3 deletions game_state.h
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@

#pragma once

#include <stdint.h>
Expand All @@ -16,7 +17,6 @@ typedef enum {
typedef struct GameState GameState;

GameState* game_state_alloc();
void game_state_free(GameState* state);
void game_state_reset(GameState* state);

void game_state_set_team(GameState* state, LaserTagTeam team);
Expand All @@ -40,5 +40,5 @@ bool game_state_is_game_over(GameState* state);
void game_state_set_game_over(GameState* state, bool game_over);

#define INITIAL_HEALTH 100
#define INITIAL_AMMO 100
#define MAX_HEALTH 100
#define INITIAL_AMMO 100
#define MAX_HEALTH 100
146 changes: 121 additions & 25 deletions infrared_controller.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,108 +5,204 @@
#include <infrared_worker.h>
#include <stdlib.h>

#define TAG "LaserTagInfrared"

#define IR_COMMAND_RED_TEAM 0xA1
#define IR_COMMAND_BLUE_TEAM 0xB2
#define TAG "InfraredController"

struct InfraredController {
LaserTagTeam team;
InfraredWorker* worker;
FuriThread* rx_thread;
volatile bool rx_running;
volatile bool hit_received;
FuriMutex* mutex;
};

static void infrared_rx_callback(void* context, InfraredWorkerSignal* received_signal) {
FURI_LOG_D(TAG, "RX callback triggered");
furi_assert(context);
furi_assert(received_signal);

InfraredController* controller = (InfraredController*)context;

furi_mutex_acquire(controller->mutex, FuriWaitForever);

FURI_LOG_D(TAG, "Context and received signal validated");

const InfraredMessage* message = infrared_worker_get_decoded_signal(received_signal);
if (message != NULL) {
if(message != NULL) {
uint32_t received_command = message->address;
FURI_LOG_D(TAG, "Received command: 0x%lx", (unsigned long)received_command);

if((controller->team == TeamRed && received_command == IR_COMMAND_BLUE_TEAM) ||
(controller->team == TeamBlue && received_command == IR_COMMAND_RED_TEAM)) {
controller->hit_received = true;
FURI_LOG_D(
TAG, "Hit detected for team: %s", controller->team == TeamRed ? "Red" : "Blue");
}
} else {
FURI_LOG_E(TAG, "Received NULL message");
}

furi_mutex_release(controller->mutex);
}

static int32_t infrared_rx_thread(void* context) {
FURI_LOG_D(TAG, "RX thread started");
furi_assert(context);

InfraredController* controller = (InfraredController*)context;

while(controller->rx_running) {
infrared_worker_rx_start(controller->worker);
furi_thread_flags_wait(0, FuriFlagWaitAny, 10);
furi_mutex_acquire(controller->mutex, FuriWaitForever);
FURI_LOG_D(TAG, "Starting infrared_worker_rx_start");

// Check for worker validity before starting
if(controller->worker) {
infrared_worker_rx_start(controller->worker);
FURI_LOG_D(TAG, "infrared_worker_rx_start succeeded");
} else {
FURI_LOG_E(TAG, "InfraredWorker is NULL");
furi_mutex_release(controller->mutex);
continue;
}

furi_mutex_release(controller->mutex);

FURI_LOG_D(TAG, "Waiting for thread flags");
FuriStatus status = furi_thread_flags_wait(0, FuriFlagWaitAny, 10);

if(status == FuriStatusErrorTimeout) {
FURI_LOG_D(TAG, "RX loop timeout, continuing");
} else {
FURI_LOG_D(TAG, "RX loop received flag: %d", status);
}
}

FURI_LOG_D(TAG, "RX thread stopping");
return 0;
}

InfraredController* infrared_controller_alloc() {
FURI_LOG_D(TAG, "Allocating InfraredController");

InfraredController* controller = malloc(sizeof(InfraredController));
if(!controller) {
FURI_LOG_E(TAG, "Failed to allocate InfraredController struct");
return NULL;
}
FURI_LOG_D(TAG, "InfraredController struct allocated");

controller->team = TeamRed;
FURI_LOG_D(TAG, "Team initialized to Red");

FURI_LOG_D(TAG, "Allocating InfraredWorker");
controller->worker = infrared_worker_alloc();
if(!controller->worker) {
FURI_LOG_E(TAG, "Failed to allocate InfraredWorker");
free(controller);
return NULL;
}
FURI_LOG_D(TAG, "InfraredWorker allocated");

controller->rx_running = true;
controller->hit_received = false;

infrared_worker_rx_set_received_signal_callback(controller->worker, infrared_rx_callback, controller);
FURI_LOG_D(TAG, "Creating mutex");
controller->mutex = furi_mutex_alloc(FuriMutexTypeNormal);
if(!controller->mutex) {
FURI_LOG_E(TAG, "Failed to create mutex");
infrared_worker_free(controller->worker);
free(controller);
return NULL;
}

FURI_LOG_D(TAG, "Setting up RX callback");
infrared_worker_rx_set_received_signal_callback(
controller->worker, infrared_rx_callback, controller);

FURI_LOG_D(TAG, "Allocating RX thread");
controller->rx_thread = furi_thread_alloc();
if(!controller->rx_thread) {
FURI_LOG_E(TAG, "Failed to allocate RX thread");
furi_mutex_free(controller->mutex);
infrared_worker_free(controller->worker);
free(controller);
return NULL;
}

furi_thread_set_name(controller->rx_thread, "IR_Rx_Thread");
furi_thread_set_stack_size(controller->rx_thread, 1024);
furi_thread_set_context(controller->rx_thread, controller);
furi_thread_set_callback(controller->rx_thread, infrared_rx_thread);

FURI_LOG_D(TAG, "Starting RX thread");
furi_thread_start(controller->rx_thread);

FURI_LOG_D(TAG, "Starting InfraredWorker RX");
infrared_worker_rx_start(controller->worker);

FURI_LOG_D(TAG, "InfraredController allocated successfully");
return controller;
}

void infrared_controller_free(InfraredController* controller) {
FURI_LOG_D(TAG, "Freeing InfraredController");
furi_assert(controller);

controller->rx_running = false;
FURI_LOG_D(TAG, "Stopping RX thread");
furi_thread_join(controller->rx_thread);
furi_thread_free(controller->rx_thread);

FURI_LOG_D(TAG, "Stopping InfraredWorker RX");
furi_mutex_acquire(controller->mutex, FuriWaitForever);
infrared_worker_rx_stop(controller->worker);
infrared_worker_free(controller->worker);
furi_mutex_release(controller->mutex);

furi_mutex_free(controller->mutex);
free(controller);
FURI_LOG_D(TAG, "InfraredController freed");
}

void infrared_controller_set_team(InfraredController* controller, LaserTagTeam team) {
furi_assert(controller);
furi_mutex_acquire(controller->mutex, FuriWaitForever);
controller->team = team;
furi_mutex_release(controller->mutex);
FURI_LOG_D(TAG, "Team set to %s", (team == TeamRed) ? "Red" : "Blue");
}

void infrared_controller_send(InfraredController* controller) {
FURI_LOG_D(TAG, "Sending IR signal");
furi_assert(controller);

furi_mutex_acquire(controller->mutex, FuriWaitForever);

uint32_t command = (controller->team == TeamRed) ? IR_COMMAND_RED_TEAM : IR_COMMAND_BLUE_TEAM;
InfraredMessage message = {
.protocol = InfraredProtocolNEC,
.address = 0x00,
.command = command,
.repeat = false
};

.protocol = InfraredProtocolNEC, .address = 0x00, .command = command, .repeat = false};

infrared_worker_set_decoded_signal(controller->worker, &message);


FURI_LOG_D(TAG, "Starting IR transmission");
infrared_worker_tx_set_get_signal_callback(
controller->worker,
infrared_worker_tx_get_signal_steady_callback,
NULL);

controller->worker, infrared_worker_tx_get_signal_steady_callback, NULL);

infrared_worker_tx_start(controller->worker);
furi_delay_ms(250); // Delay to ensure the signal is sent

furi_delay_ms(250);

infrared_worker_tx_stop(controller->worker);
FURI_LOG_D(TAG, "IR signal sent");

furi_mutex_release(controller->mutex);
}

bool infrared_controller_receive(InfraredController* controller) {
furi_assert(controller);
furi_mutex_acquire(controller->mutex, FuriWaitForever);
bool hit = controller->hit_received;
controller->hit_received = false;
furi_mutex_release(controller->mutex);
FURI_LOG_D(TAG, "Checking for hit: %s", hit ? "Hit received" : "No hit");
return hit;
}
}
Loading

0 comments on commit e1d90b0

Please sign in to comment.