diff --git a/tool/n64savetool/mempak.c b/tool/n64savetool/mempak.c index c6cc45b..1969d71 100644 --- a/tool/n64savetool/mempak.c +++ b/tool/n64savetool/mempak.c @@ -4,6 +4,7 @@ #include "mempak.h" #define DEXDRIVE_DATA_OFFSET 0x1040 +#define DEXDRIVE_COMMENT_OFFSET 0x40 mempak_structure_t *mempak_new(void) { @@ -84,18 +85,18 @@ int mempak_saveToFile(mempak_structure_t *mpk, const char *dst_filename, unsigne fclose(fptr); return -1; - case MPK_SAVE_FORMAT_MPK: + case MPK_FORMAT_MPK: fwrite(mpk->data, sizeof(mpk->data), 1, fptr); break; - case MPK_SAVE_FORMAT_MPK4: + case MPK_FORMAT_MPK4: fwrite(mpk->data, sizeof(mpk->data), 1, fptr); fwrite(mpk->data, sizeof(mpk->data), 1, fptr); fwrite(mpk->data, sizeof(mpk->data), 1, fptr); fwrite(mpk->data, sizeof(mpk->data), 1, fptr); break; - case MPK_SAVE_FORMAT_N64: + case MPK_FORMAT_N64: // Note: This should work well for files that will // be imported by non-official software which typically // only look for the 123-456-STD header and then @@ -146,7 +147,11 @@ mempak_structure_t *mempak_loadFromFile(const char *filename) if (file_size == 0x8000*i) { num_images = i+1; printf("MPK file Contains %d image(s)\n", num_images); - mpk->source = MPK_SRC_RAW_IMAGE; + if (file_size == 0x8000) { + mpk->file_format = MPK_FORMAT_MPK; + } else { + mpk->file_format = MPK_FORMAT_MPK4; + } } } @@ -157,9 +162,28 @@ mempak_structure_t *mempak_loadFromFile(const char *filename) fread(header, 11, 1, fptr); if (0 == memcmp(header, magic, sizeof(header))) { printf(".N64 file detected\n"); - // TODO : Extract comments and other info. from the header - offset = DEXDRIVE_DATA_OFFSET; // Thanks to N-Rage`s Dinput8 Plugin sources - mpk->source = MPK_SRC_DEX_IMAGE; + + /* At 0x40 there are often comments in .N64 files. + * The actual memory card data starts at 0x1040. + * This means there are exactly 0x1000 bytes for + * one large comment, or, since 0x1000 / 256 = 16, + * more likely one comment per note? That's what + * I'm assuming here. */ + fseek(fptr, DEXDRIVE_COMMENT_OFFSET, SEEK_SET); +#if MAX_NOTE_COMMENT_SIZE != 257 +#error +#endif + for (i=0; i<16; i++) { + fread(mpk->note_comments[i], 256, 1, fptr); + /* The comments appear to be zero terminated, but I don't + * know if the original tool allowed entering a maximum + * of 256 or 255 bytes. So to be safe, I use buffers of + * 257 bytes */ + mpk->note_comments[i][256] = 0; + } + + offset = DEXDRIVE_DATA_OFFSET; + mpk->file_format = MPK_FORMAT_N64; } } diff --git a/tool/n64savetool/mempak.h b/tool/n64savetool/mempak.h index a51ecc4..dee8565 100644 --- a/tool/n64savetool/mempak.h +++ b/tool/n64savetool/mempak.h @@ -3,21 +3,23 @@ #define MEMPAK_NUM_NOTES 16 -#define MPK_SRC_RAW_IMAGE 0 -#define MPK_SRC_DEX_IMAGE 1 +#define MAX_NOTE_COMMENT_SIZE 257 // including 0 termination + +#define MPK_FORMAT_MPK 0 +#define MPK_FORMAT_MPK4 1 // MPK + 3 times 32kB padding +#define MPK_FORMAT_N64 2 typedef struct mempak_structure { unsigned char data[0x8000]; - unsigned char source; + unsigned char file_format; + + char note_comments[MEMPAK_NUM_NOTES][MAX_NOTE_COMMENT_SIZE]; } mempak_structure_t; mempak_structure_t *mempak_new(void); mempak_structure_t *mempak_loadFromFile(const char *filename); -#define MPK_SAVE_FORMAT_MPK 0 -#define MPK_SAVE_FORMAT_MPK4 1 // MPK + 3 times 32kB padding -#define MPK_SAVE_FORMAT_N64 2 int mempak_saveToFile(mempak_structure_t *mpk, const char *dst_filename, unsigned char format); int mempak_exportNote(mempak_structure_t *mpk, int note_id, const char *dst_filename); void mempak_free(mempak_structure_t *mpk); diff --git a/tool/n64savetool/mempak_format.c b/tool/n64savetool/mempak_format.c index e8958d4..7aff6a7 100644 --- a/tool/n64savetool/mempak_format.c +++ b/tool/n64savetool/mempak_format.c @@ -6,9 +6,10 @@ int main(int argc, char **argv) { mempak_structure_t *mpk; const char *outfile; + unsigned char type; if (argc < 2) { - printf("Usage: ./mempak_ls file\n"); + printf("Usage: ./mempak_format file\n"); printf("\n"); printf("Raw files (.MPK, .BIN) and Dexdrive (.N64) formats accepted.\n"); return 1; @@ -20,7 +21,8 @@ int main(int argc, char **argv) return 1; } - mempak_saveToFile(mpk, outfile, MPK_SAVE_FORMAT_N64); + type = MPK_FORMAT_N64; + mempak_saveToFile(mpk, outfile, type); mempak_free(mpk); diff --git a/tool/n64savetool/mempak_ls.c b/tool/n64savetool/mempak_ls.c index d28af6b..efc148a 100644 --- a/tool/n64savetool/mempak_ls.c +++ b/tool/n64savetool/mempak_ls.c @@ -1,4 +1,5 @@ #include +#include #include "mempak.h" int main(int argc, char **argv) @@ -21,7 +22,7 @@ int main(int argc, char **argv) return 1; } - printf("Mempak image loaded. Image type %d\n", mpk->source); + printf("Mempak image loaded. Image type %d\n", mpk->file_format); if (0 != validate_mempak(mpk)) { printf("Mempak invalid (not formatted or corrupted)\n"); @@ -40,9 +41,12 @@ int main(int argc, char **argv) } else { if (note_data.valid) { printf("%s (%d blocks) ", note_data.name, note_data.blocks); - printf("%08x ", note_data.vendor); - printf("%04x ", note_data.game_id); - printf("%02x ", note_data.region); +// printf("%08x ", note_data.vendor); +// printf("%04x ", note_data.game_id); +// printf("%02x ", note_data.region); + if (strlen(mpk->note_comments[note]) > 0) { + printf("{ %s }", mpk->note_comments[note]); + } printf("\n"); } else { printf("Invalid\n");