From 102afb5bd9f224295380b004b79bdbb596be424f Mon Sep 17 00:00:00 2001 From: Steveice10 <1269164+Steveice10@users.noreply.github.com> Date: Sun, 25 Jan 2015 19:04:27 -0800 Subject: [PATCH] Code cleanup. --- CMakeLists.txt | 2 +- source/3ds/3ds.h | 2 + source/3ds/cbmd.cpp | 12 +- source/3ds/cbmd.h | 4 +- source/3ds/cwav.cpp | 87 ++++---- source/3ds/cwav.h | 11 +- source/{ => 3ds}/data.h | 2 +- source/3ds/smdh.h | 14 +- source/3ds/util.cpp | 2 +- source/cmd.cpp | 342 +++++++++++++++++++++++++++++ source/{commandline.h => cmd.h} | 5 +- source/commandline.cpp | 81 ------- source/main.cpp | 260 +--------------------- source/{lodepng => pc}/lodepng.cpp | 0 source/{lodepng => pc}/lodepng.h | 0 source/{ => pc}/wav.cpp | 26 ++- source/{ => pc}/wav.h | 7 +- 17 files changed, 443 insertions(+), 414 deletions(-) rename source/{ => 3ds}/data.h (99%) create mode 100644 source/cmd.cpp rename source/{commandline.h => cmd.h} (86%) delete mode 100644 source/commandline.cpp rename source/{lodepng => pc}/lodepng.cpp (100%) rename source/{lodepng => pc}/lodepng.h (100%) rename source/{ => pc}/wav.cpp (66%) rename source/{ => pc}/wav.h (82%) diff --git a/CMakeLists.txt b/CMakeLists.txt index f51429e..053b3d6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,5 +3,5 @@ project(bannertool) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") -set(SOURCE_FILES source/main.cpp source/commandline.cpp source/wav.cpp source/3ds/cbmd.cpp source/3ds/cwav.cpp source/3ds/lz11.cpp source/3ds/util.cpp source/lodepng/lodepng.cpp) +set(SOURCE_FILES source/main.cpp source/cmd.cpp source/pc/wav.cpp source/3ds/cbmd.cpp source/3ds/cwav.cpp source/3ds/lz11.cpp source/3ds/util.cpp source/pc/lodepng.cpp) add_executable(bannertool ${SOURCE_FILES}) \ No newline at end of file diff --git a/source/3ds/3ds.h b/source/3ds/3ds.h index 7dafa99..a02a052 100644 --- a/source/3ds/3ds.h +++ b/source/3ds/3ds.h @@ -4,6 +4,8 @@ #include "cbmd.h" #include "cwav.h" #include "smdh.h" + +#include "data.h" #include "lz11.h" #include "util.h" diff --git a/source/3ds/cbmd.cpp b/source/3ds/cbmd.cpp index 778da86..221ec76 100644 --- a/source/3ds/cbmd.cpp +++ b/source/3ds/cbmd.cpp @@ -13,11 +13,11 @@ typedef struct { u32 cwavOffset = 0; } CBMDHeader; -u8* build_cbmd_data(CBMD cbmd, u32* size, bool bnr) { +u8* cbmd_build_data(CBMD cbmd, u32* size, bool bnr) { u32 headerSize = sizeof(CBMDHeader); CBMDHeader header; - u8* compressedCGFXs[14] = {0}; + u8* compressedCGFXs[14] = {NULL}; u32 compressedCGFXSizes[14] = {0}; u32 offset = headerSize; @@ -72,10 +72,10 @@ u8* build_cbmd_data(CBMD cbmd, u32* size, bool bnr) { return output; } -u8* build_cbmd(CBMD cbmd, u32* size) { - return build_cbmd_data(cbmd, size, false); +u8* cbmd_build(CBMD cbmd, u32* size) { + return cbmd_build_data(cbmd, size, false); } -u8* build_bnr(CBMD cbmd, u32* size) { - return build_cbmd_data(cbmd, size, true); +u8* bnr_build(CBMD cbmd, u32* size) { + return cbmd_build_data(cbmd, size, true); } \ No newline at end of file diff --git a/source/3ds/cbmd.h b/source/3ds/cbmd.h index 3feb4ee..384694c 100644 --- a/source/3ds/cbmd.h +++ b/source/3ds/cbmd.h @@ -27,7 +27,7 @@ typedef struct { u32 cwavSize = 0; } CBMD; -u8* build_cbmd(CBMD cbmd, u32* size); -u8* build_bnr(CBMD cbmd, u32* size); +u8* cbmd_build(CBMD cbmd, u32* size); +u8* bnr_build(CBMD cbmd, u32* size); #endif \ No newline at end of file diff --git a/source/3ds/cwav.cpp b/source/3ds/cwav.cpp index e7288b2..1323dcb 100644 --- a/source/3ds/cwav.cpp +++ b/source/3ds/cwav.cpp @@ -3,6 +3,12 @@ #include #include +typedef enum { + PCM8, + PCM16, + TODO +} CWAVType; + typedef struct { char magic[4] = {'C', 'W', 'A', 'V'}; u16 endianess = 0xFEFF; @@ -17,7 +23,7 @@ typedef struct { u32 dataChunkOffset; u32 dataChunkLength; u8 reserved[0x14] = {0}; -} Header; +} CWAVHeader; typedef struct { char magic[4] = {'I', 'N', 'F', 'O'}; @@ -28,12 +34,12 @@ typedef struct { u32 totalSamples; u32 unknown2 = 0; u32 totalChannels; -} InfoHeader; +} CWAVInfoHeader; typedef struct { u32 flags = 0x7100; u32 offset; -} ChannelDataPointer; +} CWAVChannelDataPointer; typedef struct { u32 flags = 0x1F00; @@ -41,25 +47,25 @@ typedef struct { u32 unknown3 = 0; u32 unknown4 = 0; u32 padding = 0; -} ChannelData; +} CWAVChannelData; typedef struct { char magic[4] = {'D', 'A', 'T', 'A'}; u32 length; -} DataHeader; +} CWAVDataHeader; -u8* build_cwav(WAV wav, u32* size) { - Header header; - u32 offset = sizeof(Header); +u8* cwav_build(CWAV cwav, u32* size) { + CWAVHeader header; + u32 offset = sizeof(CWAVHeader); header.infoChunkOffset = offset; - header.infoChunkLength = sizeof(InfoHeader); + header.infoChunkLength = sizeof(CWAVInfoHeader); offset += header.infoChunkLength; - offset += (sizeof(ChannelDataPointer) + sizeof(ChannelData)) * wav.format.numChannels; + offset += (sizeof(CWAVChannelDataPointer) + sizeof(CWAVChannelData)) * cwav.channels; header.dataChunkOffset = offset; - header.dataChunkLength = (u32) sizeof(DataHeader) + wav.data.chunkSize; + header.dataChunkLength = (u32) sizeof(CWAVDataHeader) + cwav.dataSize; offset += header.dataChunkLength; header.fileSize = offset; @@ -67,45 +73,46 @@ u8* build_cwav(WAV wav, u32* size) { u8* output = (u8*) malloc(offset); u32 pos = 0; - memcpy(output + pos, &header, sizeof(Header)); - pos += sizeof(Header); + memcpy(output + pos, &header, sizeof(CWAVHeader)); + pos += sizeof(CWAVHeader); - InfoHeader infoHeader; - infoHeader.type = wav.format.bitsPerSample == 16 ? 1 : 0; - infoHeader.sampleRate = wav.format.sampleRate; - infoHeader.totalSamples = wav.data.chunkSize / (wav.format.bitsPerSample / 8) / wav.format.numChannels; - infoHeader.totalChannels = wav.format.numChannels; - memcpy(output + pos, &infoHeader, sizeof(InfoHeader)); - pos += sizeof(InfoHeader); + u32 bytesPerSample = (u32) cwav.bitsPerSample / 8; - for(int i = 0; i < wav.format.numChannels; i++) { - ChannelDataPointer pointer; - pointer.offset = 0x4 + (wav.format.numChannels * (u32) sizeof(ChannelDataPointer)) + (i * (u32) sizeof(ChannelData)); - memcpy(output + pos, &pointer, sizeof(ChannelDataPointer)); - pos += sizeof(ChannelDataPointer); + CWAVInfoHeader infoHeader; + infoHeader.type = cwav.bitsPerSample == 16 ? PCM16 : PCM8; + infoHeader.sampleRate = cwav.sampleRate; + infoHeader.totalSamples = cwav.dataSize / bytesPerSample / cwav.channels; + infoHeader.totalChannels = cwav.channels; + memcpy(output + pos, &infoHeader, sizeof(CWAVInfoHeader)); + pos += sizeof(CWAVInfoHeader); + + for(int i = 0; i < cwav.channels; i++) { + CWAVChannelDataPointer pointer; + pointer.offset = 0x4 + (cwav.channels * (u32) sizeof(CWAVChannelDataPointer)) + (i * (u32) sizeof(CWAVChannelData)); + memcpy(output + pos, &pointer, sizeof(CWAVChannelDataPointer)); + pos += sizeof(CWAVChannelDataPointer); } - for(int i = 0; i < wav.format.numChannels; i++) { - ChannelData data; - data.offset = i * (wav.data.chunkSize / wav.format.numChannels); - memcpy(output + pos, &data, sizeof(ChannelData)); - pos += sizeof(ChannelData); + u32 bytesPerChannel = cwav.dataSize / cwav.channels; + for(int i = 0; i < cwav.channels; i++) { + CWAVChannelData data; + data.offset = i * bytesPerChannel; + memcpy(output + pos, &data, sizeof(CWAVChannelData)); + pos += sizeof(CWAVChannelData); } - DataHeader dataHeader; - dataHeader.length = (u32) sizeof(DataHeader) + wav.data.chunkSize; - memcpy(output + pos, &dataHeader, sizeof(DataHeader)); - pos += sizeof(DataHeader); + CWAVDataHeader dataHeader; + dataHeader.length = (u32) sizeof(CWAVDataHeader) + cwav.dataSize; + memcpy(output + pos, &dataHeader, sizeof(CWAVDataHeader)); + pos += sizeof(CWAVDataHeader); - u32 bytesPerChannel = wav.data.chunkSize / wav.format.numChannels; - u32 bytesPerSample = (u32) wav.format.bitsPerSample / 8; - for(int i = 0; i < wav.data.chunkSize; i += wav.format.numChannels * bytesPerSample) { - for(int c = 0; c < wav.format.numChannels; c++) { - memcpy(output + pos + (bytesPerChannel * c) + (i / wav.format.numChannels), wav.dataBytes + i + (c * bytesPerSample), bytesPerSample); + for(int i = 0; i < cwav.dataSize; i += cwav.channels * bytesPerSample) { + for(int c = 0; c < cwav.channels; c++) { + memcpy(output + pos + (bytesPerChannel * c) + (i / cwav.channels), cwav.data + i + (c * bytesPerSample), bytesPerSample); } } - pos += wav.data.chunkSize; + pos += cwav.dataSize; if(size != NULL) { *size = pos; diff --git a/source/3ds/cwav.h b/source/3ds/cwav.h index ffe3741..cc04a07 100644 --- a/source/3ds/cwav.h +++ b/source/3ds/cwav.h @@ -2,8 +2,15 @@ #define __CWAV_H__ #include "../types.h" -#include "../wav.h" -u8* build_cwav(WAV wav, u32* size); +typedef struct { + u32 channels; + u32 sampleRate; + u32 bitsPerSample; + u32 dataSize; + u8* data; +} CWAV; + +u8* cwav_build(CWAV wav, u32* size); #endif \ No newline at end of file diff --git a/source/data.h b/source/3ds/data.h similarity index 99% rename from source/data.h rename to source/3ds/data.h index edf549e..664ba7d 100644 --- a/source/data.h +++ b/source/3ds/data.h @@ -1,7 +1,7 @@ #ifndef __DATA_H__ #define __DATA_H__ -#include "types.h" +#include "../types.h" u8 BANNER_CGFX_HEADER[0x1580] = { 0x43, 0x47, 0x46, 0x58, 0xFF, 0xFE, 0x14, 0x00, 0x00, 0x00, 0x00, 0x05, 0x80, 0x15, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x44, 0x41, 0x54, 0x41, 0xE4, 0x14, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x74, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x98, 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, 0x44, 0x49, 0x43, 0x54, 0x2C, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xB0, 0x0F, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x44, 0x49, 0x43, 0x54, 0x2C, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x8B, 0x0F, 0x00, 0x00, 0x24, 0x0F, 0x00, 0x00, 0x92, 0x00, 0x00, 0x40, 0x43, 0x4D, 0x44, 0x4C, 0x00, 0x00, 0x00, 0x07, 0x70, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3F, 0x00, 0x00, 0x80, 0x3F, 0x00, 0x00, 0x80, 0x3F, 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, 0x80, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x0D, 0x00, 0x00, 0x68, 0x06, 0x00, 0x00, 0x74, 0x0B, 0x00, 0x00, 0x44, 0x49, 0x43, 0x54, 0x4C, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x7B, 0x0E, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x96, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x7D, 0x0E, 0x00, 0x00, 0xC4, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x00, 0x03, 0x00, 0x01, 0x00, 0x81, 0x0E, 0x00, 0x00, 0x74, 0x01, 0x00, 0x00, 0x44, 0x49, 0x43, 0x54, 0x2C, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x67, 0x0E, 0x00, 0x00, 0x6C, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x1F, 0x0E, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x44, 0x49, 0x43, 0x54, 0x2C, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x1D, 0x0E, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x11, 0x0E, 0x00, 0x00, 0x0D, 0x0E, 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, 0xED, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0xAD, 0x0D, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x49, 0x43, 0x54, 0x3C, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xA0, 0x0D, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x96, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x9A, 0x0D, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x84, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD4, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x62, 0x0D, 0x00, 0x00, 0x72, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0D, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x44, 0x49, 0x43, 0x54, 0x2C, 0x01, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x01, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0xF4, 0x0C, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x5E, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x12, 0x0D, 0x00, 0x00, 0x24, 0x01, 0x00, 0x00, 0x5C, 0x01, 0x00, 0x00, 0x03, 0x00, 0x02, 0x00, 0x2F, 0x0D, 0x00, 0x00, 0x44, 0x01, 0x00, 0x00, 0x6D, 0x01, 0x00, 0x00, 0x01, 0x00, 0x0A, 0x00, 0x4C, 0x0D, 0x00, 0x00, 0x64, 0x01, 0x00, 0x00, 0x68, 0x01, 0x00, 0x00, 0x06, 0x00, 0x07, 0x00, 0x6B, 0x0D, 0x00, 0x00, 0x84, 0x01, 0x00, 0x00, 0x62, 0x01, 0x00, 0x00, 0x04, 0x00, 0x06, 0x00, 0x8A, 0x0D, 0x00, 0x00, 0xA4, 0x01, 0x00, 0x00, 0x62, 0x01, 0x00, 0x00, 0x05, 0x00, 0x07, 0x00, 0xA9, 0x0D, 0x00, 0x00, 0xC4, 0x01, 0x00, 0x00, 0x69, 0x01, 0x00, 0x00, 0x05, 0x00, 0x09, 0x00, 0xC8, 0x0D, 0x00, 0x00, 0xE4, 0x01, 0x00, 0x00, 0x68, 0x01, 0x00, 0x00, 0x08, 0x00, 0x09, 0x00, 0xE7, 0x0D, 0x00, 0x00, 0x04, 0x02, 0x00, 0x00, 0x6A, 0x01, 0x00, 0x00, 0x08, 0x00, 0x0B, 0x00, 0x06, 0x0E, 0x00, 0x00, 0x24, 0x02, 0x00, 0x00, 0x68, 0x01, 0x00, 0x00, 0x0A, 0x00, 0x0B, 0x00, 0x25, 0x0E, 0x00, 0x00, 0x44, 0x02, 0x00, 0x00, 0xDE, 0x01, 0x00, 0x00, 0x11, 0x00, 0x0C, 0x00, 0x44, 0x0E, 0x00, 0x00, 0x64, 0x02, 0x00, 0x00, 0x7E, 0x01, 0x00, 0x00, 0x04, 0x00, 0x0D, 0x00, 0x71, 0x0E, 0x00, 0x00, 0x88, 0x02, 0x00, 0x00, 0x0E, 0x02, 0x00, 0x00, 0x0C, 0x00, 0x0E, 0x00, 0x92, 0x0E, 0x00, 0x00, 0xAC, 0x02, 0x00, 0x00, 0x96, 0x01, 0x00, 0x00, 0x0D, 0x00, 0x0F, 0x00, 0xC5, 0x0E, 0x00, 0x00, 0xCC, 0x02, 0x00, 0x00, 0x9E, 0x01, 0x00, 0x00, 0x0F, 0x00, 0x10, 0x00, 0xE9, 0x0E, 0x00, 0x00, 0xF0, 0x02, 0x00, 0x00, 0xB6, 0x01, 0x00, 0x00, 0x10, 0x00, 0x11, 0x00, 0x0E, 0x0F, 0x00, 0x00, 0x14, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xE8, 0x0B, 0x00, 0x00, 0xB3, 0x0B, 0x00, 0x00, 0x32, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x93, 0x0B, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xE6, 0x0B, 0x00, 0x00, 0x83, 0x0B, 0x00, 0x00, 0x02, 0x0F, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x0B, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xE3, 0x0B, 0x00, 0x00, 0x53, 0x0B, 0x00, 0x00, 0xD2, 0x0E, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x0B, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xE0, 0x0B, 0x00, 0x00, 0x23, 0x0B, 0x00, 0x00, 0xA2, 0x0E, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x0B, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xDF, 0x0B, 0x00, 0x00, 0xF3, 0x0A, 0x00, 0x00, 0x72, 0x0E, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD3, 0x0A, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xDE, 0x0B, 0x00, 0x00, 0xC3, 0x0A, 0x00, 0x00, 0x42, 0x0E, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA3, 0x0A, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xDD, 0x0B, 0x00, 0x00, 0x93, 0x0A, 0x00, 0x00, 0x12, 0x0E, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x73, 0x0A, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xDC, 0x0B, 0x00, 0x00, 0x63, 0x0A, 0x00, 0x00, 0xE2, 0x0D, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0x0A, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xDB, 0x0B, 0x00, 0x00, 0x33, 0x0A, 0x00, 0x00, 0xB2, 0x0D, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x0A, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xDA, 0x0B, 0x00, 0x00, 0x03, 0x0A, 0x00, 0x00, 0x82, 0x0D, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE3, 0x09, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xD9, 0x0B, 0x00, 0x00, 0xD3, 0x09, 0x00, 0x00, 0x52, 0x0D, 0x00, 0x00, 0xA0, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB3, 0x09, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xD8, 0x0B, 0x00, 0x00, 0xA3, 0x09, 0x00, 0x00, 0x30, 0x0D, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0xE1, 0x0B, 0x00, 0x00, 0x6F, 0x09, 0x00, 0x00, 0x16, 0x0D, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4F, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xDE, 0x0B, 0x00, 0x00, 0x3B, 0x09, 0x00, 0x00, 0xF4, 0x0C, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x09, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xF1, 0x0B, 0x00, 0x00, 0x0B, 0x09, 0x00, 0x00, 0xE5, 0x0C, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xEB, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xF1, 0x0B, 0x00, 0x00, 0xD7, 0x08, 0x00, 0x00, 0xB1, 0x0C, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB7, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xF2, 0x0B, 0x00, 0x00, 0xA3, 0x08, 0x00, 0x00, 0x7D, 0x0C, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x53, 0x4F, 0x42, 0x4A, 0x00, 0x00, 0x00, 0x00, 0x60, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x94, 0xF8, 0xFF, 0xFF, 0x01, 0x00, 0xFF, 0xFF, 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, 0xFC, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x4D, 0x54, 0x4F, 0x42, 0x00, 0x00, 0x00, 0x06, 0xEB, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3F, 0x00, 0x00, 0x80, 0x3F, 0x00, 0x00, 0x80, 0x3F, 0x00, 0x00, 0x80, 0x3F, 0x00, 0x00, 0x80, 0x3F, 0x00, 0x00, 0x80, 0x3F, 0x00, 0x00, 0x80, 0x3F, 0x00, 0x00, 0x80, 0x3F, 0x00, 0x00, 0x80, 0x3F, 0x00, 0x00, 0x80, 0x3F, 0x00, 0x00, 0x80, 0x3F, 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, 0x80, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3F, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x41, 0x00, 0x00, 0x00, 0x07, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03, 0x26, 0x01, 0x08, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3F, 0x00, 0x01, 0xE4, 0x00, 0x00, 0x01, 0x3F, 0x80, 0x00, 0x00, 0x76, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x01, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x01, 0x0F, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3F, 0x00, 0x00, 0x80, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3F, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3F, 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, 0x80, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3F, 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, 0x80, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xCD, 0xE5, 0x5D, 0xDA, 0x5E, 0x65, 0x75, 0x3B, 0xF4, 0xF7, 0x3D, 0xF4, 0x22, 0x5B, 0xE7, 0x9A, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x70, 0xF7, 0x66, 0xF4, 0xC8, 0x6A, 0xC0, 0x31, 0x9C, 0x09, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x5E, 0x65, 0x75, 0x3B, 0x6C, 0x01, 0x82, 0x35, 0xF8, 0x02, 0x01, 0x64, 0xA2, 0x01, 0xF2, 0xCD, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8E, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x81, 0x00, 0x9F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x06, 0x22, 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, 0x38, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x54, 0x58, 0x4F, 0x42, 0x00, 0x00, 0x00, 0x05, 0xBC, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7B, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x90, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x80, 0x53, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x05, 0x7C, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x71, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xCC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x0E, 0x30, 0x0E, 0xC0, 0x00, 0x4F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x0E, 0x1F, 0x0E, 0xC8, 0x00, 0x4F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x0E, 0x1F, 0x0E, 0xD0, 0x00, 0x4F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x0E, 0x1F, 0x0E, 0xD8, 0x00, 0x4F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x0E, 0x1F, 0x0E, 0xF0, 0x00, 0x4F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x0E, 0x1F, 0x0E, 0xF8, 0x00, 0x4F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x01, 0x0F, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFD, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x00, 0x02, 0x00, 0x00, 0x04, 0x00, 0x00, 0xC3, 0x01, 0x02, 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, 0x01, 0x00, 0x00, 0x10, 0x53, 0x4F, 0x42, 0x4A, 0x00, 0x00, 0x00, 0x00, 0x50, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0xA4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xBF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3F, 0x00, 0x00, 0xD0, 0x41, 0x00, 0x00, 0x50, 0x41, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x14, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0xEC, 0x06, 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, 0x02, 0x00, 0x00, 0x40, 0x15, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0xBC, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x40, 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, 0x06, 0x14, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x40, 0x04, 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, 0x06, 0x14, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3F, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x53, 0x4F, 0x42, 0x4A, 0x00, 0x00, 0x00, 0x00, 0xC4, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x44, 0x49, 0x43, 0x54, 0x2C, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x95, 0x01, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x8D, 0x01, 0x00, 0x00, 0xDC, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3F, 0x00, 0x00, 0x80, 0x3F, 0x00, 0x00, 0x80, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3F, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x3F, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0xBF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x20, 0x54, 0x58, 0x4F, 0x42, 0x00, 0x00, 0x00, 0x05, 0x57, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x52, 0x67, 0x00, 0x00, 0x33, 0x80, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x2C, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0x4F, 0x4D, 0x4D, 0x4F, 0x4E, 0x00, 0x43, 0x4F, 0x4D, 0x4D, 0x4F, 0x4E, 0x31, 0x00, 0x53, 0x6B, 0x65, 0x6C, 0x65, 0x74, 0x61, 0x6C, 0x41, 0x6E, 0x69, 0x6D, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x00, 0x56, 0x69, 0x73, 0x69, 0x62, 0x69, 0x6C, 0x69, 0x74, 0x79, 0x41, 0x6E, 0x69, 0x6D, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x00, 0x4D, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6C, 0x41, 0x6E, 0x69, 0x6D, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x00, 0x6D, 0x74, 0x5F, 0x62, 0x61, 0x6E, 0x6E, 0x65, 0x72, 0x00, 0x62, 0x61, 0x6E, 0x6E, 0x65, 0x72, 0x00, 0x49, 0x73, 0x56, 0x69, 0x73, 0x69, 0x62, 0x6C, 0x65, 0x00, 0x4D, 0x65, 0x73, 0x68, 0x65, 0x73, 0x5B, 0x30, 0x5D, 0x2E, 0x49, 0x73, 0x56, 0x69, 0x73, 0x69, 0x62, 0x6C, 0x65, 0x00, 0x30, 0x00, 0x4D, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6C, 0x73, 0x5B, 0x22, 0x6D, 0x74, 0x5F, 0x62, 0x61, 0x6E, 0x6E, 0x65, 0x72, 0x22, 0x5D, 0x2E, 0x4D, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6C, 0x43, 0x6F, 0x6C, 0x6F, 0x72, 0x2E, 0x45, 0x6D, 0x69, 0x73, 0x73, 0x69, 0x6F, 0x6E, 0x00, 0x4D, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6C, 0x73, 0x5B, 0x22, 0x6D, 0x74, 0x5F, 0x62, 0x61, 0x6E, 0x6E, 0x65, 0x72, 0x22, 0x5D, 0x2E, 0x4D, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6C, 0x43, 0x6F, 0x6C, 0x6F, 0x72, 0x2E, 0x41, 0x6D, 0x62, 0x69, 0x65, 0x6E, 0x74, 0x00, 0x4D, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6C, 0x73, 0x5B, 0x22, 0x6D, 0x74, 0x5F, 0x62, 0x61, 0x6E, 0x6E, 0x65, 0x72, 0x22, 0x5D, 0x2E, 0x4D, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6C, 0x43, 0x6F, 0x6C, 0x6F, 0x72, 0x2E, 0x44, 0x69, 0x66, 0x66, 0x75, 0x73, 0x65, 0x00, 0x4D, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6C, 0x73, 0x5B, 0x22, 0x6D, 0x74, 0x5F, 0x62, 0x61, 0x6E, 0x6E, 0x65, 0x72, 0x22, 0x5D, 0x2E, 0x4D, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6C, 0x43, 0x6F, 0x6C, 0x6F, 0x72, 0x2E, 0x53, 0x70, 0x65, 0x63, 0x75, 0x6C, 0x61, 0x72, 0x30, 0x00, 0x4D, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6C, 0x73, 0x5B, 0x22, 0x6D, 0x74, 0x5F, 0x62, 0x61, 0x6E, 0x6E, 0x65, 0x72, 0x22, 0x5D, 0x2E, 0x4D, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6C, 0x43, 0x6F, 0x6C, 0x6F, 0x72, 0x2E, 0x53, 0x70, 0x65, 0x63, 0x75, 0x6C, 0x61, 0x72, 0x31, 0x00, 0x4D, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6C, 0x73, 0x5B, 0x22, 0x6D, 0x74, 0x5F, 0x62, 0x61, 0x6E, 0x6E, 0x65, 0x72, 0x22, 0x5D, 0x2E, 0x4D, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6C, 0x43, 0x6F, 0x6C, 0x6F, 0x72, 0x2E, 0x43, 0x6F, 0x6E, 0x73, 0x74, 0x61, 0x6E, 0x74, 0x30, 0x00, 0x4D, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6C, 0x73, 0x5B, 0x22, 0x6D, 0x74, 0x5F, 0x62, 0x61, 0x6E, 0x6E, 0x65, 0x72, 0x22, 0x5D, 0x2E, 0x4D, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6C, 0x43, 0x6F, 0x6C, 0x6F, 0x72, 0x2E, 0x43, 0x6F, 0x6E, 0x73, 0x74, 0x61, 0x6E, 0x74, 0x31, 0x00, 0x4D, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6C, 0x73, 0x5B, 0x22, 0x6D, 0x74, 0x5F, 0x62, 0x61, 0x6E, 0x6E, 0x65, 0x72, 0x22, 0x5D, 0x2E, 0x4D, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6C, 0x43, 0x6F, 0x6C, 0x6F, 0x72, 0x2E, 0x43, 0x6F, 0x6E, 0x73, 0x74, 0x61, 0x6E, 0x74, 0x32, 0x00, 0x4D, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6C, 0x73, 0x5B, 0x22, 0x6D, 0x74, 0x5F, 0x62, 0x61, 0x6E, 0x6E, 0x65, 0x72, 0x22, 0x5D, 0x2E, 0x4D, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6C, 0x43, 0x6F, 0x6C, 0x6F, 0x72, 0x2E, 0x43, 0x6F, 0x6E, 0x73, 0x74, 0x61, 0x6E, 0x74, 0x33, 0x00, 0x4D, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6C, 0x73, 0x5B, 0x22, 0x6D, 0x74, 0x5F, 0x62, 0x61, 0x6E, 0x6E, 0x65, 0x72, 0x22, 0x5D, 0x2E, 0x4D, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6C, 0x43, 0x6F, 0x6C, 0x6F, 0x72, 0x2E, 0x43, 0x6F, 0x6E, 0x73, 0x74, 0x61, 0x6E, 0x74, 0x34, 0x00, 0x4D, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6C, 0x73, 0x5B, 0x22, 0x6D, 0x74, 0x5F, 0x62, 0x61, 0x6E, 0x6E, 0x65, 0x72, 0x22, 0x5D, 0x2E, 0x4D, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6C, 0x43, 0x6F, 0x6C, 0x6F, 0x72, 0x2E, 0x43, 0x6F, 0x6E, 0x73, 0x74, 0x61, 0x6E, 0x74, 0x35, 0x00, 0x4D, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6C, 0x73, 0x5B, 0x22, 0x6D, 0x74, 0x5F, 0x62, 0x61, 0x6E, 0x6E, 0x65, 0x72, 0x22, 0x5D, 0x2E, 0x54, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x4D, 0x61, 0x70, 0x70, 0x65, 0x72, 0x73, 0x5B, 0x30, 0x5D, 0x2E, 0x53, 0x61, 0x6D, 0x70, 0x6C, 0x65, 0x72, 0x2E, 0x42, 0x6F, 0x72, 0x64, 0x65, 0x72, 0x43, 0x6F, 0x6C, 0x6F, 0x72, 0x00, 0x4D, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6C, 0x73, 0x5B, 0x22, 0x6D, 0x74, 0x5F, 0x62, 0x61, 0x6E, 0x6E, 0x65, 0x72, 0x22, 0x5D, 0x2E, 0x54, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x4D, 0x61, 0x70, 0x70, 0x65, 0x72, 0x73, 0x5B, 0x30, 0x5D, 0x2E, 0x54, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x00, 0x4D, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6C, 0x73, 0x5B, 0x22, 0x6D, 0x74, 0x5F, 0x62, 0x61, 0x6E, 0x6E, 0x65, 0x72, 0x22, 0x5D, 0x2E, 0x46, 0x72, 0x61, 0x67, 0x6D, 0x65, 0x6E, 0x74, 0x4F, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x2E, 0x42, 0x6C, 0x65, 0x6E, 0x64, 0x4F, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x2E, 0x42, 0x6C, 0x65, 0x6E, 0x64, 0x43, 0x6F, 0x6C, 0x6F, 0x72, 0x00, 0x4D, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6C, 0x73, 0x5B, 0x22, 0x6D, 0x74, 0x5F, 0x62, 0x61, 0x6E, 0x6E, 0x65, 0x72, 0x22, 0x5D, 0x2E, 0x54, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x43, 0x6F, 0x6F, 0x72, 0x64, 0x69, 0x6E, 0x61, 0x74, 0x6F, 0x72, 0x73, 0x5B, 0x30, 0x5D, 0x2E, 0x53, 0x63, 0x61, 0x6C, 0x65, 0x00, 0x4D, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6C, 0x73, 0x5B, 0x22, 0x6D, 0x74, 0x5F, 0x62, 0x61, 0x6E, 0x6E, 0x65, 0x72, 0x22, 0x5D, 0x2E, 0x54, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x43, 0x6F, 0x6F, 0x72, 0x64, 0x69, 0x6E, 0x61, 0x74, 0x6F, 0x72, 0x73, 0x5B, 0x30, 0x5D, 0x2E, 0x52, 0x6F, 0x74, 0x61, 0x74, 0x65, 0x00, 0x4D, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6C, 0x73, 0x5B, 0x22, 0x6D, 0x74, 0x5F, 0x62, 0x61, 0x6E, 0x6E, 0x65, 0x72, 0x22, 0x5D, 0x2E, 0x54, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x43, 0x6F, 0x6F, 0x72, 0x64, 0x69, 0x6E, 0x61, 0x74, 0x6F, 0x72, 0x73, 0x5B, 0x30, 0x5D, 0x2E, 0x54, 0x72, 0x61, 0x6E, 0x73, 0x6C, 0x61, 0x74, 0x65, 0x00, 0x4D, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6C, 0x43, 0x6F, 0x6C, 0x6F, 0x72, 0x00, 0x54, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x4D, 0x61, 0x70, 0x70, 0x65, 0x72, 0x73, 0x5B, 0x30, 0x5D, 0x2E, 0x53, 0x61, 0x6D, 0x70, 0x6C, 0x65, 0x72, 0x00, 0x54, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x4D, 0x61, 0x70, 0x70, 0x65, 0x72, 0x73, 0x5B, 0x30, 0x5D, 0x00, 0x46, 0x72, 0x61, 0x67, 0x6D, 0x65, 0x6E, 0x74, 0x4F, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x2E, 0x42, 0x6C, 0x65, 0x6E, 0x64, 0x4F, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x00, 0x54, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x43, 0x6F, 0x6F, 0x72, 0x64, 0x69, 0x6E, 0x61, 0x74, 0x6F, 0x72, 0x73, 0x5B, 0x30, 0x5D, 0x00, 0x00, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6C, 0x74, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 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, 0x49, 0x4D, 0x41, 0x47, 0x88, 0x00, 0x01, 0x00, 0x00, 0x01, 0x02, 0x01, 0x03, 0x02, 0x00, 0x00, 0x00, 0x00, 0x50, 0xC1, 0x00, 0x00, 0xF0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x41, 0x00, 0x00, 0xF0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0xC1, 0x00, 0x00, 0xB0, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3F, 0x00, 0x00, 0x50, 0x41, 0x00, 0x00, 0xB0, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3F, 0x00, 0x00, 0x80, 0x3F, 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 }; u32 BANNER_CGFX_HEADER_LENGTH = 0x1580; diff --git a/source/3ds/smdh.h b/source/3ds/smdh.h index 564caec..c245763 100644 --- a/source/3ds/smdh.h +++ b/source/3ds/smdh.h @@ -18,12 +18,6 @@ typedef enum { TRADITIONAL_CHINESE } SMDHTitleLanguage; -typedef struct { - u16 shortDescription[0x40] = {0}; - u16 longDescription[0x80] = {0}; - u16 publisher[0x40] = {0}; -} SMDHTitle; - // TODO: Provide values to set ratings to. typedef enum { CERO = 0, @@ -47,7 +41,7 @@ typedef enum { TAIWAN = 0x40, // Not a bitmask, but a value. - REGION_FREE = 0x7FFFFFFF + REGION_FREE = 0x7FFFFFFF } SMDHRegionFlag; typedef enum { @@ -63,6 +57,12 @@ typedef enum { DISABLE_SAVE_BACKUPS = 0x0400 } SMDHFlag; +typedef struct { + u16 shortDescription[0x40] = {0}; + u16 longDescription[0x80] = {0}; + u16 publisher[0x40] = {0}; +} SMDHTitle; + typedef struct { u8 gameRatings[0x10] = {0}; u32 regionLock = REGION_FREE; diff --git a/source/3ds/util.cpp b/source/3ds/util.cpp index ded3509..849a4fc 100644 --- a/source/3ds/util.cpp +++ b/source/3ds/util.cpp @@ -1,6 +1,6 @@ #include "util.h" -#include "../lodepng/lodepng.h" +#include "../pc/lodepng.h" u8 TILE_ORDER[64] = { 0, 1, 8, 9, 2, 3, 10, 11, 16, 17, 24, 25, 18, 19, 26, 27, 4, 5, 12, 13, 6, 7, 14, 15, 20, 21, 28, 29, 22, 23, 30, 31, diff --git a/source/cmd.cpp b/source/cmd.cpp new file mode 100644 index 0000000..9b72457 --- /dev/null +++ b/source/cmd.cpp @@ -0,0 +1,342 @@ +#include "cmd.h" + +#include "3ds/3ds.h" +#include "pc/wav.h" +#include "types.h" + +u8* convert_to_cgfx(const char* image, u32 width, u32 height, u32* size) { + u32 convertedSize = 0; + u16* converted = image_to_tiles(image, width, height, RGBA4444, &convertedSize); + if(converted == NULL) { + return NULL; + } + + u8* ret = (u8*) malloc(BANNER_CGFX_HEADER_LENGTH + convertedSize); + memcpy(ret, BANNER_CGFX_HEADER, BANNER_CGFX_HEADER_LENGTH); + memcpy(ret + BANNER_CGFX_HEADER_LENGTH, converted, convertedSize); + + *size = BANNER_CGFX_HEADER_LENGTH + convertedSize; + return ret; +} + +u8* convert_to_cwav(const char* file, u32* size) { + WAV* wav = wav_read(file); + if(!wav) { + return NULL; + } + + CWAV cwav; + cwav.channels = wav->format.numChannels; + cwav.sampleRate = wav->format.sampleRate; + cwav.bitsPerSample = wav->format.bitsPerSample; + cwav.dataSize = wav->data.chunkSize; + cwav.data = wav->data.data; + + u8* ret = cwav_build(cwav, size); + + wav_free(wav); + + return ret; +} + +int cmd_make_banner(const char* image, const char* audio, char* cgfxFile, char* cwavFile, const char* output) { + u32 cgfxSize = 0; + u8* cgfx = NULL; + if(cgfxFile != NULL) { + FILE* fd = fopen(cgfxFile, "r"); + if(!fd) { + printf("ERROR: Could not open CGFX file: %s\n", strerror(errno)); + } + + fseek(fd, 0, SEEK_END); + cgfxSize = (u32) ftell(fd); + fseek(fd, 0, SEEK_SET); + + cgfx = (u8*) malloc(cgfxSize); + fread(cgfx, 1, cgfxSize, fd); + fclose(fd); + } else { + cgfx = convert_to_cgfx(image, 256, 128, &cgfxSize); + if(!cgfx) { + return 1; + } + } + + u32 cwavSize = 0; + u8* cwav = NULL; + if(cwavFile != NULL) { + FILE* fd = fopen(cwavFile, "r"); + if(!fd) { + printf("ERROR: Could not open CWAV file: %s\n", strerror(errno)); + } + + fseek(fd, 0, SEEK_END); + cwavSize = (u32) ftell(fd); + fseek(fd, 0, SEEK_SET); + + cwav = (u8*) malloc(cwavSize); + fread(cwav, 1, cwavSize, fd); + fclose(fd); + } else { + cwav = convert_to_cwav(audio, &cwavSize); + if(!cwav) { + return 2; + } + } + + CBMD cbmd; + cbmd.cgfxs[CGFX_COMMON] = cgfx; + cbmd.cgfxSizes[CGFX_COMMON] = cgfxSize; + cbmd.cwav = cwav; + cbmd.cwavSize = cwavSize; + + u32 bnrSize = 0; + u8* bnr = bnr_build(cbmd, &bnrSize); + free(cgfx); + free(cwav); + + FILE* fd = fopen(output, "wb"); + if(!fd) { + printf("ERROR: Could not open output file: %s\n", strerror(errno)); + return 3; + } + + fwrite(bnr, 1, bnrSize, fd); + fclose(fd); + + free(bnr); + + printf("Created banner \"%s\".\n", output); + return 0; +} + +int cmd_make_smdh(char* shortDescription, char* longDescription, char* publisher, char* icon, char* output) { + u16* icon48 = image_to_tiles(icon, 48, 48, RGB565, NULL); + if(icon48 == NULL) { + return 1; + } + + u16 icon24[24 * 24]; + for(int y = 0; y < 24; y++) { + for(int x = 0; x < 24; x++) { + icon24[y * 24 + x] = icon48[y * 48 + x]; + } + } + + SMDH smdh; + for(int i = 0; i < 0x10; i++) { + utf8_to_utf16(smdh.titles[i].shortDescription, shortDescription, 0x40); + utf8_to_utf16(smdh.titles[i].longDescription, longDescription, 0x80); + utf8_to_utf16(smdh.titles[i].publisher, publisher, 0x40); + } + + memcpy(smdh.largeIcon, icon48, 0x1200); + memcpy(smdh.smallIcon, icon24, 0x480); + free(icon48); + + FILE* fd = fopen(output, "wb"); + if(!fd) { + printf("ERROR: Could not open output file: %s\n", strerror(errno)); + return 2; + } + + fwrite(&smdh, 1, sizeof(SMDH), fd); + fclose(fd); + + printf("Created SMDH \"%s\".\n", output); + return 0; +} + +int cmd_make_cwav(char* input, char* output) { + u32 cwavSize = 0; + u8* cwav = convert_to_cwav(input, &cwavSize); + if(!cwav) { + return 1; + } + + FILE* fd = fopen(output, "wb"); + if(!fd) { + printf("ERROR: Could not open output file: %s\n", strerror(errno)); + return 2; + } + + fwrite(cwav, 1, cwavSize, fd); + fclose(fd); + + free(cwav); + + printf("Created CWAV \"%s\".\n", output); + return 0; +} + +int cmd_lz11(char* input, char* output) { + FILE* in = fopen(input, "r"); + if(!in) { + printf("ERROR: Could not open input file: %s\n", strerror(errno)); + return 1; + } + + fseek(in, 0, SEEK_END); + u32 size = (u32) ftell(in); + fseek(in, 0, SEEK_SET); + + u8 data[size]; + fread(data, 1, size, in); + fclose(in); + + u32 compressedSize; + u8* compressed = lz11_compress(data, size, &compressedSize); + if(!compressed) { + return 2; + } + + FILE* fd = fopen(output, "wb"); + if(!fd) { + printf("ERROR: Could not open output file: %s\n", strerror(errno)); + return 3; + } + + fwrite(compressed, 1, compressedSize, fd); + fclose(fd); + + free(compressed); + + printf("Compressed to file \"%s\".\n", output); + return 0; +} + +std::map cmd_get_args(int argc, char* argv[]) { + std::map args; + for(int i = 0; i < argc; i++) { + if((strncmp(argv[i], "-", 1) == 0 || strncmp(argv[i], "--", 2) == 0) && argc != i + 1) { + args.insert(std::pair(argv[i], argv[i + 1])); + i++; + } + } + + return args; +} + +char* cmd_find_arg(std::map args, const char* shortOpt, const char* longOpt) { + char sopt[strlen(shortOpt) + 2]; + sprintf(sopt, "-%s", shortOpt); + char lopt[strlen(longOpt) + 3]; + sprintf(lopt, "--%s", longOpt); + + std::map::iterator match = args.find(sopt); + if(match != args.end()) { + return (*match).second; + } + + match = args.find(lopt); + if(match != args.end()) { + return (*match).second; + } + + return NULL; +} + +void cmd_print_usage(const char* executedFrom) { + printf("Usage: %s \n", executedFrom); + cmd_print_commands(); +} + +void cmd_print_info(const char* command) { + if(strcmp(command, "makebanner") == 0) { + printf("makebanner - Creates a .bnr file.\n"); + printf(" -i/--image: PNG file to use as the banner's image. Interchangeable with -ci.\n"); + printf(" -a/--audio: WAV file to use as the banner's tune. Interchangeable with -ca.\n"); + printf(" -ci/--cgfximage: CGFX file to use as the banner's image. Interchangeable with -i.\n"); + printf(" -ca/--cwavaudio: CWAV file to use as the banner's tune. Interchangeable with -a.\n"); + printf(" -o/--output: File to output the created banner to.\n"); + } else if(strcmp(command, "makesmdh") == 0) { + printf("makesmdh - Creates a .smdh/.icn file.\n"); + printf(" -s/--shortdescription: Short description of the application.\n"); + printf(" -l/--longdescription: Long description of the application.\n"); + printf(" -p/--publisher: Publisher of the application.\n"); + printf(" -i/--icon: PNG file to use as an icon.\n"); + printf(" -o/--output: File to output the created SMDH/ICN to.\n"); + } else if(strcmp(command, "makecwav") == 0) { + printf("makecwav - Creates a CWAV file from a WAV.\n"); + printf(" -i/--input: WAV file to convert.\n"); + printf(" -o/--output: File to output the created CWAV to.\n"); + } else if(strcmp(command, "lz11") == 0) { + printf("lz11 - Compresses a file with LZ11.\n"); + printf(" -i/--input: File to compress.\n"); + printf(" -o/--output: File to output the compressed data to.\n"); + } +} + +void cmd_print_commands() { + printf("Available commands:\n"); + cmd_print_info("makebanner"); + cmd_print_info("makesmdh"); + cmd_print_info("makecwav"); + cmd_print_info("lz11"); +} + +void cmd_missing_args(const char* command) { + printf("Missing arguments for command \"%s\".\n", command); + cmd_print_info(command); +} + +void cmd_invalid_command(const char* command) { + printf("Invalid command \"%s\".\n", command); + cmd_print_commands(); +} + +int cmd_process_command(int argc, char* argv[]) { + if(argc < 2) { + cmd_print_usage(argv[0]); + return -1; + } + + char* command = argv[1]; + std::map args = cmd_get_args(argc, argv); + if(strcmp(command, "makebanner") == 0) { + char *banner = cmd_find_arg(args, "i", "image"); + char *audio = cmd_find_arg(args, "a", "audio"); + char *cgfxFile = cmd_find_arg(args, "ci", "cgfximage"); + char *cwavFile = cmd_find_arg(args, "ca", "cwavaudio"); + char *output = cmd_find_arg(args, "o", "output"); + if(!(banner || cgfxFile) || !(audio || cwavFile) || !output) { + cmd_missing_args(command); + return -1; + } + + return cmd_make_banner(banner, audio, cgfxFile, cwavFile, output); + } else if(strcmp(command, "makesmdh") == 0) { + char* shortDescription = cmd_find_arg(args, "s", "shortdescription"); + char* longDescription = cmd_find_arg(args, "l", "longdescription"); + char* publisher = cmd_find_arg(args, "p", "publisher"); + char* icon = cmd_find_arg(args, "i", "icon"); + char* output = cmd_find_arg(args, "o", "output"); + if(!shortDescription || !longDescription || !publisher || !icon || !output) { + cmd_missing_args(command); + return -1; + } + + return cmd_make_smdh(shortDescription, longDescription, publisher, icon, output); + } else if(strcmp(command, "makecwav") == 0) { + char* input = cmd_find_arg(args, "i", "input"); + char* output = cmd_find_arg(args, "o", "output"); + if(!input || !output) { + cmd_missing_args(command); + return -1; + } + + return cmd_make_cwav(input, output); + } else if(strcmp(command, "lz11") == 0) { + char* input = cmd_find_arg(args, "i", "input"); + char* output = cmd_find_arg(args, "o", "output"); + if(!input || !output) { + cmd_missing_args(command); + return -1; + } + + return cmd_lz11(input, output); + } else { + cmd_invalid_command(command); + return -1; + } +} \ No newline at end of file diff --git a/source/commandline.h b/source/cmd.h similarity index 86% rename from source/commandline.h rename to source/cmd.h index 64f6d8e..dc74bd9 100644 --- a/source/commandline.h +++ b/source/cmd.h @@ -1,5 +1,5 @@ -#ifndef __COMMANDLINE_H__ -#define __COMMANDLINE_H__ +#ifndef __CMD_H__ +#define __CMD_H__ #include @@ -18,5 +18,6 @@ void cmd_print_info(const char* command); void cmd_print_commands(); void cmd_missing_args(const char* command); void cmd_invalid_command(const char* command); +int cmd_process_command(int argc, char* argv[]); #endif \ No newline at end of file diff --git a/source/commandline.cpp b/source/commandline.cpp deleted file mode 100644 index 6826a1c..0000000 --- a/source/commandline.cpp +++ /dev/null @@ -1,81 +0,0 @@ -#include "commandline.h" - -std::map cmd_get_args(int argc, char* argv[]) { - std::map args; - for(int i = 0; i < argc; i++) { - if((strncmp(argv[i], "-", 1) == 0 || strncmp(argv[i], "--", 2) == 0) && argc != i + 1) { - args.insert(std::pair(argv[i], argv[i + 1])); - i++; - } - } - - return args; -} - -char* cmd_find_arg(std::map args, const char* shortOpt, const char* longOpt) { - char sopt[strlen(shortOpt) + 2]; - sprintf(sopt, "-%s", shortOpt); - char lopt[strlen(longOpt) + 3]; - sprintf(lopt, "--%s", longOpt); - - std::map::iterator match = args.find(sopt); - if(match != args.end()) { - return (*match).second; - } - - match = args.find(lopt); - if(match != args.end()) { - return (*match).second; - } - - return NULL; -} - -void cmd_print_usage(const char* executedFrom) { - printf("Usage: %s \n", executedFrom); - cmd_print_commands(); -} - -void cmd_print_info(const char* command) { - if(strcmp(command, "makebanner") == 0) { - printf("makebanner - Creates a .bnr file.\n"); - printf(" -i/--image: PNG file to use as the banner's image. Interchangeable with -ci.\n"); - printf(" -a/--audio: WAV file to use as the banner's tune. Interchangeable with -ca.\n"); - printf(" -ci/--cgfximage: CGFX file to use as the banner's image. Interchangeable with -i.\n"); - printf(" -ca/--cwavaudio: CWAV file to use as the banner's tune. Interchangeable with -a.\n"); - printf(" -o/--output: File to output the created banner to.\n"); - } else if(strcmp(command, "makesmdh") == 0) { - printf("makesmdh - Creates a .smdh/.icn file.\n"); - printf(" -s/--shortdescription: Short description of the application.\n"); - printf(" -l/--longdescription: Long description of the application.\n"); - printf(" -p/--publisher: Publisher of the application.\n"); - printf(" -i/--icon: PNG file to use as an icon.\n"); - printf(" -o/--output: File to output the created SMDH/ICN to.\n"); - } else if(strcmp(command, "makecwav") == 0) { - printf("makecwav - Creates a CWAV file from a WAV.\n"); - printf(" -i/--input: WAV file to convert.\n"); - printf(" -o/--output: File to output the created CWAV to.\n"); - } else if(strcmp(command, "lz11") == 0) { - printf("lz11 - Compresses a file with LZ11.\n"); - printf(" -i/--input: File to compress.\n"); - printf(" -o/--output: File to output the compressed data to.\n"); - } -} - -void cmd_print_commands() { - printf("Available commands:\n"); - cmd_print_info("makebanner"); - cmd_print_info("makesmdh"); - cmd_print_info("makecwav"); - cmd_print_info("lz11"); -} - -void cmd_missing_args(const char* command) { - printf("Missing arguments for command \"%s\".\n", command); - cmd_print_info(command); -} - -void cmd_invalid_command(const char* command) { - printf("Invalid command \"%s\".\n", command); - cmd_print_commands(); -} \ No newline at end of file diff --git a/source/main.cpp b/source/main.cpp index da25379..ccc7319 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -1,261 +1,5 @@ -#include "3ds/3ds.h" -#include "commandline.h" -#include "data.h" -#include "types.h" -#include "wav.h" -#include "3ds/smdh.h" - -#include -#include -#include - -u8* convert_to_cgfx(const char* image, u32 width, u32 height, u32* size) { - u32 convertedSize = 0; - u16* converted = image_to_tiles(image, width, height, RGBA4444, &convertedSize); - if(converted == NULL) { - return NULL; - } - - u8* ret = (u8*) malloc(BANNER_CGFX_HEADER_LENGTH + convertedSize); - memcpy(ret, BANNER_CGFX_HEADER, BANNER_CGFX_HEADER_LENGTH); - memcpy(ret + BANNER_CGFX_HEADER_LENGTH, converted, convertedSize); - - *size = BANNER_CGFX_HEADER_LENGTH + convertedSize; - return ret; -} - -u8* convert_to_cwav(const char* file, u32* size) { - WAV* wav = read_wav(file); - if(!wav) { - return NULL; - } - - u8* cwav = build_cwav(*wav, size); - - free(wav->dataBytes); - free(wav); - - return cwav; -} - -int make_banner(const char* image, const char* audio, char* cgfxFile, char* cwavFile, const char* output) { - u32 cgfxSize = 0; - u8* cgfx = NULL; - if(cgfxFile != NULL) { - FILE* fd = fopen(cgfxFile, "r"); - if(!fd) { - printf("ERROR: Could not open CGFX file: %s\n", strerror(errno)); - } - - fseek(fd, 0, SEEK_END); - cgfxSize = (u32) ftell(fd); - fseek(fd, 0, SEEK_SET); - - cgfx = (u8*) malloc(cgfxSize); - fread(cgfx, 1, cgfxSize, fd); - fclose(fd); - } else { - cgfx = convert_to_cgfx(image, 256, 128, &cgfxSize); - if(!cgfx) { - return 1; - } - } - - u32 cwavSize = 0; - u8* cwav = NULL; - if(cwavFile != NULL) { - FILE* fd = fopen(cwavFile, "r"); - if(!fd) { - printf("ERROR: Could not open CWAV file: %s\n", strerror(errno)); - } - - fseek(fd, 0, SEEK_END); - cwavSize = (u32) ftell(fd); - fseek(fd, 0, SEEK_SET); - - cwav = (u8*) malloc(cwavSize); - fread(cwav, 1, cwavSize, fd); - fclose(fd); - } else { - cwav = convert_to_cwav(audio, &cwavSize); - if(!cwav) { - return 2; - } - } - - CBMD cbmd; - cbmd.cgfxs[CGFX_COMMON] = cgfx; - cbmd.cgfxSizes[CGFX_COMMON] = cgfxSize; - cbmd.cwav = cwav; - cbmd.cwavSize = cwavSize; - - u32 bnrSize = 0; - u8* bnr = build_bnr(cbmd, &bnrSize); - free(cgfx); - free(cwav); - - FILE* fd = fopen(output, "wb"); - if(!fd) { - printf("ERROR: Could not open output file: %s\n", strerror(errno)); - return 3; - } - - fwrite(bnr, 1, bnrSize, fd); - fclose(fd); - - free(bnr); - - printf("Created banner \"%s\".\n", output); - return 0; -} - -int make_smdh(char* shortDescription, char* longDescription, char* publisher, char* icon, char* output) { - u16* icon48 = image_to_tiles(icon, 48, 48, RGB565, NULL); - if(icon48 == NULL) { - return 1; - } - - u16 icon24[24 * 24]; - for(int y = 0; y < 24; y++) { - for(int x = 0; x < 24; x++) { - icon24[y * 24 + x] = icon48[y * 48 + x]; - } - } - - SMDH smdh; - for(int i = 0; i < 0x10; i++) { - utf8_to_utf16(smdh.titles[i].shortDescription, shortDescription, 0x40); - utf8_to_utf16(smdh.titles[i].longDescription, longDescription, 0x80); - utf8_to_utf16(smdh.titles[i].publisher, publisher, 0x40); - } - - memcpy(smdh.largeIcon, icon48, 0x1200); - memcpy(smdh.smallIcon, icon24, 0x480); - free(icon48); - - FILE* fd = fopen(output, "wb"); - if(!fd) { - printf("ERROR: Could not open output file: %s\n", strerror(errno)); - return 2; - } - - fwrite(&smdh, 1, sizeof(SMDH), fd); - fclose(fd); - - printf("Created SMDH \"%s\".\n", output); - return 0; -} - -int make_cwav(char* input, char* output) { - u32 cwavSize = 0; - u8* cwav = convert_to_cwav(input, &cwavSize); - if(!cwav) { - return 1; - } - - FILE* fd = fopen(output, "wb"); - if(!fd) { - printf("ERROR: Could not open output file: %s\n", strerror(errno)); - return 2; - } - - fwrite(cwav, 1, cwavSize, fd); - fclose(fd); - - free(cwav); - - printf("Created CWAV \"%s\".\n", output); - return 0; -} - -int lz11(char* input, char* output) { - FILE* in = fopen(input, "r"); - if(!in) { - printf("ERROR: Could not open input file: %s\n", strerror(errno)); - return 1; - } - - fseek(in, 0, SEEK_END); - u32 size = (u32) ftell(in); - fseek(in, 0, SEEK_SET); - - u8 data[size]; - fread(data, 1, size, in); - fclose(in); - - u32 compressedSize; - u8* compressed = lz11_compress(data, size, &compressedSize); - if(!compressed) { - return 2; - } - - FILE* fd = fopen(output, "wb"); - if(!fd) { - printf("ERROR: Could not open output file: %s\n", strerror(errno)); - return 3; - } - - fwrite(compressed, 1, compressedSize, fd); - fclose(fd); - - free(compressed); - - printf("Compressed to file \"%s\".\n", output); - return 0; -} +#include "cmd.h" int main(int argc, char* argv[]) { - if(argc < 2) { - cmd_print_usage(argv[0]); - return -1; - } - - char* command = argv[1]; - std::map args = cmd_get_args(argc, argv); - if(strcmp(command, "makebanner") == 0) { - char *banner = cmd_find_arg(args, "i", "image"); - char *audio = cmd_find_arg(args, "a", "audio"); - char *cgfxFile = cmd_find_arg(args, "ci", "cgfximage"); - char *cwavFile = cmd_find_arg(args, "ca", "cwavaudio"); - char *output = cmd_find_arg(args, "o", "output"); - if(!(banner || cgfxFile) || !(audio || cwavFile) || !output) { - cmd_missing_args(command); - return -1; - } - - return make_banner(banner, audio, cgfxFile, cwavFile, output); - } else if(strcmp(command, "makesmdh") == 0) { - char* shortDescription = cmd_find_arg(args, "s", "shortdescription"); - char* longDescription = cmd_find_arg(args, "l", "longdescription"); - char* publisher = cmd_find_arg(args, "p", "publisher"); - char* icon = cmd_find_arg(args, "i", "icon"); - char* output = cmd_find_arg(args, "o", "output"); - if(!shortDescription || !longDescription || !publisher || !icon || !output) { - cmd_missing_args(command); - return -1; - } - - return make_smdh(shortDescription, longDescription, publisher, icon, output); - } else if(strcmp(command, "makecwav") == 0) { - char* input = cmd_find_arg(args, "i", "input"); - char* output = cmd_find_arg(args, "o", "output"); - if(!input || !output) { - cmd_missing_args(command); - return -1; - } - - return make_cwav(input, output); - } else if(strcmp(command, "lz11") == 0) { - char* input = cmd_find_arg(args, "i", "input"); - char* output = cmd_find_arg(args, "o", "output"); - if(!input || !output) { - cmd_missing_args(command); - return -1; - } - - return lz11(input, output); - } else { - cmd_invalid_command(command); - return -1; - } + return cmd_process_command(argc, argv); } \ No newline at end of file diff --git a/source/lodepng/lodepng.cpp b/source/pc/lodepng.cpp similarity index 100% rename from source/lodepng/lodepng.cpp rename to source/pc/lodepng.cpp diff --git a/source/lodepng/lodepng.h b/source/pc/lodepng.h similarity index 100% rename from source/lodepng/lodepng.h rename to source/pc/lodepng.h diff --git a/source/wav.cpp b/source/pc/wav.cpp similarity index 66% rename from source/wav.cpp rename to source/pc/wav.cpp index d3852fc..04a2a19 100644 --- a/source/wav.cpp +++ b/source/pc/wav.cpp @@ -5,7 +5,7 @@ #include #include -bool find_chunk(FILE* fd, const char* magic) { +bool wav_find_chunk(FILE* fd, const char* magic) { char curr[5] = {0}; while(strcmp(curr, magic) != 0) { u32 read = (u32) fread(curr, 1, 4, fd); @@ -18,14 +18,14 @@ bool find_chunk(FILE* fd, const char* magic) { return true; } -WAV* read_wav(const char* file) { +WAV* wav_read(const char* file) { FILE* fd = fopen(file, "r"); if(!fd) { printf("ERROR: Could not open WAV file: %s\n", strerror(errno)); return NULL; } - if(!find_chunk(fd, "RIFF")) { + if(!wav_find_chunk(fd, "RIFF")) { printf("ERROR: Could not find WAV RIFF chunk.\n"); return NULL; } @@ -33,7 +33,7 @@ WAV* read_wav(const char* file) { Riff riff; fread(&riff, sizeof(Riff), 1, fd); - if(!find_chunk(fd, "fmt ")) { + if(!wav_find_chunk(fd, "fmt ")) { printf("ERROR: Could not find WAV format chunk.\n"); return NULL; } @@ -41,16 +41,16 @@ WAV* read_wav(const char* file) { Format format; fread(&format, sizeof(Format), 1, fd); - if(!find_chunk(fd, "data")) { + if(!wav_find_chunk(fd, "data")) { printf("ERROR: Could not find WAV data chunk.\n"); return NULL; } Data data; - fread(&data, sizeof(Data), 1, fd); - - u8* dataBytes = (u8*) malloc(data.chunkSize); - fread(dataBytes, 1, data.chunkSize, fd); + fread(&(data.chunkId), sizeof(data.chunkId), 1, fd); + fread(&(data.chunkSize), sizeof(data.chunkSize), 1, fd); + data.data = (u8*) malloc(data.chunkSize); + fread(data.data, 1, data.chunkSize, fd); fclose(fd); @@ -58,6 +58,12 @@ WAV* read_wav(const char* file) { wav->riff = riff; wav->format = format; wav->data = data; - wav->dataBytes = dataBytes; return wav; +} + +void wav_free(WAV* wav) { + if(wav != NULL) { + free(wav->data.data); + free(wav); + } } \ No newline at end of file diff --git a/source/wav.h b/source/pc/wav.h similarity index 82% rename from source/wav.h rename to source/pc/wav.h index d0a7d96..b82531c 100644 --- a/source/wav.h +++ b/source/pc/wav.h @@ -1,7 +1,7 @@ #ifndef __WAV_H__ #define __WAV_H__ -#include "types.h" +#include "../types.h" typedef struct { char chunkId[4]; @@ -23,15 +23,16 @@ typedef struct { typedef struct { char chunkId[4]; u32 chunkSize; + u8* data; } Data; typedef struct { Riff riff; Format format; Data data; - u8* dataBytes; } WAV; -WAV* read_wav(const char* file); +WAV* wav_read(const char* file); +void wav_free(WAV* wav); #endif \ No newline at end of file