Exemple #1
0
m64p_error ConfigInit(const char *ConfigDirOverride, const char *DataDirOverride)
{
    m64p_error rval;
    const char *configpath = NULL;
    char *filepath;
    long filelen;
    FILE *fPtr;
    char *configtext;

    config_section *current_section = NULL;
    char *line, *end, *lastcomment;

    if (l_ConfigInit)
        return M64ERR_ALREADY_INIT;
    l_ConfigInit = 1;

    /* if a data directory was specified, make a copy of it */
    if (DataDirOverride != NULL)
    {
        l_DataDirOverride = strdup(DataDirOverride);
        if (l_DataDirOverride == NULL)
            return M64ERR_NO_MEMORY;
         /* TODO mupen64plus-ae specific hack */
        strcpy(l_DataDirOverride, DataDirOverride);
    }

    /* if a config directory was specified, make a copy of it */
    if (ConfigDirOverride != NULL)
    {
        l_ConfigDirOverride = strdup(ConfigDirOverride);
        if (l_ConfigDirOverride == NULL)
            return M64ERR_NO_MEMORY;
    }

    /* get the full pathname to the config file and try to open it */
    configpath = ConfigGetUserConfigPath();
    if (configpath == NULL)
        return M64ERR_FILES;

    filepath = combinepath(configpath, MUPEN64PLUS_CFG_NAME);
    if (filepath == NULL)
        return M64ERR_NO_MEMORY;

    fPtr = fopen(filepath, "rb");
    if (fPtr == NULL)
    {
        DebugMessage(M64MSG_INFO, "Couldn't open configuration file '%s'.  Using defaults.", filepath);
        free(filepath);
        l_SaveConfigOnExit = 1; /* auto-save the config file so that the defaults will be saved to disk */
        return M64ERR_SUCCESS;
    }
    free(filepath);

    /* read the entire config file */
    fseek(fPtr, 0L, SEEK_END);
    filelen = ftell(fPtr);
    fseek(fPtr, 0L, SEEK_SET);

    configtext = (char *) malloc(filelen + 1);
    if (configtext == NULL)
    {
        fclose(fPtr);
        return M64ERR_NO_MEMORY;
    }
    if (fread(configtext, 1, filelen, fPtr) != filelen)
    {
        free(configtext);
        fclose(fPtr);
        return M64ERR_FILES;
    }
    fclose(fPtr);

    /* parse the file data */
    current_section = NULL;
    line = configtext;
    end = configtext + filelen;
    lastcomment = NULL;
    *end = 0;
    while (line < end)
    {
        ini_line l = ini_parse_line(&line);
        switch (l.type)
        {
            case INI_COMMENT:
                lastcomment = l.value;
                break;

            case INI_SECTION:
                rval = ConfigOpenSection(l.name, (m64p_handle *) &current_section);
                if (rval != M64ERR_SUCCESS)
                {
                    free(configtext);
                    return rval;
                }
                lastcomment = NULL;
                break;

            case INI_PROPERTY:
                if (l.value[0] == '"' && l.value[strlen(l.value)-1] == '"')
                {
                    l.value++;
                    l.value[strlen(l.value)-1] = 0;
                    ConfigSetDefaultString((m64p_handle) current_section, l.name, l.value, lastcomment);
                }
                else if (osal_insensitive_strcmp(l.value, "false") == 0)
                {
                    ConfigSetDefaultBool((m64p_handle) current_section, l.name, 0, lastcomment);
                }
                else if (osal_insensitive_strcmp(l.value, "true") == 0)
                {
                    ConfigSetDefaultBool((m64p_handle) current_section, l.name, 1, lastcomment);
                }
                else if (is_numeric(l.value))
                {
                    int val_int = (int) strtol(l.value, NULL, 10);
                    float val_float = (float) strtod(l.value, NULL);
                    if ((val_float - val_int) != 0.0)
                        ConfigSetDefaultFloat((m64p_handle) current_section, l.name, val_float, lastcomment);
                    else
                        ConfigSetDefaultInt((m64p_handle) current_section, l.name, val_int, lastcomment);
                }
                else
                {
                    /* assume that it's a string */
                    ConfigSetDefaultString((m64p_handle) current_section, l.name, l.value, lastcomment);
                }
                lastcomment = NULL;
                break;

            default:
                break;
        }
    }

    /* release memory used for config file text */
    free(configtext);

    /* duplicate the entire config data list, to store a copy of the list which represents the state of the file on disk */
    copy_configlist_active_to_saved();

    return M64ERR_SUCCESS;
}
/* global functions */
int auto_set_defaults(int iDeviceIdx, const char *joySDLName)
{
    FILE *pfIn;
    m64p_handle pConfig = NULL;
    const char *CfgFilePath = ConfigGetSharedDataFilepath(INI_FILE_NAME);
    enum { E_NAME_SEARCH, E_NAME_FOUND, E_PARAM_READ } eParseState;
    char *pchIni, *pchNextLine, *pchCurLine;
    long iniLength;
    int ControllersFound = 0;

    /* if we couldn't get a name (no joystick plugged in to given port), then return with a failure */
    if (joySDLName == NULL)
        return 0;
    /* if we couldn't find the shared data file, dump an error and return */
    if (CfgFilePath == NULL || strlen(CfgFilePath) < 1)
    {
        DebugMessage(M64MSG_ERROR, "Couldn't find config file '%s'", INI_FILE_NAME);
        return 0;
    }

    /* read the input auto-config .ini file */
    pfIn = fopen(CfgFilePath, "rb");
    if (pfIn == NULL)
    {
        DebugMessage(M64MSG_ERROR, "Couldn't open config file '%s'", CfgFilePath);
        return 0;
    }
    fseek(pfIn, 0L, SEEK_END);
    iniLength = ftell(pfIn);
    fseek(pfIn, 0L, SEEK_SET);
    pchIni = (char *) malloc(iniLength + 1);
    if (pchIni == NULL)
    {
        DebugMessage(M64MSG_ERROR, "Couldn't allocate %li bytes for config file '%s'", iniLength, CfgFilePath);
        fclose(pfIn);
        return 0;
    }
    if (fread(pchIni, 1, iniLength, pfIn) != iniLength)
    {
        DebugMessage(M64MSG_ERROR, "File read failed for %li bytes of config file '%s'", iniLength, CfgFilePath);
        free(pchIni);
        fclose(pfIn);
        return 0;
    }
    fclose(pfIn);
    pchIni[iniLength] = 0;

    /* parse the INI file, line by line */
    pchNextLine = pchIni;
    eParseState = E_NAME_SEARCH;
    while (pchNextLine != NULL && *pchNextLine != 0)
    {
        char *pivot = NULL;
        /* set up character pointers */
        pchCurLine = pchNextLine;
        pchNextLine = strchr(pchNextLine, '\n');
        if (pchNextLine != NULL)
            *pchNextLine++ = 0;
        pchCurLine = StripSpace(pchCurLine);

        /* handle blank/comment lines */
        if (strlen(pchCurLine) < 1 || *pchCurLine == ';' || *pchCurLine == '#')
            continue;

        /* handle section (joystick name in ini file) */
        if (*pchCurLine == '[' && pchCurLine[strlen(pchCurLine)-1] == ']')
        {
            char Word[64];
            char *wordPtr;
            int  joyFound = 1;

            if (eParseState == E_PARAM_READ)
            {
                /* we've finished parsing all parameters for the discovered input device */
                free(pchIni);
                return ControllersFound;
            }
            else if (eParseState == E_NAME_FOUND)
            {
                /* this is an equivalent device name to the one we're looking for (and found); keep looking for parameters */
                continue;
            }
            /* we need to look through the device name word by word to see if it matches the joySDLName that we're looking for */ 
            pchCurLine[strlen(pchCurLine)-1] = 0;
            wordPtr = StripSpace(pchCurLine + 1);
            /* first, if there is a preceding system name in this .ini device name, and the system matches, then strip out */
#if defined(__unix__)
            if (strncmp(wordPtr, "Unix:", 5) == 0)
                wordPtr = StripSpace(wordPtr + 5);
#endif
#if defined(__linux__)
            if (strncmp(wordPtr, "Linux:", 6) == 0)
                wordPtr = StripSpace(wordPtr + 6);
#endif
#if defined(__APPLE__)
            if (strncmp(wordPtr, "OSX:", 4) == 0)
                wordPtr = StripSpace(wordPtr + 4);
#endif
#if defined(WIN32)
            if (strncmp(wordPtr, "Win32:", 6) == 0)
                wordPtr = StripSpace(wordPtr + 6);
#endif
            /* search in the .ini device name for all the words in the joystick name.  If any are missing, then this is not the right joystick model */
            while (wordPtr != NULL && strlen(wordPtr) > 0)
            {
                char *nextSpace = strchr(wordPtr, ' ');
                if (nextSpace == NULL)
                {
                    strncpy(Word, wordPtr, 63);
                    Word[63] = 0;
                    wordPtr = NULL;
                }
                else
                {
                    int length = (int) (nextSpace - wordPtr);
                    if (length > 63) length = 63;
                    strncpy(Word, wordPtr, length);
                    Word[length] = 0;
                    wordPtr = nextSpace + 1;
                }
                printf("Word1: %s, Word2: %s\n", joySDLName, Word);fflush(stdout);
                if (strstr(joySDLName, Word) == NULL)
                    joyFound = 0;
            }
            /* if we found the right joystick, then open up the core config section to store parameters and set the 'device' param */
            if (joyFound)
            {
                char SectionName[32];
                sprintf(SectionName, "AutoConfig%i", ControllersFound);
                if (ConfigOpenSection(SectionName, &pConfig) != M64ERR_SUCCESS)
                {
                    DebugMessage(M64MSG_ERROR, "auto_set_defaults(): Couldn't open config section '%s'", SectionName);
                    free(pchIni);
                    return 0;
                }
                eParseState = E_NAME_FOUND;
                ControllersFound++;
                DebugMessage(M64MSG_INFO, "Using auto-configuration for device '%s'", joySDLName);
                ConfigSetParameter(pConfig, "device", M64TYPE_INT, &iDeviceIdx);
            }
            continue;
        }

        /* handle parameters */
        pivot = strchr(pchCurLine, '=');
        if (pivot != NULL)
        {
            /* if we haven't found the correct section yet, just skip this */
            if (eParseState == E_NAME_SEARCH)
                continue;
            eParseState = E_PARAM_READ;
            /* otherwise, store this parameter in the current active joystick config */
            *pivot++ = 0;
            pchCurLine = StripSpace(pchCurLine);
            pivot = StripSpace(pivot);
            if (strcasecmp(pchCurLine, "plugin") == 0 || strcasecmp(pchCurLine, "device") == 0)
            {
                int iVal = atoi(pivot);
                ConfigSetParameter(pConfig, pchCurLine, M64TYPE_INT, &iVal);
            }
            else if (strcasecmp(pchCurLine, "plugged") == 0 || strcasecmp(pchCurLine, "mouse") == 0)
            {
                int bVal = (strcasecmp(pivot, "true") == 0);
                ConfigSetParameter(pConfig, pchCurLine, M64TYPE_BOOL, &bVal);
            }
            else
            {
                ConfigSetParameter(pConfig, pchCurLine, M64TYPE_STRING, pivot);
            }
            continue;
        }

        /* handle keywords */
        if (pchCurLine[strlen(pchCurLine)-1] == ':')
        {
            /* if we haven't found the correct section yet, just skip this */
            if (eParseState == E_NAME_SEARCH)
                continue;
            /* otherwise parse the keyword */
            if (strcmp(pchCurLine, "__NextController:") == 0)
            {
                char SectionName[32];
                /* if there are no more N64 controller spaces left, then exit */
                if (ControllersFound == 4)
                {
                    free(pchIni);
                    return ControllersFound;
                }
                /* otherwise go to the next N64 controller */
                sprintf(SectionName, "AutoConfig%i", ControllersFound);
                if (ConfigOpenSection(SectionName, &pConfig) != M64ERR_SUCCESS)
                {
                    DebugMessage(M64MSG_ERROR, "auto_set_defaults(): Couldn't open config section '%s'", SectionName);
                    free(pchIni);
                    return ControllersFound;
                }
                ControllersFound++;
                DebugMessage(M64MSG_INFO, "Using auto-configuration for device '%s': %i controllers for this device", joySDLName, ControllersFound);
                ConfigSetParameter(pConfig, "device", M64TYPE_INT, &iDeviceIdx);
            }
            else
            {
                DebugMessage(M64MSG_ERROR, "Unknown keyword '%s' in %s", pchCurLine, INI_FILE_NAME);
            }
            continue;
        }

        /* unhandled line in .ini file */
        DebugMessage(M64MSG_ERROR, "Invalid line in %s: '%s'", INI_FILE_NAME, pchCurLine);
    }

    if (eParseState == E_PARAM_READ)
    {
        /* we've finished parsing all parameters for the discovered input device, which is the last in the .ini file */
        free(pchIni);
        return ControllersFound;
    }

    DebugMessage(M64MSG_INFO, "No auto-configuration found for device '%s'", joySDLName);
    free(pchIni);
    return 0;
}
static
bool Config_SetDefault()
{
	if (ConfigOpenSection("Video-General", &g_configVideoGeneral) != M64ERR_SUCCESS) {
		LOG(LOG_ERROR, "Unable to open Video-General configuration section");
		return false;
	}
	if (ConfigOpenSection("Video-GLideN64", &g_configVideoGliden64) != M64ERR_SUCCESS) {
		LOG(LOG_ERROR, "Unable to open GLideN64 configuration section");
		return false;
	}

	config.resetToDefaults();
	// Set default values for "Video-General" section, if they are not set yet. Taken from RiceVideo
	m64p_error res = ConfigSetDefaultBool(g_configVideoGeneral, "Fullscreen", config.video.fullscreen, "Use fullscreen mode if True, or windowed mode if False ");
	assert(res == M64ERR_SUCCESS);
	res = ConfigSetDefaultInt(g_configVideoGeneral, "ScreenWidth", config.video.windowedWidth, "Width of output window or fullscreen width");
	assert(res == M64ERR_SUCCESS);
	res = ConfigSetDefaultInt(g_configVideoGeneral, "ScreenHeight", config.video.windowedHeight, "Height of output window or fullscreen height");
	assert(res == M64ERR_SUCCESS);
	res = ConfigSetDefaultBool(g_configVideoGeneral, "VerticalSync", config.video.verticalSync, "If true, activate the SDL_GL_SWAP_CONTROL attribute");
	assert(res == M64ERR_SUCCESS);

	res = ConfigSetDefaultInt(g_configVideoGliden64, "configVersion", CONFIG_VERSION_CURRENT, "Settings version. Don't touch it.");
	assert(res == M64ERR_SUCCESS);

	res = ConfigSetDefaultInt(g_configVideoGliden64, "MultiSampling", config.video.multisampling, "Enable/Disable MultiSampling (0=off, 2,4,8,16=quality)");
	assert(res == M64ERR_SUCCESS);
	res = ConfigSetDefaultInt(g_configVideoGliden64, "AspectRatio", config.frameBufferEmulation.aspect, "Screen aspect ratio (0=stretch, 1=force 4:3, 2=force 16:9, 3=adjust)");
	assert(res == M64ERR_SUCCESS);

	//#Texture Settings
	res = ConfigSetDefaultBool(g_configVideoGliden64, "bilinearMode", config.texture.bilinearMode, "Bilinear filtering mode (0=N64 3point, 1=standard)");
	assert(res == M64ERR_SUCCESS);
	res = ConfigSetDefaultBool(g_configVideoGliden64, "MaxAnisotropy", config.texture.maxAnisotropy, "Max level of Anisotropic Filtering, 0 for off");
	assert(res == M64ERR_SUCCESS);
	res = ConfigSetDefaultInt(g_configVideoGliden64, "CacheSize", config.texture.maxBytes / uMegabyte, "Size of texture cache in megabytes. Good value is VRAM*3/4");
	assert(res == M64ERR_SUCCESS);
	//#Emulation Settings
	res = ConfigSetDefaultBool(g_configVideoGliden64, "EnableFog", config.generalEmulation.enableFog, "Enable fog emulation.");
	assert(res == M64ERR_SUCCESS);
	res = ConfigSetDefaultBool(g_configVideoGliden64, "EnableNoise", config.generalEmulation.enableNoise, "Enable color noise emulation.");
	assert(res == M64ERR_SUCCESS);
	res = ConfigSetDefaultBool(g_configVideoGliden64, "EnableLOD", config.generalEmulation.enableLOD, "Enable LOD emulation.");
	assert(res == M64ERR_SUCCESS);
	res = ConfigSetDefaultBool(g_configVideoGliden64, "EnableHWLighting", config.generalEmulation.enableHWLighting, "Enable hardware per-pixel lighting.");
	assert(res == M64ERR_SUCCESS);
	res = ConfigSetDefaultBool(g_configVideoGliden64, "EnableShadersStorage", config.generalEmulation.enableShadersStorage, "Use persistent storage for compiled shaders.");
	assert(res == M64ERR_SUCCESS);
	res = ConfigSetDefaultBool(g_configVideoGliden64, "ForceGammaCorrection", config.generalEmulation.forceGammaCorrection, "Force gamma correction.");
	assert(res == M64ERR_SUCCESS);
	res = ConfigSetDefaultFloat(g_configVideoGliden64, "GammaCorrectionLevel", config.generalEmulation.gammaCorrectionLevel, "Gamma correction level.");
	assert(res == M64ERR_SUCCESS);
#ifdef ANDROID
	res = ConfigSetDefaultBool(g_configVideoGliden64, "ForcePolygonOffset", config.generalEmulation.forcePolygonOffset, "If true, use polygon offset values specified below");
	assert(res == M64ERR_SUCCESS);
	res = ConfigSetDefaultFloat(g_configVideoGliden64, "PolygonOffsetFactor", config.generalEmulation.polygonOffsetFactor, "Specifies a scale factor that is used to create a variable depth offset for each polygon");
	assert(res == M64ERR_SUCCESS);
	res = ConfigSetDefaultFloat(g_configVideoGliden64, "PolygonOffsetUnits", config.generalEmulation.polygonOffsetUnits, "Is multiplied by an implementation-specific value to create a constant depth offset");
	assert(res == M64ERR_SUCCESS);
#endif
	//#Frame Buffer Settings:"
	res = ConfigSetDefaultBool(g_configVideoGliden64, "EnableFBEmulation", config.frameBufferEmulation.enable, "Enable frame and|or depth buffer emulation.");
	assert(res == M64ERR_SUCCESS);
	res = ConfigSetDefaultBool(g_configVideoGliden64, "EnableCopyAuxiliaryToRDRAM", config.frameBufferEmulation.copyAuxToRDRAM, "Copy auxiliary buffers to RDRAM");
	assert(res == M64ERR_SUCCESS);
	res = ConfigSetDefaultInt(g_configVideoGliden64, "EnableCopyColorToRDRAM", config.frameBufferEmulation.copyToRDRAM, "Enable color buffer copy to RDRAM (0=do not copy, 1=copy in sync mode, 2=copy in async mode)");
	assert(res == M64ERR_SUCCESS);
	res = ConfigSetDefaultBool(g_configVideoGliden64, "EnableCopyDepthToRDRAM", config.frameBufferEmulation.copyDepthToRDRAM, "Enable depth buffer copy to RDRAM.");
	assert(res == M64ERR_SUCCESS);
	res = ConfigSetDefaultBool(g_configVideoGliden64, "EnableCopyColorFromRDRAM", config.frameBufferEmulation.copyFromRDRAM, "Enable color buffer copy from RDRAM.");
	assert(res == M64ERR_SUCCESS);
	res = ConfigSetDefaultBool(g_configVideoGliden64, "EnableDetectCFB", config.frameBufferEmulation.detectCFB, "Detect CPU writes to frame buffer.");
	assert(res == M64ERR_SUCCESS);
	res = ConfigSetDefaultBool(g_configVideoGliden64, "EnableN64DepthCompare", config.frameBufferEmulation.N64DepthCompare, "Enable N64 depth compare instead of OpenGL standard one. Experimental.");
	assert(res == M64ERR_SUCCESS);
	//#Texture filter settings
	res = ConfigSetDefaultInt(g_configVideoGliden64, "txFilterMode", config.textureFilter.txFilterMode, "Texture filter (0=none, 1=Smooth filtering 1, 2=Smooth filtering 2, 3=Smooth filtering 3, 4=Smooth filtering 4, 5=Sharp filtering 1, 6=Sharp filtering 2)");
	assert(res == M64ERR_SUCCESS);
	res = ConfigSetDefaultInt(g_configVideoGliden64, "txEnhancementMode", config.textureFilter.txEnhancementMode, "Texture Enhancement (0=none, 1=store as is, 2=X2, 3=X2SAI, 4=HQ2X, 5=HQ2XS, 6=LQ2X, 7=LQ2XS, 8=HQ4X, 9=2xBRZ, 10=3xBRZ, 11=4xBRZ, 12=5xBRZ), 13=6xBRZ");
	assert(res == M64ERR_SUCCESS);
	res = ConfigSetDefaultBool(g_configVideoGliden64, "txFilterIgnoreBG", config.textureFilter.txFilterIgnoreBG, "Don't filter background textures.");
	assert(res == M64ERR_SUCCESS);
	res = ConfigSetDefaultInt(g_configVideoGliden64, "txCacheSize", config.textureFilter.txCacheSize/uMegabyte, "Size of filtered textures cache in megabytes.");
	assert(res == M64ERR_SUCCESS);
	res = ConfigSetDefaultBool(g_configVideoGliden64, "txHiresEnable", config.textureFilter.txHiresEnable, "Use high-resolution texture packs if available.");
	assert(res == M64ERR_SUCCESS);
	res = ConfigSetDefaultBool(g_configVideoGliden64, "txHiresFullAlphaChannel", config.textureFilter.txHiresFullAlphaChannel, "Allow to use alpha channel of high-res texture fully.");
	assert(res == M64ERR_SUCCESS);
	res = ConfigSetDefaultBool(g_configVideoGliden64, "txHresAltCRC", config.textureFilter.txHresAltCRC, "Use alternative method of paletted textures CRC calculation.");
	assert(res == M64ERR_SUCCESS);
	res = ConfigSetDefaultBool(g_configVideoGliden64, "txDump", config.textureFilter.txDump, "Enable dump of loaded N64 textures.");
	assert(res == M64ERR_SUCCESS);
	res = ConfigSetDefaultBool(g_configVideoGliden64, "txCacheCompression", config.textureFilter.txCacheCompression, "Zip textures cache.");
	assert(res == M64ERR_SUCCESS);
	res = ConfigSetDefaultBool(g_configVideoGliden64, "txForce16bpp", config.textureFilter.txForce16bpp, "Force use 16bit texture formats for HD textures.");
	assert(res == M64ERR_SUCCESS);
	res = ConfigSetDefaultBool(g_configVideoGliden64, "txSaveCache", config.textureFilter.txSaveCache, "Save texture cache to hard disk.");
	assert(res == M64ERR_SUCCESS);
	// Convert to multibyte
	char txPath[PLUGIN_PATH_SIZE * 2];
	wcstombs(txPath, config.textureFilter.txPath, PLUGIN_PATH_SIZE * 2);
	res = ConfigSetDefaultString(g_configVideoGliden64, "txPath", txPath, "Path to folder with hi-res texture packs.");
	assert(res == M64ERR_SUCCESS);

	res = ConfigSetDefaultString(g_configVideoGliden64, "fontName", config.font.name.c_str(), "File name of True Type Font for text messages.");
	assert(res == M64ERR_SUCCESS);
	res = ConfigSetDefaultInt(g_configVideoGliden64, "fontSize", config.font.size, "Font size.");
	assert(res == M64ERR_SUCCESS);
	res = ConfigSetDefaultString(g_configVideoGliden64, "fontColor", "B5E61D", "Font color in RGB format.");
	assert(res == M64ERR_SUCCESS);

	//#Bloom filter settings
	res = ConfigSetDefaultInt(g_configVideoGliden64, "EnableBloom", config.bloomFilter.enable, "Enable bloom filter");
	assert(res == M64ERR_SUCCESS);
	res = ConfigSetDefaultInt(g_configVideoGliden64, "bloomThresholdLevel", config.bloomFilter.thresholdLevel, "Brightness threshold level for bloom. Values [2, 6]");
	assert(res == M64ERR_SUCCESS);
	res = ConfigSetDefaultInt(g_configVideoGliden64, "bloomBlendMode", config.bloomFilter.blendMode, "Bloom blend mode (0=Strong, 1=Mild, 2=Light)");
	assert(res == M64ERR_SUCCESS);
	res = ConfigSetDefaultInt(g_configVideoGliden64, "blurAmount", config.bloomFilter.blurAmount, "Blur radius. Values [2, 10]");
	assert(res == M64ERR_SUCCESS);
	res = ConfigSetDefaultInt(g_configVideoGliden64, "blurStrength", config.bloomFilter.blurStrength, "Blur strength. Values [10, 100]");
	assert(res == M64ERR_SUCCESS);

	return ConfigSaveSection("Video-GLideN64") == M64ERR_SUCCESS;
}
Exemple #4
0
m64p_error ConfigInit(const char *ConfigDirOverride, const char *DataDirOverride)
{
    m64p_error rval;
    const char *configpath = NULL;
    char *filepath;
    long filelen, pathlen;
    FILE *fPtr;
    char *configtext;

    config_section *current_section = NULL;
    char *line, *end, *lastcomment;

    if (l_ConfigInit)
        return M64ERR_ALREADY_INIT;
    l_ConfigInit = 1;

    /* if a data directory was specified, make a copy of it */
    if (DataDirOverride != NULL)
    {
        l_DataDirOverride = (char *) malloc(strlen(DataDirOverride) + 1);
        if (l_DataDirOverride == NULL)
            return M64ERR_NO_MEMORY;
        strcpy(l_DataDirOverride, DataDirOverride);
    }

    /* get the full pathname to the config file and try to open it */
    if (ConfigDirOverride != NULL)
        configpath = ConfigDirOverride;
    else
    {
        configpath = ConfigGetUserConfigPath();
        if (configpath == NULL)
            return M64ERR_FILES;
    }

    filepath = (char *) malloc(strlen(configpath) + 32);
    if (filepath == NULL)
        return M64ERR_NO_MEMORY;

    strcpy(filepath, configpath);
    pathlen = strlen(filepath);
    if (filepath[pathlen - 1] != OSAL_DIR_SEPARATOR)
    {
        filepath[pathlen] = OSAL_DIR_SEPARATOR;
        filepath[pathlen + 1] = 0;
    }
    strcat(filepath, MUPEN64PLUS_CFG_NAME);
    fPtr = fopen(filepath, "rb");
    if (fPtr == NULL)
    {
        DebugMessage(M64MSG_INFO, "Couldn't open configuration file '%s'.  Using defaults.", filepath);
        free(filepath);
        l_SaveConfigOnExit = 1; /* auto-save the config file so that the defaults will be saved to disk */
        return M64ERR_SUCCESS;
    }
    free(filepath);

    /* read the entire config file */
    fseek(fPtr, 0L, SEEK_END);
    filelen = ftell(fPtr);
    fseek(fPtr, 0L, SEEK_SET);

    configtext = (char *) malloc(filelen + 16);
    if (configtext == NULL)
    {
        fclose(fPtr);
        return M64ERR_NO_MEMORY;
    }
    if (fread(configtext, 1, filelen, fPtr) != filelen)
    {
        free(configtext);
        fclose(fPtr);
        return M64ERR_FILES;
    }
    fclose(fPtr);

    /* parse the file data */
    current_section = NULL;
    line = configtext;
    end = configtext + filelen;
    lastcomment = NULL;
    *end = 0;
    while (line < end)
    {
        char *pivot, *varname, *varvalue;
        /* get the pointer to the next line, and null-terminate this line */
        char *nextline = strchr(line, '\n');
        if (nextline == NULL)
            nextline = end;
        *nextline++ = 0;
        /* strip the whitespace and handle comment */
        strip_whitespace(line);
        if (strlen(line) < 1)
        {
            line = nextline;
            continue;
        }
        if (line[0] == '#')
        {
            line++;
            strip_whitespace(line);
            lastcomment = line;
            line = nextline;
            continue;
        }
        /* handle section definition line */
        if (strlen(line) > 2 && line[0] == '[' && line[strlen(line)-1] == ']')
        {
            line++;
            line[strlen(line)-1] = 0;
            rval = ConfigOpenSection(line, (m64p_handle *) &current_section);
            if (rval != M64ERR_SUCCESS)
            {
                free(configtext);
                return rval;
            }
            lastcomment = NULL;
            line = nextline;
            continue;
        }
        /* handle variable definition */
        pivot = strchr(line, '=');
        if (current_section == NULL || pivot == NULL)
        {
            line = nextline;
            continue;
        }
        varname = line;
        varvalue = pivot + 1;
        *pivot = 0;
        strip_whitespace(varname);
        strip_whitespace(varvalue);
        if (varvalue[0] == '"' && varvalue[strlen(varvalue)-1] == '"')
        {
            varvalue++;
            varvalue[strlen(varvalue)-1] = 0;
            ConfigSetDefaultString((m64p_handle) current_section, varname, varvalue, lastcomment);
        }
        else if (osal_insensitive_strcmp(varvalue, "false") == 0)
        {
            ConfigSetDefaultBool((m64p_handle) current_section, varname, 0, lastcomment);
        }
        else if (osal_insensitive_strcmp(varvalue, "true") == 0)
        {
            ConfigSetDefaultBool((m64p_handle) current_section, varname, 1, lastcomment);
        }
        else if (is_numeric(varvalue))
        {
            int val_int = (int) strtol(varvalue, NULL, 10);
            float val_float = (float) strtod(varvalue, NULL);
            if ((val_float - val_int) != 0.0)
                ConfigSetDefaultFloat((m64p_handle) current_section, varname, val_float, lastcomment);
            else
                ConfigSetDefaultInt((m64p_handle) current_section, varname, val_int, lastcomment);
        }
        else
        {
            /* assume that it's a string */
            ConfigSetDefaultString((m64p_handle) current_section, varname, varvalue, lastcomment);
        }
        lastcomment = NULL;
        line = nextline;
    }

    /* release memory used for config file text */
    free(configtext);

    /* duplicate the entire config data list, to store a copy of the list which represents the state of the file on disk */
    copy_configlist_active_to_saved();

    return M64ERR_SUCCESS;
}
Exemple #5
0
static void save_controller_config(int iCtrlIdx, const char *pccDeviceName)
{
    m64p_handle pConfig;
    char SectionName[32], Param[32], ParamString[128];
    int j;

    /* Delete the configuration section for this controller, so we can use SetDefaults and save the help comments also */
    sprintf(SectionName, "Input-SDL-Control%i", iCtrlIdx + 1);
    ConfigDeleteSection(SectionName);
    /* Open the configuration section for this controller (create a new one) */
    if (ConfigOpenSection(SectionName, &pConfig) != M64ERR_SUCCESS)
    {
        DebugMessage(M64MSG_ERROR, "Couldn't open config section '%s'", SectionName);
        return;
    }

    /* save the general controller parameters */
    ConfigSetDefaultFloat(pConfig, "version", CONFIG_VERSION, "Mupen64Plus SDL Input Plugin config parameter version number.  Please don't change this version number.");
    ConfigSetDefaultBool(pConfig, "plugged", controller[iCtrlIdx].control->Present, "Specifies whether this controller is 'plugged in' to the simulated N64");
    ConfigSetDefaultInt(pConfig, "plugin", controller[iCtrlIdx].control->Plugin, "Specifies which type of expansion pak is in the controller: 1=None, 2=Mem pak, 5=Rumble pak");
    ConfigSetDefaultBool(pConfig, "mouse", controller[iCtrlIdx].mouse, "If True, then mouse buttons may be used with this controller");
    ConfigSetDefaultInt(pConfig, "device", controller[iCtrlIdx].device, "Specifies which joystick is bound to this controller: -2=Keyboard/mouse, -1=Auto config, 0 or more= SDL Joystick number");
    ConfigSetDefaultString(pConfig, "name", pccDeviceName, "SDL joystick name (name check disabled if this is empty string)");

    sprintf(Param, "%.2f,%.2f", controller[iCtrlIdx].mouse_sens[0], controller[iCtrlIdx].mouse_sens[1]);
    ConfigSetDefaultString(pConfig, "MouseSensitivity", Param, "Scaling factor for mouse movements.  For X, Y axes.");
    sprintf(Param, "%i,%i", controller[iCtrlIdx].axis_deadzone[0], controller[iCtrlIdx].axis_deadzone[1]);
    ConfigSetDefaultString(pConfig, "AnalogDeadzone", Param, "The minimum absolute value of the SDL analog joystick axis to move the N64 controller axis value from 0.  For X, Y axes.");
    sprintf(Param, "%i,%i", controller[iCtrlIdx].axis_peak[0], controller[iCtrlIdx].axis_peak[1]);
    ConfigSetDefaultString(pConfig, "AnalogPeak", Param, "An absolute value of the SDL joystick axis >= AnalogPeak will saturate the N64 controller axis value (at 80).  For X, Y axes. For each axis, this must be greater than the corresponding AnalogDeadzone value");

    /* save configuration for all the digital buttons */
    for (j = 0; j < X_AXIS; j++ )
    {
        const char *Help;
        int len = 0;
        ParamString[0] = 0;
        if (controller[iCtrlIdx].button[j].key > 0)
        {
            sprintf(Param, "key(%i) ", controller[iCtrlIdx].button[j].key);
            strcat(ParamString, Param);
        }
        if (controller[iCtrlIdx].button[j].button >= 0)
        {
            sprintf(Param, "button(%i) ", controller[iCtrlIdx].button[j].button);
            strcat(ParamString, Param);
        }
        if (controller[iCtrlIdx].button[j].axis >= 0)
        {
            if (controller[iCtrlIdx].button[j].axis_deadzone >= 0)
                sprintf(Param, "axis(%i%c,%i) ", controller[iCtrlIdx].button[j].axis, (controller[iCtrlIdx].button[j].axis_dir == -1) ? '-' : '+',
                        controller[iCtrlIdx].button[j].axis_deadzone);
            else
                sprintf(Param, "axis(%i%c) ", controller[iCtrlIdx].button[j].axis, (controller[iCtrlIdx].button[j].axis_dir == -1) ? '-' : '+');
            strcat(ParamString, Param);
        }
        if (controller[iCtrlIdx].button[j].hat >= 0)
        {
            sprintf(Param, "hat(%i %s) ", controller[iCtrlIdx].button[j].hat, HAT_POS_NAME(controller[iCtrlIdx].button[j].hat_pos));
            strcat(ParamString, Param);
        }
        if (controller[iCtrlIdx].button[j].mouse >= 0)
        {
            sprintf(Param, "mouse(%i) ", controller[iCtrlIdx].button[j].mouse);
            strcat(ParamString, Param);
        }
        if (j == 0)
            Help = "Digital button configuration mappings";
        else
            Help = NULL;
        /* if last character is a space, chop it off */
        len = strlen(ParamString);
        if (len > 0 && ParamString[len-1] == ' ')
            ParamString[len-1] = 0;
        ConfigSetDefaultString(pConfig, button_names[j], ParamString, Help);
    }

    /* save configuration for the 2 analog axes */
    for (j = 0; j < 2; j++ )
    {
        const char *Help;
        int len = 0;
        ParamString[0] = 0;
        if (controller[iCtrlIdx].axis[j].key_a > 0 && controller[iCtrlIdx].axis[j].key_b > 0)
        {
            sprintf(Param, "key(%i,%i) ", controller[iCtrlIdx].axis[j].key_a, controller[iCtrlIdx].axis[j].key_b);
            strcat(ParamString, Param);
        }
        if (controller[iCtrlIdx].axis[j].button_a >= 0 && controller[iCtrlIdx].axis[j].button_b >= 0)
        {
            sprintf(Param, "button(%i,%i) ", controller[iCtrlIdx].axis[j].button_a, controller[iCtrlIdx].axis[j].button_b);
            strcat(ParamString, Param);
        }
        if (controller[iCtrlIdx].axis[j].axis_a >= 0 && controller[iCtrlIdx].axis[j].axis_b >= 0)
        {
            sprintf(Param, "axis(%i%c,%i%c) ", controller[iCtrlIdx].axis[j].axis_a, (controller[iCtrlIdx].axis[j].axis_dir_a <= 0) ? '-' : '+',
                                               controller[iCtrlIdx].axis[j].axis_b, (controller[iCtrlIdx].axis[j].axis_dir_b <= 0) ? '-' : '+' );
            strcat(ParamString, Param);
        }
        if (controller[iCtrlIdx].axis[j].hat >= 0)
        {
            sprintf(Param, "hat(%i %s %s) ", controller[iCtrlIdx].axis[j].hat,
                                             HAT_POS_NAME(controller[iCtrlIdx].axis[j].hat_pos_a),
                                             HAT_POS_NAME(controller[iCtrlIdx].axis[j].hat_pos_b));
            strcat(ParamString, Param);
        }
        if (j == 0)
            Help = "Analog axis configuration mappings";
        else
            Help = NULL;
        /* if last character is a space, chop it off */
        len = strlen(ParamString);
        if (len > 0 && ParamString[len-1] == ' ')
            ParamString[len-1] = 0;
        ConfigSetDefaultString(pConfig, button_names[X_AXIS + j], ParamString, Help);
    }

}
int auto_set_defaults(int iDeviceIdx, const char *joySDLName)
{
    FILE *pfIn;
    m64p_handle pConfig = NULL;
    const char *CfgFilePath = ConfigGetSharedDataFilepath(INI_FILE_NAME);
    enum { E_NAME_SEARCH, E_NAME_FOUND, E_PARAM_READ } eParseState;
    char *pchIni, *pchNextLine, *pchCurLine;
    long iniLength;
    int ControllersFound = 0;
    int joyFoundScore = -1;

    /* if we couldn't get a name (no joystick plugged in to given port), then return with a failure */
    if (joySDLName == NULL)
        return 0;
    /* if we couldn't find the shared data file, dump an error and return */
    if (CfgFilePath == NULL || strlen(CfgFilePath) < 1)
    {
        DebugMessage(M64MSG_ERROR, "Couldn't find config file '%s'", INI_FILE_NAME);
        return 0;
    }

    /* read the input auto-config .ini file */
    pfIn = fopen(CfgFilePath, "rb");
    if (pfIn == NULL)
    {
        DebugMessage(M64MSG_ERROR, "Couldn't open config file '%s'", CfgFilePath);
        return 0;
    }
    fseek(pfIn, 0L, SEEK_END);
    iniLength = ftell(pfIn);
    fseek(pfIn, 0L, SEEK_SET);
    if (iniLength < 0) {
        DebugMessage(M64MSG_ERROR, "Couldn't get size of config file '%s'", CfgFilePath);
        fclose(pfIn);
        return 0;
    }

    pchIni = (char *) malloc(iniLength + 1);
    if (pchIni == NULL)
    {
        DebugMessage(M64MSG_ERROR, "Couldn't allocate %li bytes for config file '%s'", iniLength, CfgFilePath);
        fclose(pfIn);
        return 0;
    }
    if (fread(pchIni, 1, iniLength, pfIn) != iniLength)
    {
        DebugMessage(M64MSG_ERROR, "File read failed for %li bytes of config file '%s'", iniLength, CfgFilePath);
        free(pchIni);
        fclose(pfIn);
        return 0;
    }
    fclose(pfIn);
    pchIni[iniLength] = 0;

    /* parse the INI file, line by line */
    DebugMessage(M64MSG_INFO, "Using auto-config file at: '%s'", CfgFilePath);
    pchNextLine = pchIni;
    eParseState = E_NAME_SEARCH;
    while (pchNextLine != NULL && *pchNextLine != 0)
    {
        char *pivot = NULL;
        int  joyFound = 0;
        /* set up character pointers */
        pchCurLine = pchNextLine;
        pchNextLine = strchr(pchNextLine, '\n');
        if (pchNextLine != NULL)
            *pchNextLine++ = 0;
        pchCurLine = StripSpace(pchCurLine);

        /* handle blank/comment lines */
        if (strlen(pchCurLine) < 1 || *pchCurLine == ';' || *pchCurLine == '#')
            continue;

        /* handle section (joystick name in ini file) */
        if (*pchCurLine == '[' && pchCurLine[strlen(pchCurLine)-1] == ']')
        {
            /* only switch to name search when some section body was identified since last header */
            if (eParseState == E_PARAM_READ)
                eParseState = E_NAME_SEARCH;

            /* we need to look through the device name word by word to see if it matches the joySDLName that we're looking for */ 
            pchCurLine[strlen(pchCurLine)-1] = 0;
            joyFound = auto_compare_name(joySDLName, StripSpace(pchCurLine + 1));
            /* if we found the right joystick, then open up the core config section to store parameters and set the 'device' param */
            if (joyFound > joyFoundScore)
            {
                char SectionName[32];
                ControllersFound = 0;
                sprintf(SectionName, "AutoConfig%i", ControllersFound);
                if (ConfigOpenSection(SectionName, &pConfig) != M64ERR_SUCCESS)
                {
                    DebugMessage(M64MSG_ERROR, "auto_set_defaults(): Couldn't open config section '%s'", SectionName);
                    free(pchIni);
                    return 0;
                }
                eParseState = E_NAME_FOUND;
                ControllersFound++;
                ConfigSetParameter(pConfig, "device", M64TYPE_INT, &iDeviceIdx);
                joyFoundScore = joyFound;
            }
            continue;
        }

        /* handle parameters */
        pivot = strchr(pchCurLine, '=');
        if (pivot != NULL)
        {
            /* if we haven't found the correct section yet, just skip this */
            if (eParseState == E_NAME_SEARCH)
                continue;
            eParseState = E_PARAM_READ;
            /* otherwise, store this parameter in the current active joystick config */
            *pivot++ = 0;
            pchCurLine = StripSpace(pchCurLine);
            pivot = StripSpace(pivot);
            if (strcasecmp(pchCurLine, "device") == 0)
            {
                int iVal = atoi(pivot);
                ConfigSetParameter(pConfig, pchCurLine, M64TYPE_INT, &iVal);
            }
            else if (strcasecmp(pchCurLine, "plugged") == 0 || strcasecmp(pchCurLine, "mouse") == 0)
            {
                int bVal = (strcasecmp(pivot, "true") == 0);
                ConfigSetParameter(pConfig, pchCurLine, M64TYPE_BOOL, &bVal);
            }
            else
            {
                ConfigSetParameter(pConfig, pchCurLine, M64TYPE_STRING, pivot);
            }
            continue;
        }

        /* handle keywords */
        if (pchCurLine[strlen(pchCurLine)-1] == ':')
        {
            /* if we haven't found the correct section yet, just skip this */
            if (eParseState == E_NAME_SEARCH)
                continue;
            eParseState = E_PARAM_READ;
            /* otherwise parse the keyword */
            if (strcmp(pchCurLine, "__NextController:") == 0)
            {
                char SectionName[32];
                /* if there are no more N64 controller spaces left, then exit */
                if (ControllersFound == 4)
                {
                    free(pchIni);
                    return ControllersFound;
                }
                /* otherwise go to the next N64 controller */
                sprintf(SectionName, "AutoConfig%i", ControllersFound);
                if (ConfigOpenSection(SectionName, &pConfig) != M64ERR_SUCCESS)
                {
                    DebugMessage(M64MSG_ERROR, "auto_set_defaults(): Couldn't open config section '%s'", SectionName);
                    free(pchIni);
                    return ControllersFound;
                }
                ControllersFound++;
                ConfigSetParameter(pConfig, "device", M64TYPE_INT, &iDeviceIdx);
            }
            else
            {
                DebugMessage(M64MSG_ERROR, "Unknown keyword '%s' in %s", pchCurLine, INI_FILE_NAME);
            }
            continue;
        }

        /* unhandled line in .ini file */
        DebugMessage(M64MSG_ERROR, "Invalid line in %s: '%s'", INI_FILE_NAME, pchCurLine);
    }

    if (joyFoundScore != -1)
    {
        /* we've finished parsing all parameters for the discovered input device, which is the last in the .ini file */
        free(pchIni);
        return ControllersFound;
    }

    free(pchIni);
    return 0;
}
Exemple #7
0
static int load_controller_config(const char *SectionName, int i, int bIsAutoconfig)
{
    m64p_handle pConfig;
    char input_str[256], value1_str[16], value2_str[16];
    const char *config_ptr;
    int j;

    /* Open the configuration section for this controller */
    if (ConfigOpenSection(SectionName, &pConfig) != M64ERR_SUCCESS)
    {
        DebugMessage(M64MSG_ERROR, "Couldn't open config section '%s'", SectionName);
        return 0;
    }
    /* Check version number, and if it doesn't match: delete the config section and return with error */
    if (!bIsAutoconfig)
    {
        float fVersion = 0.0f;
        if (ConfigGetParameter(pConfig, "version", M64TYPE_FLOAT, &fVersion, sizeof(float)) != M64ERR_SUCCESS)
        {
            ConfigDeleteSection(SectionName);
            return -1;
        }
        if (((int) fVersion) != ((int) CONFIG_VERSION))
        {
            DebugMessage(M64MSG_WARNING, "Incompatible version %.2f in config section '%s': current is %.2f. Clearing.", fVersion, SectionName, (float) CONFIG_VERSION);
            ConfigDeleteSection(SectionName);
            return -1;
        }
    }
    /* check for the required parameters */
    if (ConfigGetParameter(pConfig, "plugged", M64TYPE_BOOL, &controller[i].control->Present, sizeof(int)) != M64ERR_SUCCESS)
        return -1;
    if (ConfigGetParameter(pConfig, "plugin", M64TYPE_INT, &controller[i].control->Plugin, sizeof(int)) != M64ERR_SUCCESS)
        return -1;
    if (ConfigGetParameter(pConfig, "device", M64TYPE_INT, &controller[i].device, sizeof(int)) != M64ERR_SUCCESS)
        return -1;
    /* Name validation only applies to stored configurations (not auto-configs) */
    if (!bIsAutoconfig)
    {
        char device_name[256];
        if (ConfigGetParameter(pConfig, "name", M64TYPE_STRING, device_name, 256) != M64ERR_SUCCESS)
            device_name[0] = 0;
        if (controller[i].device == DEVICE_NOT_JOYSTICK)
        {
            /* do not load automatically generated keyboard config that was stored to disk (prefer any joysticks attached) */
            if (strcmp(device_name, "AutoKeyboard") == 0)
                return -2;
        }
        else if (controller[i].device >= 0 && device_name[0] != 0)
        {
            /* check that the SDL device name matches the name stored in the config section */
            const char *sdl_name = get_sdl_joystick_name(controller[i].device);
            if (sdl_name == NULL || strncmp(device_name, sdl_name, 255) != 0)
            {
                DebugMessage(M64MSG_WARNING, "N64 Controller #%i: SDL joystick name '%s' doesn't match stored configuration name '%s'", i + 1, sdl_name, device_name);
                return -3;
            }
        }
    }
    /* then do the optional parameters */
    ConfigGetParameter(pConfig, "mouse", M64TYPE_BOOL, &controller[i].mouse, sizeof(int));
    if (ConfigGetParameter(pConfig, "MouseSensitivity", M64TYPE_STRING, input_str, 256) == M64ERR_SUCCESS)
    {
        if (sscanf(input_str, "%f,%f", &controller[i].mouse_sens[0], &controller[i].mouse_sens[1]) != 2)
            DebugMessage(M64MSG_WARNING, "parsing error in MouseSensitivity parameter for controller %i", i + 1);
    }
    if (ConfigGetParameter(pConfig, "AnalogDeadzone", M64TYPE_STRING, input_str, 256) == M64ERR_SUCCESS)
    {
        if (sscanf(input_str, "%i,%i", &controller[i].axis_deadzone[0], &controller[i].axis_deadzone[1]) != 2)
            DebugMessage(M64MSG_WARNING, "parsing error in AnalogDeadzone parameter for controller %i", i + 1);
    }
    if (ConfigGetParameter(pConfig, "AnalogPeak", M64TYPE_STRING, input_str, 256) == M64ERR_SUCCESS)
    {
        if (sscanf(input_str, "%i,%i", &controller[i].axis_peak[0], &controller[i].axis_peak[1]) != 2)
            DebugMessage(M64MSG_WARNING, "parsing error in AnalogPeak parameter for controller %i", i + 1);
    }
    /* load configuration for all the digital buttons */
    for (j = 0; j < X_AXIS; j++)
    {
        if (ConfigGetParameter(pConfig, button_names[j], M64TYPE_STRING, input_str, 256) != M64ERR_SUCCESS)
        {
            DebugMessage(M64MSG_WARNING, "missing config key '%s' for controller %i button %i", button_names[j], i+1, j);
            continue;
        }
        if ((config_ptr = strstr(input_str, "key")) != NULL)
            if (sscanf(config_ptr, "key(%i)", (int *) &controller[i].button[j].key) != 1)
                DebugMessage(M64MSG_WARNING, "parsing error in key() parameter of button '%s' for controller %i", button_names[j], i + 1);
        if ((config_ptr = strstr(input_str, "button")) != NULL)
            if (sscanf(config_ptr, "button(%i)", &controller[i].button[j].button) != 1)
                DebugMessage(M64MSG_WARNING, "parsing error in button() parameter of button '%s' for controller %i", button_names[j], i + 1);
        if ((config_ptr = strstr(input_str, "axis")) != NULL)
        {
            char chAxisDir;
            if (sscanf(config_ptr, "axis(%d%c,%d", &controller[i].button[j].axis, &chAxisDir, &controller[i].button[j].axis_deadzone) != 3 &&
                sscanf(config_ptr, "axis(%i%c", &controller[i].button[j].axis, &chAxisDir) != 2)
                DebugMessage(M64MSG_WARNING, "parsing error in axis() parameter of button '%s' for controller %i", button_names[j], i + 1);
            controller[i].button[j].axis_dir = (chAxisDir == '+' ? 1 : (chAxisDir == '-' ? -1 : 0));
        }
        if ((config_ptr = strstr(input_str, "hat")) != NULL)
        {
            char *lastchar = NULL;
            if (sscanf(config_ptr, "hat(%i %15s", &controller[i].button[j].hat, value1_str) != 2)
                DebugMessage(M64MSG_WARNING, "parsing error in hat() parameter of button '%s' for controller %i", button_names[j], i + 1);
            value1_str[15] = 0;
            /* chop off the last character of value1_str if it is the closing parenthesis */
            lastchar = &value1_str[strlen(value1_str) - 1];
            if (lastchar > value1_str && *lastchar == ')') *lastchar = 0;
            controller[i].button[j].hat_pos = get_hat_pos_by_name(value1_str);
        }
        if ((config_ptr = strstr(input_str, "mouse")) != NULL)
            if (sscanf(config_ptr, "mouse(%i)", &controller[i].button[j].mouse) != 1)
                DebugMessage(M64MSG_WARNING, "parsing error in mouse() parameter of button '%s' for controller %i", button_names[j], i + 1);
    }
    /* load configuration for the 2 analog joystick axes */
    for (j = X_AXIS; j <= Y_AXIS; j++)
    {
        int axis_idx = j - X_AXIS;
        if (ConfigGetParameter(pConfig, button_names[j], M64TYPE_STRING, input_str, 256) != M64ERR_SUCCESS)
        {
            DebugMessage(M64MSG_WARNING, "missing config key '%s' for controller %i axis %i", button_names[j], i+1, axis_idx);
            continue;
        }
        if ((config_ptr = strstr(input_str, "key")) != NULL)
            if (sscanf(config_ptr, "key(%i,%i)", (int *) &controller[i].axis[axis_idx].key_a, (int *) &controller[i].axis[axis_idx].key_b) != 2)
                DebugMessage(M64MSG_WARNING, "parsing error in key() parameter of axis '%s' for controller %i", button_names[j], i + 1);
        if ((config_ptr = strstr(input_str, "button")) != NULL)
            if (sscanf(config_ptr, "button(%i,%i)", &controller[i].axis[axis_idx].button_a, &controller[i].axis[axis_idx].button_b) != 2)
                DebugMessage(M64MSG_WARNING, "parsing error in button() parameter of axis '%s' for controller %i", button_names[j], i + 1);
        if ((config_ptr = strstr(input_str, "axis")) != NULL)
        {
            char chAxisDir1, chAxisDir2;
            if (sscanf(config_ptr, "axis(%i%c,%i%c)", &controller[i].axis[axis_idx].axis_a, &chAxisDir1,
                                                      &controller[i].axis[axis_idx].axis_b, &chAxisDir2) != 4)
                DebugMessage(M64MSG_WARNING, "parsing error in axis() parameter of axis '%s' for controller %i", button_names[j], i + 1);
            controller[i].axis[axis_idx].axis_dir_a = (chAxisDir1 == '+' ? 1 : (chAxisDir1 == '-' ? -1 : 0));
            controller[i].axis[axis_idx].axis_dir_b = (chAxisDir2 == '+' ? 1 : (chAxisDir2 == '-' ? -1 : 0));
        }
        if ((config_ptr = strstr(input_str, "hat")) != NULL)
        {
            char *lastchar = NULL;
            if (sscanf(config_ptr, "hat(%i %15s %15s", &controller[i].axis[axis_idx].hat, value1_str, value2_str) != 3)
                DebugMessage(M64MSG_WARNING, "parsing error in hat() parameter of axis '%s' for controller %i", button_names[j], i + 1);
            value1_str[15] = value2_str[15] = 0;
            /* chop off the last character of value2_str if it is the closing parenthesis */
            lastchar = &value2_str[strlen(value2_str) - 1];
            if (lastchar > value2_str && *lastchar == ')') *lastchar = 0;
            controller[i].axis[axis_idx].hat_pos_a = get_hat_pos_by_name(value1_str);
            controller[i].axis[axis_idx].hat_pos_b = get_hat_pos_by_name(value2_str);
        }
    }

    return 1;
}
Exemple #8
0
m64p_error open_rom(const unsigned char* romimage, unsigned int size)
{
    md5_state_t state;
    md5_byte_t digest[16];
    romdatabase_entry* entry;
    char buffer[256];
    unsigned char imagetype;
    int i;
	m64p_handle CoreSection = NULL;

    /* check input requirements */
    if (rom != NULL)
    {
        DebugMessage(M64MSG_ERROR, "open_rom(): previous ROM image was not freed");
        return M64ERR_INTERNAL;
    }
    if (romimage == NULL || !is_valid_rom(romimage))
    {
        DebugMessage(M64MSG_ERROR, "open_rom(): not a valid ROM image");
        return M64ERR_INPUT_INVALID;
    }

    /* Clear Byte-swapped flag, since ROM is now deleted. */
    g_MemHasBeenBSwapped = 0;
    /* allocate new buffer for ROM and copy into this buffer */
    rom_size = size;
    rom = (unsigned char *) malloc(size);
    if (rom == NULL)
        return M64ERR_NO_MEMORY;
    memcpy(rom, romimage, size);
    swap_rom(rom, &imagetype, rom_size);

    memcpy(&ROM_HEADER, rom, sizeof(m64p_rom_header));

    /* Calculate MD5 hash  */
    md5_init(&state);
    md5_append(&state, (const md5_byte_t*)rom, rom_size);
    md5_finish(&state, digest);
    for ( i = 0; i < 16; ++i )
        sprintf(buffer+i*2, "%02X", digest[i]);
    buffer[32] = '\0';
    strcpy(ROM_SETTINGS.MD5, buffer);

    /* add some useful properties to ROM_PARAMS */
    ROM_PARAMS.systemtype = rom_country_code_to_system_type(ROM_HEADER.Country_code);
    ROM_PARAMS.vilimit = rom_system_type_to_vi_limit(ROM_PARAMS.systemtype);
    ROM_PARAMS.aidacrate = rom_system_type_to_ai_dac_rate(ROM_PARAMS.systemtype);

    memcpy(ROM_PARAMS.headername, ROM_HEADER.Name, 20);
    ROM_PARAMS.headername[20] = '\0';
    trim(ROM_PARAMS.headername); /* Remove trailing whitespace from ROM name. */

    /* Look up this ROM in the .ini file and fill in goodname, etc */
	/*
    if ((entry=ini_search_by_md5(digest)) != NULL ||
        (entry=ini_search_by_crc(sl(ROM_HEADER.CRC1),sl(ROM_HEADER.CRC2))) != NULL)
    {
        strncpy(ROM_SETTINGS.goodname, entry->goodname, 255);
        ROM_SETTINGS.goodname[255] = '\0';
        ROM_SETTINGS.savetype = entry->savetype;
        ROM_SETTINGS.status = entry->status;
        ROM_SETTINGS.players = entry->players;
        ROM_SETTINGS.rumble = entry->rumble;
    }
    else
    {
        strcpy(ROM_SETTINGS.goodname, ROM_PARAMS.headername);
        strcat(ROM_SETTINGS.goodname, " (unknown rom)");
        ROM_SETTINGS.savetype = NONE;
        ROM_SETTINGS.status = 0;
        ROM_SETTINGS.players = 0;
        ROM_SETTINGS.rumble = 0;
    }
	*/

	strcpy(ROM_SETTINGS.goodname, ROM_PARAMS.headername);
    strcat(ROM_SETTINGS.goodname, " (unknown rom)");

	ROM_SETTINGS.savetype = 0;
    if (ConfigOpenSection("Core", &CoreSection) == M64ERR_SUCCESS)
    {
		ConfigSetDefaultInt(CoreSection, "SaveType", NONE, "The savetype for the game");
		ROM_SETTINGS.savetype = ConfigGetParamInt(CoreSection, "SaveType");
    }
    
    ROM_SETTINGS.status = 0;
    ROM_SETTINGS.players = 0;
    ROM_SETTINGS.rumble = 0;


    /* print out a bunch of info about the ROM */
    DebugMessage(M64MSG_INFO, "Goodname: %s", ROM_SETTINGS.goodname);
    DebugMessage(M64MSG_INFO, "Name: %s", ROM_HEADER.Name);
    imagestring(imagetype, buffer);
    DebugMessage(M64MSG_INFO, "MD5: %s", ROM_SETTINGS.MD5);
    DebugMessage(M64MSG_INFO, "CRC: %x %x", sl(ROM_HEADER.CRC1), sl(ROM_HEADER.CRC2));
    DebugMessage(M64MSG_INFO, "Imagetype: %s", buffer);
    DebugMessage(M64MSG_INFO, "Rom size: %d bytes (or %d Mb or %d Megabits)", rom_size, rom_size/1024/1024, rom_size/1024/1024*8);
    DebugMessage(M64MSG_VERBOSE, "ClockRate = %x", sl(ROM_HEADER.ClockRate));
    DebugMessage(M64MSG_INFO, "Version: %x", sl(ROM_HEADER.Release));
    if(sl(ROM_HEADER.Manufacturer_ID) == 'N')
        DebugMessage(M64MSG_INFO, "Manufacturer: Nintendo");
    else
        DebugMessage(M64MSG_INFO, "Manufacturer: %x", sl(ROM_HEADER.Manufacturer_ID));
    DebugMessage(M64MSG_VERBOSE, "Cartridge_ID: %x", ROM_HEADER.Cartridge_ID);
    countrycodestring(ROM_HEADER.Country_code, buffer);
    DebugMessage(M64MSG_INFO, "Country: %s", buffer);
    DebugMessage(M64MSG_VERBOSE, "PC = %x", sl((unsigned int)ROM_HEADER.PC));
    DebugMessage(M64MSG_VERBOSE, "Save type: %d", ROM_SETTINGS.savetype);

    //Prepare Hack for GOLDENEYE
    isGoldeneyeRom = 0;
    if(strcmp(ROM_PARAMS.headername, "GOLDENEYE") == 0)
       isGoldeneyeRom = 1;

    return M64ERR_SUCCESS;
}
int event_set_core_defaults(void)
{
    float fConfigParamsVersion;
    int bSaveConfig = 0;

    if (ConfigOpenSection("CoreEvents", &l_CoreEventsConfig) != M64ERR_SUCCESS || l_CoreEventsConfig == NULL)
    {
        DebugMessage(M64MSG_ERROR, "Failed to open CoreEvents config section.");
        return 0; /* fail */
    }

    if (ConfigGetParameter(l_CoreEventsConfig, "Version", M64TYPE_FLOAT, &fConfigParamsVersion, sizeof(float)) != M64ERR_SUCCESS)
    {
        DebugMessage(M64MSG_WARNING, "No version number in 'CoreEvents' config section. Setting defaults.");
        ConfigDeleteSection("CoreEvents");
        ConfigOpenSection("CoreEvents", &l_CoreEventsConfig);
        bSaveConfig = 1;
    }
    else if (((int) fConfigParamsVersion) != ((int) CONFIG_PARAM_VERSION))
    {
        DebugMessage(M64MSG_WARNING, "Incompatible version %.2f in 'CoreEvents' config section: current is %.2f. Setting defaults.", fConfigParamsVersion, (float) CONFIG_PARAM_VERSION);
        ConfigDeleteSection("CoreEvents");
        ConfigOpenSection("CoreEvents", &l_CoreEventsConfig);
        bSaveConfig = 1;
    }
    else if ((CONFIG_PARAM_VERSION - fConfigParamsVersion) >= 0.0001f)
    {
        /* handle upgrades */
        float fVersion = CONFIG_PARAM_VERSION;
        ConfigSetParameter(l_CoreEventsConfig, "Version", M64TYPE_FLOAT, &fVersion);
        DebugMessage(M64MSG_INFO, "Updating parameter set version in 'CoreEvents' config section to %.2f", fVersion);
        bSaveConfig = 1;
    }

    ConfigSetDefaultFloat(l_CoreEventsConfig, "Version", CONFIG_PARAM_VERSION,  "Mupen64Plus CoreEvents config parameter set version number.  Please don't change this version number.");
    /* Keyboard presses mapped to core functions */
    ConfigSetDefaultInt(l_CoreEventsConfig, kbdStop, sdl_native2keysym(SDL_SCANCODE_ESCAPE),          "SDL keysym for stopping the emulator");
    ConfigSetDefaultInt(l_CoreEventsConfig, kbdFullscreen, sdl_native2keysym(SDL_NUM_SCANCODES),      "SDL keysym for switching between fullscreen/windowed modes");
    ConfigSetDefaultInt(l_CoreEventsConfig, kbdSave, sdl_native2keysym(SDL_SCANCODE_F5),              "SDL keysym for saving the emulator state");
    ConfigSetDefaultInt(l_CoreEventsConfig, kbdLoad, sdl_native2keysym(SDL_SCANCODE_F7),              "SDL keysym for loading the emulator state");
    ConfigSetDefaultInt(l_CoreEventsConfig, kbdIncrement, sdl_native2keysym(SDL_SCANCODE_UNKNOWN),    "SDL keysym for advancing the save state slot");
    ConfigSetDefaultInt(l_CoreEventsConfig, kbdReset, sdl_native2keysym(SDL_SCANCODE_F9),             "SDL keysym for resetting the emulator");
    ConfigSetDefaultInt(l_CoreEventsConfig, kbdSpeeddown, sdl_native2keysym(SDL_SCANCODE_F10),        "SDL keysym for slowing down the emulator");
    ConfigSetDefaultInt(l_CoreEventsConfig, kbdSpeedup, sdl_native2keysym(SDL_SCANCODE_F11),          "SDL keysym for speeding up the emulator");
    ConfigSetDefaultInt(l_CoreEventsConfig, kbdScreenshot, sdl_native2keysym(SDL_SCANCODE_F12),       "SDL keysym for taking a screenshot");
    ConfigSetDefaultInt(l_CoreEventsConfig, kbdPause, sdl_native2keysym(SDL_SCANCODE_P),              "SDL keysym for pausing the emulator");
    ConfigSetDefaultInt(l_CoreEventsConfig, kbdMute, sdl_native2keysym(SDL_SCANCODE_M),               "SDL keysym for muting/unmuting the sound");
    ConfigSetDefaultInt(l_CoreEventsConfig, kbdIncrease, sdl_native2keysym(SDL_SCANCODE_RIGHTBRACKET),"SDL keysym for increasing the volume");
    ConfigSetDefaultInt(l_CoreEventsConfig, kbdDecrease, sdl_native2keysym(SDL_SCANCODE_LEFTBRACKET), "SDL keysym for decreasing the volume");
    ConfigSetDefaultInt(l_CoreEventsConfig, kbdForward, sdl_native2keysym(SDL_SCANCODE_F),            "SDL keysym for temporarily going really fast");
    ConfigSetDefaultInt(l_CoreEventsConfig, kbdAdvance, sdl_native2keysym(SDL_SCANCODE_SLASH),        "SDL keysym for advancing by one frame when paused");
    ConfigSetDefaultInt(l_CoreEventsConfig, kbdGameshark, sdl_native2keysym(SDL_SCANCODE_G),          "SDL keysym for pressing the game shark button");
    /* Joystick events mapped to core functions */
    ConfigSetDefaultString(l_CoreEventsConfig, JoyCmdName[joyStop], "",       "Joystick event string for stopping the emulator");
    ConfigSetDefaultString(l_CoreEventsConfig, JoyCmdName[joyFullscreen], "", "Joystick event string for switching between fullscreen/windowed modes");
    ConfigSetDefaultString(l_CoreEventsConfig, JoyCmdName[joySave], "",       "Joystick event string for saving the emulator state");
    ConfigSetDefaultString(l_CoreEventsConfig, JoyCmdName[joyLoad], "",       "Joystick event string for loading the emulator state");
    ConfigSetDefaultString(l_CoreEventsConfig, JoyCmdName[joyIncrement], "",  "Joystick event string for advancing the save state slot");
    ConfigSetDefaultString(l_CoreEventsConfig, JoyCmdName[joyScreenshot], "", "Joystick event string for taking a screenshot");
    ConfigSetDefaultString(l_CoreEventsConfig, JoyCmdName[joyPause], "",      "Joystick event string for pausing the emulator");
    ConfigSetDefaultString(l_CoreEventsConfig, JoyCmdName[joyMute], "",       "Joystick event string for muting/unmuting the sound");
    ConfigSetDefaultString(l_CoreEventsConfig, JoyCmdName[joyIncrease], "",   "Joystick event string for increasing the volume");
    ConfigSetDefaultString(l_CoreEventsConfig, JoyCmdName[joyDecrease], "",   "Joystick event string for decreasing the volume");
    ConfigSetDefaultString(l_CoreEventsConfig, JoyCmdName[joyForward], "",    "Joystick event string for fast-forward");
    ConfigSetDefaultString(l_CoreEventsConfig, JoyCmdName[joyGameshark], "",  "Joystick event string for pressing the game shark button");

    if (bSaveConfig)
        ConfigSaveSection("CoreEvents");

    return 1;
}
Exemple #10
0
void load_configuration(int bPreConfig)
{
    char SectionName[32];
    int joy_plugged = 0;
    int n64CtrlIdx, sdlCtrlIdx, j;
    int sdlNumDevUsed = 0;
    int sdlDevicesUsed[4];
    eModeType OrigControlMode[4], ControlMode[4];
    int ControlDevice[4];
    char DeviceName[4][256];
    int ActiveControllers = 0;
    int sdlNumJoysticks = get_sdl_num_joysticks();
    float fVersion = 0.0f;
    const char *sdl_name;
    int ControllersFound = 0;

    /* tell user how many SDL joysticks are available */
    if (!bPreConfig)
        DebugMessage(M64MSG_INFO, "%i SDL joysticks were found.", sdlNumJoysticks);

    /* loop through 4 N64 controllers, initializing and validating special section parameters */
    for (n64CtrlIdx=0; n64CtrlIdx < 4; n64CtrlIdx++)
    {
        m64p_handle pConfig;
        /* reset the controller configuration */
        clear_controller(n64CtrlIdx);

        /* Open the configuration section for this controller */
        sprintf(SectionName, "Input-SDL-Control%i", n64CtrlIdx + 1);
        if (ConfigOpenSection(SectionName, &pConfig) != M64ERR_SUCCESS)
        {
            // this should never happen
            DebugMessage(M64MSG_ERROR, "Couldn't open config section '%s'.  Aborting...", SectionName);
            return;
        }
        /* Check version number, and if it doesn't match: delete the config section */
        fVersion = 0.0f;
        if (ConfigGetParameter(pConfig, "version", M64TYPE_FLOAT, &fVersion, sizeof(float)) != M64ERR_SUCCESS || ((int) fVersion) != ((int) CONFIG_VERSION))
        {
            DebugMessage(M64MSG_WARNING, "Missing or incompatible config section '%s'. Clearing.", SectionName);
            ConfigDeleteSection(SectionName);
            // set local controller default parameters
            OrigControlMode[n64CtrlIdx] = ControlMode[n64CtrlIdx] = E_MODE_FULL_AUTO;
            ControlDevice[n64CtrlIdx] = DEVICE_NO_JOYSTICK;
            DeviceName[n64CtrlIdx][0] = 0;
            // write blank config for GUI front-ends
            init_controller_config(n64CtrlIdx, "", E_MODE_FULL_AUTO);
            // save it to the file too
            ConfigSaveSection(SectionName);
        }
        else
        {
            if (ConfigGetParameter(pConfig, "mode", M64TYPE_INT, &OrigControlMode[n64CtrlIdx], sizeof(int)) != M64ERR_SUCCESS ||
                (int) OrigControlMode[n64CtrlIdx] < 0 || (int) OrigControlMode[n64CtrlIdx] > 2)
            {
                if (!bPreConfig)
                    DebugMessage(M64MSG_WARNING, "Missing or invalid 'mode' parameter in config section '%s'.  Setting to 2 (Fully Auto)", SectionName);
                OrigControlMode[n64CtrlIdx] = E_MODE_FULL_AUTO;
            }
            ControlMode[n64CtrlIdx] = OrigControlMode[n64CtrlIdx];
            if (ConfigGetParameter(pConfig, "device", M64TYPE_INT, &ControlDevice[n64CtrlIdx], sizeof(int)) != M64ERR_SUCCESS)
            {
                if (!bPreConfig)
                    DebugMessage(M64MSG_WARNING, "Missing 'device' parameter in config section '%s'.  Setting to -1 (No joystick)", SectionName);
                ControlDevice[n64CtrlIdx] = DEVICE_NO_JOYSTICK;
            }
            if (ConfigGetParameter(pConfig, "name", M64TYPE_STRING, DeviceName[n64CtrlIdx], 256) != M64ERR_SUCCESS)
            {
                DeviceName[n64CtrlIdx][0] = 0;
            }
        }
    }

    /* loop through 4 N64 controllers and set up those in Fully Manual mode */
    for (n64CtrlIdx=0; n64CtrlIdx < 4; n64CtrlIdx++)
    {
        if (ControlMode[n64CtrlIdx] != E_MODE_MANUAL)
            continue;
        /* load the stored configuration (disregard any errors) */
        sprintf(SectionName, "Input-SDL-Control%i", n64CtrlIdx + 1);
        load_controller_config(SectionName, n64CtrlIdx, ControlDevice[n64CtrlIdx]);
        /* if this config uses an SDL joystick, mark it as used */
        if (ControlDevice[n64CtrlIdx] == DEVICE_NO_JOYSTICK)
        {
            if (!bPreConfig)
                DebugMessage(M64MSG_INFO, "N64 Controller #%i: Using manual config with no SDL joystick (keyboard/mouse only)", n64CtrlIdx+1);
        }
        else
        {
            sdlDevicesUsed[sdlNumDevUsed++] = ControlDevice[n64CtrlIdx];
            if (!bPreConfig)
                DebugMessage(M64MSG_INFO, "N64 Controller #%i: Using manual config for SDL joystick %i", n64CtrlIdx+1, ControlDevice[n64CtrlIdx]);
        }
        ActiveControllers++;
    }

    /* now loop through again, setting up those in Named Auto mode */
    for (n64CtrlIdx=0; n64CtrlIdx < 4; n64CtrlIdx++)
    {
        if (ControlMode[n64CtrlIdx] != E_MODE_NAMED_AUTO)
            continue;
        /* if name is empty, then use full auto mode instead */
        if (DeviceName[n64CtrlIdx][0] == 0)
        {
            ControlMode[n64CtrlIdx] = E_MODE_FULL_AUTO;
            continue;
        }
        sprintf(SectionName, "Input-SDL-Control%i", n64CtrlIdx + 1);
        /* if user is looking for a keyboard, set that up */
        if (strcasecmp(DeviceName[n64CtrlIdx], "Keyboard") == 0)
        {
            auto_set_defaults(DEVICE_NO_JOYSTICK, "Keyboard");
            if (load_controller_config("AutoConfig0", n64CtrlIdx, DEVICE_NO_JOYSTICK) > 0)
            {
                if (!bPreConfig)
                    DebugMessage(M64MSG_INFO, "N64 Controller #%i: Using auto-config for keyboard", n64CtrlIdx+1);
                /* copy the auto-config settings to the controller config section */
                auto_copy_inputconfig("AutoConfig0", SectionName, "Keyboard");
                ActiveControllers++;
                ConfigSaveSection(SectionName);
            }
            else
            {
                DebugMessage(M64MSG_ERROR, "Autoconfig keyboard setup invalid");
            }
            ConfigDeleteSection("AutoConfig0");
            continue;
        }
        /* search for an unused SDL device with the matching name */
        for (sdlCtrlIdx=0; sdlCtrlIdx < sdlNumJoysticks; sdlCtrlIdx++)
        {
            /* check if this one is in use */
            int deviceAlreadyUsed = 0;
            for (j = 0; j < sdlNumDevUsed; j++)
            {
                if (sdlDevicesUsed[j] == sdlCtrlIdx)
                    deviceAlreadyUsed = 1;
            }
            if (deviceAlreadyUsed)
                continue;
            /* check if the name matches */
            sdl_name = get_sdl_joystick_name(sdlCtrlIdx);
            if (sdl_name != NULL && strncmp(DeviceName[n64CtrlIdx], sdl_name, 255) == 0)
            {
                /* set up one or more controllers for this SDL device, if present in InputAutoConfig.ini */
                int ControllersFound = setup_auto_controllers(bPreConfig, n64CtrlIdx, sdlCtrlIdx, sdl_name, ControlMode, OrigControlMode, DeviceName);
                if (ControllersFound == 0)
                {
                    // error: no auto-config found for this SDL device
                    DebugMessage(M64MSG_ERROR, "No auto-config found for joystick named '%s' in InputAutoConfig.ini", sdl_name);
                    // mark this device as being used just so we don't complain about it again
                    sdlDevicesUsed[sdlNumDevUsed++] = sdlCtrlIdx;
                    // quit looking for SDL joysticks which match the name, because there's no valid autoconfig for that name.
                    // this controller will be unused; skip to the next one
                    break;
                }
                /* mark this sdl device as used */
                sdlDevicesUsed[sdlNumDevUsed++] = sdlCtrlIdx;
                ActiveControllers += ControllersFound;
                break;
            }
        }
        /* if we didn't find a match for this joystick name, then set the controller to fully auto */
        if (sdlCtrlIdx == sdlNumJoysticks)
        {
            if (!bPreConfig)
                DebugMessage(M64MSG_WARNING, "N64 Controller #%i: No SDL joystick found matching name '%s'.  Using full auto mode.", n64CtrlIdx+1, DeviceName[n64CtrlIdx]);
            ControlMode[n64CtrlIdx] = E_MODE_FULL_AUTO;
        }
    }

    /* Final loop through N64 controllers, setting up those in Full Auto mode */
    for (n64CtrlIdx=0; n64CtrlIdx < 4; n64CtrlIdx++)
    {
        if (ControlMode[n64CtrlIdx] != E_MODE_FULL_AUTO)
            continue;
        sprintf(SectionName, "Input-SDL-Control%i", n64CtrlIdx + 1);
        /* search for an unused SDL device */
        for (sdlCtrlIdx=0; sdlCtrlIdx < sdlNumJoysticks; sdlCtrlIdx++)
        {
            /* check if this one is in use */
            int deviceAlreadyUsed = 0;
            for (j = 0; j < sdlNumDevUsed; j++)
            {
                if (sdlDevicesUsed[j] == sdlCtrlIdx)
                    deviceAlreadyUsed = 1;
            }
            if (deviceAlreadyUsed)
                continue;
            /* set up one or more controllers for this SDL device, if present in InputAutoConfig.ini */
            sdl_name = get_sdl_joystick_name(sdlCtrlIdx);
            ControllersFound = setup_auto_controllers(bPreConfig, n64CtrlIdx, sdlCtrlIdx, sdl_name, ControlMode, OrigControlMode, DeviceName);
            if (!bPreConfig && ControllersFound == 0)
            {
                // error: no auto-config found for this SDL device
                DebugMessage(M64MSG_ERROR, "No auto-config found for joystick named '%s' in InputAutoConfig.ini", sdl_name);
                // mark this device as being used just so we don't complain about it again
                sdlDevicesUsed[sdlNumDevUsed++] = sdlCtrlIdx;
                // keep trying more SDL devices to see if we can auto-config one for this N64 controller
                continue;
            }
            /* mark this sdl device as used */
            sdlDevicesUsed[sdlNumDevUsed++] = sdlCtrlIdx;
            ActiveControllers += ControllersFound;
            break;
        }
        /* if this N64 controller was not activated, set device to -1 */
        if (sdlCtrlIdx == sdlNumJoysticks)
        {
            m64p_handle section;
            if (ConfigOpenSection(SectionName, &section) == M64ERR_SUCCESS)
            {
                const int iNoDevice = -1;
                ConfigSetParameter(section, "device", M64TYPE_INT, &iNoDevice);
                if (OrigControlMode[n64CtrlIdx] == E_MODE_FULL_AUTO)
                    ConfigSetParameter(section, "name", M64TYPE_STRING, "");
                ConfigSaveSection(SectionName);
            }
        }
    }

    /* fallback to keyboard if no controllers were configured */
    if (ActiveControllers == 0)
    {
        if (!bPreConfig)
            DebugMessage(M64MSG_INFO, "N64 Controller #1: Forcing default keyboard configuration");
        auto_set_defaults(DEVICE_NO_JOYSTICK, "Keyboard");
        if (load_controller_config("AutoConfig0", 0, DEVICE_NO_JOYSTICK) > 0)
        {
            /* copy the auto-config settings to the controller config section */
            if (OrigControlMode[0] == E_MODE_FULL_AUTO)
                auto_copy_inputconfig("AutoConfig0", "Input-SDL-Control1", "Keyboard");
            else
                auto_copy_inputconfig("AutoConfig0", "Input-SDL-Control1", NULL);  // don't overwrite 'name' parameter
            ActiveControllers++;
            ConfigSaveSection("Input-SDL-Control1");
        }
        else
        {
            DebugMessage(M64MSG_ERROR, "Autoconfig keyboard setup invalid");
        }
        ConfigDeleteSection("AutoConfig0");
    }

    /* see how many joysticks are plugged in */
    joy_plugged = 0;
    for (j = 0; j < 4; j++)
    {
        if (controller[j].control->Present)
            joy_plugged++;
    }

    /* print out summary info message */
    if (!bPreConfig)
    {
        if (joy_plugged > 0)
        {
            DebugMessage(M64MSG_INFO, "%i controller(s) found, %i plugged in and usable in the emulator", ActiveControllers, joy_plugged);
        }
        else
        {
            if (ActiveControllers == 0)
                DebugMessage(M64MSG_WARNING, "No joysticks/controllers found");
            else
                DebugMessage(M64MSG_WARNING, "%i controllers found, but none were 'plugged in'", ActiveControllers);
        }
    }

}
Exemple #11
0
static int load_controller_config(const char *SectionName, int i, int sdlDeviceIdx)
{
    m64p_handle pConfig;
    char input_str[256], value1_str[NUM_BUTTONS], value2_str[NUM_BUTTONS];
    const char *config_ptr;
    int j;

    /* Open the configuration section for this controller */
    if (ConfigOpenSection(SectionName, &pConfig) != M64ERR_SUCCESS)
    {
        DebugMessage(M64MSG_ERROR, "Couldn't open config section '%s'", SectionName);
        return 0;
    }

    /* set SDL device number */
    controller[i].device = sdlDeviceIdx;

    /* throw warnings if 'plugged' or 'plugin' are missing */
    if (ConfigGetParameter(pConfig, "plugged", M64TYPE_BOOL, &controller[i].control->Present, sizeof(int)) != M64ERR_SUCCESS)
    {
        DebugMessage(M64MSG_WARNING, "missing 'plugged' parameter from config section %s. Setting to 1 (true).", SectionName);
        controller[i].control->Present = 1;
    }
    if (ConfigGetParameter(pConfig, "plugin", M64TYPE_INT, &controller[i].control->Plugin, sizeof(int)) != M64ERR_SUCCESS)
    {
        DebugMessage(M64MSG_WARNING, "missing 'plugin' parameter from config section %s. Setting to 1 (none).", SectionName);
        controller[i].control->Plugin = PLUGIN_NONE;
    }
    /* load optional parameters */
    ConfigGetParameter(pConfig, "mouse", M64TYPE_BOOL, &controller[i].mouse, sizeof(int));
    if (ConfigGetParameter(pConfig, "MouseSensitivity", M64TYPE_STRING, input_str, 256) == M64ERR_SUCCESS)
    {
        if (sscanf(input_str, "%f,%f", &controller[i].mouse_sens[0], &controller[i].mouse_sens[1]) != 2)
            DebugMessage(M64MSG_WARNING, "parsing error in MouseSensitivity parameter for controller %i", i + 1);
    }
    if (ConfigGetParameter(pConfig, "AnalogDeadzone", M64TYPE_STRING, input_str, 256) == M64ERR_SUCCESS)
    {
        if (sscanf(input_str, "%i,%i", &controller[i].axis_deadzone[0], &controller[i].axis_deadzone[1]) != 2)
            DebugMessage(M64MSG_WARNING, "parsing error in AnalogDeadzone parameter for controller %i", i + 1);
    }
    if (ConfigGetParameter(pConfig, "AnalogPeak", M64TYPE_STRING, input_str, 256) == M64ERR_SUCCESS)
    {
        if (sscanf(input_str, "%i,%i", &controller[i].axis_peak[0], &controller[i].axis_peak[1]) != 2)
            DebugMessage(M64MSG_WARNING, "parsing error in AnalogPeak parameter for controller %i", i + 1);
    }
    /* load configuration for all the digital buttons */
    for (j = 0; j < X_AXIS; j++)
    {
        if (ConfigGetParameter(pConfig, button_names[j], M64TYPE_STRING, input_str, 256) != M64ERR_SUCCESS)
        {
            DebugMessage(M64MSG_WARNING, "missing config key '%s' for controller %i button %i", button_names[j], i+1, j);
            continue;
        }
        if ((config_ptr = strstr(input_str, "key")) != NULL)
            if (sscanf(config_ptr, "key(%i)", (int *) &controller[i].button[j].key) != 1)
                DebugMessage(M64MSG_WARNING, "parsing error in key() parameter of button '%s' for controller %i", button_names[j], i + 1);
        if ((config_ptr = strstr(input_str, "button")) != NULL)
            if (sscanf(config_ptr, "button(%i)", &controller[i].button[j].button) != 1)
                DebugMessage(M64MSG_WARNING, "parsing error in button() parameter of button '%s' for controller %i", button_names[j], i + 1);
        if ((config_ptr = strstr(input_str, "axis")) != NULL)
        {
            char chAxisDir;
            if (sscanf(config_ptr, "axis(%d%c,%d", &controller[i].button[j].axis, &chAxisDir, &controller[i].button[j].axis_deadzone) != 3 &&
                sscanf(config_ptr, "axis(%i%c", &controller[i].button[j].axis, &chAxisDir) != 2)
                DebugMessage(M64MSG_WARNING, "parsing error in axis() parameter of button '%s' for controller %i", button_names[j], i + 1);
            controller[i].button[j].axis_dir = (chAxisDir == '+' ? 1 : (chAxisDir == '-' ? -1 : 0));
        }
        if ((config_ptr = strstr(input_str, "hat")) != NULL)
        {
            char *lastchar = NULL;
            if (sscanf(config_ptr, "hat(%i %15s", &controller[i].button[j].hat, value1_str) != 2)
                DebugMessage(M64MSG_WARNING, "parsing error in hat() parameter of button '%s' for controller %i", button_names[j], i + 1);
            value1_str[15] = 0;
            /* chop off the last character of value1_str if it is the closing parenthesis */
            lastchar = &value1_str[strlen(value1_str) - 1];
            if (lastchar > value1_str && *lastchar == ')') *lastchar = 0;
            controller[i].button[j].hat_pos = get_hat_pos_by_name(value1_str);
        }
        if ((config_ptr = strstr(input_str, "mouse")) != NULL) {
			// check for mouse_pseudo button first
			if ((config_ptr = strstr(input_str, "mouse_up")) != NULL) {controller[i].button[j].mouse_up=1; controller[i].mouse_up=1;}
			else if ((config_ptr = strstr(input_str, "mouse_down")) != NULL) {controller[i].button[j].mouse_down=1; controller[i].mouse_down=1;}
			else if ((config_ptr = strstr(input_str, "mouse_left")) != NULL) {controller[i].button[j].mouse_left=1; controller[i].mouse_left=1;}
			else if ((config_ptr = strstr(input_str, "mouse_right")) != NULL) {controller[i].button[j].mouse_right=1; controller[i].mouse_right=1;}
            else if (sscanf(config_ptr, "mouse(%i)", &controller[i].button[j].mouse) != 1)
                DebugMessage(M64MSG_WARNING, "parsing error in mouse() parameter of button '%s' for controller %i", button_names[j], i + 1);
		}
    }
    /* load configuration for the 2 analog joystick axes */
    for (j = X_AXIS; j <= Y_AXIS; j++)
    {
        int axis_idx = j - X_AXIS;
        if (ConfigGetParameter(pConfig, button_names[j], M64TYPE_STRING, input_str, 256) != M64ERR_SUCCESS)
        {
            DebugMessage(M64MSG_WARNING, "missing config key '%s' for controller %i axis %i", button_names[j], i+1, axis_idx);
            continue;
        }
        if ((config_ptr = strstr(input_str, "key")) != NULL)
            if (sscanf(config_ptr, "key(%i,%i)", (int *) &controller[i].axis[axis_idx].key_a, (int *) &controller[i].axis[axis_idx].key_b) != 2)
                DebugMessage(M64MSG_WARNING, "parsing error in key() parameter of axis '%s' for controller %i", button_names[j], i + 1);
        if ((config_ptr = strstr(input_str, "button")) != NULL)
            if (sscanf(config_ptr, "button(%i,%i)", &controller[i].axis[axis_idx].button_a, &controller[i].axis[axis_idx].button_b) != 2)
                DebugMessage(M64MSG_WARNING, "parsing error in button() parameter of axis '%s' for controller %i", button_names[j], i + 1);
        if ((config_ptr = strstr(input_str, "axis")) != NULL)
        {
            char chAxisDir1, chAxisDir2;
            if (sscanf(config_ptr, "axis(%i%c,%i%c)", &controller[i].axis[axis_idx].axis_a, &chAxisDir1,
                                                      &controller[i].axis[axis_idx].axis_b, &chAxisDir2) != 4)
                DebugMessage(M64MSG_WARNING, "parsing error in axis() parameter of axis '%s' for controller %i", button_names[j], i + 1);
            controller[i].axis[axis_idx].axis_dir_a = (chAxisDir1 == '+' ? 1 : (chAxisDir1 == '-' ? -1 : 0));
            controller[i].axis[axis_idx].axis_dir_b = (chAxisDir2 == '+' ? 1 : (chAxisDir2 == '-' ? -1 : 0));
        }
        if ((config_ptr = strstr(input_str, "hat")) != NULL)
        {
            char *lastchar = NULL;
            if (sscanf(config_ptr, "hat(%i %15s %15s", &controller[i].axis[axis_idx].hat, value1_str, value2_str) != 3)
                DebugMessage(M64MSG_WARNING, "parsing error in hat() parameter of axis '%s' for controller %i", button_names[j], i + 1);
            value1_str[15] = value2_str[15] = 0;
            /* chop off the last character of value2_str if it is the closing parenthesis */
            lastchar = &value2_str[strlen(value2_str) - 1];
            if (lastchar > value2_str && *lastchar == ')') *lastchar = 0;
            controller[i].axis[axis_idx].hat_pos_a = get_hat_pos_by_name(value1_str);
            controller[i].axis[axis_idx].hat_pos_b = get_hat_pos_by_name(value2_str);
        }
    }

    return 1;
}