Add dexdrive N64 save comments support

This commit is contained in:
Raphael Assenat 2015-10-25 02:41:54 -04:00
parent 5a7ae24bb9
commit 3a65359501
4 changed files with 51 additions and 19 deletions

View File

@ -4,6 +4,7 @@
#include "mempak.h" #include "mempak.h"
#define DEXDRIVE_DATA_OFFSET 0x1040 #define DEXDRIVE_DATA_OFFSET 0x1040
#define DEXDRIVE_COMMENT_OFFSET 0x40
mempak_structure_t *mempak_new(void) mempak_structure_t *mempak_new(void)
{ {
@ -84,18 +85,18 @@ int mempak_saveToFile(mempak_structure_t *mpk, const char *dst_filename, unsigne
fclose(fptr); fclose(fptr);
return -1; return -1;
case MPK_SAVE_FORMAT_MPK: case MPK_FORMAT_MPK:
fwrite(mpk->data, sizeof(mpk->data), 1, fptr); fwrite(mpk->data, sizeof(mpk->data), 1, fptr);
break; 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);
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; break;
case MPK_SAVE_FORMAT_N64: case MPK_FORMAT_N64:
// Note: This should work well for files that will // Note: This should work well for files that will
// be imported by non-official software which typically // be imported by non-official software which typically
// only look for the 123-456-STD header and then // 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) { if (file_size == 0x8000*i) {
num_images = i+1; num_images = i+1;
printf("MPK file Contains %d image(s)\n", num_images); 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); fread(header, 11, 1, fptr);
if (0 == memcmp(header, magic, sizeof(header))) { if (0 == memcmp(header, magic, sizeof(header))) {
printf(".N64 file detected\n"); 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 /* At 0x40 there are often comments in .N64 files.
mpk->source = MPK_SRC_DEX_IMAGE; * 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;
} }
} }

View File

@ -3,21 +3,23 @@
#define MEMPAK_NUM_NOTES 16 #define MEMPAK_NUM_NOTES 16
#define MPK_SRC_RAW_IMAGE 0 #define MAX_NOTE_COMMENT_SIZE 257 // including 0 termination
#define MPK_SRC_DEX_IMAGE 1
#define MPK_FORMAT_MPK 0
#define MPK_FORMAT_MPK4 1 // MPK + 3 times 32kB padding
#define MPK_FORMAT_N64 2
typedef struct mempak_structure typedef struct mempak_structure
{ {
unsigned char data[0x8000]; 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_structure_t *mempak_new(void); mempak_structure_t *mempak_new(void);
mempak_structure_t *mempak_loadFromFile(const char *filename); 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_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); int mempak_exportNote(mempak_structure_t *mpk, int note_id, const char *dst_filename);
void mempak_free(mempak_structure_t *mpk); void mempak_free(mempak_structure_t *mpk);

View File

@ -6,9 +6,10 @@ int main(int argc, char **argv)
{ {
mempak_structure_t *mpk; mempak_structure_t *mpk;
const char *outfile; const char *outfile;
unsigned char type;
if (argc < 2) { if (argc < 2) {
printf("Usage: ./mempak_ls file\n"); printf("Usage: ./mempak_format file\n");
printf("\n"); printf("\n");
printf("Raw files (.MPK, .BIN) and Dexdrive (.N64) formats accepted.\n"); printf("Raw files (.MPK, .BIN) and Dexdrive (.N64) formats accepted.\n");
return 1; return 1;
@ -20,7 +21,8 @@ int main(int argc, char **argv)
return 1; return 1;
} }
mempak_saveToFile(mpk, outfile, MPK_SAVE_FORMAT_N64); type = MPK_FORMAT_N64;
mempak_saveToFile(mpk, outfile, type);
mempak_free(mpk); mempak_free(mpk);

View File

@ -1,4 +1,5 @@
#include <stdio.h> #include <stdio.h>
#include <string.h>
#include "mempak.h" #include "mempak.h"
int main(int argc, char **argv) int main(int argc, char **argv)
@ -21,7 +22,7 @@ int main(int argc, char **argv)
return 1; 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)) { if (0 != validate_mempak(mpk)) {
printf("Mempak invalid (not formatted or corrupted)\n"); printf("Mempak invalid (not formatted or corrupted)\n");
@ -40,9 +41,12 @@ int main(int argc, char **argv)
} else { } else {
if (note_data.valid) { if (note_data.valid) {
printf("%s (%d blocks) ", note_data.name, note_data.blocks); printf("%s (%d blocks) ", note_data.name, note_data.blocks);
printf("%08x ", note_data.vendor); // printf("%08x ", note_data.vendor);
printf("%04x ", note_data.game_id); // printf("%04x ", note_data.game_id);
printf("%02x ", note_data.region); // printf("%02x ", note_data.region);
if (strlen(mpk->note_comments[note]) > 0) {
printf("{ %s }", mpk->note_comments[note]);
}
printf("\n"); printf("\n");
} else { } else {
printf("Invalid\n"); printf("Invalid\n");