Exemple #1
0
void Game::parseCmdLine(const mkString& cmd_line)
{
    std::vector<mkString> tokens;
    extractTokens(cmd_line, tokens);

    for (size_t i = 0; i < tokens.size(); ++i)
    {
        const mkString& token = tokens[i];
        const mkString* next_token_ptr = (i < tokens.size() - 1) ? &tokens[i+1] : NULL;

        if (token == "-freelook")
            m_startWithFreelook = true;
        else if (token == "-disable_shadows")
            m_disableShadows = true;
        else if (token == "-level")
        {
            CHK_ARG("-level");
            m_levelName = *next_token_ptr;
            ++i;
        }
        else
        {
            Ogre::StringStream ss;
            ss << "Unrecognized command line parameter '" << token << "'";
            MessageBoxA(NULL, ss.str().c_str(), NULL, MB_OK);
        }
    }
}
Exemple #2
0
int main(int argc, char **argv)
{
    int i, j;
    int input = -1, output = -1, src_fmt = -1, dst_fmt = -1;
    
    if (argc == 9)
    {
        for (i = 1; i < argc; i++)
        {
            if (CHK_ARG("-i"))
            {
                if (input < 0)
                {
                    /* Get index value for the input file name */
                    i++;
                    input = i;
                } else {
                    input = -1;
                    break;
                }
            } else
            if (CHK_ARG("-o"))
            {
                if (output < 0)
                {
                    /* Get index value for the output file name */
                    i++;
                    output = i;
                } else {
                    output = -1;
                    break;
                }
            } else
            if (CHK_ARG("-s"))
            {
                if (src_fmt < 0)
                {
                    i++;
                    
                    /* Validate option */
                    for (j = 0; j < format_cnt; j++)
                    {
                        if (CHK_ARG(formats[j]))
                        {
                            /* Get index value for the input file format */
                            src_fmt = j;
                            break;
                        }
                    }
                    
                    if (src_fmt < 0) break;
                } else {
                    src_fmt = -1;
                    break;
                }
            } else
            if (CHK_ARG("-d"))
            {
                if (dst_fmt < 0)
                {
                    i++;
                    
                    /* Validate option */
                    for (j = 0; j < format_cnt; j++)
                    {
                        if (CHK_ARG(formats[j]))
                        {
                            /* Get index value for the input file format */
                            dst_fmt = j;
                            break;
                        }
                    }
                    
                    if (dst_fmt < 0) break;
                } else {
                    dst_fmt = -1;
                    break;
                }
            }
        }
    }
    
    if (input < 0 || output < 0 || src_fmt < 0 || dst_fmt < 0)
    {
        usage(argv);
        return 1;
    }
    
    if (src_fmt == dst_fmt)
    {
        printf("\n\tDestination file format cannot be the same as the source file format.\n\tProcess aborted.\n");
        return 1;
    }
    
    sixty_t *sixty_header = malloc(sizeof(sixty_t));
    if (!sixty_header)
    {
        printf("\n\tError allocating memory for the save header.\n");
        return 1;
    }
    
    memset(sixty_header, 0, sizeof(sixty_t));
    
    FILE *infile = fopen(argv[input], "rb");
    if (!infile)
    {
        printf("\n\tError opening \"%s\" for reading.\n", argv[input]);
        free(sixty_header);
        return 1;
    }
    
    fseek(infile, 0, SEEK_END);
    uint32_t fsize = ftell(infile);
    rewind(infile);
    
    if (fsize == 0 || fsize > CtrlPakx8 || (fsize % 4) != 0)
    {
        printf("\n\tInvalid N64 save file.\n");
        if (fsize == 0) printf("\n\tFile size is zero!\n");
        if (fsize > CtrlPakx8) printf("\n\tFile size is greater than %u KiB!\n", CtrlPakx8 / 1024);
        if ((fsize % 4) != 0) printf("\n\tFile size is not a multiple of 4!\n");
        free(sixty_header);
        fclose(infile);
        return 1;
    }
    
    if (src_fmt == 3 && fsize < sizeof(sixty_t))
    {
        printf("\n\tInput save file is not big enough to store a Sixtyforce save header!\n");
        free(sixty_header);
        fclose(infile);
        return 1;
    }
    
    FILE *outfile = fopen(argv[output], "wb");
    if (!outfile)
    {
        printf("\n\tError opening \"%s\" for writing.\n", argv[output]);
        free(sixty_header);
        fclose(infile);
        return 1;
    }
    
    char tmp[256] = {0};
    bool sixty_cp = false;
    uint32_t data = 0, save_size = 0;
    
    if (src_fmt == 3)
    {
        /* Check if this is a Sixtyforce save */
        
        fread(sixty_header, sizeof(sixty_t), 1, infile);
        rewind(infile);
        
        if (!strncmp(sixty_header->magic1, "60cs", 4) && !strncmp(sixty_header->magic2, "head", 4) && !strncmp(sixty_header->magic3, "time", 4) && \
            !strncmp(sixty_header->magic4, "save", 4) && !strncmp(sixty_header->magic5, "type", 4) && !strncmp(sixty_header->magic6, "size", 4) && \
            !strncmp(sixty_header->magic7, "data", 4))
        {
#ifdef DEBUG
            print_sixty_header(sixty_header);
#endif
            
            /* Get save size */
            save_size = bswap_32(sixty_header->datasize2); // Stored in Big Endian
            
            /* Check if this file contains a Controller Pak save */
            if (fsize > (0x84 + save_size + 8)) // Sixtyforce header + save data + "pak0" block
            {
                fseek(infile, 0x84 + save_size, SEEK_SET);
                fread(&data, 4, 1, infile);
                rewind(infile);
                sixty_cp = (data == bswap_32(PAK0_MAGIC));
            }
            
            /* Prepare file stream position for data access */
            fseek(infile, 0x84, SEEK_SET);
        } else {
            printf("\n\tInput save file is not a Sixtyforce save!\n");
            free(sixty_header);
            fclose(infile);
            fclose(outfile);
            remove(argv[output]);
            return 1;
        }
    } else {
        /* Get save size */
        save_size = fsize;
    }
    
    /* Try to guess the most probable save type using the save file size */
    int type = -1;
    uint32_t type_size = 0;
    
    if (save_size <= EEPROM)
    {
        type = 0;
        type_size = EEPROM;
    } else
    if (save_size <= EEPROMx4)
    {
        type = 0;
        type_size = EEPROMx4;
    } else
    if (save_size <= EEPROMx8)
    {
        type = 0;
        type_size = EEPROMx8;
    } else
    if (save_size <= EEPROMx32)
    {
        type = 0;
        type_size = EEPROMx32;
    } else
    if (save_size <= SRAM)
    {
        /* Even though this is the real size for Controller Pak saves, only Sixtyforce seems to use it */
        /* Let's just assume it's a SRAM save and call it a day */
        type = 1;
        type_size = SRAM;
    } else
    if (save_size <= FlashRAM)
    {
        /* Also applies to Controller Pak saves from Wii64. We'll ask about this later. */
        type = 2;
        type_size = FlashRAM;
    } else
    if (save_size <= CtrlPakx8)
    {
        type = 3;
        type_size = CtrlPakx8;
    }
    
    if (src_fmt == 0 && type == 2) // Input: Wii64 FlashRAM
    {
        if (!strncasecmp(argv[input] + strlen(argv[input]) - 4, ".fla", 4))
        {
            /* Assume that the input file is actually a FlashRAM save and remain unchanged */
        } else
        if (!strncasecmp(argv[input] + strlen(argv[input]) - 4, ".mpk", 4))
        {
            /* Assume that the input file is actually a Controller Pak save */
            type = 3;
        } else {
            /* Ask the user if the input save is actually a Controller Pak save */
            while(true)
            {
                if (getLine("\n\tIs the input file a Controller Pak save? (yes/no): ", tmp, sizeof(tmp)) == 0)
                {
                    if (strlen(tmp) == 3 && !strncmp(tmp, "yes", 3))
                    {
                        /* Change save type */
                        type = 3;
                        break;
                    } else
                    if (strlen(tmp) == 2 && !strncmp(tmp, "no", 2))
                    {
                        /* Remain unchanged */
                        break;
                    } else {
                        printf("\tInvalid input. Please answer with \"yes\" or \"no\".\n");
                    }
                } else {
                    printf("\tInvalid input. Please answer with \"yes\" or \"no\".\n");
                }
            }
        }
    }
    
    printf("\n\tDetected save type: %s (%u Kbits).\n", SAVE_TYPE_STR(type), ((type_size * 8) / 1024));
    if (src_fmt == 3 && sixty_cp && (dst_fmt == 0 || dst_fmt == 1)) printf("\n\tDetected Sixtyforce Controller Pak save data (SRAM %u Kbits).\n", ((CtrlPak * 8) / 1024));
    
    /* Redundancy checks: */
    /* Wii64 EEPROM -> Project64 EEPROM */
    /* Project64 EEPROM -> Wii64 EEPROM */
    /* Wii64 SRAM -> Wii N64 VC SRAM */
    /* Wii N64 VC SRAM -> Wii64 SRAM */
    /* Wii64 FlashRAM -> Wii N64 VC FlashRAM */
    /* Wii N64 VC FlashRAM -> Wii64 FlashRAM */
    if ((((src_fmt == 0 && dst_fmt == 1) || (src_fmt == 1 && dst_fmt == 0)) && type == 0) || \
        (((src_fmt == 0 && dst_fmt == 2) || (src_fmt == 2 && dst_fmt == 0)) && (type == 1 || type == 2)))
    {
        printf("\n\tThis %s save file doesn't need to be modified.\n\tJust try it with %s.\n", \
            SAVE_TYPE_STR(type), \
            (dst_fmt == 0 ? "Wii64" : (dst_fmt == 1 ? "Project64" : "your Wii N64 Virtual Console title")));
        free(sixty_header);
        fclose(infile);
        fclose(outfile);
        remove(argv[output]);
        return 1;
    }
    
    if (dst_fmt == 2 && type == 3) // Output: Wii N64 VC Controller Pak
    {
        printf("\n\tWii N64 Virtual Console isn't compatible with\n\tController Pak save data.\n");
        free(sixty_header);
        fclose(infile);
        fclose(outfile);
        remove(argv[output]);
        return 1;
    }
    
    if (dst_fmt == 3 && type == 3) // Output: Sixtyforce Controller Pak
    {
        printf("\n\tConversion of Controller Pak data to the Sixtyforce format\n\tisn't supported (yet).\n");
        free(sixty_header);
        fclose(infile);
        fclose(outfile);
        remove(argv[output]);
        return 1;
    }
    
    uint32_t outsize = 0;
    bool byteswap = false;
    
    switch(type)
    {
        case 0: // EEPROM
            /* Byteswapping isn't needed */
            byteswap = false;
            
            /* Adjust output save size according to the destination format */
            outsize = ((dst_fmt == 0 || dst_fmt == 1) ? EEPROMx4 : (dst_fmt == 2 ? EEPROMx32 : EEPROMx8));
            
            break;
        case 1: // SRAM
            /* Only apply 32-bit byteswapping if either the source or destiny format is Project64 */
            byteswap = (src_fmt == 1 || dst_fmt == 1);
            
            /* Adjust output save size */
            outsize = SRAM;
            
            break;
        case 2: // Flash RAM
            /* Only apply 32-bit byteswapping if either the source or destiny format is Project64 */
            byteswap = (src_fmt == 1 || dst_fmt == 1);
            
            /* Adjust output save size */
            outsize = FlashRAM;
            
            break;
        case 3: // Controller Pak
            /* Byteswapping isn't needed */
            byteswap = false;
            
            /* Adjust output save size according to the destination format */
            outsize = (dst_fmt == 0 ? CtrlPakx4 : CtrlPakx8);
            
            break;
        default:
            break;
    }
    
    /* Time to do the magic */
    
    if (dst_fmt == 3) // Sixtyforce
    {
        /* Generate Sixtyforce header */
        strcpy(sixty_header->magic1, "60cs");
        sixty_header->filesize = bswap_32((uint32_t)(0x84 - 0x08 + outsize));
        strcpy(sixty_header->magic2, "head");
        strcpy(sixty_header->magic3, "time");
        sixty_header->unk1 = bswap_32((uint32_t)0x04);
        strcpy(sixty_header->magic4, "save");
        sixty_header->savesize = bswap_32((uint32_t)(0x84 - 0x64 + outsize));
        strcpy(sixty_header->magic5, "type");
        sixty_header->unk2 = bswap_32((uint32_t)0x04);
        sixty_header->type = bswap_32((uint32_t)(type == 0 ? 0x01 : (type == 1 ? 0x03 : 0x04)));
        strcpy(sixty_header->magic6, "size");
        sixty_header->unk3 = bswap_32((uint32_t)0x04);
        sixty_header->datasize1 = bswap_32(outsize);
        strcpy(sixty_header->magic7, "data");
        sixty_header->datasize2 = bswap_32(outsize);
        
#ifdef DEBUG
        print_sixty_header(sixty_header);
#endif
        
        /* Write header to the output file */
        fwrite(sixty_header, sizeof(sixty_t), 1, outfile);
    }
    
    /* Write save data */
    write_data(data, infile, outfile, (outsize > save_size ? save_size : outsize), byteswap);
    if (outsize > save_size) pad_data((dst_fmt == 2), (outsize - save_size), outfile);
    
    /* Extract the Controller Pak data from the Sixtyforce save (if available) */
    if (sixty_cp && (dst_fmt == 0 || dst_fmt == 1))
    {
        rewind(infile);
        fseek(infile, (0x84 + save_size + 8), SEEK_SET); // Sixtyforce header + save data + "pak0" block
        
        uint32_t pak0_size = (fsize - (0x84 + save_size + 8)); // Remaining data
        
        snprintf(tmp, strlen(argv[output]), argv[output]);
        
        for(i = strlen(tmp); tmp[i] != '.'; i--);
        
        if (i > 0) tmp[i] = '\0';
        strncat(tmp, ".mpk", 4);
        
        FILE *cpak = fopen(tmp, "wb");
        if (!cpak)
        {
            printf("\n\tError opening \"%s\" for writing.\n", tmp);
        } else {
            write_data(data, infile, cpak, pak0_size, false);
            pad_data(false, (dst_fmt == 0 ? (CtrlPakx4 - pak0_size) : (CtrlPakx8 - pak0_size)), cpak);
            
            fclose(cpak);
            
            printf("\n\tSaved additional Controller Pak data to \"%s\".", tmp);
            printf("\n\tYou can use it with %s.\n", (dst_fmt == 0 ? "Wii64" : "Project64"));
        }
    }
    
    printf("\n\tConversion process successfully completed!\n");
    
    free(sixty_header);
    fclose(infile);
    fclose(outfile);
    
    return 0;
}