Parse index file (TLV) for multiple stories

This commit is contained in:
Anthony Rabine 2023-07-31 14:08:47 +02:00
parent fea5bc9c17
commit 5bf26b500b
5 changed files with 136 additions and 25 deletions

View file

@ -140,9 +140,15 @@ void disk_start()
}
*/
// ===========================================================================================================
// INDEX FILE MANAGEMENT
// ===========================================================================================================
static file_t IndexFile;
static uint8_t IndexBuf[260];
static uint8_t ImageBuf[100];
static uint8_t SoundBuf[100];
static const char *IndexFileName = "index.ost";
@ -150,6 +156,8 @@ static const char *IndexFileName = "index.ost";
#define TLV_OBJECT_TYPE 0xE7
#define TLV_STRING_TYPE 0x3D
#define TL_SIZE 3
bool filesystem_read_index_file(ost_context_t *ctx)
{
FILINFO fno;
@ -167,21 +175,17 @@ bool filesystem_read_index_file(ost_context_t *ctx)
bool valid_file = false;
// Minimum size of TLV is type + length, so check if there is potential data
if (ctx->index_file_size > 3)
if (ctx->index_file_size > TL_SIZE)
{
FRESULT fr = f_open(&IndexFile, IndexFileName, FA_READ);
if (fr == FR_OK)
{
fr = f_read(&IndexFile, IndexBuf, 3, &br);
if (fr == FR_OK)
fr = f_read(&IndexFile, &IndexBuf[0], TL_SIZE, &br);
if ((fr == FR_OK) && (br == TL_SIZE) && (IndexBuf[0] = TLV_ARRAY_TYPE))
{
if ((br == 3) && (IndexBuf[0] = TLV_ARRAY_TYPE)) // Must be an array
{
// nomber of stories
ctx->number_of_stories = leu16_get(&IndexBuf[1]);
ctx->rd = 3;
debug_printf("SUCCESS: found %d stories\r\n", ctx->number_of_stories);
}
// nomber of stories
ctx->number_of_stories = leu16_get(&IndexBuf[1]);
debug_printf("SUCCESS: found %d stories\r\n", ctx->number_of_stories);
}
}
}
@ -192,6 +196,57 @@ bool filesystem_read_index_file(ost_context_t *ctx)
}
}
static uint32_t tlv_get_string(char *destination)
{
uint32_t size = 0;
UINT br;
FRESULT fr = f_read(&IndexFile, &IndexBuf[0], TL_SIZE, &br);
if ((fr == FR_OK) && (br == TL_SIZE) && (IndexBuf[0] = TLV_STRING_TYPE))
{
size = leu16_get(&IndexBuf[1]);
// read string, directly fill destination
f_read(&IndexFile, destination, size, &br);
if ((fr == FR_OK) && (br == size))
{
// good, end propertly with zero
destination[size] = 0;
}
else
{
size = 0;
}
}
return size;
}
void filesystem_get_story_title(ost_context_t *ctx)
{
UINT br;
ctx->current_story++;
if (ctx->current_story >= ctx->number_of_stories)
{
// Rewind to the begining of the index file data (first array element)
f_lseek(&IndexFile, TL_SIZE);
}
FRESULT fr = f_read(&IndexFile, &IndexBuf[0], 3, &br);
if ((fr == FR_OK) && (br == 3) && (IndexBuf[0] = TLV_OBJECT_TYPE))
{
tlv_get_string(ctx->uuid);
tlv_get_string(ImageBuf);
tlv_get_string(SoundBuf);
ctx->image = ImageBuf;
ctx->sound = SoundBuf;
}
}
// ===========================================================================================================
// IMAGE DECODER
// ===========================================================================================================
static mqoi_dec_t dec;
static mqoi_desc_t desc;

View file

@ -8,5 +8,6 @@ bool filesystem_read_index_file(ost_context_t *ctx);
void filesystem_mount();
void filesystem_display_image(const char *filename);
void filesystem_load_rom(uint8_t *mem, const char *filename);
void filesystem_get_story_title(ost_context_t *ctx);
#endif // FILESYSTEM_H

View file

@ -13,6 +13,7 @@
#include <stdint.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include "ost_hal.h"
#include "debug.h"
@ -125,25 +126,78 @@ void play_sound_file(const char *filename)
show_duration(executionTime);
}
static char ScratchFile[260];
static const char *ImagesDir = "/images/";
static const char *SoundsDir = "/sounds/";
#define STORY_DIR_OFFSET (UUID_SIZE + 1)
static uint8_t LedState = 0;
void FsTask(void *args)
{
ost_fs_event_t *fs_ev = NULL;
uint32_t res = 0;
filesystem_read_index_file(&OstContext);
FsState = FS_LOAD_INDEX;
while (1)
{
switch (FsState)
{
case FS_PLAY_SOUND:
play_sound_file(fs_ev->filename);
ScratchFile[STORY_DIR_OFFSET] = 0;
strcat(ScratchFile, SoundsDir);
strcat(ScratchFile, OstContext.sound);
play_sound_file(ScratchFile);
FsState = FS_WAIT_FOR_EVENT;
break;
case FS_DISPLAY_IMAGE:
filesystem_display_image(fs_ev->filename);
FsState = FS_WAIT_FOR_EVENT;
ScratchFile[STORY_DIR_OFFSET] = 0;
strcat(ScratchFile, ImagesDir);
strcat(ScratchFile, OstContext.image);
filesystem_display_image(ScratchFile);
if (OstContext.sound != NULL)
{
FsState = FS_PLAY_SOUND;
}
else
{
FsState = FS_WAIT_FOR_EVENT;
}
break;
case FS_LOAD_INDEX:
filesystem_read_index_file(&OstContext);
FsState = FS_WAIT_FOR_EVENT;
if (OstContext.number_of_stories > 0)
{
filesystem_get_story_title(&OstContext);
// Init current directory
ScratchFile[0] = '/';
memcpy(&ScratchFile[1], OstContext.uuid, UUID_SIZE);
ScratchFile[1 + UUID_SIZE] = 0;
// first, display image, then sound
if (OstContext.image != NULL)
{
FsState = FS_DISPLAY_IMAGE;
}
else if (OstContext.sound != NULL)
{
FsState = FS_PLAY_SOUND;
}
else
{
FsState = FS_WAIT_FOR_EVENT;
}
}
else
{
FsState = FS_WAIT_FOR_EVENT;
}
break;
case FS_LOAD_STORY:
filesystem_load_rom(fs_ev->mem, fs_ev->filename);
@ -159,16 +213,13 @@ void FsTask(void *args)
// valid event, accept it
FsState = fs_ev->ev;
}
else
{
LedState = 1 - LedState;
ost_hal_gpio_set(OST_GPIO_DEBUG_LED, LedState);
}
break;
}
// for (;;)
// {
// ost_hal_gpio_set(OST_GPIO_DEBUG_LED, 0);
// qor_sleep(500);
// ost_hal_gpio_set(OST_GPIO_DEBUG_LED, 1);
// qor_sleep(500);
// }
}
}

View file

@ -66,7 +66,7 @@ void HmiTask(void *args)
// filesystem_display_image("/ba869e4b-03d6-4249-9202-85b4cec767a7/images/bird.qoi");
// Start by scanning the index file
fs_task_scan_index();
// fs_task_scan_index();
while (1)
{

View file

@ -8,12 +8,16 @@
#define VM_TASK_PRIORITY 2
#define FS_TASK_PRIORITY 3 ///< High priority for audio / file system access
#define UUID_SIZE 36 // 32 + 4 dashes in string format
typedef struct
{
uint32_t number_of_stories;
uint32_t current_story;
uint32_t index_file_size;
uint32_t rd; ///!< Read index in the Index file
char uuid[UUID_SIZE + 1]; // +1 for end of string zero marker
char *image;
char *sound;
} ost_context_t;