/* * This program source code file is part of SystemK, a library in the KTag project. * * 🛡️ 🃞 * * Copyright © 2016-2025 Joseph P. Kearney and the KTag developers. * * This program is free software: you can redistribute it and/or modify it under * the terms of the GNU Affero General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) any * later version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more * details. * * There should be a copy of the GNU Affero General Public License in the LICENSE * file in the root of this repository. If not, see . */ /* Include Files */ #include "SystemK.h" static const char *KLOG_TAG = "STATE_READY"; static const uint16_t LONG_PRESS_TO_INITIATE_GAME_in_ms = 5000; static void Ready_Entry(StateMachineContext_T * context); static void Ready_Do(StateMachineContext_T * context); static void Ready_Exit(StateMachineContext_T * context); //! Activities for the **Ready** state. const StateActivity_T STATE_READY_Activities = { .Entry = Ready_Entry, .Do = Ready_Do, .Exit = Ready_Exit }; //! Sets up the Ready state. /*! * \param context Context in which this state is being run. */ static void Ready_Entry(StateMachineContext_T * context) { LOG("Entering the Ready state."); NeoPixelsAction_T neopixels_action = {.ID = NEOPIXELS_IDLE, .Prominence = NEOPIXELS_FOREGROUND, .Data = (void *)0x00}; xQueueSend(xQueueNeoPixels, &neopixels_action, 0); BLE_UpdateStatusPacket(STATE_READY); if (BLE_ScanAndAdvertise() != SYSTEMK_RESULT_SUCCESS) { KLOG_ERROR(KLOG_TAG, "Couldn't start BLE!"); } AudioAction_T audio_action = {.ID = AUDIO_PLAY_GAME_ON, .Data = (void *)0x00}; Perform_Audio_Action(&audio_action); } //! Executes the Ready state. /*! * \param context Context in which this state is being run. */ static void Ready_Do(StateMachineContext_T * context) { portBASE_TYPE xStatus; static KEvent_T Event; xStatus = Receive_KEvent(&Event); if (xStatus == pdPASS) { switch (Event.ID) { case KEVENT_TRIGGER_SWITCH_PRESSED: break; case KEVENT_TRIGGER_SWITCH_RELEASED: { uint32_t duration_of_press_in_ms = (uint32_t)Event.Data; if (duration_of_press_in_ms > LONG_PRESS_TO_INITIATE_GAME_in_ms) { Transition_For_Event(context, STATE_STARTING_GAME__INSTIGATING, &Event); } } break; case KEVENT_BLE_PACKET_RECEIVED: if (((BLE_Packet_T *)Event.Data)->Generic.type == BLE_PACKET_TYPE_INSTIGATE_GAME) { Transition_For_Event(context, STATE_STARTING_GAME__RESPONDING, &Event); } else { BLE_FreePacketBuffer(Event.Data); } break; case KEVENT_MENU_ENTER: case KEVENT_BACKWARD_SWITCH_LONG_PRESSED: Transition_For_Event(context, STATE_CONFIGURING, &Event); break; case KEVENT_PLAY_PRESSED_ON_REMOTE: Transition_For_Event(context, STATE_STARTING_GAME__INSTIGATING, &Event); break; default: // All other events are ignored in this state. ProcessUnhandledEvent(&Event); break; } } } //! Cleans up the Ready state. /*! * \param context Context in which this state is being run. */ static void Ready_Exit(StateMachineContext_T * context) { NeoPixelsAction_T neopixels_action = {.ID = NEOPIXELS_ALL_OFF, .Prominence = NEOPIXELS_FOREGROUND, .Data = (void *)0x00}; xQueueSend(xQueueNeoPixels, &neopixels_action, 0); AudioAction_T audio_action = {.ID = AUDIO_SILENCE, .Data = (void *)0x00}; Perform_Audio_Action(&audio_action); }