mirror of
https://github.com/arabine/open-story-teller.git
synced 2025-12-07 01:15:14 +01:00
fix sdcard buffer overflow, fix switch case, use of TLV index file for stories
This commit is contained in:
parent
084af988cb
commit
fea5bc9c17
12 changed files with 182 additions and 62 deletions
|
|
@ -5,6 +5,7 @@
|
||||||
|
|
||||||
#include "filesystem.h"
|
#include "filesystem.h"
|
||||||
#include "mini_qoi.h"
|
#include "mini_qoi.h"
|
||||||
|
#include "serializers.h"
|
||||||
|
|
||||||
#ifdef OST_USE_FF_LIBRARY
|
#ifdef OST_USE_FF_LIBRARY
|
||||||
#include "ff.h"
|
#include "ff.h"
|
||||||
|
|
@ -27,6 +28,21 @@ static FIL File[2]; /* File object */
|
||||||
static DIR Dir; /* Directory object */
|
static DIR Dir; /* Directory object */
|
||||||
static FILINFO Finfo;
|
static FILINFO Finfo;
|
||||||
|
|
||||||
|
file_t file_open(const char *filename)
|
||||||
|
{
|
||||||
|
#ifdef OST_USE_FF_LIBRARY
|
||||||
|
file_t fil;
|
||||||
|
FRESULT fr = f_open(&fil, filename, FA_READ);
|
||||||
|
if (fr != FR_OK)
|
||||||
|
{
|
||||||
|
debug_printf("ERROR: f_open %d\n\r", (int)fr);
|
||||||
|
}
|
||||||
|
return fil;
|
||||||
|
#else
|
||||||
|
return fopen(filename, "r");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
static FRESULT scan_files(
|
static FRESULT scan_files(
|
||||||
char *path /* Pointer to the working buffer with start path */
|
char *path /* Pointer to the working buffer with start path */
|
||||||
)
|
)
|
||||||
|
|
@ -82,20 +98,6 @@ void filesystem_mount()
|
||||||
scan_files("");
|
scan_files("");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ouvre le fichier d'index d'histoires
|
|
||||||
// Le format est le suivant :
|
|
||||||
// - Fichier texte, avec fin de ligne \n
|
|
||||||
// - Une ligne par histoire
|
|
||||||
// - la ligne contient le nom du répertoire au format UUIDv4 (36 caractères ASCII avec 4 tirets '-')
|
|
||||||
|
|
||||||
// Exemple: d0ad13e4-06de-4e00-877c-d922fdd37d13
|
|
||||||
|
|
||||||
int is_multiple_of_37(int nombre)
|
|
||||||
{
|
|
||||||
int plusGrandMultiple = (nombre / 37) * 37;
|
|
||||||
return (nombre - plusGrandMultiple) == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
// Loop in all directories
|
// Loop in all directories
|
||||||
void disk_start()
|
void disk_start()
|
||||||
|
|
@ -138,30 +140,55 @@ void disk_start()
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
static file_t IndexFile;
|
||||||
|
|
||||||
|
static uint8_t IndexBuf[260];
|
||||||
|
|
||||||
|
static const char *IndexFileName = "index.ost";
|
||||||
|
|
||||||
|
#define TLV_ARRAY_TYPE 0xAB
|
||||||
|
#define TLV_OBJECT_TYPE 0xE7
|
||||||
|
#define TLV_STRING_TYPE 0x3D
|
||||||
|
|
||||||
bool filesystem_read_index_file(ost_context_t *ctx)
|
bool filesystem_read_index_file(ost_context_t *ctx)
|
||||||
{
|
{
|
||||||
FILINFO fno;
|
FILINFO fno;
|
||||||
FRESULT fr = f_stat("index.ost", &fno);
|
FRESULT fr = f_stat(IndexFileName, &fno);
|
||||||
|
|
||||||
ctx->number_of_stories = 0;
|
ctx->number_of_stories = 0;
|
||||||
ctx->current_story = 0;
|
ctx->current_story = 0;
|
||||||
|
|
||||||
if (fr == FR_OK)
|
if (fr == FR_OK)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
ctx->index_file_size = fno.fsize;
|
||||||
|
UINT br;
|
||||||
|
|
||||||
bool valid_file = false;
|
bool valid_file = false;
|
||||||
int size = fno.fsize;
|
|
||||||
// une ligne = 36 octets (UUID) + 1 octet (\n) = 37
|
// Minimum size of TLV is type + length, so check if there is potential data
|
||||||
// Déjà, la taille doit être multiple de 37
|
if (ctx->index_file_size > 3)
|
||||||
if (is_multiple_of_37(size) && (size > 0))
|
|
||||||
{
|
{
|
||||||
valid_file = true;
|
FRESULT fr = f_open(&IndexFile, IndexFileName, FA_READ);
|
||||||
ctx->number_of_stories = size / 37;
|
if (fr == FR_OK)
|
||||||
debug_printf("SUCCESS: found %d stories\r\n", ctx->number_of_stories);
|
{
|
||||||
|
fr = f_read(&IndexFile, IndexBuf, 3, &br);
|
||||||
|
if (fr == FR_OK)
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
debug_printf("ERROR: index.ost not found\r\n");
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
debug_printf("ERROR: index.ost not found\r\n");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -172,21 +199,6 @@ static uint8_t bmpImage[256];
|
||||||
|
|
||||||
static color_t line[320];
|
static color_t line[320];
|
||||||
|
|
||||||
file_t file_open(const char *filename)
|
|
||||||
{
|
|
||||||
#ifdef OST_USE_FF_LIBRARY
|
|
||||||
file_t fil;
|
|
||||||
FRESULT fr = f_open(&fil, filename, FA_READ);
|
|
||||||
if (fr != FR_OK)
|
|
||||||
{
|
|
||||||
debug_printf("ERROR: f_open %d\n\r", (int)fr);
|
|
||||||
}
|
|
||||||
return fil;
|
|
||||||
#else
|
|
||||||
return fopen(filename, "r");
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void filesystem_display_image(const char *filename)
|
void filesystem_display_image(const char *filename)
|
||||||
{
|
{
|
||||||
file_t fil;
|
file_t fil;
|
||||||
|
|
|
||||||
|
|
@ -2,12 +2,7 @@
|
||||||
#define FILESYSTEM_H
|
#define FILESYSTEM_H
|
||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
#include "system.h"
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
uint32_t number_of_stories;
|
|
||||||
uint32_t current_story;
|
|
||||||
} ost_context_t;
|
|
||||||
|
|
||||||
bool filesystem_read_index_file(ost_context_t *ctx);
|
bool filesystem_read_index_file(ost_context_t *ctx);
|
||||||
void filesystem_mount();
|
void filesystem_mount();
|
||||||
|
|
|
||||||
|
|
@ -133,25 +133,25 @@ void FsTask(void *args)
|
||||||
{
|
{
|
||||||
switch (FsState)
|
switch (FsState)
|
||||||
{
|
{
|
||||||
FS_PLAY_SOUND:
|
case FS_PLAY_SOUND:
|
||||||
play_sound_file(fs_ev->filename);
|
play_sound_file(fs_ev->filename);
|
||||||
FsState = FS_WAIT_FOR_EVENT;
|
FsState = FS_WAIT_FOR_EVENT;
|
||||||
break;
|
break;
|
||||||
FS_DISPLAY_IMAGE:
|
case FS_DISPLAY_IMAGE:
|
||||||
filesystem_display_image(fs_ev->filename);
|
filesystem_display_image(fs_ev->filename);
|
||||||
FsState = FS_WAIT_FOR_EVENT;
|
FsState = FS_WAIT_FOR_EVENT;
|
||||||
break;
|
break;
|
||||||
FS_LOAD_INDEX:
|
case FS_LOAD_INDEX:
|
||||||
filesystem_read_index_file(&OstContext);
|
filesystem_read_index_file(&OstContext);
|
||||||
FsState = FS_WAIT_FOR_EVENT;
|
FsState = FS_WAIT_FOR_EVENT;
|
||||||
break;
|
break;
|
||||||
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);
|
||||||
// ROM loaded, execute story
|
// ROM loaded, execute story
|
||||||
FsState = FS_WAIT_FOR_EVENT;
|
FsState = FS_WAIT_FOR_EVENT;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
FS_WAIT_FOR_EVENT:
|
case FS_WAIT_FOR_EVENT:
|
||||||
default:
|
default:
|
||||||
res = qor_mbox_wait(&FsMailBox, (void **)&fs_ev, 1000);
|
res = qor_mbox_wait(&FsMailBox, (void **)&fs_ev, 1000);
|
||||||
if (res == QOR_MBOX_OK)
|
if (res == QOR_MBOX_OK)
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
#ifndef FS_TASK_H
|
#ifndef FS_TASK_H
|
||||||
#define FS_TASK_H
|
#define FS_TASK_H
|
||||||
|
|
||||||
|
void fs_task_scan_index();
|
||||||
void fs_task_initialize();
|
void fs_task_initialize();
|
||||||
|
|
||||||
#endif // FS_TASK_H
|
#endif // FS_TASK_H
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,13 @@ typedef struct
|
||||||
uint8_t ev;
|
uint8_t ev;
|
||||||
} ost_hmi_event_t;
|
} ost_hmi_event_t;
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
OST_SYS_WAIT_INDEX,
|
||||||
|
OST_SYS_PLAY_STORY_TITLE,
|
||||||
|
OST_SYS_WAIT_USER_EVENT
|
||||||
|
} ost_system_state_t;
|
||||||
|
|
||||||
// ===========================================================================================================
|
// ===========================================================================================================
|
||||||
// GLOBAL STORY VARIABLES
|
// GLOBAL STORY VARIABLES
|
||||||
// ===========================================================================================================
|
// ===========================================================================================================
|
||||||
|
|
@ -44,6 +51,10 @@ static ost_hmi_event_t HmiEvent;
|
||||||
|
|
||||||
static ost_hmi_event_t HmiQueue[10];
|
static ost_hmi_event_t HmiQueue[10];
|
||||||
|
|
||||||
|
static ost_system_state_t OstState = OST_SYS_WAIT_INDEX;
|
||||||
|
|
||||||
|
static ost_context_t OstContext;
|
||||||
|
|
||||||
// ===========================================================================================================
|
// ===========================================================================================================
|
||||||
// HMI TASK (user interface, buttons manager, LCD)
|
// HMI TASK (user interface, buttons manager, LCD)
|
||||||
// ===========================================================================================================
|
// ===========================================================================================================
|
||||||
|
|
@ -55,6 +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();
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
|
|
@ -62,6 +74,18 @@ void HmiTask(void *args)
|
||||||
|
|
||||||
if (res == QOR_MBOX_OK)
|
if (res == QOR_MBOX_OK)
|
||||||
{
|
{
|
||||||
|
switch (OstState)
|
||||||
|
{
|
||||||
|
case OST_SYS_PLAY_STORY_TITLE:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OST_SYS_WAIT_USER_EVENT:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OST_SYS_WAIT_INDEX:
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -70,8 +94,19 @@ void HmiTask(void *args)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void hmi_task_ost_ready(uint32_t number_of_stories)
|
||||||
|
{
|
||||||
|
static ost_hmi_event_t OsReadyEv = {
|
||||||
|
.ev = OST_SYS_PLAY_STORY_TITLE};
|
||||||
|
|
||||||
|
OstContext.number_of_stories = number_of_stories;
|
||||||
|
OstContext.current_story = 0;
|
||||||
|
qor_mbox_notify(&HmiMailBox, (void **)&OsReadyEv, QOR_MBOX_OPTION_SEND_BACK);
|
||||||
|
}
|
||||||
|
|
||||||
void hmi_task_initialize()
|
void hmi_task_initialize()
|
||||||
{
|
{
|
||||||
|
OstState = OST_SYS_WAIT_INDEX;
|
||||||
qor_mbox_init(&HmiMailBox, (void **)&HmiQueue, 10);
|
qor_mbox_init(&HmiMailBox, (void **)&HmiQueue, 10);
|
||||||
|
|
||||||
qor_create_thread(&HmiTcb, HmiTask, HmiStack, sizeof(HmiStack) / sizeof(HmiStack[0]), HMI_TASK_PRIORITY, "HmiTask"); // less priority is the HMI (user inputs and LCD)
|
qor_create_thread(&HmiTcb, HmiTask, HmiStack, sizeof(HmiStack) / sizeof(HmiStack[0]), HMI_TASK_PRIORITY, "HmiTask"); // less priority is the HMI (user inputs and LCD)
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,10 @@
|
||||||
#ifndef HMI_TASK_H
|
#ifndef HMI_TASK_H
|
||||||
#define HMI_TASK_H
|
#define HMI_TASK_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
void hmi_task_initialize();
|
void hmi_task_initialize();
|
||||||
|
|
||||||
|
void hmi_task_ost_ready(uint32_t number_of_stories);
|
||||||
|
|
||||||
#endif // HMI_TASK_H
|
#endif // HMI_TASK_H
|
||||||
|
|
|
||||||
|
|
@ -102,7 +102,7 @@ qor_switch_context:
|
||||||
|
|
||||||
|
|
||||||
msr psp, r0 @ new task stack top address
|
msr psp, r0 @ new task stack top address
|
||||||
str r0, [r1] @ Save the new top of stack
|
// str r0, [r1] @ Save the new top of stack
|
||||||
|
|
||||||
subs r0, r0, #32
|
subs r0, r0, #32
|
||||||
ldmia r0!, {r4-r7}
|
ldmia r0!, {r4-r7}
|
||||||
|
|
|
||||||
|
|
@ -304,7 +304,7 @@ static SD_Error SD_ReceiveData(uint8_t *data, uint16_t len)
|
||||||
/* receive the rest of data... */
|
/* receive the rest of data... */
|
||||||
// for (i = 1; i < len; ++i)
|
// for (i = 1; i < len; ++i)
|
||||||
// data[i] = SD_SpiWriteByte(0xFF);
|
// data[i] = SD_SpiWriteByte(0xFF);
|
||||||
ost_hal_sdcard_spi_read(&data[1], len);
|
ost_hal_sdcard_spi_read(&data[1], (len - 1));
|
||||||
|
|
||||||
/* get CRC bytes (not really needed by us, but required by SD) */
|
/* get CRC bytes (not really needed by us, but required by SD) */
|
||||||
SD_SpiWriteByte(0xFF);
|
SD_SpiWriteByte(0xFF);
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,20 @@
|
||||||
#ifndef SYSTEM_H
|
#ifndef SYSTEM_H
|
||||||
#define SYSTEM_H
|
#define SYSTEM_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
// On regroupe ici au les priorités des différents threads afin d'avoir une vision plus large
|
// On regroupe ici au les priorités des différents threads afin d'avoir une vision plus large
|
||||||
#define HMI_TASK_PRIORITY 1
|
#define HMI_TASK_PRIORITY 1
|
||||||
#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
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
} ost_context_t;
|
||||||
|
|
||||||
#endif // SYSTEM_H
|
#endif // SYSTEM_H
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,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"
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,12 @@ ResourcesDock::ResourcesDock(StoryProject &project, ResourceModel &model)
|
||||||
std::filesystem::copy(p, p2, std::filesystem::copy_options::overwrite_existing);
|
std::filesystem::copy(p, p2, std::filesystem::copy_options::overwrite_existing);
|
||||||
|
|
||||||
Resource res;
|
Resource res;
|
||||||
res.format = "BMP";
|
|
||||||
|
std::string ext = p.extension();
|
||||||
|
ext.erase(ext.begin()); // remove '.' dot sign
|
||||||
|
std::transform(ext.begin(), ext.end(), ext.begin(), ::toupper);
|
||||||
|
|
||||||
|
res.format = ext;
|
||||||
res.type = "image";
|
res.type = "image";
|
||||||
res.file = p.filename().generic_string();
|
res.file = p.filename().generic_string();
|
||||||
m_resourcesModel.Append(res);
|
m_resourcesModel.Append(res);
|
||||||
|
|
@ -38,7 +43,7 @@ ResourcesDock::ResourcesDock(StoryProject &project, ResourceModel &model)
|
||||||
|
|
||||||
QString fileName = QFileDialog::getOpenFileName(this, tr("Open File"),
|
QString fileName = QFileDialog::getOpenFileName(this, tr("Open File"),
|
||||||
".",
|
".",
|
||||||
tr("Sound files (*.wav *.mp3 *.m4a)"));
|
tr("Sound files (*.wav *.mp3)"));
|
||||||
|
|
||||||
if (std::filesystem::exists(fileName.toStdString()))
|
if (std::filesystem::exists(fileName.toStdString()))
|
||||||
{
|
{
|
||||||
|
|
@ -47,7 +52,12 @@ ResourcesDock::ResourcesDock(StoryProject &project, ResourceModel &model)
|
||||||
std::filesystem::copy(p, p2, std::filesystem::copy_options::overwrite_existing);
|
std::filesystem::copy(p, p2, std::filesystem::copy_options::overwrite_existing);
|
||||||
|
|
||||||
Resource res;
|
Resource res;
|
||||||
res.format = "WAV";
|
|
||||||
|
std::string ext = p.extension();
|
||||||
|
ext.erase(ext.begin()); // remove '.' dot sign
|
||||||
|
std::transform(ext.begin(), ext.end(), ext.begin(), ::toupper);
|
||||||
|
|
||||||
|
res.format = ext;
|
||||||
res.type = "sound";
|
res.type = "sound";
|
||||||
res.file = p.filename().generic_string();
|
res.file = p.filename().generic_string();
|
||||||
m_resourcesModel.Append(res);
|
m_resourcesModel.Append(res);
|
||||||
|
|
|
||||||
|
|
@ -12,18 +12,68 @@ void StoryProject::New(const std::string &uuid, const std::string &file_path)
|
||||||
Initialize(file_path);
|
Initialize(file_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define TLV_ARRAY_TYPE 0xAB
|
||||||
|
#define TLV_OBJECT_TYPE 0xE7
|
||||||
|
#define TLV_STRING_TYPE 0x3D
|
||||||
|
|
||||||
|
|
||||||
|
class Tlv
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit Tlv(const std::string &filename)
|
||||||
|
{
|
||||||
|
m_file = std::ofstream(filename, std::ios::out | std::ios::binary);
|
||||||
|
}
|
||||||
|
|
||||||
|
~Tlv() {
|
||||||
|
m_file.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
void add_array(uint16_t size)
|
||||||
|
{
|
||||||
|
m_file.write(reinterpret_cast<const char*>(&m_objectType), sizeof(m_objectType));
|
||||||
|
m_file.write(reinterpret_cast<const char*>(&size), sizeof(size));
|
||||||
|
}
|
||||||
|
|
||||||
|
void add_string(const char *s, uint16_t size)
|
||||||
|
{
|
||||||
|
m_file.write(reinterpret_cast<const char*>(&m_stringType), sizeof(m_stringType));
|
||||||
|
m_file.write(reinterpret_cast<const char*>(&size), sizeof(size));
|
||||||
|
m_file.write(s, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void add_object(uint16_t entries)
|
||||||
|
{
|
||||||
|
m_file.write(reinterpret_cast<const char*>(&m_arrayType), sizeof(m_arrayType));
|
||||||
|
m_file.write(reinterpret_cast<const char*>(&entries), sizeof(entries));
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::ofstream m_file;
|
||||||
|
|
||||||
|
uint8_t m_arrayType = TLV_ARRAY_TYPE;
|
||||||
|
uint8_t m_objectType = TLV_OBJECT_TYPE;
|
||||||
|
uint8_t m_stringType = TLV_STRING_TYPE;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void StoryProject::SaveStory(const std::vector<uint8_t> &m_program)
|
void StoryProject::SaveStory(const std::vector<uint8_t> &m_program)
|
||||||
{
|
{
|
||||||
std::ofstream o(m_working_dir + std::filesystem::path::preferred_separator + "story.c32", std::ios::out | std::ios::binary);
|
std::ofstream o(m_working_dir + std::filesystem::path::preferred_separator + "story.c32", std::ios::out | std::ios::binary);
|
||||||
o.write(reinterpret_cast<const char*>(m_program.data()), m_program.size());
|
o.write(reinterpret_cast<const char*>(m_program.data()), m_program.size());
|
||||||
o.close();
|
o.close();
|
||||||
|
|
||||||
// Generate title files
|
|
||||||
std::ofstream index(m_working_dir + std::filesystem::path::preferred_separator + "index.ost");
|
|
||||||
index << "/" << m_uuid << "/images/" << m_titleImage << "\n";
|
|
||||||
index << "/" << m_uuid << "/sounds/" << m_titleSound << "\n";
|
|
||||||
index.close();
|
|
||||||
|
|
||||||
|
Tlv tlv(m_working_dir + std::filesystem::path::preferred_separator + "index.ost");
|
||||||
|
|
||||||
|
tlv.add_array(1);
|
||||||
|
|
||||||
|
tlv.add_object(3);
|
||||||
|
tlv.add_string(m_uuid.c_str(), m_uuid.size()); // uuid
|
||||||
|
tlv.add_string(m_titleImage.c_str(), m_titleImage.size()); // title image
|
||||||
|
tlv.add_string(m_titleSound.c_str(), m_titleSound.size()); // title sound
|
||||||
}
|
}
|
||||||
|
|
||||||
void StoryProject::Initialize(const std::string &file_path)
|
void StoryProject::Initialize(const std::string &file_path)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue