move quest structs and helper functions to separate c/h file

will be used elsewhere too, soon
This commit is contained in:
Gered 2021-03-20 13:44:46 -04:00
parent 7276b19e17
commit 50532638dc
5 changed files with 99 additions and 63 deletions

View file

@ -14,7 +14,7 @@ add_executable(decrypt_packets decrypt_packets.c utils.c)
target_link_libraries(decrypt_packets ${SYLVERANT_LIBRARY})
# gen_qst_header
add_executable(gen_qst_header gen_qst_header.c utils.c)
add_executable(gen_qst_header gen_qst_header.c quests.c utils.c)
target_link_libraries(gen_qst_header ${SYLVERANT_LIBRARY} ${ICONV_LIBRARIES})
target_compile_definitions(gen_qst_header PRIVATE ICONV_CONST=${ICONV_CONST})
target_include_directories(gen_qst_header PRIVATE ${ICONV_INCLUDE_DIR})

View file

@ -7,31 +7,12 @@
#include <sylverant/prs.h>
#include "utils.h"
typedef struct __attribute__((packed)) {
uint32_t object_code_offset;
uint32_t function_offset_table_offset;
uint32_t bin_size;
uint32_t xffffffff;
uint16_t language;
uint16_t quest_number;
char name[32];
char short_description[128];
char long_description[288];
} QUEST_BIN_HEADER;
typedef struct __attribute__((packed)) {
uint8_t pkt_id;
uint8_t pkt_flags;
uint16_t pkt_size;
char name[32];
uint16_t unused;
uint16_t flags;
char filename[16];
uint32_t size;
} QST_HEADER;
#include "quests.h"
int sjis_to_utf8(char *s, size_t length) {
if (!s)
return ERROR_INVALID_PARAMS;
iconv_t conv;
size_t in_size, out_size;
@ -49,49 +30,18 @@ int sjis_to_utf8(char *s, size_t length) {
memcpy(s, outbuf, length);
free(outbuf);
return 0;
return SUCCESS;
}
void generate_qst_header(const char *src_file, size_t src_file_size, QUEST_BIN_HEADER *bin_header, QST_HEADER *out_header) {
memset(out_header, 0, sizeof(QST_HEADER));
// 0xA6 = download to memcard, 0x44 = download for online play
// (quest file data chunks must then be encoded accordingly. 0xA6 = use 0xA7, and 0x44 = use 0x13)
out_header->pkt_id = 0xa6;
out_header->pkt_size = sizeof(QST_HEADER);
// khyller sets .dat header value to 0xC9, .bin header value to 0x88
// newserv sets both to 0x00
// sylverant appears to set it differently per quest, logic/reasoning is unknown to me
// ... so, this value is probably unimportant
out_header->pkt_flags = 0;
// khyller sets .dat header value to 0x02, .bin header value to 0x00
// newserv sets both to 0x02
// sylverant sets both to 0x00
// ... and so, this value is also probably unimportant
out_header->flags = 0;
out_header->size = src_file_size;
memcpy(out_header->name, bin_header->name, sizeof(out_header->name));
memcpy(out_header->filename, src_file, strlen(src_file));
}
int write_qst_header(const char *src_file, QST_HEADER *header) {
char *header_file = append_string(src_file, ".hdr");
FILE *fp = fopen(header_file, "wb");
if (!fp) {
printf("Error creating header file: %s\n", header_file);
free(header_file);
return 1;
}
int write_qst_header(const char *filename, const QST_HEADER *header) {
FILE *fp = fopen(filename, "wb");
if (!fp)
return ERROR_CREATING_FILE;
fwrite(header, sizeof(QST_HEADER), 1, fp);
fclose(fp);
free(header_file);
return SUCCESS;
}
int main(int argc, char *argv[]) {
@ -167,13 +117,17 @@ int main(int argc, char *argv[]) {
printf("Quest: id=%d, language=0x%04x, name=%s\n", bin_header->quest_number, bin_header->language, bin_header->name);
QST_HEADER qst_bin_header, qst_dat_header;
generate_qst_header(bin_base_filename, bin_compressed_size, bin_header, &qst_bin_header);
generate_qst_header(dat_base_filename, dat_compressed_size, bin_header, &qst_dat_header);
if (write_qst_header(bin_file, &qst_bin_header)) {
char *bin_hdr_file = append_string(bin_file, ".hdr");
char *dat_hdr_file = append_string(dat_file, ".hdr");
if (write_qst_header(bin_hdr_file, &qst_bin_header)) {
return 1;
}
if (write_qst_header(dat_file, &qst_dat_header)) {
if (write_qst_header(dat_hdr_file, &qst_dat_header)) {
return 1;
}

24
quests.c Normal file
View file

@ -0,0 +1,24 @@
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include "utils.h"
#include "quests.h"
int generate_qst_header(const char *src_file, size_t src_file_size, QUEST_BIN_HEADER *bin_header, QST_HEADER *out_header) {
if (!src_file || !bin_header || !out_header)
return ERROR_INVALID_PARAMS;
memset(out_header, 0, sizeof(QST_HEADER));
out_header->pkt_id = PACKET_ID_QUEST_INFO_DOWNLOAD;
out_header->pkt_size = sizeof(QST_HEADER);
out_header->pkt_flags = 0;
out_header->flags = 0;
out_header->size = src_file_size;
memcpy(out_header->name, bin_header->name, sizeof(out_header->name));
memcpy(out_header->filename, src_file, strlen(src_file));
return SUCCESS;
}

57
quests.h Normal file
View file

@ -0,0 +1,57 @@
#ifndef QUESTS_H_INCLUDED
#define QUESTS_H_INCLUDED
#include <stdio.h>
#include <stdint.h>
#define PACKET_ID_QUEST_INFO_ONLINE 0x44
#define PACKET_ID_QUEST_INFO_DOWNLOAD 0xa6
#define PACKET_ID_QUEST_CHUNK_ONLINE 0x13
#define PACKET_ID_QUEST_CHUNK_DOWNLOAD 0xa7
// quest .bin file header (after file contents have been prs-decompressed)
typedef struct __attribute__((packed)) {
uint32_t object_code_offset;
uint32_t function_offset_table_offset;
uint32_t bin_size;
uint32_t xffffffff; // always 0xffffffff ?
uint16_t language;
uint16_t quest_number;
// some sources say these strings are all UTF-16LE, but i'm not sure that is really the case for gamecube data?
// for gamecube-format quest .bin files, it instead looks like SHIFT-JIS probably ... ?
char name[32];
char short_description[128];
char long_description[288];
} QUEST_BIN_HEADER;
// .qst file header, for either the embedded bin or dat quest data
typedef struct __attribute__((packed)) {
// 0xA6 = download to memcard, 0x44 = download for online play
// (quest file data chunks must then be encoded accordingly. 0xA6 = use 0xA7, and 0x44 = use 0x13)
uint8_t pkt_id;
// khyller sets .dat header value to 0xC9, .bin header value to 0x88
// newserv sets both to 0x00
// sylverant appears to set it differently per quest, the logic/reasoning behind it is unknown to me
// ... so, this value is probably unimportant?
uint8_t pkt_flags;
uint16_t pkt_size;
char name[32];
uint16_t unused;
// khyller sets .dat header value to 0x02, .bin header value to 0x00
// newserv sets both to 0x02
// sylverant sets both to 0x00
// ... and so, this value is also probably unimportant?
uint16_t flags;
char filename[16];
uint32_t size;
} QST_HEADER;
int generate_qst_header(const char *src_file, size_t src_file_size, QUEST_BIN_HEADER *bin_header, QST_HEADER *out_header);
#endif

View file

@ -6,6 +6,7 @@
#define SUCCESS 0
#define ERROR_INVALID_PARAMS 1
#define ERROR_FILE_NOT_FOUND 2
#define ERROR_CREATING_FILE 3
int read_file(const char *filename, uint8_t** out_file_data, uint32_t *out_file_size);
int get_filesize(const char *filename, size_t *out_size);