mirror of
https://github.com/arabine/open-story-teller.git
synced 2025-12-07 01:15:14 +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 file_t IndexFile;
|
||||||
|
|
||||||
static uint8_t IndexBuf[260];
|
static uint8_t IndexBuf[260];
|
||||||
|
static uint8_t ImageBuf[100];
|
||||||
|
static uint8_t SoundBuf[100];
|
||||||
|
|
||||||
static const char *IndexFileName = "index.ost";
|
static const char *IndexFileName = "index.ost";
|
||||||
|
|
||||||
|
|
@ -150,6 +156,8 @@ static const char *IndexFileName = "index.ost";
|
||||||
#define TLV_OBJECT_TYPE 0xE7
|
#define TLV_OBJECT_TYPE 0xE7
|
||||||
#define TLV_STRING_TYPE 0x3D
|
#define TLV_STRING_TYPE 0x3D
|
||||||
|
|
||||||
|
#define TL_SIZE 3
|
||||||
|
|
||||||
bool filesystem_read_index_file(ost_context_t *ctx)
|
bool filesystem_read_index_file(ost_context_t *ctx)
|
||||||
{
|
{
|
||||||
FILINFO fno;
|
FILINFO fno;
|
||||||
|
|
@ -167,21 +175,17 @@ bool filesystem_read_index_file(ost_context_t *ctx)
|
||||||
bool valid_file = false;
|
bool valid_file = false;
|
||||||
|
|
||||||
// Minimum size of TLV is type + length, so check if there is potential data
|
// 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);
|
FRESULT fr = f_open(&IndexFile, IndexFileName, FA_READ);
|
||||||
if (fr == FR_OK)
|
if (fr == FR_OK)
|
||||||
{
|
{
|
||||||
fr = f_read(&IndexFile, IndexBuf, 3, &br);
|
fr = f_read(&IndexFile, &IndexBuf[0], TL_SIZE, &br);
|
||||||
if (fr == FR_OK)
|
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]);
|
||||||
// nomber of stories
|
debug_printf("SUCCESS: found %d stories\r\n", ctx->number_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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -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_dec_t dec;
|
||||||
static mqoi_desc_t desc;
|
static mqoi_desc_t desc;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,5 +8,6 @@ bool filesystem_read_index_file(ost_context_t *ctx);
|
||||||
void filesystem_mount();
|
void filesystem_mount();
|
||||||
void filesystem_display_image(const char *filename);
|
void filesystem_display_image(const char *filename);
|
||||||
void filesystem_load_rom(uint8_t *mem, 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
|
#endif // FILESYSTEM_H
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#include "ost_hal.h"
|
#include "ost_hal.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
|
@ -125,25 +126,78 @@ void play_sound_file(const char *filename)
|
||||||
show_duration(executionTime);
|
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)
|
void FsTask(void *args)
|
||||||
{
|
{
|
||||||
ost_fs_event_t *fs_ev = NULL;
|
ost_fs_event_t *fs_ev = NULL;
|
||||||
uint32_t res = 0;
|
uint32_t res = 0;
|
||||||
|
|
||||||
|
filesystem_read_index_file(&OstContext);
|
||||||
|
FsState = FS_LOAD_INDEX;
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
switch (FsState)
|
switch (FsState)
|
||||||
{
|
{
|
||||||
case FS_PLAY_SOUND:
|
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;
|
FsState = FS_WAIT_FOR_EVENT;
|
||||||
break;
|
break;
|
||||||
case FS_DISPLAY_IMAGE:
|
case FS_DISPLAY_IMAGE:
|
||||||
filesystem_display_image(fs_ev->filename);
|
ScratchFile[STORY_DIR_OFFSET] = 0;
|
||||||
FsState = FS_WAIT_FOR_EVENT;
|
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;
|
break;
|
||||||
|
|
||||||
case FS_LOAD_INDEX:
|
case FS_LOAD_INDEX:
|
||||||
filesystem_read_index_file(&OstContext);
|
if (OstContext.number_of_stories > 0)
|
||||||
FsState = FS_WAIT_FOR_EVENT;
|
{
|
||||||
|
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;
|
break;
|
||||||
case FS_LOAD_STORY:
|
case FS_LOAD_STORY:
|
||||||
filesystem_load_rom(fs_ev->mem, fs_ev->filename);
|
filesystem_load_rom(fs_ev->mem, fs_ev->filename);
|
||||||
|
|
@ -159,16 +213,13 @@ void FsTask(void *args)
|
||||||
// valid event, accept it
|
// valid event, accept it
|
||||||
FsState = fs_ev->ev;
|
FsState = fs_ev->ev;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LedState = 1 - LedState;
|
||||||
|
ost_hal_gpio_set(OST_GPIO_DEBUG_LED, LedState);
|
||||||
|
}
|
||||||
break;
|
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");
|
// filesystem_display_image("/ba869e4b-03d6-4249-9202-85b4cec767a7/images/bird.qoi");
|
||||||
|
|
||||||
// Start by scanning the index file
|
// Start by scanning the index file
|
||||||
fs_task_scan_index();
|
// fs_task_scan_index();
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -8,12 +8,16 @@
|
||||||
#define VM_TASK_PRIORITY 2
|
#define VM_TASK_PRIORITY 2
|
||||||
#define FS_TASK_PRIORITY 3 ///< High priority for audio / file system access
|
#define FS_TASK_PRIORITY 3 ///< High priority for audio / file system access
|
||||||
|
|
||||||
|
#define UUID_SIZE 36 // 32 + 4 dashes in string format
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
uint32_t number_of_stories;
|
uint32_t number_of_stories;
|
||||||
uint32_t current_story;
|
uint32_t current_story;
|
||||||
uint32_t index_file_size;
|
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;
|
} ost_context_t;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue