/* * This program source code file is part of the KTag project. * * 🛡️ 🃞 * * Copyright © 2024-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 #include #include #include static const char *TAG = "Settings"; // Cache variable declarations // 1 if this device is configured for a right-handed player, 0 otherwise. static uint8_t Cached_Is_Right_Handed = 1; // Value from CONFIG_KTAG_MIN_AUDIO_VOLUME to CONFIG_KTAG_MAX_AUDIO_VOLUME representing the current volume. static uint8_t Cached_Audio_Volume = CONFIG_KTAG_MAX_AUDIO_VOLUME; // Selected team. static uint8_t Cached_Team_ID = BASIC_TEAMS_MINIMUM; // Unique-per-team identification of a player. static uint8_t Cached_Player_ID = 0; // Selected weapon. static uint8_t Cached_Weapon_ID = DUBUQUE_PROTOCOL_ID; // Maximum health for the game. static uint8_t Cached_Max_Health = 100; // Number of special weapons (currently only bombs) obtained when reentering after being tagged out. static uint8_t Cached_N_Special_Weapons_On_Reentry = 1; // Time (in milliseconds) after starting a game before the countdown begins. static uint32_t Cached_T_Start_Game_in_ms = 30000; // Duration of a game (in milliseconds). If this is zero or UINT32_MAX, the game is untimed. static uint32_t Cached_T_Game_Length_in_ms = 600000; // Color in addition to the team color used to identify a player's device. The format is Brightness-Red-Green-Blue, where a brightness of 0xFF indicates a false flag. static uint32_t Cached_Secondary_Color = 0xFE000000; SystemKResult_T SETTINGS_get_uint8_t(SystemKSettingID_T id, uint8_t *value) { SystemKResult_T result = SYSTEMK_RESULT_UNSPECIFIED_FAILURE; switch (id) { case SYSTEMK_SETTING_IS_RIGHT_HANDED: *value = Cached_Is_Right_Handed; result = SYSTEMK_RESULT_SUCCESS; break; case SYSTEMK_SETTING_AUDIO_VOLUME: *value = Cached_Audio_Volume; result = SYSTEMK_RESULT_SUCCESS; break; case SYSTEMK_SETTING_TEAMID: *value = Cached_Team_ID; result = SYSTEMK_RESULT_SUCCESS; break; case SYSTEMK_SETTING_PLAYERID: *value = Cached_Player_ID; result = SYSTEMK_RESULT_SUCCESS; break; case SYSTEMK_SETTING_WEAPONID: *value = Cached_Weapon_ID; result = SYSTEMK_RESULT_SUCCESS; break; case SYSTEMK_SETTING_MAX_HEALTH: *value = Cached_Max_Health; result = SYSTEMK_RESULT_SUCCESS; break; case SYSTEMK_SETTING_N_SPECIAL_WEAPONS_ON_REENTRY: *value = Cached_N_Special_Weapons_On_Reentry; result = SYSTEMK_RESULT_SUCCESS; break; default: result = SYSTEMK_RESULT_WRONG_DATATYPE; break; } return result; } SystemKResult_T SETTINGS_set_uint8_t(SystemKSettingID_T id, uint8_t value) { SystemKResult_T result = SYSTEMK_RESULT_SUCCESS; switch (id) { case SYSTEMK_SETTING_IS_RIGHT_HANDED: Cached_Is_Right_Handed = value; result = KV_Set_Value_uint8(CONFIG_FILE, "Is_Right_Handed", &value); break; case SYSTEMK_SETTING_AUDIO_VOLUME: Cached_Audio_Volume = value; result = KV_Set_Value_uint8(CONFIG_FILE, "Audio_Volume", &value); break; case SYSTEMK_SETTING_TEAMID: Cached_Team_ID = value; result = KV_Set_Value_uint8(CONFIG_FILE, "Team_ID", &value); break; case SYSTEMK_SETTING_PLAYERID: Cached_Player_ID = value; result = KV_Set_Value_uint8(CONFIG_FILE, "Player_ID", &value); break; case SYSTEMK_SETTING_WEAPONID: Cached_Weapon_ID = value; result = KV_Set_Value_uint8(CONFIG_FILE, "Weapon_ID", &value); break; case SYSTEMK_SETTING_MAX_HEALTH: Cached_Max_Health = value; result = KV_Set_Value_uint8(CONFIG_FILE, "Max_Health", &value); break; case SYSTEMK_SETTING_N_SPECIAL_WEAPONS_ON_REENTRY: Cached_N_Special_Weapons_On_Reentry = value; result = KV_Set_Value_uint8(CONFIG_FILE, "N_Special_Weapons_On_Reentry", &value); break; default: result = SYSTEMK_RESULT_WRONG_DATATYPE; break; } return result; } SystemKResult_T SETTINGS_get_uint32_t(SystemKSettingID_T id, uint32_t *value) { SystemKResult_T result = SYSTEMK_RESULT_UNSPECIFIED_FAILURE; switch (id) { case SYSTEMK_SETTING_T_START_GAME_in_ms: *value = Cached_T_Start_Game_in_ms; result = SYSTEMK_RESULT_SUCCESS; break; case SYSTEMK_SETTING_T_GAME_LENGTH_in_ms: *value = Cached_T_Game_Length_in_ms; result = SYSTEMK_RESULT_SUCCESS; break; case SYSTEMK_SETTING_SECONDARY_COLOR: *value = Cached_Secondary_Color; result = SYSTEMK_RESULT_SUCCESS; break; default: result = SYSTEMK_RESULT_WRONG_DATATYPE; break; } return result; } SystemKResult_T SETTINGS_set_uint32_t(SystemKSettingID_T id, uint32_t value) { SystemKResult_T result = SYSTEMK_RESULT_SUCCESS; switch (id) { case SYSTEMK_SETTING_T_START_GAME_in_ms: Cached_T_Start_Game_in_ms = value; result = KV_Set_Value_uint32(CONFIG_FILE, "T_Start_Game_in_ms", &value); break; case SYSTEMK_SETTING_T_GAME_LENGTH_in_ms: Cached_T_Game_Length_in_ms = value; result = KV_Set_Value_uint32(CONFIG_FILE, "T_Game_Length_in_ms", &value); break; case SYSTEMK_SETTING_SECONDARY_COLOR: Cached_Secondary_Color = value; result = KV_Set_Value_uint32(CONFIG_FILE, "Secondary_Color", &value); break; default: result = SYSTEMK_RESULT_WRONG_DATATYPE; break; } return result; } SystemKResult_T SETTINGS_get_device_name(char *name) { char buffer[KV_MAX_VALUE_LENGTH]; SystemKResult_T result = KV_Get_Value_string(CONFIG_FILE, "Device_Name", buffer); if (result == SYSTEMK_RESULT_SUCCESS) { memcpy(name, buffer, SYSTEMK_MAX_CHARS_IN_DEVICE_NAME); buffer[SYSTEMK_MAX_CHARS_IN_DEVICE_NAME] = 0x00; } return result; } SystemKResult_T SETTINGS_set_device_name(char *name) { SystemKResult_T result = KV_Set_Value_string(CONFIG_FILE, "Device_Name", name); return result; } // Settings are saved on change in this implementation. SystemKResult_T SETTINGS_Save(void) { return SYSTEMK_RESULT_SUCCESS; } SystemKResult_T Initialize_Settings(void) { SystemKResult_T result = SYSTEMK_RESULT_SUCCESS; SystemKResult_T temp_result; uint32_t value_uint32_t; uint8_t value_uint8_t; KLOG_INFO(TAG, "Initializing settings..."); // Initialize Is_Right_Handed temp_result = KV_Get_Value_uint8(CONFIG_FILE, "Is_Right_Handed", &value_uint8_t); if (temp_result != SYSTEMK_RESULT_SUCCESS) { // Try to get from default config temp_result = KV_Get_Value_uint8(DEFAULT_CONFIG_FILE, "Is_Right_Handed", &value_uint8_t); if (temp_result != SYSTEMK_RESULT_SUCCESS) { // Use hardcoded default value_uint8_t = 1; KLOG_WARN(TAG, "Is_Right_Handed not found in config files; using default value of 1."); } // Save to config file temp_result = KV_Set_Value_uint8(CONFIG_FILE, "Is_Right_Handed", &value_uint8_t); if (temp_result != SYSTEMK_RESULT_SUCCESS) { result = temp_result; KLOG_ERROR(TAG, "Failed to set Is_Right_Handed in config file."); } } Cached_Is_Right_Handed = value_uint8_t; // Initialize Audio_Volume temp_result = KV_Get_Value_uint8(CONFIG_FILE, "Audio_Volume", &value_uint8_t); if (temp_result != SYSTEMK_RESULT_SUCCESS) { // Try to get from default config temp_result = KV_Get_Value_uint8(DEFAULT_CONFIG_FILE, "Audio_Volume", &value_uint8_t); if (temp_result != SYSTEMK_RESULT_SUCCESS) { // Use hardcoded default value_uint8_t = CONFIG_KTAG_MAX_AUDIO_VOLUME; KLOG_WARN(TAG, "Audio_Volume not found in config files; using default value of CONFIG_KTAG_MAX_AUDIO_VOLUME."); } // Save to config file temp_result = KV_Set_Value_uint8(CONFIG_FILE, "Audio_Volume", &value_uint8_t); if (temp_result != SYSTEMK_RESULT_SUCCESS) { result = temp_result; KLOG_ERROR(TAG, "Failed to set Audio_Volume in config file."); } } Cached_Audio_Volume = value_uint8_t; // Initialize Team_ID temp_result = KV_Get_Value_uint8(CONFIG_FILE, "Team_ID", &value_uint8_t); if (temp_result != SYSTEMK_RESULT_SUCCESS) { // Try to get from default config temp_result = KV_Get_Value_uint8(DEFAULT_CONFIG_FILE, "Team_ID", &value_uint8_t); if (temp_result != SYSTEMK_RESULT_SUCCESS) { // Use hardcoded default value_uint8_t = BASIC_TEAMS_MINIMUM; KLOG_WARN(TAG, "Team_ID not found in config files; using default value of BASIC_TEAMS_MINIMUM."); } // Save to config file temp_result = KV_Set_Value_uint8(CONFIG_FILE, "Team_ID", &value_uint8_t); if (temp_result != SYSTEMK_RESULT_SUCCESS) { result = temp_result; KLOG_ERROR(TAG, "Failed to set Team_ID in config file."); } } Cached_Team_ID = value_uint8_t; // Initialize Player_ID temp_result = KV_Get_Value_uint8(CONFIG_FILE, "Player_ID", &value_uint8_t); if (temp_result != SYSTEMK_RESULT_SUCCESS) { // Try to get from default config temp_result = KV_Get_Value_uint8(DEFAULT_CONFIG_FILE, "Player_ID", &value_uint8_t); if (temp_result != SYSTEMK_RESULT_SUCCESS) { // Use hardcoded default value_uint8_t = 0; KLOG_WARN(TAG, "Player_ID not found in config files; using default value of 0."); } // Save to config file temp_result = KV_Set_Value_uint8(CONFIG_FILE, "Player_ID", &value_uint8_t); if (temp_result != SYSTEMK_RESULT_SUCCESS) { result = temp_result; KLOG_ERROR(TAG, "Failed to set Player_ID in config file."); } } Cached_Player_ID = value_uint8_t; // Initialize Weapon_ID temp_result = KV_Get_Value_uint8(CONFIG_FILE, "Weapon_ID", &value_uint8_t); if (temp_result != SYSTEMK_RESULT_SUCCESS) { // Try to get from default config temp_result = KV_Get_Value_uint8(DEFAULT_CONFIG_FILE, "Weapon_ID", &value_uint8_t); if (temp_result != SYSTEMK_RESULT_SUCCESS) { // Use hardcoded default value_uint8_t = DUBUQUE_PROTOCOL_ID; KLOG_WARN(TAG, "Weapon_ID not found in config files; using default value of DUBUQUE_PROTOCOL_ID."); } // Save to config file temp_result = KV_Set_Value_uint8(CONFIG_FILE, "Weapon_ID", &value_uint8_t); if (temp_result != SYSTEMK_RESULT_SUCCESS) { result = temp_result; KLOG_ERROR(TAG, "Failed to set Weapon_ID in config file."); } } Cached_Weapon_ID = value_uint8_t; // Initialize Max_Health temp_result = KV_Get_Value_uint8(CONFIG_FILE, "Max_Health", &value_uint8_t); if (temp_result != SYSTEMK_RESULT_SUCCESS) { // Try to get from default config temp_result = KV_Get_Value_uint8(DEFAULT_CONFIG_FILE, "Max_Health", &value_uint8_t); if (temp_result != SYSTEMK_RESULT_SUCCESS) { // Use hardcoded default value_uint8_t = 100; KLOG_WARN(TAG, "Max_Health not found in config files; using default value of 100."); } // Save to config file temp_result = KV_Set_Value_uint8(CONFIG_FILE, "Max_Health", &value_uint8_t); if (temp_result != SYSTEMK_RESULT_SUCCESS) { result = temp_result; KLOG_ERROR(TAG, "Failed to set Max_Health in config file."); } } Cached_Max_Health = value_uint8_t; // Initialize N_Special_Weapons_On_Reentry temp_result = KV_Get_Value_uint8(CONFIG_FILE, "N_Special_Weapons_On_Reentry", &value_uint8_t); if (temp_result != SYSTEMK_RESULT_SUCCESS) { // Try to get from default config temp_result = KV_Get_Value_uint8(DEFAULT_CONFIG_FILE, "N_Special_Weapons_On_Reentry", &value_uint8_t); if (temp_result != SYSTEMK_RESULT_SUCCESS) { // Use hardcoded default value_uint8_t = 1; KLOG_WARN(TAG, "N_Special_Weapons_On_Reentry not found in config files; using default value of 1."); } // Save to config file temp_result = KV_Set_Value_uint8(CONFIG_FILE, "N_Special_Weapons_On_Reentry", &value_uint8_t); if (temp_result != SYSTEMK_RESULT_SUCCESS) { result = temp_result; KLOG_ERROR(TAG, "Failed to set N_Special_Weapons_On_Reentry in config file."); } } Cached_N_Special_Weapons_On_Reentry = value_uint8_t; // Initialize T_Start_Game_in_ms temp_result = KV_Get_Value_uint32(CONFIG_FILE, "T_Start_Game_in_ms", &value_uint32_t); if (temp_result != SYSTEMK_RESULT_SUCCESS) { // Try to get from default config temp_result = KV_Get_Value_uint32(DEFAULT_CONFIG_FILE, "T_Start_Game_in_ms", &value_uint32_t); if (temp_result != SYSTEMK_RESULT_SUCCESS) { // Use hardcoded default value_uint32_t = 30000; KLOG_WARN(TAG, "T_Start_Game_in_ms not found in config files; using default value of 30000."); } // Save to config file temp_result = KV_Set_Value_uint32(CONFIG_FILE, "T_Start_Game_in_ms", &value_uint32_t); if (temp_result != SYSTEMK_RESULT_SUCCESS) { result = temp_result; KLOG_ERROR(TAG, "Failed to set T_Start_Game_in_ms in config file."); } } Cached_T_Start_Game_in_ms = value_uint32_t; // Initialize T_Game_Length_in_ms temp_result = KV_Get_Value_uint32(CONFIG_FILE, "T_Game_Length_in_ms", &value_uint32_t); if (temp_result != SYSTEMK_RESULT_SUCCESS) { // Try to get from default config temp_result = KV_Get_Value_uint32(DEFAULT_CONFIG_FILE, "T_Game_Length_in_ms", &value_uint32_t); if (temp_result != SYSTEMK_RESULT_SUCCESS) { // Use hardcoded default value_uint32_t = 600000; KLOG_WARN(TAG, "T_Game_Length_in_ms not found in config files; using default value of 600000."); } // Save to config file temp_result = KV_Set_Value_uint32(CONFIG_FILE, "T_Game_Length_in_ms", &value_uint32_t); if (temp_result != SYSTEMK_RESULT_SUCCESS) { result = temp_result; KLOG_ERROR(TAG, "Failed to set T_Game_Length_in_ms in config file."); } } Cached_T_Game_Length_in_ms = value_uint32_t; // Initialize Secondary_Color temp_result = KV_Get_Value_uint32(CONFIG_FILE, "Secondary_Color", &value_uint32_t); if (temp_result != SYSTEMK_RESULT_SUCCESS) { // Try to get from default config temp_result = KV_Get_Value_uint32(DEFAULT_CONFIG_FILE, "Secondary_Color", &value_uint32_t); if (temp_result != SYSTEMK_RESULT_SUCCESS) { // Use hardcoded default value_uint32_t = 0xFE000000; KLOG_WARN(TAG, "Secondary_Color not found in config files; using default value of 0xFE000000."); } // Save to config file temp_result = KV_Set_Value_uint32(CONFIG_FILE, "Secondary_Color", &value_uint32_t); if (temp_result != SYSTEMK_RESULT_SUCCESS) { result = temp_result; KLOG_ERROR(TAG, "Failed to set Secondary_Color in config file."); } } Cached_Secondary_Color = value_uint32_t; xEventGroupSetBits(Get_System_Events(), SYS_SETTINGS_READY); KLOG_INFO(TAG, "Settings initialized."); return result; }