mirror of https://github.com/mgba-emu/mgba.git
Util: Add PS Vita SFO generator
This commit is contained in:
parent
15e8b20537
commit
c49f09dabc
|
@ -0,0 +1,30 @@
|
||||||
|
/* Copyright (c) 2013-2022 Jeffrey Pfau
|
||||||
|
*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
#ifndef SFO_H
|
||||||
|
#define SFO_H
|
||||||
|
|
||||||
|
#include <mgba-util/common.h>
|
||||||
|
|
||||||
|
CXX_GUARD_START
|
||||||
|
|
||||||
|
#include <mgba-util/table.h>
|
||||||
|
|
||||||
|
void SfoInit(struct Table* sfo);
|
||||||
|
|
||||||
|
static inline void SfoDeinit(struct Table* sfo) {
|
||||||
|
HashTableDeinit(sfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct VFile;
|
||||||
|
bool SfoWrite(struct Table* sfo, struct VFile* vf);
|
||||||
|
|
||||||
|
bool SfoAddU32Value(struct Table* sfo, const char* name, uint32_t value);
|
||||||
|
bool SfoAddStrValue(struct Table* sfo, const char* name, const char* value);
|
||||||
|
bool SfoSetTitle(struct Table* sfo, const char* title);
|
||||||
|
|
||||||
|
CXX_GUARD_END
|
||||||
|
|
||||||
|
#endif
|
|
@ -21,6 +21,7 @@ set(SOURCE_FILES
|
||||||
patch-ups.c
|
patch-ups.c
|
||||||
png-io.c
|
png-io.c
|
||||||
ring-fifo.c
|
ring-fifo.c
|
||||||
|
sfo.c
|
||||||
text-codec.c)
|
text-codec.c)
|
||||||
|
|
||||||
set(GUI_FILES
|
set(GUI_FILES
|
||||||
|
@ -31,6 +32,7 @@ set(GUI_FILES
|
||||||
gui/menu.c)
|
gui/menu.c)
|
||||||
|
|
||||||
set(TEST_FILES
|
set(TEST_FILES
|
||||||
|
test/sfo.c
|
||||||
test/string-parser.c
|
test/string-parser.c
|
||||||
test/string-utf8.c
|
test/string-utf8.c
|
||||||
test/table.c
|
test/table.c
|
||||||
|
|
|
@ -0,0 +1,228 @@
|
||||||
|
/* Copyright (c) 2013-2022 Jeffrey Pfau
|
||||||
|
*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
/* This code is loosely based on vita-mksfoex.c from the vitasdk
|
||||||
|
* Copyright (c) 2015 Sergi Granell
|
||||||
|
* Copyright (c) 2015 Danielle Church
|
||||||
|
* Used under the MIT license
|
||||||
|
*
|
||||||
|
* Which itself is based on mksfoex.c from the pspsdk
|
||||||
|
* Copyright (c) 2005 adresd
|
||||||
|
* Copyright (c) 2005 Marcus R. Brown
|
||||||
|
* Copyright (c) 2005 James Forshaw
|
||||||
|
* Copyright (c) 2005 John Kelley
|
||||||
|
* Copyright (c) 2005 Jesper Svennevid
|
||||||
|
* Used under the BSD 3-clause license
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <mgba-util/common.h>
|
||||||
|
#include <mgba-util/table.h>
|
||||||
|
#include <mgba-util/vfs.h>
|
||||||
|
|
||||||
|
#define PSF_MAGIC 0x46535000
|
||||||
|
#define PSF_VERSION 0x00000101
|
||||||
|
|
||||||
|
struct SfoHeader {
|
||||||
|
uint32_t magic;
|
||||||
|
uint32_t version;
|
||||||
|
uint32_t keyofs;
|
||||||
|
uint32_t valofs;
|
||||||
|
uint32_t count;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SfoEntry {
|
||||||
|
uint16_t nameofs;
|
||||||
|
uint8_t alignment;
|
||||||
|
uint8_t type;
|
||||||
|
uint32_t valsize;
|
||||||
|
uint32_t totalsize;
|
||||||
|
uint32_t dataofs;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum PSFType {
|
||||||
|
PSF_TYPE_BIN = 0,
|
||||||
|
PSF_TYPE_STR = 2,
|
||||||
|
PSF_TYPE_U32 = 4,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SfoEntryContainer {
|
||||||
|
const char* name;
|
||||||
|
enum PSFType type;
|
||||||
|
union {
|
||||||
|
const char* str;
|
||||||
|
uint32_t u32;
|
||||||
|
} data;
|
||||||
|
uint32_t size;
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct SfoEntryContainer sfoDefaults[] = {
|
||||||
|
{ "APP_VER", PSF_TYPE_STR, { .str = "00.00" } },
|
||||||
|
{ "ATTRIBUTE", PSF_TYPE_U32, { .u32 = 0x8000 } },
|
||||||
|
{ "ATTRIBUTE2", PSF_TYPE_U32, { .u32 = 0 } },
|
||||||
|
{ "ATTRIBUTE_MINOR", PSF_TYPE_U32, { .u32 = 0x10 } },
|
||||||
|
{ "BOOT_FILE", PSF_TYPE_STR, { .str = ""}, 0x20 },
|
||||||
|
{ "CATEGORY", PSF_TYPE_STR, { .str = "gd" } },
|
||||||
|
{ "CONTENT_ID", PSF_TYPE_STR, { .str = "" }, 0x30 },
|
||||||
|
{ "EBOOT_APP_MEMSIZE", PSF_TYPE_U32, { .u32 = 0 } },
|
||||||
|
{ "EBOOT_ATTRIBUTE", PSF_TYPE_U32, { .u32 = 0 } },
|
||||||
|
{ "EBOOT_PHY_MEMSIZE", PSF_TYPE_U32, { .u32 = 0 } },
|
||||||
|
{ "LAREA_TYPE", PSF_TYPE_U32, { .u32 = 0 } },
|
||||||
|
{ "NP_COMMUNICATION_ID", PSF_TYPE_STR, { .str = "" }, 0x10 },
|
||||||
|
{ "PARENTAL_LEVEL", PSF_TYPE_U32, { .u32 = 0 } },
|
||||||
|
{ "PSP2_DISP_VER", PSF_TYPE_STR, { .str = "00.000" } },
|
||||||
|
{ "PSP2_SYSTEM_VER", PSF_TYPE_U32, { .u32 = 0 } },
|
||||||
|
{ "STITLE", PSF_TYPE_STR, { .str = "Homebrew" }, 52 },
|
||||||
|
{ "TITLE", PSF_TYPE_STR, { .str = "Homebrew" }, 0x80 },
|
||||||
|
{ "TITLE_ID", PSF_TYPE_STR, { .str = "ABCD99999" } },
|
||||||
|
{ "VERSION", PSF_TYPE_STR, { .str = "00.00" } },
|
||||||
|
};
|
||||||
|
|
||||||
|
bool SfoAddStrValue(struct Table* sfo, const char* name, const char* value) {
|
||||||
|
struct SfoEntryContainer* entry = HashTableLookup(sfo, name);
|
||||||
|
if (!entry) {
|
||||||
|
entry = calloc(1, sizeof(*entry));
|
||||||
|
if (!entry) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
entry->name = name;
|
||||||
|
HashTableInsert(sfo, name, entry);
|
||||||
|
}
|
||||||
|
entry->type = PSF_TYPE_STR;
|
||||||
|
entry->data.str = value;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SfoAddU32Value(struct Table* sfo, const char* name, uint32_t value) {
|
||||||
|
struct SfoEntryContainer* entry = HashTableLookup(sfo, name);
|
||||||
|
if (!entry) {
|
||||||
|
entry = calloc(1, sizeof(*entry));
|
||||||
|
if (!entry) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
entry->name = name;
|
||||||
|
HashTableInsert(sfo, name, entry);
|
||||||
|
}
|
||||||
|
entry->type = PSF_TYPE_U32;
|
||||||
|
entry->data.u32 = value;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SfoSetTitle(struct Table* sfo, const char* title) {
|
||||||
|
return SfoAddStrValue(sfo, "TITLE", title) && SfoAddStrValue(sfo, "STITLE", title);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SfoInit(struct Table* sfo) {
|
||||||
|
HashTableInit(sfo, 32, free);
|
||||||
|
|
||||||
|
size_t i;
|
||||||
|
for (i = 0; i < sizeof(sfoDefaults) / sizeof(sfoDefaults[0]); ++i) {
|
||||||
|
struct SfoEntryContainer* entry = calloc(1, sizeof(*entry));
|
||||||
|
memcpy(entry, &sfoDefaults[i], sizeof(*entry));
|
||||||
|
HashTableInsert(sfo, entry->name, entry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#define ALIGN4(X) (((X) + 3) & ~3)
|
||||||
|
|
||||||
|
static int _sfoSort(const void* a, const void* b) {
|
||||||
|
const struct SfoEntryContainer* ea = a;
|
||||||
|
const struct SfoEntryContainer* eb = b;
|
||||||
|
return strcmp(ea->name, eb->name);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SfoWrite(struct Table* sfo, struct VFile* vf) {
|
||||||
|
struct SfoHeader header;
|
||||||
|
size_t count = HashTableSize(sfo);
|
||||||
|
STORE_32LE(PSF_MAGIC, 0, &header.magic);
|
||||||
|
STORE_32LE(PSF_VERSION, 0, &header.version);
|
||||||
|
STORE_32LE(count, 0, &header.count);
|
||||||
|
|
||||||
|
struct TableIterator iter;
|
||||||
|
if (!TableIteratorStart(sfo, &iter)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct SfoEntryContainer* sortedEntries = calloc(count, sizeof(struct SfoEntryContainer));
|
||||||
|
|
||||||
|
uint32_t keysSize = 0;
|
||||||
|
uint32_t dataSize = 0;
|
||||||
|
size_t i = 0;
|
||||||
|
do {
|
||||||
|
memcpy(&sortedEntries[i], TableIteratorGetValue(sfo, &iter), sizeof(struct SfoEntryContainer));
|
||||||
|
keysSize += strlen(sortedEntries[i].name) + 1;
|
||||||
|
if (!sortedEntries[i].size) {
|
||||||
|
switch (sortedEntries[i].type) {
|
||||||
|
case PSF_TYPE_STR:
|
||||||
|
sortedEntries[i].size = strlen(sortedEntries[i].data.str) + 1;
|
||||||
|
break;
|
||||||
|
case PSF_TYPE_U32:
|
||||||
|
sortedEntries[i].size = 4;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dataSize += ALIGN4(sortedEntries[i].size);
|
||||||
|
++i;
|
||||||
|
} while (TableIteratorNext(sfo, &iter));
|
||||||
|
|
||||||
|
keysSize = ALIGN4(keysSize);
|
||||||
|
|
||||||
|
qsort(sortedEntries, count, sizeof(struct SfoEntryContainer), _sfoSort);
|
||||||
|
|
||||||
|
uint32_t keysOffset = 0;
|
||||||
|
uint32_t dataOffset = 0;
|
||||||
|
|
||||||
|
char* keys = calloc(1, keysSize);
|
||||||
|
char* data = calloc(1, dataSize);
|
||||||
|
|
||||||
|
struct SfoEntry* entries = calloc(count, sizeof(struct SfoEntry));
|
||||||
|
for (i = 0; i < count; ++i) {
|
||||||
|
STORE_16LE(keysOffset, 0, &entries[i].nameofs);
|
||||||
|
STORE_32LE(dataOffset, 0, &entries[i].dataofs);
|
||||||
|
entries[i].alignment = 4;
|
||||||
|
entries[i].type = sortedEntries[i].type;
|
||||||
|
|
||||||
|
strcpy(&keys[keysOffset], sortedEntries[i].name);
|
||||||
|
keysOffset += strlen(sortedEntries[i].name) + 1;
|
||||||
|
|
||||||
|
if (sortedEntries[i].type == PSF_TYPE_U32) {
|
||||||
|
STORE_32LE(4, 0, &entries[i].valsize);
|
||||||
|
STORE_32LE(4, 0, &entries[i].totalsize);
|
||||||
|
STORE_32LE(sortedEntries[i].data.u32, dataOffset, data);
|
||||||
|
dataOffset += 4;
|
||||||
|
} else {
|
||||||
|
STORE_32LE(ALIGN4(sortedEntries[i].size), 0, &entries[i].totalsize);
|
||||||
|
|
||||||
|
memset(&data[dataOffset], 0, ALIGN4(sortedEntries[i].size));
|
||||||
|
if (sortedEntries[i].data.str) {
|
||||||
|
STORE_32LE(strlen(sortedEntries[i].data.str) + 1, 0, &entries[i].valsize);
|
||||||
|
strncpy(&data[dataOffset], sortedEntries[i].data.str, sortedEntries[i].size);
|
||||||
|
} else {
|
||||||
|
STORE_32LE(sortedEntries[i].size, 0, &entries[i].valsize);
|
||||||
|
}
|
||||||
|
dataOffset += ALIGN4(sortedEntries[i].size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (keysSize != ALIGN4(keysOffset) || dataSize != dataOffset) {
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
free(sortedEntries);
|
||||||
|
|
||||||
|
STORE_32LE(count * sizeof(struct SfoEntry) + sizeof(header), 0, &header.keyofs);
|
||||||
|
STORE_32LE(count * sizeof(struct SfoEntry) + sizeof(header) + keysSize, 0, &header.valofs);
|
||||||
|
|
||||||
|
vf->write(vf, &header, sizeof(header));
|
||||||
|
vf->write(vf, entries, sizeof(entries[0]) * count);
|
||||||
|
vf->write(vf, keys, keysSize);
|
||||||
|
vf->write(vf, data, dataSize);
|
||||||
|
|
||||||
|
free(entries);
|
||||||
|
free(keys);
|
||||||
|
free(data);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
|
@ -0,0 +1,107 @@
|
||||||
|
/* Copyright (c) 2013-2022 Jeffrey Pfau
|
||||||
|
*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
#include "util/test/suite.h"
|
||||||
|
|
||||||
|
#include <mgba-util/sfo.h>
|
||||||
|
#include <mgba-util/vfs.h>
|
||||||
|
|
||||||
|
const char defaultMksfoex[] = {
|
||||||
|
0x00, 0x50, 0x53, 0x46, 0x01, 0x01, 0x00, 0x00, 0x44, 0x01, 0x00, 0x00,
|
||||||
|
0x30, 0x02, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x02,
|
||||||
|
0x06, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x08, 0x00, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
|
||||||
|
0x08, 0x00, 0x00, 0x00, 0x12, 0x00, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00,
|
||||||
|
0x04, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x04, 0x04,
|
||||||
|
0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
|
||||||
|
0x2d, 0x00, 0x04, 0x02, 0x01, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
|
||||||
|
0x14, 0x00, 0x00, 0x00, 0x37, 0x00, 0x04, 0x02, 0x03, 0x00, 0x00, 0x00,
|
||||||
|
0x04, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x40, 0x00, 0x04, 0x02,
|
||||||
|
0x01, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00,
|
||||||
|
0x4b, 0x00, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
|
||||||
|
0x68, 0x00, 0x00, 0x00, 0x5d, 0x00, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00,
|
||||||
|
0x04, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00, 0x6d, 0x00, 0x04, 0x04,
|
||||||
|
0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00,
|
||||||
|
0x7f, 0x00, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
|
||||||
|
0x74, 0x00, 0x00, 0x00, 0x8a, 0x00, 0x04, 0x02, 0x01, 0x00, 0x00, 0x00,
|
||||||
|
0x10, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x9e, 0x00, 0x04, 0x04,
|
||||||
|
0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00,
|
||||||
|
0xad, 0x00, 0x04, 0x02, 0x07, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
|
||||||
|
0x8c, 0x00, 0x00, 0x00, 0xbb, 0x00, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00,
|
||||||
|
0x04, 0x00, 0x00, 0x00, 0x94, 0x00, 0x00, 0x00, 0xcb, 0x00, 0x04, 0x02,
|
||||||
|
0x09, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00,
|
||||||
|
0xd2, 0x00, 0x04, 0x02, 0x09, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
|
||||||
|
0xcc, 0x00, 0x00, 0x00, 0xd8, 0x00, 0x04, 0x02, 0x0a, 0x00, 0x00, 0x00,
|
||||||
|
0x0c, 0x00, 0x00, 0x00, 0x4c, 0x01, 0x00, 0x00, 0xe1, 0x00, 0x04, 0x02,
|
||||||
|
0x06, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x58, 0x01, 0x00, 0x00,
|
||||||
|
0x41, 0x50, 0x50, 0x5f, 0x56, 0x45, 0x52, 0x00, 0x41, 0x54, 0x54, 0x52,
|
||||||
|
0x49, 0x42, 0x55, 0x54, 0x45, 0x00, 0x41, 0x54, 0x54, 0x52, 0x49, 0x42,
|
||||||
|
0x55, 0x54, 0x45, 0x32, 0x00, 0x41, 0x54, 0x54, 0x52, 0x49, 0x42, 0x55,
|
||||||
|
0x54, 0x45, 0x5f, 0x4d, 0x49, 0x4e, 0x4f, 0x52, 0x00, 0x42, 0x4f, 0x4f,
|
||||||
|
0x54, 0x5f, 0x46, 0x49, 0x4c, 0x45, 0x00, 0x43, 0x41, 0x54, 0x45, 0x47,
|
||||||
|
0x4f, 0x52, 0x59, 0x00, 0x43, 0x4f, 0x4e, 0x54, 0x45, 0x4e, 0x54, 0x5f,
|
||||||
|
0x49, 0x44, 0x00, 0x45, 0x42, 0x4f, 0x4f, 0x54, 0x5f, 0x41, 0x50, 0x50,
|
||||||
|
0x5f, 0x4d, 0x45, 0x4d, 0x53, 0x49, 0x5a, 0x45, 0x00, 0x45, 0x42, 0x4f,
|
||||||
|
0x4f, 0x54, 0x5f, 0x41, 0x54, 0x54, 0x52, 0x49, 0x42, 0x55, 0x54, 0x45,
|
||||||
|
0x00, 0x45, 0x42, 0x4f, 0x4f, 0x54, 0x5f, 0x50, 0x48, 0x59, 0x5f, 0x4d,
|
||||||
|
0x45, 0x4d, 0x53, 0x49, 0x5a, 0x45, 0x00, 0x4c, 0x41, 0x52, 0x45, 0x41,
|
||||||
|
0x5f, 0x54, 0x59, 0x50, 0x45, 0x00, 0x4e, 0x50, 0x5f, 0x43, 0x4f, 0x4d,
|
||||||
|
0x4d, 0x55, 0x4e, 0x49, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x49,
|
||||||
|
0x44, 0x00, 0x50, 0x41, 0x52, 0x45, 0x4e, 0x54, 0x41, 0x4c, 0x5f, 0x4c,
|
||||||
|
0x45, 0x56, 0x45, 0x4c, 0x00, 0x50, 0x53, 0x50, 0x32, 0x5f, 0x44, 0x49,
|
||||||
|
0x53, 0x50, 0x5f, 0x56, 0x45, 0x52, 0x00, 0x50, 0x53, 0x50, 0x32, 0x5f,
|
||||||
|
0x53, 0x59, 0x53, 0x54, 0x45, 0x4d, 0x5f, 0x56, 0x45, 0x52, 0x00, 0x53,
|
||||||
|
0x54, 0x49, 0x54, 0x4c, 0x45, 0x00, 0x54, 0x49, 0x54, 0x4c, 0x45, 0x00,
|
||||||
|
0x54, 0x49, 0x54, 0x4c, 0x45, 0x5f, 0x49, 0x44, 0x00, 0x56, 0x45, 0x52,
|
||||||
|
0x53, 0x49, 0x4f, 0x4e, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x2e, 0x30,
|
||||||
|
0x30, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x67, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x2e, 0x30, 0x30, 0x30, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x48, 0x6f, 0x6d, 0x65, 0x62, 0x72, 0x65, 0x77,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x6f, 0x6d, 0x65,
|
||||||
|
0x62, 0x72, 0x65, 0x77, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x41, 0x42, 0x43, 0x44, 0x39, 0x39, 0x39, 0x39,
|
||||||
|
0x39, 0x00, 0x00, 0x00, 0x30, 0x30, 0x2e, 0x30, 0x30, 0x00, 0x00, 0x00
|
||||||
|
};
|
||||||
|
|
||||||
|
M_TEST_DEFINE(defaultSfo) {
|
||||||
|
struct VFile* vf = VFileMemChunk(NULL, 0);
|
||||||
|
struct Table sfo;
|
||||||
|
SfoInit(&sfo);
|
||||||
|
SfoWrite(&sfo, vf);
|
||||||
|
SfoDeinit(&sfo);
|
||||||
|
|
||||||
|
assert_int_equal(vf->size(vf), sizeof(defaultMksfoex));
|
||||||
|
void* buffer = vf->map(vf, sizeof(defaultMksfoex), MAP_READ);
|
||||||
|
assert_memory_equal(defaultMksfoex, buffer, sizeof(defaultMksfoex));
|
||||||
|
|
||||||
|
vf->unmap(vf, buffer, sizeof(defaultMksfoex));
|
||||||
|
vf->close(vf);
|
||||||
|
}
|
||||||
|
|
||||||
|
M_TEST_SUITE_DEFINE(Sfo,
|
||||||
|
cmocka_unit_test(defaultSfo),
|
||||||
|
)
|
Loading…
Reference in New Issue