mirror of
https://protopirate.net/ProtoPirate/ProtoPirate.git
synced 2026-10-15 14:09:55 +00:00
Merge pull request 'RAM Optimizations and (Including ABOUT scene moved to new PLUGIN)' (#62) from RalphWiggum/ProtoPirate:about_plugin into main
FAP Build / ufbt: Build for Momentum dev (push) Canceled after 0s
FAP Build / ufbt: Build for Momentum release (push) Canceled after 0s
FAP Build / ufbt: Build for OFW dev channel (push) Canceled after 0s
FAP Build / ufbt: Build for OFW release channel (push) Canceled after 0s
FAP Build / ufbt: Build for Unleashed dev (push) Canceled after 0s
FAP Build / ufbt: Build for Unleashed release (push) Canceled after 0s
FAP Build / ufbt: Build for Momentum dev (push) Canceled after 0s
FAP Build / ufbt: Build for Momentum release (push) Canceled after 0s
FAP Build / ufbt: Build for OFW dev channel (push) Canceled after 0s
FAP Build / ufbt: Build for OFW release channel (push) Canceled after 0s
FAP Build / ufbt: Build for Unleashed dev (push) Canceled after 0s
FAP Build / ufbt: Build for Unleashed release (push) Canceled after 0s
Reviewed-on: http://protopirate.net/ProtoPirate/ProtoPirate/pulls/62 Reviewed-by: MMX <mmx@no-reply.protopirate.net>
This commit is contained in:
+27
-13
@@ -25,6 +25,7 @@ _MAIN_APP_SOURCES = [
|
||||
"!protopirate_emulate_plugin.c",
|
||||
"!protopirate_psa_bf_plugin.c",
|
||||
"!protopirate_saved_info_plugin.c",
|
||||
"!protopirate_about_plugin.c",
|
||||
"!protopirate_config_plugin.c",
|
||||
"protocols/protocol_items.c",
|
||||
"protocols/protocols_common.c",
|
||||
@@ -63,7 +64,7 @@ App(
|
||||
# --- RX protocol plugins ---
|
||||
|
||||
App(
|
||||
appid="protopirate_am_plugin",
|
||||
appid="pp_am",
|
||||
apptype=FlipperAppType.PLUGIN,
|
||||
entry_point="protopirate_am_plugin_ep",
|
||||
requires=["proto_pirate"],
|
||||
@@ -92,7 +93,7 @@ App(
|
||||
)
|
||||
|
||||
App(
|
||||
appid="protopirate_am_vag_plugin",
|
||||
appid="pp_am_vag",
|
||||
apptype=FlipperAppType.PLUGIN,
|
||||
entry_point="protopirate_am_vag_plugin_ep",
|
||||
requires=["proto_pirate"],
|
||||
@@ -107,7 +108,7 @@ App(
|
||||
)
|
||||
|
||||
App(
|
||||
appid="protopirate_fm_plugin",
|
||||
appid="pp_fm",
|
||||
apptype=FlipperAppType.PLUGIN,
|
||||
entry_point="protopirate_fm_plugin_ep",
|
||||
requires=["proto_pirate"],
|
||||
@@ -131,7 +132,7 @@ App(
|
||||
)
|
||||
|
||||
App(
|
||||
appid="protopirate_fm_f4_plugin",
|
||||
appid="pp_fm_f4",
|
||||
apptype=FlipperAppType.PLUGIN,
|
||||
entry_point="protopirate_fm_f4_plugin_ep",
|
||||
requires=["proto_pirate"],
|
||||
@@ -148,7 +149,7 @@ App(
|
||||
)
|
||||
|
||||
App(
|
||||
appid="protopirate_fm_honda1_plugin",
|
||||
appid="pp_fm_honda1",
|
||||
apptype=FlipperAppType.PLUGIN,
|
||||
entry_point="protopirate_fm_honda1_plugin_ep",
|
||||
requires=["proto_pirate"],
|
||||
@@ -183,7 +184,7 @@ def ProtoPirateTxProtocolPlugin(
|
||||
return
|
||||
|
||||
App(
|
||||
appid=f"protopirate_tx_{key}_plugin",
|
||||
appid=f"pp_tx_{key}",
|
||||
apptype=FlipperAppType.PLUGIN,
|
||||
entry_point="protopirate_tx_protocol_plugin_ep",
|
||||
requires=["proto_pirate"],
|
||||
@@ -362,7 +363,7 @@ ProtoPirateTxProtocolPlugin(
|
||||
# --- Tool / scene plugins ---
|
||||
|
||||
App(
|
||||
appid="protopirate_sub_decode_plugin",
|
||||
appid="pp_sub_decode",
|
||||
apptype=FlipperAppType.PLUGIN,
|
||||
entry_point="protopirate_sub_decode_plugin_ep",
|
||||
requires=["proto_pirate"],
|
||||
@@ -381,7 +382,7 @@ App(
|
||||
|
||||
if _ENABLE_TIMING_TUNER:
|
||||
App(
|
||||
appid="protopirate_timing_tuner_plugin",
|
||||
appid="pp_timing_tuner",
|
||||
apptype=FlipperAppType.PLUGIN,
|
||||
entry_point="protopirate_timing_tuner_plugin_ep",
|
||||
requires=["proto_pirate"],
|
||||
@@ -395,7 +396,7 @@ if _ENABLE_TIMING_TUNER:
|
||||
|
||||
if _ENABLE_EMULATE:
|
||||
App(
|
||||
appid="protopirate_emulate_plugin",
|
||||
appid="pp_emulate",
|
||||
apptype=FlipperAppType.PLUGIN,
|
||||
entry_point="protopirate_emulate_plugin_ep",
|
||||
requires=["proto_pirate"],
|
||||
@@ -407,7 +408,7 @@ if _ENABLE_EMULATE:
|
||||
)
|
||||
|
||||
App(
|
||||
appid="protopirate_psa_bf_plugin",
|
||||
appid="pp_bf",
|
||||
apptype=FlipperAppType.PLUGIN,
|
||||
entry_point="protopirate_psa_bf_plugin_ep",
|
||||
requires=["proto_pirate"],
|
||||
@@ -425,7 +426,7 @@ App(
|
||||
)
|
||||
|
||||
App(
|
||||
appid="protopirate_config_plugin",
|
||||
appid="pp_config",
|
||||
apptype=FlipperAppType.PLUGIN,
|
||||
entry_point="protopirate_config_plugin_ep",
|
||||
requires=["proto_pirate"],
|
||||
@@ -435,12 +436,12 @@ App(
|
||||
"helpers/variable_item_list.c",
|
||||
"scenes/plugins/protopirate_config_plugin.c",
|
||||
],
|
||||
fap_icon_assets="images",
|
||||
fap_icon_assets="helpers/variable_item_list_images",
|
||||
fal_embedded=True,
|
||||
)
|
||||
|
||||
App(
|
||||
appid="protopirate_saved_info_plugin",
|
||||
appid="pp_saved_info",
|
||||
apptype=FlipperAppType.PLUGIN,
|
||||
entry_point="protopirate_saved_info_plugin_ep",
|
||||
requires=["proto_pirate"],
|
||||
@@ -451,4 +452,17 @@ App(
|
||||
],
|
||||
fap_icon_assets="images",
|
||||
fal_embedded=True,
|
||||
)
|
||||
|
||||
App(
|
||||
appid="pp_about",
|
||||
apptype=FlipperAppType.PLUGIN,
|
||||
entry_point="protopirate_about_plugin_ep",
|
||||
requires=["proto_pirate"],
|
||||
cdefines=["PROTOPIRATE_ABOUT_PLUGIN_BUILD"],
|
||||
sources=[
|
||||
"scenes/plugins/protopirate_about_plugin.c",
|
||||
],
|
||||
fap_icon_assets="images",
|
||||
fal_embedded=True,
|
||||
)
|
||||
@@ -1,6 +1,6 @@
|
||||
#include "protopirate_models.h"
|
||||
|
||||
#define TAG "ProtoPirateModels"
|
||||
#define TAG "PPModels"
|
||||
|
||||
#define PROTOPIRATE_MODELS_FILE APP_ASSETS_PATH("models.txt")
|
||||
|
||||
@@ -73,7 +73,7 @@ bool car_model_get_by_index(
|
||||
|
||||
//Read the Model Name.
|
||||
if(!flipper_format_read_string(ff, model_name_index, model_name)) {
|
||||
FURI_LOG_E("ProtoPirate", "Failed to read %s", model_name_index);
|
||||
FURI_LOG_E(TAG, "Failed to read %s", model_name_index);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -168,7 +168,7 @@ bool car_model_get_by_index(
|
||||
preset_data_size > 0) {
|
||||
if(preset_data_size >= 1024) {
|
||||
FURI_LOG_E(
|
||||
"ProtoPirate",
|
||||
TAG,
|
||||
"%s too large: %lu",
|
||||
preset_data_index,
|
||||
(unsigned long)preset_data_size);
|
||||
@@ -178,7 +178,7 @@ bool car_model_get_by_index(
|
||||
preset_data = malloc(preset_data_size);
|
||||
if(!preset_data) {
|
||||
FURI_LOG_E(
|
||||
"ProtoPirate",
|
||||
TAG,
|
||||
"Malloc failed: %s (%lu bytes)",
|
||||
preset_data_index,
|
||||
(unsigned long)preset_data_size);
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#define TAG "ProtoPirateProtocolPlugin"
|
||||
#define TAG "PPProtocolPlugin"
|
||||
#ifdef ENABLE_EMULATE_FEATURE
|
||||
#define PROTOPIRATE_TX_PLUGIN_PATH_MAX 160U
|
||||
#endif
|
||||
@@ -14,16 +14,16 @@
|
||||
static const char* protopirate_get_registry_plugin_path(ProtoPirateProtocolRegistryRoute route) {
|
||||
switch(route) {
|
||||
case ProtoPirateProtocolRegistryRouteAMVag:
|
||||
return APP_ASSETS_PATH("plugins/protopirate_am_vag_plugin.fal");
|
||||
return APP_ASSETS_PATH("plugins/pp_am_vag.fal");
|
||||
case ProtoPirateProtocolRegistryRouteFMDefault:
|
||||
return APP_ASSETS_PATH("plugins/protopirate_fm_plugin.fal");
|
||||
return APP_ASSETS_PATH("plugins/pp_fm.fal");
|
||||
case ProtoPirateProtocolRegistryRouteFMF4:
|
||||
return APP_ASSETS_PATH("plugins/protopirate_fm_f4_plugin.fal");
|
||||
return APP_ASSETS_PATH("plugins/pp_fm_f4.fal");
|
||||
case ProtoPirateProtocolRegistryRouteFMHonda1:
|
||||
return APP_ASSETS_PATH("plugins/protopirate_fm_honda1_plugin.fal");
|
||||
return APP_ASSETS_PATH("plugins/pp_fm_honda1.fal");
|
||||
case ProtoPirateProtocolRegistryRouteAMDefault:
|
||||
default:
|
||||
return APP_ASSETS_PATH("plugins/protopirate_am_plugin.fal");
|
||||
return APP_ASSETS_PATH("plugins/pp_am.fal");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,11 +36,8 @@ static bool protopirate_build_tx_protocol_plugin_path(
|
||||
return false;
|
||||
}
|
||||
|
||||
int written = snprintf(
|
||||
plugin_path,
|
||||
plugin_path_size,
|
||||
APP_ASSETS_PATH("plugins/protopirate_tx_%s_plugin.fal"),
|
||||
tx_key);
|
||||
int written =
|
||||
snprintf(plugin_path, plugin_path_size, APP_ASSETS_PATH("plugins/pp_tx_%s.fal"), tx_key);
|
||||
return (written > 0) && ((size_t)written < plugin_path_size);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -9,8 +9,8 @@
|
||||
#include <lib/flipper_application/plugins/composite_resolver.h>
|
||||
#include <notification/notification_messages.h>
|
||||
|
||||
#define TAG "ProtoPiratePsaBfHost"
|
||||
#define PSA_BF_PLUGIN_PATH APP_ASSETS_PATH("plugins/protopirate_psa_bf_plugin.fal")
|
||||
#define TAG "PPPsaBfHost"
|
||||
#define PSA_BF_PLUGIN_PATH APP_ASSETS_PATH("plugins/pp_bf.fal")
|
||||
|
||||
static bool host_ensure_widget(void* app) {
|
||||
return protopirate_ensure_widget((ProtoPirateApp*)app);
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#include <furi.h>
|
||||
#include <string.h>
|
||||
|
||||
#define TAG "ProtoPirateRadio"
|
||||
#define TAG "PPRadio"
|
||||
|
||||
static void protopirate_radio_free_receiver(ProtoPirateApp* app) {
|
||||
furi_check(app);
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#include <storage/storage.h>
|
||||
#include <string.h>
|
||||
|
||||
#define TAG "ProtoPirateMatch"
|
||||
#define TAG "PPMatch"
|
||||
#define CNT_MATCH_MARGIN 50
|
||||
|
||||
bool protopirate_saved_match_signal(
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
#include "../defines.h"
|
||||
#include "../protocols/protocols_common.h"
|
||||
|
||||
#define TAG "ProtoPirateSettings"
|
||||
#define TAG "PPSettings"
|
||||
|
||||
#define SETTINGS_FILE_HEADER "ProtoPirate Settings"
|
||||
#define SETTINGS_FILE_VERSION 1
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
#include <toolbox/stream/stream.h>
|
||||
#include <string.h>
|
||||
|
||||
#define TAG "ProtoPirateStorage"
|
||||
#define TAG "PPStorage"
|
||||
|
||||
bool protopirate_storage_init(void) {
|
||||
Storage* storage = furi_record_open(RECORD_STORAGE);
|
||||
|
||||
@@ -5,11 +5,11 @@
|
||||
#include <loader/firmware_api/firmware_api.h>
|
||||
#include <notification/notification_messages.h>
|
||||
|
||||
#define TAG "ProtoPirateToolScene"
|
||||
#define TAG "PPToolScene"
|
||||
|
||||
#define SUB_DECODE_PLUGIN_PATH APP_ASSETS_PATH("plugins/protopirate_sub_decode_plugin.fal")
|
||||
#define SUB_DECODE_PLUGIN_PATH APP_ASSETS_PATH("plugins/pp_sub_decode.fal")
|
||||
#ifdef ENABLE_TIMING_TUNER_SCENE
|
||||
#define TIMING_TUNER_PLUGIN_PATH APP_ASSETS_PATH("plugins/protopirate_timing_tuner_plugin.fal")
|
||||
#define TIMING_TUNER_PLUGIN_PATH APP_ASSETS_PATH("plugins/pp_timing_tuner.fal")
|
||||
#endif
|
||||
|
||||
static const char* protopirate_tool_scene_plugin_path(ProtoPirateToolScenePluginKind kind) {
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#define TAG "ProtoPirateTxRx"
|
||||
#define TAG "PPTxRx"
|
||||
|
||||
void protopirate_rx_stack_teardown_for_registry_switch(ProtoPirateApp* app) {
|
||||
furi_check(app);
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
#include <furi.h>
|
||||
|
||||
#define TAG "ProtoPirateViews"
|
||||
#define TAG "PPViews"
|
||||
|
||||
bool protopirate_ensure_widget(ProtoPirateApp* app) {
|
||||
furi_check(app);
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef PROTOPIRATE_CONFIG_PLUGIN_BUILD
|
||||
#include "protopirate_config_plugin_icons.h"
|
||||
#include "pp_config_icons.h"
|
||||
#else
|
||||
#include "proto_pirate_icons.h"
|
||||
#endif
|
||||
|
||||
|
Before Width: | Height: | Size: 3.5 KiB After Width: | Height: | Size: 3.5 KiB |
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
@@ -41,7 +41,7 @@ static const SubGhzProtocolRegistry protopirate_protocol_registry_am = {
|
||||
};
|
||||
|
||||
static const ProtoPirateProtocolPlugin protopirate_am_plugin = {
|
||||
.plugin_name = "ProtoPirate AM Default Registry",
|
||||
.plugin_name = "AM Registry",
|
||||
.kind = ProtoPirateProtocolPluginKindRx,
|
||||
.route = ProtoPirateProtocolRegistryRouteAMDefault,
|
||||
.registry = &protopirate_protocol_registry_am,
|
||||
|
||||
@@ -13,7 +13,7 @@ static const SubGhzProtocolRegistry protopirate_protocol_registry_am_vag = {
|
||||
};
|
||||
|
||||
static const ProtoPirateProtocolPlugin protopirate_am_vag_plugin = {
|
||||
.plugin_name = "ProtoPirate AM VAG Registry",
|
||||
.plugin_name = "AM VAG Registry",
|
||||
.kind = ProtoPirateProtocolPluginKindRx,
|
||||
.route = ProtoPirateProtocolRegistryRouteAMVag,
|
||||
.registry = &protopirate_protocol_registry_am_vag,
|
||||
|
||||
@@ -19,7 +19,7 @@ static const SubGhzProtocolRegistry protopirate_protocol_registry_fm_f4 = {
|
||||
};
|
||||
|
||||
static const ProtoPirateProtocolPlugin protopirate_fm_f4_plugin = {
|
||||
.plugin_name = "ProtoPirate FM F4 Registry",
|
||||
.plugin_name = "FM F4 Registry",
|
||||
.kind = ProtoPirateProtocolPluginKindRx,
|
||||
.route = ProtoPirateProtocolRegistryRouteFMF4,
|
||||
.registry = &protopirate_protocol_registry_fm_f4,
|
||||
|
||||
@@ -13,7 +13,7 @@ static const SubGhzProtocolRegistry protopirate_protocol_registry_fm_honda1 = {
|
||||
};
|
||||
|
||||
static const ProtoPirateProtocolPlugin protopirate_fm_honda1_plugin = {
|
||||
.plugin_name = "ProtoPirate FM Honda1 Registry",
|
||||
.plugin_name = "FM Honda1 Registry",
|
||||
.kind = ProtoPirateProtocolPluginKindRx,
|
||||
.route = ProtoPirateProtocolRegistryRouteFMHonda1,
|
||||
.registry = &protopirate_protocol_registry_fm_honda1,
|
||||
|
||||
@@ -29,7 +29,7 @@ static const SubGhzProtocolRegistry protopirate_protocol_registry_fm = {
|
||||
};
|
||||
|
||||
static const ProtoPirateProtocolPlugin protopirate_fm_plugin = {
|
||||
.plugin_name = "ProtoPirate FM Default Registry",
|
||||
.plugin_name = "FM Default Registry",
|
||||
.kind = ProtoPirateProtocolPluginKindRx,
|
||||
.route = ProtoPirateProtocolRegistryRouteFMDefault,
|
||||
.registry = &protopirate_protocol_registry_fm,
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
#include "../defines.h"
|
||||
|
||||
#define TAG "ProtoPirateCatalog"
|
||||
#define TAG "PPCatalog"
|
||||
|
||||
#define PROTOPIRATE_CC1101_REG_MDMCFG2 0x12U
|
||||
#define PROTOPIRATE_CC1101_MOD_FORMAT_MASK 0x70U
|
||||
|
||||
+79
-36
@@ -10,18 +10,21 @@
|
||||
#include "helpers/protopirate_radio.h"
|
||||
#include <string.h>
|
||||
|
||||
#define TAG "ProtoPirateApp"
|
||||
#define TAG "PPApp"
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Plugin load / unload
|
||||
// -----------------------------------------------------------------------------
|
||||
void config_or_saved_plugin_unload(ProtoPirateApp* app, bool unload_config) {
|
||||
void shared_plugin_unload(ProtoPirateApp* app, ProtoPirateSharedPlugin plugin_type) {
|
||||
furi_check(app);
|
||||
|
||||
if(unload_config)
|
||||
if(plugin_type == ProtoPirateSharedPluginsConfig) {
|
||||
app->config_plugin = NULL;
|
||||
else
|
||||
} else if(plugin_type == ProtoPirateSharedPluginsSavedInfo) {
|
||||
app->saved_info_plugin = NULL;
|
||||
} else if(plugin_type == ProtoPirateSharedPluginsAbout) {
|
||||
app->about_plugin = NULL;
|
||||
}
|
||||
|
||||
if(app->plugin_manager) {
|
||||
plugin_manager_free(app->plugin_manager);
|
||||
@@ -34,17 +37,19 @@ void config_or_saved_plugin_unload(ProtoPirateApp* app, bool unload_config) {
|
||||
}
|
||||
}
|
||||
|
||||
bool config_or_saved_plugin_load(ProtoPirateApp* app, bool load_config) {
|
||||
bool shared_plugin_load(ProtoPirateApp* app, ProtoPirateSharedPlugin plugin_type) {
|
||||
furi_check(app);
|
||||
|
||||
if(load_config) {
|
||||
if(plugin_type == ProtoPirateSharedPluginsConfig) {
|
||||
if(app->config_plugin) return true;
|
||||
} else {
|
||||
} else if(plugin_type == ProtoPirateSharedPluginsSavedInfo) {
|
||||
if(app->saved_info_plugin) return true;
|
||||
} else if(plugin_type == ProtoPirateSharedPluginsAbout) {
|
||||
if(app->about_plugin) return true;
|
||||
}
|
||||
|
||||
if(app->plugin_manager || app->plugin_resolver) {
|
||||
config_or_saved_plugin_unload(app, load_config);
|
||||
shared_plugin_unload(app, plugin_type);
|
||||
}
|
||||
|
||||
CompositeApiResolver* resolver = composite_api_resolver_alloc();
|
||||
@@ -54,27 +59,41 @@ bool config_or_saved_plugin_load(ProtoPirateApp* app, bool load_config) {
|
||||
}
|
||||
composite_api_resolver_add(resolver, firmware_api_interface);
|
||||
|
||||
PluginManager* manager = plugin_manager_alloc(
|
||||
(load_config) ? PROTOPIRATE_CONFIG_PLUGIN_APP_ID : PROTOPIRATE_SAVED_INFO_PLUGIN_APP_ID,
|
||||
(load_config) ? PROTOPIRATE_CONFIG_PLUGIN_API_VERSION :
|
||||
PROTOPIRATE_SAVED_INFO_PLUGIN_API_VERSION,
|
||||
composite_api_resolver_get(resolver));
|
||||
//Get the APPID and API VERSION for the Plugin we are loading.
|
||||
const char* application_id = NULL;
|
||||
const char* plugin_path = NULL;
|
||||
uint32_t api_version = 0;
|
||||
if(plugin_type == ProtoPirateSharedPluginsConfig) {
|
||||
application_id = PROTOPIRATE_CONFIG_PLUGIN_APP_ID;
|
||||
api_version = PROTOPIRATE_CONFIG_PLUGIN_API_VERSION;
|
||||
plugin_path = CONFIG_PLUGIN_PATH;
|
||||
} else if(plugin_type == ProtoPirateSharedPluginsSavedInfo) {
|
||||
application_id = PROTOPIRATE_SAVED_INFO_PLUGIN_APP_ID;
|
||||
api_version = PROTOPIRATE_SAVED_INFO_PLUGIN_API_VERSION;
|
||||
plugin_path = SAVED_INFO_PLUGIN_PATH;
|
||||
} else if(plugin_type == ProtoPirateSharedPluginsAbout) {
|
||||
application_id = PROTOPIRATE_ABOUT_PLUGIN_APP_ID;
|
||||
api_version = PROTOPIRATE_ABOUT_PLUGIN_API_VERSION;
|
||||
plugin_path = ABOUT_PLUGIN_PATH;
|
||||
}
|
||||
|
||||
PluginManager* manager =
|
||||
plugin_manager_alloc(application_id, api_version, composite_api_resolver_get(resolver));
|
||||
if(!manager) {
|
||||
FURI_LOG_E(TAG, "Failed to allocate plugin manager");
|
||||
composite_api_resolver_free(resolver);
|
||||
return false;
|
||||
}
|
||||
|
||||
PluginManagerError error = plugin_manager_load_single(
|
||||
manager, (load_config) ? CONFIG_PLUGIN_PATH : SAVED_INFO_PLUGIN_PATH);
|
||||
PluginManagerError error = plugin_manager_load_single(manager, plugin_path);
|
||||
if(error != PluginManagerErrorNone) {
|
||||
FURI_LOG_E(TAG, "Failed to load config plugin %s: %d", CONFIG_PLUGIN_PATH, (int)error);
|
||||
FURI_LOG_E(TAG, "Failed to load plugin %s: %d", plugin_path, (int)error);
|
||||
plugin_manager_free(manager);
|
||||
composite_api_resolver_free(resolver);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(load_config) {
|
||||
if(plugin_type == ProtoPirateSharedPluginsConfig) {
|
||||
const ProtoPirateConfigPlugin* plugin_config = plugin_manager_get_ep(manager, 0U);
|
||||
if(!plugin_config || !plugin_config->on_enter) {
|
||||
FURI_LOG_E(TAG, "Config plugin entry point is invalid");
|
||||
@@ -83,7 +102,7 @@ bool config_or_saved_plugin_load(ProtoPirateApp* app, bool load_config) {
|
||||
return false;
|
||||
}
|
||||
app->config_plugin = plugin_config;
|
||||
} else {
|
||||
} else if(plugin_type == ProtoPirateSharedPluginsSavedInfo) {
|
||||
const ProtoPirateSavedInfoPlugin* plugin_saved_info = plugin_manager_get_ep(manager, 0U);
|
||||
if(!plugin_saved_info || !plugin_saved_info->on_enter) {
|
||||
FURI_LOG_E(TAG, "Saved Info plugin entry point is invalid");
|
||||
@@ -92,7 +111,16 @@ bool config_or_saved_plugin_load(ProtoPirateApp* app, bool load_config) {
|
||||
return false;
|
||||
}
|
||||
app->saved_info_plugin = plugin_saved_info;
|
||||
};
|
||||
} else if(plugin_type == ProtoPirateSharedPluginsAbout) {
|
||||
const ProtoPirateAboutPlugin* plugin_about = plugin_manager_get_ep(manager, 0U);
|
||||
if(!plugin_about || !plugin_about->on_enter) {
|
||||
FURI_LOG_E(TAG, "About plugin entry point is invalid");
|
||||
plugin_manager_free(manager);
|
||||
composite_api_resolver_free(resolver);
|
||||
return false;
|
||||
}
|
||||
app->about_plugin = plugin_about;
|
||||
}
|
||||
|
||||
app->plugin_resolver = resolver;
|
||||
app->plugin_manager = manager;
|
||||
@@ -160,7 +188,6 @@ ProtoPirateApp* protopirate_app_alloc() {
|
||||
app->view_dispatcher, ProtoPirateViewSubmenu, submenu_get_view(app->submenu));
|
||||
|
||||
app->save_protocol = NULL;
|
||||
app->save_from_saved_info = false;
|
||||
app->save_history_idx = 0;
|
||||
app->emulate_disabled_for_loaded = false;
|
||||
memset(app->save_filename, 0, sizeof(app->save_filename));
|
||||
@@ -242,8 +269,13 @@ ProtoPirateApp* protopirate_app_alloc() {
|
||||
settings.auto_save,
|
||||
settings.hopping_enabled);
|
||||
|
||||
config_or_saved_plugin_load(app, true);
|
||||
app->car_models_count = app->config_plugin->car_model_get_count();
|
||||
//Load the models database, get the count of the models for the list.
|
||||
if(shared_plugin_load(app, ProtoPirateSharedPluginsConfig) && app->config_plugin) {
|
||||
app->car_models_count = app->config_plugin->car_model_get_count();
|
||||
} else {
|
||||
notification_message(app->notifications, &sequence_error);
|
||||
app->car_models_count = 0;
|
||||
}
|
||||
app->selected_model = malloc(sizeof(ProtoPirateCarModel));
|
||||
app->selected_model->name = furi_string_alloc();
|
||||
app->selected_model->preset = NULL; // important initialization
|
||||
@@ -251,24 +283,35 @@ ProtoPirateApp* protopirate_app_alloc() {
|
||||
app->variable_item_list = NULL;
|
||||
|
||||
//Grab selected car model.
|
||||
if(settings.car_model_index) {
|
||||
app->config_plugin->car_model_get_by_index(
|
||||
app->selected_model, settings.car_model_index, app->car_models_count, app->setting);
|
||||
app->selected_model->last_preset_index = settings.preset_index;
|
||||
if(app->config_plugin) {
|
||||
if(settings.car_model_index) {
|
||||
//Get the selected car model.
|
||||
app->config_plugin->car_model_get_by_index(
|
||||
app->selected_model, settings.car_model_index, app->car_models_count, app->setting);
|
||||
app->selected_model->last_preset_index = settings.preset_index;
|
||||
|
||||
protopirate_preset_init(
|
||||
app,
|
||||
furi_string_get_cstr(app->selected_model->preset->name),
|
||||
app->selected_model->preset->frequency,
|
||||
app->selected_model->preset->data,
|
||||
app->selected_model->preset->data_size);
|
||||
//Preset for the selected model...
|
||||
protopirate_preset_init(
|
||||
app,
|
||||
furi_string_get_cstr(app->selected_model->preset->name),
|
||||
app->selected_model->preset->frequency,
|
||||
app->selected_model->preset->data,
|
||||
app->selected_model->preset->data_size);
|
||||
} else {
|
||||
//This will return Select a model or No Models in Database
|
||||
app->config_plugin->car_model_get_by_index(
|
||||
app->selected_model, 0, app->car_models_count, app->setting);
|
||||
|
||||
//Preset set in Config.
|
||||
protopirate_preset_init(app, preset_name, frequency, preset_data, preset_data_size);
|
||||
}
|
||||
|
||||
//Kill the config plugin now.
|
||||
shared_plugin_unload(app, ProtoPirateSharedPluginsConfig);
|
||||
} else {
|
||||
app->config_plugin->car_model_get_by_index(
|
||||
app->selected_model, 0, app->car_models_count, app->setting);
|
||||
|
||||
//Preset set in Config.
|
||||
protopirate_preset_init(app, preset_name, frequency, preset_data, preset_data_size);
|
||||
}
|
||||
config_or_saved_plugin_unload(app, true);
|
||||
|
||||
// Apply hopping state from settings
|
||||
app->txrx->hopper_state = settings.hopping_enabled ? ProtoPirateHopperStateRunning :
|
||||
|
||||
+22
-14
@@ -34,6 +34,7 @@
|
||||
#endif
|
||||
#include "scenes/plugins/protopirate_config_plugin.h"
|
||||
#include "scenes/plugins/protopirate_saved_info_plugin.h"
|
||||
#include "scenes/plugins/protopirate_about_plugin.h"
|
||||
#include "scenes/plugins/protopirate_psa_bf_plugin.h"
|
||||
#include "scenes/plugins/protopirate_tool_scene_plugin.h"
|
||||
#include "helpers/protopirate_views.h"
|
||||
@@ -44,8 +45,9 @@
|
||||
#include <loader/firmware_api/firmware_api.h>
|
||||
#include "helpers/protopirate_settings.h"
|
||||
|
||||
#define CONFIG_PLUGIN_PATH APP_ASSETS_PATH("plugins/protopirate_config_plugin.fal")
|
||||
#define SAVED_INFO_PLUGIN_PATH APP_ASSETS_PATH("plugins/protopirate_saved_info_plugin.fal")
|
||||
#define CONFIG_PLUGIN_PATH APP_ASSETS_PATH("plugins/pp_config.fal")
|
||||
#define SAVED_INFO_PLUGIN_PATH APP_ASSETS_PATH("plugins/pp_saved_info.fal")
|
||||
#define ABOUT_PLUGIN_PATH APP_ASSETS_PATH("plugins/pp_about.fal")
|
||||
|
||||
#define PROTOPIRATE_KEYSTORE_DIR_NAME APP_ASSETS_PATH("encrypted")
|
||||
|
||||
@@ -89,20 +91,19 @@ struct ProtoPirateApp {
|
||||
SubGhzSetting* setting;
|
||||
ProtoPirateLock lock;
|
||||
FuriString* loaded_file_path;
|
||||
bool deferred_storage_in_progress;
|
||||
bool auto_save;
|
||||
bool check_saved;
|
||||
bool sound;
|
||||
bool datetime_filenames;
|
||||
bool radio_initialized;
|
||||
uint8_t deferred_storage_in_progress : 1;
|
||||
uint8_t auto_save : 1;
|
||||
uint8_t check_saved : 1;
|
||||
uint8_t sound : 1;
|
||||
uint8_t datetime_filenames : 1;
|
||||
uint8_t radio_initialized : 1;
|
||||
uint8_t emulate_disabled_for_loaded : 1;
|
||||
uint8_t emulate_feature_enabled : 1;
|
||||
uint32_t start_tx_time;
|
||||
uint8_t tx_power;
|
||||
char save_filename[64];
|
||||
FuriString* save_protocol;
|
||||
uint16_t save_history_idx;
|
||||
bool save_from_saved_info;
|
||||
bool emulate_disabled_for_loaded;
|
||||
bool emulate_feature_enabled;
|
||||
CompositeApiResolver* plugin_resolver;
|
||||
PluginManager* plugin_manager;
|
||||
#ifdef ENABLE_EMULATE_FEATURE
|
||||
@@ -114,6 +115,7 @@ struct ProtoPirateApp {
|
||||
#endif
|
||||
const ProtoPirateConfigPlugin* config_plugin;
|
||||
const ProtoPirateSavedInfoPlugin* saved_info_plugin;
|
||||
const ProtoPirateAboutPlugin* about_plugin;
|
||||
CompositeApiResolver* psa_bf_plugin_resolver;
|
||||
PluginManager* psa_bf_plugin_manager;
|
||||
const ProtoPiratePsaBfPlugin* psa_bf_plugin;
|
||||
@@ -129,7 +131,7 @@ struct ProtoPirateApp {
|
||||
uint32_t tool_scene_nav_target;
|
||||
|
||||
ProtoPirateCarModel* selected_model;
|
||||
uint32_t car_models_count;
|
||||
uint16_t car_models_count;
|
||||
};
|
||||
|
||||
#ifdef ENABLE_EMULATE_FEATURE
|
||||
@@ -146,8 +148,14 @@ bool protopirate_tool_scene_on_event(void* app, SceneManagerEvent event);
|
||||
void protopirate_tool_scene_on_exit(void* app);
|
||||
void protopirate_tool_scene_plugin_release(ProtoPirateApp* app);
|
||||
|
||||
bool config_or_saved_plugin_load(ProtoPirateApp* app, bool load_config);
|
||||
void config_or_saved_plugin_unload(ProtoPirateApp* app, bool unload_config);
|
||||
typedef enum ProtoPirateSharedPlugin {
|
||||
ProtoPirateSharedPluginsConfig,
|
||||
ProtoPirateSharedPluginsSavedInfo,
|
||||
ProtoPirateSharedPluginsAbout,
|
||||
} ProtoPirateSharedPlugin;
|
||||
|
||||
bool shared_plugin_load(ProtoPirateApp* app, ProtoPirateSharedPlugin plugin_type);
|
||||
void shared_plugin_unload(ProtoPirateApp* app, ProtoPirateSharedPlugin plugin_type);
|
||||
|
||||
void protopirate_app_free(ProtoPirateApp* app);
|
||||
|
||||
|
||||
@@ -0,0 +1,310 @@
|
||||
#include "../../protopirate_app_i.h"
|
||||
//#include "protopirate_about_plugin.h"
|
||||
#include "pp_about_icons.h"
|
||||
|
||||
static const ProtoPirateAboutSceneHostApi* g_about_scene_host_api = NULL;
|
||||
|
||||
#define TAG "PPAboutPlugin"
|
||||
|
||||
#define CREDITS_START_Y 28
|
||||
#define CREDITS_END_Y 52
|
||||
#define CREDIT_LINE_HEIGHT 10
|
||||
#define SCROLL_SPEED 1
|
||||
|
||||
#ifdef ENABLE_EMULATE_FEATURE
|
||||
static const InputKey EMULATE_TOGGLE_COMBO[] = {
|
||||
InputKeyUp,
|
||||
InputKeyUp,
|
||||
InputKeyDown,
|
||||
InputKeyDown,
|
||||
InputKeyLeft,
|
||||
InputKeyRight,
|
||||
InputKeyLeft,
|
||||
InputKeyRight,
|
||||
};
|
||||
#define EMULATE_TOGGLE_COMBO_LEN (sizeof(EMULATE_TOGGLE_COMBO) / sizeof(EMULATE_TOGGLE_COMBO[0]))
|
||||
#endif
|
||||
|
||||
static const char* credits[] = {
|
||||
"",
|
||||
"-=> App Development by <=-",
|
||||
"RocketGod",
|
||||
"MMX",
|
||||
"Leeroy",
|
||||
"gullradriel",
|
||||
"Skorp's Weather App",
|
||||
"Vadim's Radio Driver",
|
||||
"",
|
||||
"-=> Protocol Magic by <=-",
|
||||
"L0rdDiakon",
|
||||
"Leeroy",
|
||||
"Li0ard",
|
||||
"MMX",
|
||||
"YougZ",
|
||||
"DoobTheGoober",
|
||||
"RocketGod",
|
||||
"Skorp",
|
||||
"Slackware",
|
||||
"Trikk",
|
||||
"Wootini",
|
||||
"",
|
||||
"-=> RE Support <=-",
|
||||
"DoobTheGoober",
|
||||
"Li0ard",
|
||||
"MMX",
|
||||
"NeedNotApply",
|
||||
"RocketGod",
|
||||
"Slackware",
|
||||
"Trikk",
|
||||
// can add more
|
||||
};
|
||||
|
||||
#define CREDITS_COUNT (sizeof(credits) / sizeof(credits[0]))
|
||||
|
||||
typedef struct {
|
||||
uint8_t frame;
|
||||
uint8_t seed;
|
||||
int16_t scroll_offset;
|
||||
#ifdef ENABLE_EMULATE_FEATURE
|
||||
uint8_t combo_progress;
|
||||
#endif
|
||||
} GlitchState;
|
||||
|
||||
static GlitchState g_state = {0};
|
||||
|
||||
static void draw_noise_pixels(Canvas* canvas, uint8_t density) {
|
||||
for(uint8_t i = 0; i < density; i++) {
|
||||
canvas_draw_dot(canvas, rand() % 128, rand() % 64);
|
||||
}
|
||||
}
|
||||
|
||||
static void about_draw_callback(Canvas* canvas, void* context) {
|
||||
UNUSED(context);
|
||||
|
||||
srand(g_state.seed);
|
||||
canvas_clear(canvas);
|
||||
|
||||
// Light background static
|
||||
canvas_set_color(canvas, ColorBlack);
|
||||
draw_noise_pixels(canvas, 6 + (rand() % 6));
|
||||
|
||||
// Occasional subtle x-jitter
|
||||
int8_t x_off = (rand() % 15 == 0) ? ((rand() % 4) - 2) : 0;
|
||||
|
||||
// Animated TPP decoration (centered)
|
||||
canvas_set_font(canvas, FontKeyboard);
|
||||
if(g_state.frame % 8 < 4) {
|
||||
canvas_draw_str_aligned(
|
||||
canvas, 64, 18, AlignCenter, AlignBottom, ">>>=================<<<");
|
||||
} else {
|
||||
canvas_draw_str_aligned(
|
||||
canvas, 64, 18, AlignCenter, AlignBottom, ">>>======[TPP]======<<<");
|
||||
}
|
||||
|
||||
// Draw credits region (clip area)
|
||||
canvas_set_font(canvas, FontSecondary);
|
||||
|
||||
// Calculate total scroll height
|
||||
int16_t total_height = CREDITS_COUNT * CREDIT_LINE_HEIGHT;
|
||||
|
||||
// Draw scrolling credits
|
||||
for(size_t i = 0; i < CREDITS_COUNT; i++) {
|
||||
int16_t y = CREDITS_START_Y + (i * CREDIT_LINE_HEIGHT) - g_state.scroll_offset;
|
||||
|
||||
// Wrap around for endless scroll
|
||||
while(y < CREDITS_START_Y - CREDIT_LINE_HEIGHT) {
|
||||
y += total_height;
|
||||
}
|
||||
while(y > CREDITS_START_Y + total_height) {
|
||||
y -= total_height;
|
||||
}
|
||||
|
||||
// Only draw if in visible region
|
||||
if(y >= CREDITS_START_Y - CREDIT_LINE_HEIGHT && y <= CREDITS_END_Y) {
|
||||
canvas_draw_str(canvas, x_off, y, credits[i]);
|
||||
}
|
||||
}
|
||||
|
||||
// Draw fade/mask bars at top and bottom of credits area
|
||||
canvas_set_color(canvas, ColorWhite);
|
||||
canvas_draw_box(canvas, 0, 0, 128, CREDITS_START_Y - CREDIT_LINE_HEIGHT);
|
||||
canvas_draw_box(canvas, 0, CREDITS_END_Y, 128, 14);
|
||||
|
||||
// Redraw header over mask
|
||||
canvas_set_color(canvas, ColorBlack);
|
||||
canvas_set_font(canvas, FontPrimary);
|
||||
canvas_draw_str(canvas, x_off, 10, "ProtoPirate v" FAP_VERSION);
|
||||
|
||||
canvas_set_font(canvas, FontKeyboard);
|
||||
if(g_state.frame % 8 < 4) {
|
||||
canvas_draw_str_aligned(
|
||||
canvas, 64, 18, AlignCenter, AlignBottom, ">>>=================<<<");
|
||||
} else {
|
||||
canvas_draw_str_aligned(
|
||||
canvas, 64, 18, AlignCenter, AlignBottom, ">>>======[TPP]======<<<");
|
||||
}
|
||||
|
||||
// Redraw static in header area
|
||||
srand(g_state.seed + 1);
|
||||
for(uint8_t i = 0; i < 3; i++) {
|
||||
canvas_draw_dot(canvas, rand() % 128, rand() % (CREDITS_START_Y - CREDIT_LINE_HEIGHT));
|
||||
}
|
||||
|
||||
// Footer: The Pirate's Plunder Discord
|
||||
canvas_set_font(canvas, FontKeyboard);
|
||||
canvas_draw_str_aligned(canvas, 127, 62, AlignRight, AlignBottom, "discord.gg/thepirates");
|
||||
|
||||
// Rare subtle glitch bar
|
||||
if(rand() % 30 == 0) {
|
||||
canvas_set_color(canvas, ColorXOR);
|
||||
uint8_t y = rand() % 60;
|
||||
canvas_draw_box(canvas, 0, y, 128, 2);
|
||||
}
|
||||
}
|
||||
|
||||
static bool about_input_callback(InputEvent* event, void* context) {
|
||||
furi_check(context);
|
||||
#ifdef ENABLE_EMULATE_FEATURE
|
||||
ProtoPirateApp* app = context;
|
||||
|
||||
if(event->type != InputTypePress) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if(event->key == InputKeyBack) {
|
||||
return false;
|
||||
}
|
||||
|
||||
InputKey expected = EMULATE_TOGGLE_COMBO[g_state.combo_progress];
|
||||
if(event->key == expected) {
|
||||
g_state.combo_progress++;
|
||||
if(g_state.combo_progress >= EMULATE_TOGGLE_COMBO_LEN) {
|
||||
g_state.combo_progress = 0;
|
||||
view_dispatcher_send_custom_event(
|
||||
app->view_dispatcher, ProtoPirateCustomEventAboutToggleEmulate);
|
||||
}
|
||||
} else if(event->key == EMULATE_TOGGLE_COMBO[0]) {
|
||||
g_state.combo_progress = 1;
|
||||
} else {
|
||||
g_state.combo_progress = 0;
|
||||
}
|
||||
|
||||
return true;
|
||||
#else
|
||||
UNUSED(event);
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef ENABLE_EMULATE_FEATURE
|
||||
static void about_show_emulate_toggle_popup(ProtoPirateApp* app) {
|
||||
const bool now_enabled = app->emulate_feature_enabled;
|
||||
|
||||
DialogMessage* message = dialog_message_alloc();
|
||||
dialog_message_set_buttons(message, NULL, "OK", NULL);
|
||||
dialog_message_set_icon(message, &I_WarningDolphin_45x42, 0, 12);
|
||||
dialog_message_set_header(
|
||||
message, now_enabled ? "Emulate Unlocked" : "Emulate Locked", 64, 0, AlignCenter, AlignTop);
|
||||
dialog_message_set_text(
|
||||
message,
|
||||
now_enabled ? "Transmission is\nnow enabled!" : "Transmission is\nnow disabled!",
|
||||
50,
|
||||
14,
|
||||
AlignLeft,
|
||||
AlignTop);
|
||||
dialog_message_show(app->dialogs, message);
|
||||
dialog_message_free(message);
|
||||
}
|
||||
#endif
|
||||
|
||||
void plugin_protopirate_scene_about_on_enter(void* context) {
|
||||
furi_check(context);
|
||||
ProtoPirateApp* app = context;
|
||||
|
||||
if(!g_about_scene_host_api->ensure_view_about(app)) {
|
||||
notification_message(app->notifications, &sequence_error);
|
||||
scene_manager_previous_scene(app->scene_manager);
|
||||
return;
|
||||
}
|
||||
|
||||
g_state.frame = 0;
|
||||
g_state.seed = furi_get_tick() & 0xFF;
|
||||
g_state.scroll_offset = 0;
|
||||
#ifdef ENABLE_EMULATE_FEATURE
|
||||
g_state.combo_progress = 0;
|
||||
#endif
|
||||
|
||||
view_set_draw_callback(app->view_about, about_draw_callback);
|
||||
view_set_input_callback(app->view_about, about_input_callback);
|
||||
view_set_context(app->view_about, app);
|
||||
|
||||
view_dispatcher_switch_to_view(app->view_dispatcher, ProtoPirateViewAbout);
|
||||
}
|
||||
|
||||
bool plugin_protopirate_scene_about_on_event(void* context, SceneManagerEvent event) {
|
||||
ProtoPirateApp* app = context;
|
||||
bool consumed = false;
|
||||
|
||||
if(event.type == SceneManagerEventTypeTick) {
|
||||
g_state.frame++;
|
||||
|
||||
if(g_state.frame % 2 == 0) {
|
||||
g_state.scroll_offset += SCROLL_SPEED;
|
||||
int16_t total_height = CREDITS_COUNT * CREDIT_LINE_HEIGHT;
|
||||
if(g_state.scroll_offset >= total_height) {
|
||||
g_state.scroll_offset = 0;
|
||||
}
|
||||
}
|
||||
|
||||
view_commit_model(app->view_about, true);
|
||||
consumed = true;
|
||||
}
|
||||
#ifdef ENABLE_EMULATE_FEATURE
|
||||
else if(event.type == SceneManagerEventTypeCustom) {
|
||||
if(event.event == ProtoPirateCustomEventAboutToggleEmulate) {
|
||||
//Toggle Emulate on
|
||||
app->emulate_feature_enabled = !app->emulate_feature_enabled;
|
||||
|
||||
ProtoPirateSettings settings;
|
||||
g_about_scene_host_api->settings_load(&settings);
|
||||
|
||||
settings.emulate_feature_enabled = app->emulate_feature_enabled;
|
||||
g_about_scene_host_api->settings_save(&settings);
|
||||
|
||||
notification_message(
|
||||
app->notifications,
|
||||
app->emulate_feature_enabled ? &sequence_success : &sequence_semi_success);
|
||||
|
||||
about_show_emulate_toggle_popup(app);
|
||||
consumed = true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return consumed;
|
||||
}
|
||||
|
||||
void plugin_protopirate_scene_about_on_exit(void* context) {
|
||||
UNUSED(context);
|
||||
}
|
||||
|
||||
void about_plugin_set_host_api(const ProtoPirateAboutSceneHostApi* host_api) {
|
||||
g_about_scene_host_api = host_api;
|
||||
}
|
||||
|
||||
static const ProtoPirateAboutPlugin protopirate_about_plugin = {
|
||||
.plugin_name = "About",
|
||||
.on_enter = plugin_protopirate_scene_about_on_enter,
|
||||
.on_event = plugin_protopirate_scene_about_on_event,
|
||||
.on_exit = plugin_protopirate_scene_about_on_exit,
|
||||
.set_host_api = about_plugin_set_host_api,
|
||||
};
|
||||
|
||||
static const FlipperAppPluginDescriptor protopirate_about_plugin_descriptor = {
|
||||
.appid = PROTOPIRATE_ABOUT_PLUGIN_APP_ID,
|
||||
.ep_api_version = PROTOPIRATE_ABOUT_PLUGIN_API_VERSION,
|
||||
.entry_point = &protopirate_about_plugin,
|
||||
};
|
||||
|
||||
const FlipperAppPluginDescriptor* protopirate_about_plugin_ep(void) {
|
||||
return &protopirate_about_plugin_descriptor;
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
#pragma once
|
||||
#include <gui/scene_manager.h>
|
||||
#include "../../helpers/protopirate_settings.h"
|
||||
|
||||
#define PROTOPIRATE_ABOUT_PLUGIN_APP_ID "pp_about"
|
||||
#define PROTOPIRATE_ABOUT_PLUGIN_API_VERSION 1U
|
||||
|
||||
typedef struct ProtoPirateApp ProtoPirateApp;
|
||||
|
||||
typedef struct ProtoPirateAboutSceneHostApi {
|
||||
bool (*ensure_view_about)(ProtoPirateApp* app);
|
||||
void (*settings_load)(ProtoPirateSettings* settings);
|
||||
void (*settings_save)(ProtoPirateSettings* settings);
|
||||
} ProtoPirateAboutSceneHostApi;
|
||||
|
||||
typedef struct ProtoPirateAboutPlugin {
|
||||
const char* plugin_name;
|
||||
void (*on_enter)(void* app);
|
||||
void (*on_exit)(void* app);
|
||||
bool (*on_event)(void* app, SceneManagerEvent event);
|
||||
void (*set_host_api)(const ProtoPirateAboutSceneHostApi* host_api);
|
||||
} ProtoPirateAboutPlugin;
|
||||
@@ -490,7 +490,7 @@ void config_plugin_set_host_api(const ProtoPirateConfigSceneHostApi* host_api) {
|
||||
}
|
||||
|
||||
static const ProtoPirateConfigPlugin protopirate_config_plugin = {
|
||||
.plugin_name = "ProtoPirate Config",
|
||||
.plugin_name = "Config",
|
||||
.car_model_get_by_index = car_model_get_by_index,
|
||||
.car_model_get_count = car_model_get_count,
|
||||
.on_enter = plugin_on_enter,
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
#include <lib/flipper_application/flipper_application.h>
|
||||
#include "helpers/variable_item_list.h"
|
||||
|
||||
#define PROTOPIRATE_CONFIG_PLUGIN_APP_ID "protopirate_config_plugin"
|
||||
#define PROTOPIRATE_CONFIG_PLUGIN_APP_ID "pp_config"
|
||||
#define PROTOPIRATE_CONFIG_PLUGIN_API_VERSION 2U
|
||||
|
||||
enum ProtoPirateSettingIndex {
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
#include <furi.h>
|
||||
#include <string.h>
|
||||
|
||||
#define TAG "ProtoPirateEmulatePlugin"
|
||||
#define TAG "PPEmulatePlugin"
|
||||
|
||||
#define MIN_TX_TIME 666U
|
||||
#define MIN_TX_TIME_KIA_V3_V4 1600U
|
||||
@@ -1571,7 +1571,7 @@ static void plugin_set_host_api(const ProtoPirateEmulateHostApi* host_api) {
|
||||
}
|
||||
|
||||
static const ProtoPirateEmulatePlugin protopirate_emulate_plugin = {
|
||||
.plugin_name = "ProtoPirate Emulate",
|
||||
.plugin_name = "Emulate",
|
||||
.set_host_api = plugin_set_host_api,
|
||||
.on_enter = plugin_on_enter,
|
||||
.on_event = plugin_on_event,
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#include <lib/flipper_application/flipper_application.h>
|
||||
#include <gui/scene_manager.h>
|
||||
|
||||
#define PROTOPIRATE_EMULATE_PLUGIN_APP_ID "protopirate_emulate_plugin"
|
||||
#define PROTOPIRATE_EMULATE_PLUGIN_APP_ID "pp_emulate"
|
||||
#define PROTOPIRATE_EMULATE_PLUGIN_API_VERSION 2U
|
||||
|
||||
typedef struct {
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#include <gui/modules/widget.h>
|
||||
#include <gui/modules/widget_elements/widget_element.h>
|
||||
#ifdef PROTOPIRATE_PSA_BF_PLUGIN_BUILD
|
||||
#include "protopirate_psa_bf_plugin_icons.h"
|
||||
#include "pp_bf_icons.h"
|
||||
#else
|
||||
#include "proto_pirate_icons.h"
|
||||
#endif
|
||||
@@ -521,7 +521,7 @@ static void plugin_set_host_api(const ProtoPiratePsaBfHostApi* api) {
|
||||
}
|
||||
|
||||
static const ProtoPiratePsaBfPlugin protopirate_psa_bf_plugin = {
|
||||
.plugin_name = "ProtoPirate PSA BF",
|
||||
.plugin_name = "BF",
|
||||
.set_host_api = plugin_set_host_api,
|
||||
.needs_bruteforce = plugin_needs_bruteforce,
|
||||
.is_running = plugin_is_running,
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
#include "../../protocols/psa_bf_types.h"
|
||||
|
||||
#define PROTOPIRATE_PSA_BF_PLUGIN_APP_ID "protopirate_psa_bf_plugin"
|
||||
#define PROTOPIRATE_PSA_BF_PLUGIN_APP_ID "pp_bf"
|
||||
#define PROTOPIRATE_PSA_BF_PLUGIN_API_VERSION 2U
|
||||
|
||||
typedef struct ProtoPirateApp ProtoPirateApp;
|
||||
|
||||
@@ -3,11 +3,11 @@
|
||||
#include "../../helpers/protopirate_storage.h"
|
||||
#include "../../protocols/protocols_common.h"
|
||||
#include "../../protocols/protocol_items.h"
|
||||
#include "protopirate_saved_info_plugin_icons.h"
|
||||
#include "pp_saved_info_icons.h"
|
||||
|
||||
static const ProtoPirateSavedInfoSceneHostApi* g_saved_info_scene_host_api = NULL;
|
||||
|
||||
#define TAG "ProtoPirateSavedInfoPlugin"
|
||||
#define TAG "PPSavedInfoPlugin"
|
||||
|
||||
#define STATE_EMULATE 0
|
||||
#define STATE_BF 1
|
||||
@@ -359,7 +359,7 @@ void saved_info_plugin_set_host_api(const ProtoPirateSavedInfoSceneHostApi* host
|
||||
}
|
||||
|
||||
static const ProtoPirateSavedInfoPlugin protopirate_saved_info_plugin = {
|
||||
.plugin_name = "ProtoPirate Saved Info",
|
||||
.plugin_name = "Saved",
|
||||
.on_enter = plugin_protopirate_scene_saved_info_on_enter,
|
||||
.on_event = plugin_protopirate_scene_saved_info_on_event,
|
||||
.on_exit = plugin_protopirate_scene_saved_info_on_exit,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#pragma once
|
||||
#include <gui/scene_manager.h>
|
||||
|
||||
#define PROTOPIRATE_SAVED_INFO_PLUGIN_APP_ID "protopirate_saved_info_plugin"
|
||||
#define PROTOPIRATE_SAVED_INFO_PLUGIN_APP_ID "pp_saved_info"
|
||||
#define PROTOPIRATE_SAVED_INFO_PLUGIN_API_VERSION 1U
|
||||
|
||||
typedef struct ProtoPirateApp ProtoPirateApp;
|
||||
|
||||
@@ -1,292 +1,43 @@
|
||||
// scenes/protopirate_scene_about.c
|
||||
#include "../protopirate_app_i.h"
|
||||
#include "../helpers/protopirate_settings.h"
|
||||
#include "proto_pirate_icons.h"
|
||||
#include <gui/elements.h>
|
||||
#include <input/input.h>
|
||||
#include <dialogs/dialogs.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define CREDITS_START_Y 28
|
||||
#define CREDITS_END_Y 52
|
||||
#define CREDIT_LINE_HEIGHT 10
|
||||
#define SCROLL_SPEED 1
|
||||
|
||||
#ifdef ENABLE_EMULATE_FEATURE
|
||||
static const InputKey EMULATE_TOGGLE_COMBO[] = {
|
||||
InputKeyUp,
|
||||
InputKeyUp,
|
||||
InputKeyDown,
|
||||
InputKeyDown,
|
||||
InputKeyLeft,
|
||||
InputKeyRight,
|
||||
InputKeyLeft,
|
||||
InputKeyRight,
|
||||
static const ProtoPirateAboutSceneHostApi protopirate_about_scene_host_api = {
|
||||
.ensure_view_about = protopirate_ensure_view_about,
|
||||
.settings_load = protopirate_settings_load,
|
||||
.settings_save = protopirate_settings_save,
|
||||
};
|
||||
#define EMULATE_TOGGLE_COMBO_LEN (sizeof(EMULATE_TOGGLE_COMBO) / sizeof(EMULATE_TOGGLE_COMBO[0]))
|
||||
#endif
|
||||
|
||||
static const char* credits[] = {
|
||||
"",
|
||||
"-=> App Development by",
|
||||
"RocketGod",
|
||||
"MMX",
|
||||
"Leeroy",
|
||||
"gullradriel",
|
||||
"Skorp's Weather App",
|
||||
"Vadim's Radio Driver",
|
||||
"-=> Protocol Magic by",
|
||||
"L0rdDiakon",
|
||||
"Leeroy",
|
||||
"Li0ard",
|
||||
"MMX",
|
||||
"YougZ",
|
||||
"DoobTheGoober",
|
||||
"RocketGod",
|
||||
"Skorp",
|
||||
"Slackware",
|
||||
"Trikk",
|
||||
"Wootini",
|
||||
"-=> RE Support",
|
||||
"DoobTheGoober",
|
||||
"Li0ard",
|
||||
"MMX",
|
||||
"NeedNotApply",
|
||||
"RocketGod",
|
||||
"Slackware",
|
||||
"Trikk",
|
||||
// can add more
|
||||
};
|
||||
|
||||
#define CREDITS_COUNT (sizeof(credits) / sizeof(credits[0]))
|
||||
|
||||
typedef struct {
|
||||
uint8_t frame;
|
||||
uint8_t seed;
|
||||
int16_t scroll_offset;
|
||||
#ifdef ENABLE_EMULATE_FEATURE
|
||||
uint8_t combo_progress;
|
||||
#endif
|
||||
} GlitchState;
|
||||
|
||||
static GlitchState g_state = {0};
|
||||
|
||||
static void draw_noise_pixels(Canvas* canvas, uint8_t density) {
|
||||
for(uint8_t i = 0; i < density; i++) {
|
||||
canvas_draw_dot(canvas, rand() % 128, rand() % 64);
|
||||
}
|
||||
}
|
||||
|
||||
static void about_draw_callback(Canvas* canvas, void* context) {
|
||||
UNUSED(context);
|
||||
|
||||
srand(g_state.seed);
|
||||
canvas_clear(canvas);
|
||||
|
||||
// Light background static
|
||||
canvas_set_color(canvas, ColorBlack);
|
||||
draw_noise_pixels(canvas, 6 + (rand() % 6));
|
||||
|
||||
// Occasional subtle x-jitter
|
||||
int8_t x_off = (rand() % 15 == 0) ? ((rand() % 4) - 2) : 0;
|
||||
|
||||
// Animated TPP decoration (centered)
|
||||
canvas_set_font(canvas, FontKeyboard);
|
||||
if(g_state.frame % 8 < 4) {
|
||||
canvas_draw_str_aligned(
|
||||
canvas, 64, 18, AlignCenter, AlignBottom, ">>>=================<<<");
|
||||
} else {
|
||||
canvas_draw_str_aligned(
|
||||
canvas, 64, 18, AlignCenter, AlignBottom, ">>>======[TPP]======<<<");
|
||||
}
|
||||
|
||||
// Draw credits region (clip area)
|
||||
canvas_set_font(canvas, FontSecondary);
|
||||
|
||||
// Calculate total scroll height
|
||||
int16_t total_height = CREDITS_COUNT * CREDIT_LINE_HEIGHT;
|
||||
|
||||
// Draw scrolling credits
|
||||
for(size_t i = 0; i < CREDITS_COUNT; i++) {
|
||||
int16_t y = CREDITS_START_Y + (i * CREDIT_LINE_HEIGHT) - g_state.scroll_offset;
|
||||
|
||||
// Wrap around for endless scroll
|
||||
while(y < CREDITS_START_Y - CREDIT_LINE_HEIGHT) {
|
||||
y += total_height;
|
||||
}
|
||||
while(y > CREDITS_START_Y + total_height) {
|
||||
y -= total_height;
|
||||
}
|
||||
|
||||
// Only draw if in visible region
|
||||
if(y >= CREDITS_START_Y - CREDIT_LINE_HEIGHT && y <= CREDITS_END_Y) {
|
||||
canvas_draw_str(canvas, x_off, y, credits[i]);
|
||||
}
|
||||
}
|
||||
|
||||
// Draw fade/mask bars at top and bottom of credits area
|
||||
canvas_set_color(canvas, ColorWhite);
|
||||
canvas_draw_box(canvas, 0, 0, 128, CREDITS_START_Y - CREDIT_LINE_HEIGHT);
|
||||
canvas_draw_box(canvas, 0, CREDITS_END_Y, 128, 14);
|
||||
|
||||
// Redraw header over mask
|
||||
canvas_set_color(canvas, ColorBlack);
|
||||
canvas_set_font(canvas, FontPrimary);
|
||||
canvas_draw_str(canvas, x_off, 10, "ProtoPirate v" FAP_VERSION);
|
||||
|
||||
canvas_set_font(canvas, FontKeyboard);
|
||||
if(g_state.frame % 8 < 4) {
|
||||
canvas_draw_str_aligned(
|
||||
canvas, 64, 18, AlignCenter, AlignBottom, ">>>=================<<<");
|
||||
} else {
|
||||
canvas_draw_str_aligned(
|
||||
canvas, 64, 18, AlignCenter, AlignBottom, ">>>======[TPP]======<<<");
|
||||
}
|
||||
|
||||
// Redraw static in header area
|
||||
srand(g_state.seed + 1);
|
||||
for(uint8_t i = 0; i < 3; i++) {
|
||||
canvas_draw_dot(canvas, rand() % 128, rand() % (CREDITS_START_Y - CREDIT_LINE_HEIGHT));
|
||||
}
|
||||
|
||||
// Footer: The Pirate's Plunder Discord
|
||||
canvas_set_font(canvas, FontKeyboard);
|
||||
canvas_draw_str_aligned(canvas, 127, 62, AlignRight, AlignBottom, "discord.gg/thepirates");
|
||||
|
||||
// Rare subtle glitch bar
|
||||
if(rand() % 30 == 0) {
|
||||
canvas_set_color(canvas, ColorXOR);
|
||||
uint8_t y = rand() % 60;
|
||||
canvas_draw_box(canvas, 0, y, 128, 2);
|
||||
}
|
||||
}
|
||||
|
||||
static bool about_input_callback(InputEvent* event, void* context) {
|
||||
furi_check(context);
|
||||
#ifdef ENABLE_EMULATE_FEATURE
|
||||
ProtoPirateApp* app = context;
|
||||
|
||||
if(event->type != InputTypePress) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if(event->key == InputKeyBack) {
|
||||
return false;
|
||||
}
|
||||
|
||||
InputKey expected = EMULATE_TOGGLE_COMBO[g_state.combo_progress];
|
||||
if(event->key == expected) {
|
||||
g_state.combo_progress++;
|
||||
if(g_state.combo_progress >= EMULATE_TOGGLE_COMBO_LEN) {
|
||||
g_state.combo_progress = 0;
|
||||
view_dispatcher_send_custom_event(
|
||||
app->view_dispatcher, ProtoPirateCustomEventAboutToggleEmulate);
|
||||
}
|
||||
} else if(event->key == EMULATE_TOGGLE_COMBO[0]) {
|
||||
g_state.combo_progress = 1;
|
||||
} else {
|
||||
g_state.combo_progress = 0;
|
||||
}
|
||||
|
||||
return true;
|
||||
#else
|
||||
UNUSED(event);
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef ENABLE_EMULATE_FEATURE
|
||||
static void about_show_emulate_toggle_popup(ProtoPirateApp* app) {
|
||||
const bool now_enabled = app->emulate_feature_enabled;
|
||||
|
||||
DialogMessage* message = dialog_message_alloc();
|
||||
dialog_message_set_buttons(message, NULL, "OK", NULL);
|
||||
dialog_message_set_icon(message, &I_WarningDolphin_45x42, 0, 12);
|
||||
dialog_message_set_header(
|
||||
message, now_enabled ? "Emulate Unlocked" : "Emulate Locked", 64, 0, AlignCenter, AlignTop);
|
||||
dialog_message_set_text(
|
||||
message,
|
||||
now_enabled ? "Transmission is\nnow enabled!" : "Transmission is\nnow disabled!",
|
||||
50,
|
||||
14,
|
||||
AlignLeft,
|
||||
AlignTop);
|
||||
dialog_message_show(app->dialogs, message);
|
||||
dialog_message_free(message);
|
||||
}
|
||||
#endif
|
||||
|
||||
void protopirate_scene_about_on_enter(void* context) {
|
||||
furi_check(context);
|
||||
ProtoPirateApp* app = context;
|
||||
|
||||
if(!protopirate_ensure_view_about(app)) {
|
||||
if(!shared_plugin_load(app, ProtoPirateSharedPluginsAbout)) {
|
||||
notification_message(app->notifications, &sequence_error);
|
||||
scene_manager_previous_scene(app->scene_manager);
|
||||
return;
|
||||
}
|
||||
|
||||
g_state.frame = 0;
|
||||
g_state.seed = furi_get_tick() & 0xFF;
|
||||
g_state.scroll_offset = 0;
|
||||
#ifdef ENABLE_EMULATE_FEATURE
|
||||
g_state.combo_progress = 0;
|
||||
#endif
|
||||
|
||||
view_set_draw_callback(app->view_about, about_draw_callback);
|
||||
view_set_input_callback(app->view_about, about_input_callback);
|
||||
view_set_context(app->view_about, app);
|
||||
|
||||
view_dispatcher_switch_to_view(app->view_dispatcher, ProtoPirateViewAbout);
|
||||
app->about_plugin->set_host_api(&protopirate_about_scene_host_api);
|
||||
app->about_plugin->on_enter(app);
|
||||
}
|
||||
|
||||
bool protopirate_scene_about_on_event(void* context, SceneManagerEvent event) {
|
||||
ProtoPirateApp* app = context;
|
||||
bool consumed = false;
|
||||
ProtoPirateApp* app = (ProtoPirateApp*)context;
|
||||
|
||||
if(event.type == SceneManagerEventTypeTick) {
|
||||
g_state.frame++;
|
||||
g_state.seed = rand();
|
||||
|
||||
if(g_state.frame % 2 == 0) {
|
||||
g_state.scroll_offset += SCROLL_SPEED;
|
||||
int16_t total_height = CREDITS_COUNT * CREDIT_LINE_HEIGHT;
|
||||
if(g_state.scroll_offset >= total_height) {
|
||||
g_state.scroll_offset = 0;
|
||||
}
|
||||
}
|
||||
|
||||
view_commit_model(app->view_about, true);
|
||||
consumed = true;
|
||||
//I can't set the next scene from inside the plugin, or it causes crazy crashes.
|
||||
if(event.type == SceneManagerEventTypeBack) {
|
||||
scene_manager_previous_scene(app->scene_manager);
|
||||
return true;
|
||||
}
|
||||
#ifdef ENABLE_EMULATE_FEATURE
|
||||
else if(event.type == SceneManagerEventTypeCustom) {
|
||||
if(event.event == ProtoPirateCustomEventAboutToggleEmulate) {
|
||||
app->emulate_feature_enabled = !app->emulate_feature_enabled;
|
||||
|
||||
ProtoPirateSettings settings;
|
||||
protopirate_settings_load(&settings);
|
||||
settings.emulate_feature_enabled = app->emulate_feature_enabled;
|
||||
protopirate_settings_save(&settings);
|
||||
|
||||
notification_message(
|
||||
app->notifications,
|
||||
app->emulate_feature_enabled ? &sequence_success : &sequence_semi_success);
|
||||
|
||||
about_show_emulate_toggle_popup(app);
|
||||
consumed = true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return consumed;
|
||||
//Handle About event in plugin.
|
||||
return app->about_plugin->on_event(app, event);
|
||||
}
|
||||
|
||||
void protopirate_scene_about_on_exit(void* context) {
|
||||
furi_check(context);
|
||||
ProtoPirateApp* app = context;
|
||||
|
||||
view_set_draw_callback(app->view_about, NULL);
|
||||
view_set_input_callback(app->view_about, NULL);
|
||||
view_set_context(app->view_about, NULL);
|
||||
shared_plugin_unload(app, ProtoPirateSharedPluginsAbout);
|
||||
}
|
||||
|
||||
@@ -11,9 +11,9 @@
|
||||
#include <lib/flipper_application/plugins/plugin_manager.h>
|
||||
#include <lib/flipper_application/plugins/composite_resolver.h>
|
||||
|
||||
#define TAG "ProtoPirateSceneEmulate"
|
||||
#define TAG "PPSceneEmulate"
|
||||
|
||||
#define EMULATE_PLUGIN_PATH APP_ASSETS_PATH("plugins/protopirate_emulate_plugin.fal")
|
||||
#define EMULATE_PLUGIN_PATH APP_ASSETS_PATH("plugins/pp_emulate.fal")
|
||||
|
||||
static bool host_radio_init(void* app) {
|
||||
return protopirate_radio_init((ProtoPirateApp*)app);
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#include "../protopirate_app_i.h"
|
||||
#include "proto_pirate_icons.h"
|
||||
|
||||
#define TAG "ProtoPirateNeedSaving"
|
||||
#define TAG "PPNeedSaving"
|
||||
|
||||
static void
|
||||
protopirate_scene_need_saving_callback(GuiButtonType result, InputType type, void* context) {
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
#include <stdio.h>
|
||||
#include "proto_pirate_icons.h"
|
||||
|
||||
#define TAG "ProtoPirateSceneRx"
|
||||
#define TAG "PPSceneRx"
|
||||
|
||||
#define DEFERRED_STORAGE_TIME 1000
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ static const ProtoPirateConfigSceneHostApi protopirate_config_scene_host_api = {
|
||||
void protopirate_scene_receiver_config_on_enter(void* context) {
|
||||
ProtoPirateApp* app = context;
|
||||
|
||||
if(!config_or_saved_plugin_load(app, true)) {
|
||||
if(!shared_plugin_load(app, ProtoPirateSharedPluginsConfig)) {
|
||||
notification_message(app->notifications, &sequence_error);
|
||||
scene_manager_previous_scene(app->scene_manager);
|
||||
return;
|
||||
@@ -37,5 +37,5 @@ bool protopirate_scene_receiver_config_on_event(void* context, SceneManagerEvent
|
||||
void protopirate_scene_receiver_config_on_exit(void* context) {
|
||||
ProtoPirateApp* app = context;
|
||||
|
||||
config_or_saved_plugin_unload(app, true);
|
||||
shared_plugin_unload(app, ProtoPirateSharedPluginsConfig);
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#include "proto_pirate_icons.h"
|
||||
#include <storage/storage.h>
|
||||
|
||||
#define TAG "ProtoPirateReceiverInfo"
|
||||
#define TAG "PPReceiverInfo"
|
||||
|
||||
#define STATE_EMULATE 0
|
||||
#define STATE_BF 1
|
||||
@@ -329,7 +329,6 @@ bool protopirate_scene_receiver_info_on_event(void* context, SceneManagerEvent e
|
||||
if(app->save_protocol) furi_string_free(app->save_protocol);
|
||||
app->save_protocol = protocol; // transfer ownership
|
||||
app->save_history_idx = app->txrx->idx_menu_chosen;
|
||||
app->save_from_saved_info = false;
|
||||
|
||||
// Configure and show text input
|
||||
text_input_reset(app->text_input);
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
#include "proto_pirate_icons.h"
|
||||
|
||||
#define TAG "ProtoPirateSceneSaved"
|
||||
#define TAG "PPSceneSaved"
|
||||
|
||||
void protopirate_scene_saved_on_enter(void* context) {
|
||||
furi_check(context);
|
||||
@@ -34,7 +34,7 @@ void protopirate_scene_saved_on_enter(void* context) {
|
||||
}
|
||||
|
||||
DialogsFileBrowserOptions browser_options;
|
||||
dialog_file_browser_set_basic_options(&browser_options, ".psf", &I_subghz_10px);
|
||||
dialog_file_browser_set_basic_options(&browser_options, ".psf", &I_protopirate_10px);
|
||||
browser_options.base_path = PROTOPIRATE_APP_FOLDER;
|
||||
browser_options.skip_assets = true;
|
||||
browser_options.hide_dot_files = true;
|
||||
|
||||
@@ -16,7 +16,7 @@ static const ProtoPirateSavedInfoSceneHostApi protopirate_saved_info_scene_host_
|
||||
void protopirate_scene_saved_info_on_enter(void* context) {
|
||||
ProtoPirateApp* app = context;
|
||||
|
||||
if(!config_or_saved_plugin_load(app, false)) {
|
||||
if(!shared_plugin_load(app, ProtoPirateSharedPluginsSavedInfo)) {
|
||||
notification_message(app->notifications, &sequence_error);
|
||||
scene_manager_previous_scene(app->scene_manager);
|
||||
return;
|
||||
@@ -27,13 +27,14 @@ void protopirate_scene_saved_info_on_enter(void* context) {
|
||||
}
|
||||
|
||||
bool protopirate_scene_saved_info_on_event(void* context, SceneManagerEvent event) {
|
||||
ProtoPirateApp* app = ((ProtoPirateApp*)context);
|
||||
|
||||
//I can't set the next scene from inside the plugin, or it causes crazy crashes.
|
||||
if(event.type == SceneManagerEventTypeCustom) {
|
||||
if(event.event == ProtoPirateCustomEventSavedInfoEmulateDelayedStart) {
|
||||
//Start Emulate Scene.
|
||||
#ifdef ENABLE_EMULATE_FEATURE
|
||||
scene_manager_next_scene(
|
||||
((ProtoPirateApp*)context)->scene_manager, ProtoPirateSceneEmulate);
|
||||
scene_manager_next_scene(app->scene_manager, ProtoPirateSceneEmulate);
|
||||
return true;
|
||||
#endif
|
||||
} else if(event.event == ProtoPirateCustomEventSavedInfoExit) {
|
||||
@@ -43,12 +44,11 @@ bool protopirate_scene_saved_info_on_event(void* context, SceneManagerEvent even
|
||||
}
|
||||
|
||||
//Handle Saved Info event in plugin.
|
||||
return ((ProtoPirateApp*)context)->saved_info_plugin->on_event(context, event);
|
||||
return app->saved_info_plugin->on_event(app, event);
|
||||
}
|
||||
|
||||
void protopirate_scene_saved_info_on_exit(void* context) {
|
||||
ProtoPirateApp* app = context;
|
||||
UNUSED(app);
|
||||
|
||||
config_or_saved_plugin_unload(app, false);
|
||||
shared_plugin_unload(app, ProtoPirateSharedPluginsSavedInfo);
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
#include "proto_pirate_icons.h"
|
||||
|
||||
#define TAG "ProtoPirateSceneStart"
|
||||
#define TAG "PPSceneStart"
|
||||
|
||||
typedef enum {
|
||||
SubmenuIndexProtoPirateReceiver,
|
||||
|
||||
@@ -36,12 +36,12 @@ void protopirate_scene_sub_decode_on_exit(void* context) {
|
||||
#include <lib/subghz/types.h>
|
||||
|
||||
#ifdef PROTOPIRATE_SUB_DECODE_PLUGIN_BUILD
|
||||
#include "protopirate_sub_decode_plugin_icons.h"
|
||||
#include "pp_sub_decode_icons.h"
|
||||
#else
|
||||
#include "proto_pirate_icons.h"
|
||||
#endif
|
||||
|
||||
#define TAG "ProtoPirateSubDecode"
|
||||
#define TAG "PPSubDecode"
|
||||
|
||||
static const ProtoPirateToolSceneHostApi* g_tool_scene_host_api = NULL;
|
||||
|
||||
@@ -689,7 +689,6 @@ bool protopirate_scene_sub_decode_on_event(void* context, SceneManagerEvent even
|
||||
|
||||
// Store context for when text input confirms
|
||||
app->save_history_idx = app->txrx->idx_menu_chosen;
|
||||
app->save_from_saved_info = false;
|
||||
|
||||
//Make sure we have a text input window.
|
||||
app->text_input = text_input_alloc();
|
||||
@@ -1468,7 +1467,7 @@ static void sub_decode_plugin_set_host_api(const ProtoPirateToolSceneHostApi* ho
|
||||
}
|
||||
|
||||
static const ProtoPirateToolScenePlugin protopirate_sub_decode_plugin = {
|
||||
.plugin_name = "ProtoPirate Sub Decode",
|
||||
.plugin_name = "Sub Decode",
|
||||
.kind = ProtoPirateToolScenePluginKindSubDecode,
|
||||
.set_host_api = sub_decode_plugin_set_host_api,
|
||||
.on_enter = protopirate_scene_sub_decode_on_enter,
|
||||
|
||||
@@ -23,7 +23,7 @@ void protopirate_scene_timing_tuner_on_exit(void* context) {
|
||||
#include <gui/elements.h>
|
||||
#include <math.h>
|
||||
|
||||
#define TAG "ProtoPirateTimingTuner"
|
||||
#define TAG "PPTimingTuner"
|
||||
|
||||
static const ProtoPirateToolSceneHostApi* g_tool_scene_host_api = NULL;
|
||||
|
||||
@@ -808,7 +808,7 @@ static void timing_tuner_plugin_set_host_api(const ProtoPirateToolSceneHostApi*
|
||||
}
|
||||
|
||||
static const ProtoPirateToolScenePlugin protopirate_timing_tuner_plugin = {
|
||||
.plugin_name = "ProtoPirate Timing Tuner",
|
||||
.plugin_name = "Timing Tuner",
|
||||
.kind = ProtoPirateToolScenePluginKindTimingTuner,
|
||||
.set_host_api = timing_tuner_plugin_set_host_api,
|
||||
.on_enter = protopirate_scene_timing_tuner_on_enter,
|
||||
|
||||
Reference in New Issue
Block a user