mirror of
https://github.com/arabine/open-story-teller.git
synced 2025-12-06 17:09:06 +01:00
Parse index file (TLV) for multiple stories
This commit is contained in:
parent
fea5bc9c17
commit
5bf26b500b
5 changed files with 136 additions and 25 deletions
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue