It is currently Fri Aug 18, 2017 11:28 am

All times are UTC - 7 hours





Post new topic Reply to topic  [ 1 post ] 
Author Message
PostPosted: Tue Apr 10, 2007 8:44 pm 
Offline
User avatar

Joined: Tue Jul 12, 2005 4:37 pm
Posts: 121
こんな物を見付けないので、今日はこれを書きました。ソースコードです:

【Cで書いて、MinGWでコンパイルをしました。ファイルの名は「fdsinfo.c」です。】

Code:
/*

FDS Infolizer
Written by Beneficii on April 10, 2007--finished at 10:38 PM CDT (GMT -05)
beneficii@gmail.com

Prints information about an FDS file stored in fwNES format; also can output
files from the FDS disks to your file system
You might want to use redirection ">filename" to redirect the standard output of
this program
Parameters:
    fdsinfo     program filename
    fds-file    filename of FDS file to read
    -o          adding this tells the program to output the files from the FDS
                (optional)
    base dir    provides a base directory to store the output files
                (optional; defaults to current console window directory)
   
When this saves the files, it creates a directory for each of the disks and puts
the files in their respective disks' directories

^_^ Special thanks to Nori's and Brad Taylor's Docs ^_^
^_^ And the wonderful people at nesdev.com and acmlm.no-ip.org ^_^

*/

#include <stdio.h>
#include <string.h>
#include <dir.h>

#define START_ADDRESS     0x10
#define DISK_SIZE         (size_t) 65500
#define DISK_HEADER       41
#define FILE_AMOUNT       1
#define FILE_HEADER       15
#define F(e,b)            sprintf(e, "Bad format at %s!\n", b);
#define S(e)              sprintf(e, "Bad file size!\n");
#define ERROR(c,s,e,f,n)  \
if(c) { \
    fclose(f); \
    s \
    perror(e); \
    return (n); \
}
#define FP(c,e,b,f)       ERROR(c, F(e,b), e, f, 4)
#define SP(c,e,f)         ERROR(c, S(e), e, f, 5)
#define COMP_CONDITION1   ((ftell(in)-START_ADDRESS) / DISK_SIZE != nodisks)
#define COMP_CONDITION2   ((ftell(in)-START_ADDRESS) % DISK_SIZE)

typedef unsigned char data;

const char title[]     = "fdsinfo <fds-file> [-o [base directory]]\n\
\t-o\toutput fds files\n\n";
const char fds_check[] = "FDS\x1a";
const char hvc_check[] = "*NINTENDO-HVC*";
const char *strings[] = {
    "10-Byte Check",
    "Manufacture Code",
    "Game Name",
    "Game Version Number",
    "Side Number",
    "Disk Number",
    "Err. 9",
    "Err. 10",
    "Boot Read File Code",
    "Manufacture Permit Date (?)",
    "Create Date",
};
const char *fstrings[] = {
    "File Number",
    "File ID Code",
    "Filename",
    "File (Memory) Address",
    "File Size",
    "File Kind",
};
const char *fkinds[] = {
    "Program (PRAM)",
    "Character (CRAM)",
    "Name Table (VRAM)",
};
/* starting byte of each piece of info from disk header starting with first
   byte after *NINTENDO-HVC* */
const int  dstart[] = {0, 0, 1, 5, 6, 7, 8, 9, 10, 16, 29};
const int  fstart[] = {0, 1, 2, 10, 12, 14};
const char sides[]  = {'A', 'B'};

void buildspacebuffer(char *buff, int num) {
int i;
     for(i = 0; i < num; i++) {
           buff[i] = ' ';
     }
     if(num < 0) num = 0;
     buff[num] = '\0';
}

int main(int argc, char **argv) {
    int outfiles = 0, nodisks = 0, i = 0, j = 0, k = 0, cflag = 0,
      dirflag = 0, dircheck = 0;
    size_t memstart = 0, outsize = 0;
    data input[DISK_SIZE];
    data *ptr = NULL;
    FILE *in = NULL, *out = NULL;
    char error[300], space[50], filename[9], fileout[350];
    if(argc < 2) {
        printf(title);
        return 0;
    }
    if(argc > 4) {
        printf(title);
        perror("Too many parameters!\n");
        return 1;
    }
    in = fopen(argv[1], "rb");
    if(in == NULL) {
        perror("Bad filename!\n");
        return 2;
    }
    if(argc >= 3) {
        if(strcmp("-o", argv[2])) {
            fclose(in);
            printf(title);
            perror("Bad parameter after file!\n");
            return 3;
        }
        outfiles = 1;
    }
    if(argc==4) {
        dircheck = chdir(argv[3]);
        if(dircheck < 0) {
            dircheck = mkdir(argv[3]);
            if(dircheck < 0) {
                perror("Could not create base directory.  Cannot write files.\n");
                outfiles = 0;
            } else {
                dircheck = chdir(argv[3]);
                if(dircheck < 0) {
                    perror("Could not switch to base directory. Cannot write files.\n");
                    outfiles = 0;
                }
            }
        }   
    }
    /* deal with fwNES header and total size check */
    SP(fread(input, sizeof(data), strlen(fds_check), in)!=strlen(fds_check), error, in)
    FP(strncmp(fds_check, input, strlen(fds_check)), error, "fwNES check", in)
    nodisks = fgetc(in);
    SP(nodisks < 0, error, in)
    rewind(in);
    fseek(in, 0, SEEK_END);
    SP(COMP_CONDITION1 || COMP_CONDITION2, error, in)
    /* do each disk */
    for(i = 0; i < nodisks; i++) {
        printf("Disk %i:\n", i);
        rewind(in);
        fseek(in, START_ADDRESS + i * DISK_SIZE, SEEK_SET);
        SP(fread(input, sizeof(data), DISK_SIZE, in)!=DISK_SIZE, error, in)
        if(outfiles) {
            /* check if already in sub-directory */
            if(dirflag) {
                j = chdir("..");
                if(j < 0) {
                    perror("Error coming out of directory.  Cannot write files.\n");
                    outfiles = 0;
                }
            }
            sprintf(fileout, "DISK_%02X", i);
            j = chdir(fileout);
            if(j < 0) {
                j = mkdir(fileout);
                if(j < 0) {
                    sprintf(error,
                      "Cannot create directory %s!  Cannot write files.\n",
                      fileout);
                    perror(error);
                    outfiles = 0;
                } else {
                    j = chdir(fileout);
                    if(j < 0) {
                        sprintf(error,
                          "Cannot create directory %s!  Cannot write files.\n",
                          fileout);
                        perror(error);
                        outfiles = 0;   
                    }
                }
            }
            dirflag = 1;
        }
        memstart = outsize = 0;
        ptr = input;
        cflag = 1;
        do {
            if(ptr - input >= DISK_SIZE) /* if not enough room on disk */ {
                perror("Disk overflow?\nNot enough room on disk for exit byte!\n");
                break;
            }
            switch(*ptr) {
                case 1: /*disk header*/
                    /* if not enough room for disk header */
                    if(ptr - input + 1 + strlen(hvc_check) + DISK_HEADER
                      > DISK_SIZE) {
                        perror("Not enough room for disk header!\n");
                        cflag = 0;
                        break;
                    }
                    ptr++;
                    printf("Header:\n");
                    if(strncmp(hvc_check, ptr, strlen(hvc_check))) {
                        perror("Bad header format for disk!\n");
                        cflag = 0;
                        break;
                    }
                    ptr += strlen(hvc_check);
                    /* print disk header info */
                    for(j = 0; j < 11; j++) {
                        buildspacebuffer(space, 30 - strlen(strings[j]));
                        printf("%s:%s", strings[j], space);
                        switch(j) {
                            case 0:
                                for(k = 0; k < 10; k++)
                                    printf("$%02X ", ptr[k+dstart[j]]);
                                break;
                            case 2:
                                for(k = 0; k < 4; k++)
                                    printf("%c", ptr[k+dstart[j]]);
                                break;
                            case 4:
                                printf("Side %c", sides[ptr[dstart[j]] & 1]);
                                break;
                            case 9:
                            case 10:
                                printf("%x-%x in the year of Showa %x",
                                  ptr[1+dstart[j]], ptr[2+dstart[j]], ptr[0+dstart[j]]);
                                break;
                            default:
                                printf("$%02X", ptr[dstart[j]]);
                                break;
                        }
                        printf("\n");
                    }
                    printf("End of block\n\n");
                    ptr += DISK_HEADER;
                    break;
                case 2:   /*file amount block*/
                    if(ptr - input + 2 > DISK_SIZE) {
                        perror("Not enough space for file amount block!\n");
                        cflag = 0;
                        break;
                    }
                    ptr++;
                    buildspacebuffer(space, 30 - strlen("Number of files"));
                    printf("File amount block:\nNumber of files:%s%i\n",
                      space, *ptr);
                    printf("End of block\n\n");
                    ptr++;
                    break;
                case 3:   /*file header info*/
                    if(ptr - input + 1 + FILE_HEADER > DISK_SIZE) {
                        perror("Not enough space for file header block!\n");
                        cflag = 0;
                        break;
                    }
                    ptr++;
                    for(j = 0; j < 6; j++) {
                        buildspacebuffer(space, 30 - strlen(fstrings[j]));
                        printf("%s:%s", fstrings[j], space);
                        switch(j) {
                            case 2:
                                for(k = 0; k < 8; k++) {
                                    filename[k] = ptr[fstart[j]+k];
                                    printf("%c", filename[k]);
                                }
                                filename[k] = '\0';
                                break;
                            case 3:
                                memstart = ptr[fstart[j]] | (ptr[fstart[j]+1]<<8);
                                printf("$%04X", memstart);
                                break;
                            case 4:
                                outsize  = ptr[fstart[j]] | (ptr[fstart[j]+1]<<8);
                                printf("$%04X", outsize);
                                break;
                            case 5:
                                if(ptr[fstart[j]] > 2)
                                    printf("Unknown (UNKT)");
                                else
                                    printf("%s", fkinds[ptr[fstart[j]]]);
                                break;
                            default:
                                printf("$%02X", ptr[fstart[j]]);
                                break;
                        }
                        printf("\n");
                    }
                    printf("End of block\n\n");
                    ptr += FILE_HEADER;
                    break;
                case 4:
                    if(ptr - input + 1 + outsize > DISK_SIZE) {
                        perror("Not enough room for file on disk!\n");
                        cflag = 0;
                        break;
                    }
                    ptr++;
                    printf("File %s\n", filename);
                    if(outfiles) {
                        printf("Printing file from disk %i...\n", i);
                        for(j = 0; j < 8; j++)
                            if(isspace(filename[j]))
                                filename[j] = '_';
                        sprintf(fileout, "%s.BIN", filename);
                        out = fopen(fileout, "wb");
                        if(out==NULL) {
                            outfiles = 0;
                            sprintf(error, "Could not open %s for writing!\n",
                                fileout);
                            perror(error);
                            printf("Cancelling all file write-outs!\n");
                        } else {
                            fwrite(ptr, sizeof(data), outsize, out);
                            j = fclose(out);
                            if(j) {
                                perror("Ouch, error while closing out file\n");
                                perror("Aborting program\n");
                                j = fclose(in);
                                if(j) {
                                    perror("Ouch, error while closing in file too\n");
                                    perror("Something's wrong\n");
                                }
                                return j;
                            }   
                            printf("File write to %s successful!\n", fileout);
                        }
                    }
                    printf("End of file\n\n");
                    ptr += outsize;
                    memstart = outsize = 0; /*resetting file info*/
                    filename[0] = '\0';
                    break;
                case 0:
                case 255: /* disk end block */
                    cflag = 0;
                    break;
                default:
                    sprintf(error,
                      "Unknown/Invalid block type at disk %i byte %04X!\n",
                      i, ptr - input);
                    perror(error);
                    cflag = 0;
                    break;
            }
        } while(cflag);
        printf("End of disk\n\n\n\n");
    }
    i = fclose(in);
    if(i) {
        perror("Error closing in file\nAborting program\n");
        return i;
    }
    printf("End of FDS Disk Set\n");
    printf("Success!\n");
    return 0;
}
/* updated at 5:18 PM CDT (GMT -5) on Wednesday, May 2, 2007 */


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 1 post ] 

All times are UTC - 7 hours


Who is online

Users browsing this forum: No registered users and 1 guest


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group