libElysianVMU 1.6.0
Full-featured, accurate, cross-platform library emulating the Dreamcast's Visual Memory Unit
Loading...
Searching...
No Matches
evmu_vmi.h
Go to the documentation of this file.
1/*! \file
2 * \ingroup file_formats
3 * \brief EvmuVmi: Decoding and encoding of the .VMI format
4 *
5 * This file contains the structure and API around
6 * managing and working with the .VMI file format,
7 * whose data is represented by the EvmuVmi structure.
8 *
9 * The .VMI format basically serves as a metadata file
10 * descriptor for .VMS files, and were used as the VMU
11 * file format with Dreamcast web browsers.
12 *
13 * A web browser would follow a link to the .VMI file,
14 * which would then point to a corresponding .VMS file,
15 * and the two together would provide enough information
16 * to load the file onto the VMU.
17 *
18 * \warning
19 * Because the .VMI file is only a metadata descriptor
20 * file, it is never standalone, as it has no real data
21 * payload of its own. It must have a corresponding VMS
22 * file.
23 *
24 * \note
25 * At the low level, the .VMI format is essentially
26 * providing the filesystem with the same information
27 * as an \ref EvmuDirEntry, such as the size of the
28 * corresponding file, its filesystem name, file type,
29 * copy protection mode, etc.
30 *
31 * \author 2023 Falco Girgis
32 * \copyright MIT License
33 *
34 * \sa evmu_vms.h
35 */
36#ifndef EVMU_VMI_H
37#define EVMU_VMI_H
38
39#include "evmu_fat.h"
40
41#include <gimbal/strings/gimbal_string_buffer.h>
42#include <gimbal/utils/gimbal_date_time.h>
43
44/*! \name Sizes and Limits
45 * \brief Sizes for EvmuVmi and its fields
46 * @{
47*/
48#define EVMU_VMI_FILE_SIZE 108 //!< Size of a .vmi file the EvmuVmi structure
49#define EVMU_VMI_DESCRIPTION_SIZE 32 //!< Size of the EvmuVmi::description field
50#define EVMU_VMI_COPYRIGHT_SIZE 32 //!< Size of the EvmuVmi::copyright field
51#define EVMU_VMI_VMS_RESOURCE_SIZE 8 //!< Size of the EvmuVmi::vmsResourceName field
52#define EVMU_VMI_VMS_NAME_SIZE 12 //!< Size of the EvmuVmi::fileNameOnVms field
53//! @}
54
55/*! \name File Mode Flags
56 * \brief Bit positions and masks for EvmuVmi::fileMode fields
57 * @{
58*/
59#define EVMU_VMI_GAME_POS 1 //!< Bit of the GAME flag within EvmuVmi::fileMode
60#define EVMU_VMI_GAME_MASK 0x2 //!< Mask of the GAME flag within EvmuVmi::fileMode
61#define EVMU_VMI_PROTECTED_POS 0 //!< Bit of the PROTECTED flag within EvmuVmi::fileMode
62#define EVMU_VMI_PROTECTED_MASK 0x1 //!< Mask of the PROTECTED flag within EvmuVmi::fileMode
63//! @}
64
65#define EVMU_VMI_VERSION 0 //!< Value of the EvmuVmi::vmiVersion field
66
67#define GBL_SELF_TYPE EvmuVmi
68
69GBL_DECLS_BEGIN
70
71GBL_FORWARD_DECLARE_STRUCT(EvmuVms);
72
73//! .VMI timestamp. Unlike EvmuTimestamp it is not stored in BCD format
74typedef struct EvmuVmiTimestamp {
75 uint16_t year; //!< Date year
76 uint8_t month; //!< Date month (1-12)
77 uint8_t day; //!< Date day (1-31)
78 uint8_t hour; //!< Time hour (0-23)
79 uint8_t minute; //!< Time minute (0-59)
80 uint8_t second; //!< Time second (0-59)
81 uint8_t weekDay; //!< Day of the week (0-6)
82} EvmuVmiTimestamp;
83
84/*! Structure of the .VMI file format
85 * \ingroup file_formats
86 *
87 * EvmuVmi offers a structure and C API around
88 * the decoded .VMI file format.
89 *
90 * \note
91 * All string fields are in Shift-JS format and
92 * are NOT NULL-terminated, hence the accessor
93 * utility methods.
94 *
95 * \sa EvmuVms
96 */
97typedef struct EvmuVmi {
98 uint32_t checksum; //!< Checksum value for entire structure
99 char description[EVMU_VMI_DESCRIPTION_SIZE]; //!< Description of VMI file string
100 char copyright[EVMU_VMI_COPYRIGHT_SIZE]; //!< Copyright information string
101 EvmuVmiTimestamp creationTimestamp; //!< File creation date
102 uint16_t vmiVersion; //!< VMI version of the file, see \ref EVMU_VMI_VERSION
103 uint16_t fileNumber; //!< File number in a series
104 char vmsResourceName[EVMU_VMI_VMS_RESOURCE_SIZE]; //!< File name of the corresponding VMS file, expected within the same directory
105 char fileNameOnVms[EVMU_VMI_VMS_NAME_SIZE]; //!< File name field within the .VMS file
106 uint16_t fileMode; //!< File mode bitfield (GAME bit + PROTECTED bit)
107 uint16_t unknown; //!< Unknown and undocumented (assumed to be 0)
108 uint32_t fileSize; //!< File size of VMS (in bytes?)
109} EvmuVmi;
110
111GBL_STATIC_ASSERT(sizeof(EvmuVmi) == EVMU_VMI_FILE_SIZE)
112
113/*! \name Read Accessors
114 * \brief Methods for reading/Calculating fields
115 * \relatesalso EvmuVmi
116 * @{
117 */
118//! Returns whether the VMI structure passes a series of validation/sanity checks on its fields
119EVMU_EXPORT GblBool EvmuVmi_isValid (GBL_CSELF) GBL_NOEXCEPT;
120//! Copies the EvmuVmi::description field to the given buffer
121EVMU_EXPORT const char* EvmuVmi_description (GBL_CSELF, GblStringBuffer* pBuff) GBL_NOEXCEPT;
122//! Copies the EvmuVmi::copyright field to the given buffer
123EVMU_EXPORT const char* EvmuVmi_copyright (GBL_CSELF, GblStringBuffer* pBuff) GBL_NOEXCEPT;
124//! Converts the EvmuVmi::creationTimestamp field to GblDateTime
125EVMU_EXPORT GblDateTime* EvmuVmi_creation (GBL_CSELF, GblDateTime* pDateTime) GBL_NOEXCEPT;
126//! Copies the EvmuVmi::vmsResourceName field to the given buffer
127EVMU_EXPORT const char* EvmuVmi_vmsResource (GBL_CSELF, GblStringBuffer* pBuff) GBL_NOEXCEPT;
128//! Copies the EvmuVmi::fileNameOnVms field to the given buffer
129EVMU_EXPORT const char* EvmuVmi_fileName (GBL_CSELF, GblStringBuffer* pbuff) GBL_NOEXCEPT;
130//! Returns whether the EvmuVmi::fileMode type field signifies a GAME file
131EVMU_EXPORT GblBool EvmuVmi_isGame (GBL_CSELF) GBL_NOEXCEPT;
132//! Returns whether the EvmuVmi::fileMode protected field signifies copy protection
133EVMU_EXPORT GblBool EvmuVmi_isProtected (GBL_CSELF) GBL_NOEXCEPT;
134//! Computes the checksum for the given VMI data
135EVMU_EXPORT uint32_t EvmuVmi_computeChecksum (GBL_CSELF) GBL_NOEXCEPT;
136//! @}
137
138/*! \name Write Accessors
139 * \brief Methods for writing to fields
140 * \relatesalso EvmuVmi
141 * @{
142 */
143//! Sets the EvmuVmi::description field to the given string, returning the number of bytes copied
144EVMU_EXPORT size_t EvmuVmi_setDescription (GBL_SELF, const char* pStr) GBL_NOEXCEPT;
145//! Sets the EvmuVmi::copyright field to the given string, returning the number of bytes copied
146EVMU_EXPORT size_t EvmuVmi_setCopyright (GBL_SELF, const char* pStr) GBL_NOEXCEPT;
147//! Sets the EvmuVmi::creationTimestamp field to the given GblDateTime value
148EVMU_EXPORT void EvmuVmi_setCreation (GBL_SELF, const GblDateTime* pDt) GBL_NOEXCEPT;
149//! Sets the EvmuVmi::vmsResourceName field to the given string, returning the number of bytes copied
150EVMU_EXPORT size_t EvmuVmi_setVmsResource (GBL_SELF, const char* pStr) GBL_NOEXCEPT;
151//! Sets the EvmuVmi::fileNameOnVms field to the given string, returning the number of bytes copied
152EVMU_EXPORT size_t EvmuVmi_setFileName (GBL_SELF, const char* pStr) GBL_NOEXCEPT;
153//! Sets the EvmuVmi::fileMode type field signifying whether or not file is a GAME
154EVMU_EXPORT void EvmuVmi_setGame (GBL_SELF, GblBool val) GBL_NOEXCEPT;
155//! Sets the EvmuVmi::fileMode protected filed to signify whether or not the file is copy protected
156EVMU_EXPORT void EvmuVmi_setProtected (GBL_SELF, GblBool val) GBL_NOEXCEPT;
157//! @}
158
159/*! \name Utilities
160 * \brief Miscellaneous methods
161 * \relatesalso EvmuVmi
162 * @{
163 */
164//! Populates the given structure by loading its contents from an external .VMI file
165EVMU_EXPORT EVMU_RESULT EvmuVmi_load (GBL_SELF, const char* pPath) GBL_NOEXCEPT;
166//! Writes the contens of the given structure to an external .VMI file
167EVMU_EXPORT EVMU_RESULT EvmuVmi_save (GBL_CSELF, const char* pPath) GBL_NOEXCEPT;
168//! Logs the fields of the VMI file to the libGimbal log system
169EVMU_EXPORT void EvmuVmi_log (GBL_CSELF) GBL_NOEXCEPT;
170//! @}
171
172/*! \name Conversions
173 * \brief Methods for going to and from EvmuVmi and related types
174 * \relatesalso EvmuVmi
175 * @{
176 */
177//! Populates the given structure from an EvmuDirEntry, also needing a pointer to EvmuFat and a VMS name
178EVMU_EXPORT EVMU_RESULT EvmuVmi_fromDirEntry (GBL_SELF,
179 const EvmuFat* pFat,
180 const EvmuDirEntry* pDirEntry,
181 const char* pVmsName) GBL_NOEXCEPT;
182//! Populates the given structure from a VMS image, needing to know whether it's a GAME file or not
183EVMU_EXPORT EVMU_RESULT EvmuVmi_fromVmsFile (GBL_SELF,
184 const void* pData,
185 size_t bytes) GBL_NOEXCEPT;
186//! Finds the path for the VMS file coresponding to the given VMI file
187EVMU_EXPORT const char* EvmuVmi_findVmsPath (GBL_CSELF,
188 const char* pVmiPath,
189 GblStringBuffer* pVmsPath) GBL_NOEXCEPT;
190//! @}
191
192GBL_DECLS_END
193
194#undef GBL_SELF_TYPE
195
196#endif // EVMU_VMI_H
#define EVMU_EXPORT
Define used for adding attributes to export public symbols.
Definition evmu_api.h:18
#define EVMU_VMI_FILE_SIZE
Size of a .vmi file the EvmuVmi structure.
Definition evmu_vmi.h:48
#define EVMU_VMI_VMS_NAME_SIZE
Definition evmu_vmi.h:52
#define EVMU_VMI_DESCRIPTION_SIZE
Size of the EvmuVmi::description field.
Definition evmu_vmi.h:49
#define EVMU_VMI_COPYRIGHT_SIZE
Size of the EvmuVmi::copyright field.
Definition evmu_vmi.h:50
#define EVMU_VMI_VMS_RESOURCE_SIZE
Size of the EvmuVmi::vmsResourceName field.
Definition evmu_vmi.h:51
Structure of the .VMI file format.
Definition evmu_vmi.h:97
const char * EvmuVmi_fileName(const EvmuVmi *pSelf, GblStringBuffer *pbuff)
Copies the EvmuVmi::fileNameOnVms field to the given buffer.
EVMU_RESULT EvmuVmi_fromVmsFile(EvmuVmi *pSelf, const void *pData, size_t bytes)
Populates the given structure from a VMS image, needing to know whether it's a GAME file or not.
uint32_t checksum
Checksum value for entire structure.
Definition evmu_vmi.h:98
size_t EvmuVmi_setVmsResource(EvmuVmi *pSelf, const char *pStr)
Sets the EvmuVmi::vmsResourceName field to the given string, returning the number of bytes copied.
GblBool EvmuVmi_isValid(const EvmuVmi *pSelf)
Returns whether the VMI structure passes a series of validation/sanity checks on its fields.
EvmuVmiTimestamp creationTimestamp
File creation date.
Definition evmu_vmi.h:101
GblDateTime * EvmuVmi_creation(const EvmuVmi *pSelf, GblDateTime *pDateTime)
Converts the EvmuVmi::creationTimestamp field to GblDateTime.
EVMU_RESULT EvmuVmi_load(EvmuVmi *pSelf, const char *pPath)
Populates the given structure by loading its contents from an external .VMI file.
size_t EvmuVmi_setDescription(EvmuVmi *pSelf, const char *pStr)
Sets the EvmuVmi::description field to the given string, returning the number of bytes copied.
size_t EvmuVmi_setFileName(EvmuVmi *pSelf, const char *pStr)
Sets the EvmuVmi::fileNameOnVms field to the given string, returning the number of bytes copied.
void EvmuVmi_setGame(EvmuVmi *pSelf, GblBool val)
Sets the EvmuVmi::fileMode type field signifying whether or not file is a GAME.
GblBool EvmuVmi_isGame(const EvmuVmi *pSelf)
Returns whether the EvmuVmi::fileMode type field signifies a GAME file.
void EvmuVmi_setCreation(EvmuVmi *pSelf, const GblDateTime *pDt)
Sets the EvmuVmi::creationTimestamp field to the given GblDateTime value.
uint16_t vmiVersion
VMI version of the file, see EVMU_VMI_VERSION.
Definition evmu_vmi.h:102
char fileNameOnVms[12]
File name field within the .VMS file.
Definition evmu_vmi.h:105
uint16_t unknown
Unknown and undocumented (assumed to be 0)
Definition evmu_vmi.h:107
void EvmuVmi_log(const EvmuVmi *pSelf)
Logs the fields of the VMI file to the libGimbal log system.
EVMU_RESULT EvmuVmi_fromDirEntry(EvmuVmi *pSelf, const EvmuFat *pFat, const EvmuDirEntry *pDirEntry, const char *pVmsName)
Populates the given structure from an EvmuDirEntry, also needing a pointer to EvmuFat and a VMS name.
uint32_t EvmuVmi_computeChecksum(const EvmuVmi *pSelf)
Computes the checksum for the given VMI data.
GblBool EvmuVmi_isProtected(const EvmuVmi *pSelf)
Returns whether the EvmuVmi::fileMode protected field signifies copy protection.
uint16_t fileNumber
File number in a series.
Definition evmu_vmi.h:103
char description[32]
Description of VMI file string.
Definition evmu_vmi.h:99
void EvmuVmi_setProtected(EvmuVmi *pSelf, GblBool val)
Sets the EvmuVmi::fileMode protected filed to signify whether or not the file is copy protected.
const char * EvmuVmi_copyright(const EvmuVmi *pSelf, GblStringBuffer *pBuff)
Copies the EvmuVmi::copyright field to the given buffer.
size_t EvmuVmi_setCopyright(EvmuVmi *pSelf, const char *pStr)
Sets the EvmuVmi::copyright field to the given string, returning the number of bytes copied.
char vmsResourceName[8]
File name of the corresponding VMS file, expected within the same directory.
Definition evmu_vmi.h:104
uint32_t fileSize
File size of VMS (in bytes?)
Definition evmu_vmi.h:108
const char * EvmuVmi_vmsResource(const EvmuVmi *pSelf, GblStringBuffer *pBuff)
Copies the EvmuVmi::vmsResourceName field to the given buffer.
const char * EvmuVmi_findVmsPath(const EvmuVmi *pSelf, const char *pVmiPath, GblStringBuffer *pVmsPath)
Finds the path for the VMS file coresponding to the given VMI file.
char copyright[32]
Copyright information string.
Definition evmu_vmi.h:100
uint16_t fileMode
File mode bitfield (GAME bit + PROTECTED bit)
Definition evmu_vmi.h:106
const char * EvmuVmi_description(const EvmuVmi *pSelf, GblStringBuffer *pBuff)
Copies the EvmuVmi::description field to the given buffer.
EVMU_RESULT EvmuVmi_save(const EvmuVmi *pSelf, const char *pPath)
Writes the contens of the given structure to an external .VMI file.
.VMI timestamp. Unlike EvmuTimestamp it is not stored in BCD format
Definition evmu_vmi.h:74
uint16_t year
Date year.
Definition evmu_vmi.h:75
uint8_t minute
Time minute (0-59)
Definition evmu_vmi.h:79
uint8_t day
Date day (1-31)
Definition evmu_vmi.h:77
uint8_t month
Date month (1-12)
Definition evmu_vmi.h:76
uint8_t second
Time second (0-59)
Definition evmu_vmi.h:80
uint8_t hour
Time hour (0-23)
Definition evmu_vmi.h:78
uint8_t weekDay
Day of the week (0-6)
Definition evmu_vmi.h:81