start to replay
This commit is contained in:
parent
232c9ddce1
commit
361a14aa09
@ -8,7 +8,7 @@ enum state_t {
|
|||||||
STATE_PLAYBACK = 2,
|
STATE_PLAYBACK = 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
static std::vector<EventCB> event_cbs;
|
static std::vector<void(*)(const char*, const char*)> replay_fns;
|
||||||
|
|
||||||
static bool should_close_recording_stream;
|
static bool should_close_recording_stream;
|
||||||
static FILE* recording_stream;
|
static FILE* recording_stream;
|
||||||
@ -17,6 +17,9 @@ TaskHandle_t flush_file_task_handle;
|
|||||||
|
|
||||||
static bool should_close_playback_stream;
|
static bool should_close_playback_stream;
|
||||||
static FILE* playback_stream;
|
static FILE* playback_stream;
|
||||||
|
static uint32_t playback_start_time;
|
||||||
|
TaskHandle_t playback_task_handle;
|
||||||
|
|
||||||
static volatile state_t state = STATE_IDLE;
|
static volatile state_t state = STATE_IDLE;
|
||||||
|
|
||||||
|
|
||||||
@ -37,12 +40,64 @@ static void flush_file_task(void* arg) {
|
|||||||
vTaskDelete(NULL);
|
vTaskDelete(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void register_event_cb(const char* name, void (*replay_callback)(uint32_t, const char*)) {
|
static void playback_task(void* arg) {
|
||||||
EventCB event = {
|
const size_t size = 16*1024;
|
||||||
.name = name,
|
char* buf = (char*) malloc(size*sizeof(char));
|
||||||
.replay_callback = replay_callback,
|
|
||||||
};
|
while (state == STATE_PLAYBACK && playback_stream != nullptr) {
|
||||||
event_cbs.push_back(event);
|
fgets(buf, size, playback_stream);
|
||||||
|
|
||||||
|
// look for a comma, indicating the end of the "ticks" part
|
||||||
|
size_t comma_pos = 0;
|
||||||
|
for (int i = 0; i < 11; i++) {
|
||||||
|
if (buf[i] == ',') {
|
||||||
|
comma_pos = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (comma_pos == 0) {
|
||||||
|
ESP_LOGE("playback", "Failed to find comma in playback line");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
buf[comma_pos] = '\0';
|
||||||
|
uint32_t tick = atoi(buf);
|
||||||
|
|
||||||
|
// now look for the colon to indicate the end of the event name
|
||||||
|
size_t colon_pos = 0;
|
||||||
|
int i = comma_pos + 1; // start looking right after the comma
|
||||||
|
while (i < size) {
|
||||||
|
if (buf[i] == ':') {
|
||||||
|
colon_pos = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (colon_pos == 0) {
|
||||||
|
ESP_LOGE("playback", "Failed to find colon in playback line");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
buf[colon_pos] = '\0';
|
||||||
|
char* event_name = buf + (comma_pos + 1);
|
||||||
|
char* arg = buf + (colon_pos + 1);
|
||||||
|
|
||||||
|
int32_t ticks_to_wait = ((int32_t) tick) - (int32_t)(xTaskGetTickCount() - playback_start_time);
|
||||||
|
|
||||||
|
if (ticks_to_wait < 0) {
|
||||||
|
ESP_LOGW("playback", "Playback is behind by %ld ticks!", ticks_to_wait);
|
||||||
|
}
|
||||||
|
if (ticks_to_wait > 0) {
|
||||||
|
vTaskDelay(ticks_to_wait);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const auto& fn : replay_fns) {
|
||||||
|
(fn)(event_name, arg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void register_event_cb(void (*replay_callback)(const char*, const char*)) {
|
||||||
|
replay_fns.push_back(replay_callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
void event_occured(const char* name, const char* arg) {
|
void event_occured(const char* name, const char* arg) {
|
||||||
@ -102,8 +157,13 @@ bool stop_recording() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool start_playback() {
|
bool start_playback() {
|
||||||
// TODO: impl
|
if (state != STATE_IDLE) return false;
|
||||||
return false;
|
if (playback_stream == nullptr) return false;
|
||||||
|
|
||||||
|
state = STATE_PLAYBACK;
|
||||||
|
playback_start_time = xTaskGetTickCount();
|
||||||
|
xTaskCreate(playback_task, "playback", 2048, NULL, 2, &playback_task_handle);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool stop_playback() {
|
bool stop_playback() {
|
||||||
|
|||||||
@ -4,20 +4,9 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include "esp_vfs_fat.h"
|
#include "esp_vfs_fat.h"
|
||||||
|
|
||||||
/// @brief An event that represents the physical bomb state moving.
|
/// @brief Registers function to be called on replay.
|
||||||
struct EventCB {
|
/// @param replay_callback A function to call to playback the event.
|
||||||
// The name of the event.
|
void register_replay_fn(void (*replay_fn)(const char*, const char*));
|
||||||
// This should not contain whitespace or the characters ':', ','
|
|
||||||
const char* name;
|
|
||||||
// An optional callback function for recreating the state.
|
|
||||||
// Arguments are "ticks" and the serialized argument
|
|
||||||
void (*replay_callback)(uint32_t, const char*);
|
|
||||||
};
|
|
||||||
|
|
||||||
/// @brief Registers a callback for a certain event to be called on replay.
|
|
||||||
/// @param name The name of the event to respond to.
|
|
||||||
/// @param replay_callback A function to call to playback this state transition.
|
|
||||||
void register_event_cb(const char* name, void (*replay_callback)(uint32_t, const char*));
|
|
||||||
|
|
||||||
// TODO: add one for generically responding to all events.
|
// TODO: add one for generically responding to all events.
|
||||||
|
|
||||||
|
|||||||
@ -17,6 +17,10 @@ static lv_style_t style_screen;
|
|||||||
|
|
||||||
SemaphoreHandle_t xGuiSemaphore;
|
SemaphoreHandle_t xGuiSemaphore;
|
||||||
|
|
||||||
|
static void replay_handler(const char* event, const char* arg) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
static bool notify_lvgl_flush_ready(
|
static bool notify_lvgl_flush_ready(
|
||||||
esp_lcd_panel_io_handle_t panel_io,
|
esp_lcd_panel_io_handle_t panel_io,
|
||||||
esp_lcd_panel_io_event_data_t *edata,
|
esp_lcd_panel_io_event_data_t *edata,
|
||||||
@ -224,5 +228,7 @@ void init_tft() {
|
|||||||
initialize_display();
|
initialize_display();
|
||||||
xTaskCreatePinnedToCore(guiTask, "gui", 4096*2, NULL, 5, NULL, 1);
|
xTaskCreatePinnedToCore(guiTask, "gui", 4096*2, NULL, 5, NULL, 1);
|
||||||
|
|
||||||
|
register_replay_fn(replay_handler);
|
||||||
|
|
||||||
ESP_LOGI(TAG, "TFT initialized!");
|
ESP_LOGI(TAG, "TFT initialized!");
|
||||||
}
|
}
|
||||||
|
|||||||
@ -36,6 +36,10 @@ extern "C" void app_main(void) {
|
|||||||
init_wires();
|
init_wires();
|
||||||
vTaskDelay(pdMS_TO_TICKS(1000));
|
vTaskDelay(pdMS_TO_TICKS(1000));
|
||||||
|
|
||||||
|
|
||||||
|
clean_bomb();
|
||||||
|
step0();
|
||||||
|
|
||||||
// set_recording_source(stdout, false);
|
// set_recording_source(stdout, false);
|
||||||
FILE* record_file = fopen(MOUNT_POINT "/record.txt", "w");
|
FILE* record_file = fopen(MOUNT_POINT "/record.txt", "w");
|
||||||
if (record_file == nullptr) {
|
if (record_file == nullptr) {
|
||||||
@ -44,10 +48,6 @@ extern "C" void app_main(void) {
|
|||||||
set_recording_source(record_file, true);
|
set_recording_source(record_file, true);
|
||||||
start_recording();
|
start_recording();
|
||||||
|
|
||||||
clean_bomb();
|
|
||||||
step0();
|
|
||||||
|
|
||||||
|
|
||||||
set_game_time(initial_game_time);
|
set_game_time(initial_game_time);
|
||||||
start_game_timer();
|
start_game_timer();
|
||||||
total_strikes = 0;
|
total_strikes = 0;
|
||||||
@ -55,7 +55,6 @@ extern "C" void app_main(void) {
|
|||||||
current_step = 1;
|
current_step = 1;
|
||||||
if (skip_to_step <= 1) step1();
|
if (skip_to_step <= 1) step1();
|
||||||
step_finish_times[current_step-1] = get_game_time();
|
step_finish_times[current_step-1] = get_game_time();
|
||||||
stop_recording();
|
|
||||||
clean_bomb();
|
clean_bomb();
|
||||||
current_step = 2;
|
current_step = 2;
|
||||||
if (skip_to_step <= 2) step2();
|
if (skip_to_step <= 2) step2();
|
||||||
@ -84,5 +83,6 @@ extern "C" void app_main(void) {
|
|||||||
play_clip_wav(MOUNT_POINT "/diffuse.wav", true, false, 3, 0);
|
play_clip_wav(MOUNT_POINT "/diffuse.wav", true, false, 3, 0);
|
||||||
|
|
||||||
display_game_results();
|
display_game_results();
|
||||||
|
stop_recording();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user