void GBAConfigMap(const struct GBAConfig* config, struct GBAOptions* opts) { _lookupCharValue(config, "bios", &opts->bios); _lookupCharValue(config, "shader", &opts->shader); _lookupIntValue(config, "logLevel", &opts->logLevel); _lookupIntValue(config, "frameskip", &opts->frameskip); _lookupIntValue(config, "volume", &opts->volume); _lookupIntValue(config, "rewindBufferCapacity", &opts->rewindBufferCapacity); _lookupIntValue(config, "rewindBufferInterval", &opts->rewindBufferInterval); _lookupFloatValue(config, "fpsTarget", &opts->fpsTarget); unsigned audioBuffers; if (_lookupUIntValue(config, "audioBuffers", &audioBuffers)) { opts->audioBuffers = audioBuffers; } _lookupUIntValue(config, "sampleRate", &opts->sampleRate); int fakeBool; if (_lookupIntValue(config, "useBios", &fakeBool)) { opts->useBios = fakeBool; } if (_lookupIntValue(config, "audioSync", &fakeBool)) { opts->audioSync = fakeBool; } if (_lookupIntValue(config, "videoSync", &fakeBool)) { opts->videoSync = fakeBool; } if (_lookupIntValue(config, "lockAspectRatio", &fakeBool)) { opts->lockAspectRatio = fakeBool; } if (_lookupIntValue(config, "resampleVideo", &fakeBool)) { opts->resampleVideo = fakeBool; } if (_lookupIntValue(config, "suspendScreensaver", &fakeBool)) { opts->suspendScreensaver = fakeBool; } if (_lookupIntValue(config, "mute", &fakeBool)) { opts->mute = fakeBool; } if (_lookupIntValue(config, "skipBios", &fakeBool)) { opts->skipBios = fakeBool; } if (_lookupIntValue(config, "rewindEnable", &fakeBool)) { opts->rewindEnable = fakeBool; } _lookupIntValue(config, "fullscreen", &opts->fullscreen); _lookupIntValue(config, "width", &opts->width); _lookupIntValue(config, "height", &opts->height); _lookupCharValue(config, "savegamePath", &opts->savegamePath); _lookupCharValue(config, "savestatePath", &opts->savestatePath); _lookupCharValue(config, "screenshotPath", &opts->screenshotPath); _lookupCharValue(config, "patchPath", &opts->patchPath); char* idleOptimization = 0; if (_lookupCharValue(config, "idleOptimization", &idleOptimization)) { if (strcasecmp(idleOptimization, "ignore") == 0) { opts->idleOptimization = IDLE_LOOP_IGNORE; } else if (strcasecmp(idleOptimization, "remove") == 0) { opts->idleOptimization = IDLE_LOOP_REMOVE; } else if (strcasecmp(idleOptimization, "detect") == 0) { opts->idleOptimization = IDLE_LOOP_DETECT; } free(idleOptimization); } }
bool mGLES2ShaderLoad(struct VideoShader* shader, struct VDir* dir) { struct VFile* manifest = dir->openFile(dir, "manifest.ini", O_RDONLY); if (!manifest) { return false; } bool success = false; struct Configuration description; ConfigurationInit(&description); if (ConfigurationReadVFile(&description, manifest)) { int inShaders; success = _lookupIntValue(&description, "shader", "passes", &inShaders); if (inShaders > MAX_PASSES || inShaders < 1) { success = false; } if (success) { struct mGLES2Shader* shaderBlock = malloc(sizeof(struct mGLES2Shader) * inShaders); int n; for (n = 0; n < inShaders; ++n) { char passName[12]; snprintf(passName, sizeof(passName), "pass.%u", n); const char* fs = ConfigurationGetValue(&description, passName, "fragmentShader"); const char* vs = ConfigurationGetValue(&description, passName, "vertexShader"); if (fs && (fs[0] == '.' || strstr(fs, PATH_SEP))) { success = false; break; } if (vs && (vs[0] == '.' || strstr(vs, PATH_SEP))) { success = false; break; } char* fssrc = 0; char* vssrc = 0; if (fs) { struct VFile* fsf = dir->openFile(dir, fs, O_RDONLY); if (!fsf) { success = false; break; } fssrc = malloc(fsf->size(fsf) + 1); fssrc[fsf->size(fsf)] = '\0'; fsf->read(fsf, fssrc, fsf->size(fsf)); fsf->close(fsf); } if (vs) { struct VFile* vsf = dir->openFile(dir, vs, O_RDONLY); if (!vsf) { success = false; free(fssrc); break; } vssrc = malloc(vsf->size(vsf) + 1); vssrc[vsf->size(vsf)] = '\0'; vsf->read(vsf, vssrc, vsf->size(vsf)); vsf->close(vsf); } int width = 0; int height = 0; int scaling = 0; _lookupIntValue(&description, passName, "width", &width); _lookupIntValue(&description, passName, "height", &height); _lookupIntValue(&description, passName, "integerScaling", &scaling); struct mGLES2UniformList uniformVector; mGLES2UniformListInit(&uniformVector, 0); ConfigurationEnumerateSections(&description, _uniformHandler, &uniformVector); size_t u; for (u = 0; u < mGLES2UniformListSize(&uniformVector); ++u) { struct mGLES2Uniform* uniform = mGLES2UniformListGetPointer(&uniformVector, u); if (!_loadUniform(&description, n, uniform)) { mGLES2UniformListShift(&uniformVector, u, 1); --u; } } u = mGLES2UniformListSize(&uniformVector); struct mGLES2Uniform* uniformBlock = malloc(sizeof(*uniformBlock) * u); memcpy(uniformBlock, mGLES2UniformListGetPointer(&uniformVector, 0), sizeof(*uniformBlock) * u); mGLES2UniformListDeinit(&uniformVector); mGLES2ShaderInit(&shaderBlock[n], vssrc, fssrc, width, height, scaling, uniformBlock, u); int b = 0; _lookupIntValue(&description, passName, "blend", &b); if (b) { shaderBlock[n].blend = b; } b = 0; _lookupIntValue(&description, passName, "filter", &b); if (b) { shaderBlock[n].filter = b; } free(fssrc); free(vssrc); } if (success) { shader->nPasses = inShaders; shader->passes = shaderBlock; shader->name = ConfigurationGetValue(&description, "shader", "name"); if (shader->name) { shader->name = strdup(shader->name); } shader->author = ConfigurationGetValue(&description, "shader", "author"); if (shader->author) { shader->author = strdup(shader->author); } shader->description = ConfigurationGetValue(&description, "shader", "description"); if (shader->description) { shader->description = strdup(shader->description); } } else { inShaders = n; for (n = 0; n < inShaders; ++n) { mGLES2ShaderDeinit(&shaderBlock[n]); } } } } manifest->close(manifest); ConfigurationDeinit(&description); return success; }
bool GBAConfigGetIntValue(const struct GBAConfig* config, const char* key, int* value) { return _lookupIntValue(config, key, value); }
static void _loadValue(struct Configuration* description, const char* name, GLenum type, const char* field, union mGLES2UniformValue* value) { char fieldName[16]; switch (type) { case GL_FLOAT: value->f = 0; _lookupFloatValue(description, name, field, &value->f); break; case GL_FLOAT_VEC2: value->fvec2[0] = 0; value->fvec2[1] = 0; snprintf(fieldName, sizeof(fieldName), "%s[0]", field); _lookupFloatValue(description, name, fieldName, &value->fvec2[0]); snprintf(fieldName, sizeof(fieldName), "%s[1]", field); _lookupFloatValue(description, name, fieldName, &value->fvec2[1]); break; case GL_FLOAT_VEC3: value->fvec3[0] = 0; value->fvec3[1] = 0; value->fvec3[2] = 0; snprintf(fieldName, sizeof(fieldName), "%s[0]", field); _lookupFloatValue(description, name, fieldName, &value->fvec3[0]); snprintf(fieldName, sizeof(fieldName), "%s[1]", field); _lookupFloatValue(description, name, fieldName, &value->fvec3[1]); snprintf(fieldName, sizeof(fieldName), "%s[2]", field); _lookupFloatValue(description, name, fieldName, &value->fvec3[2]); break; case GL_FLOAT_VEC4: value->fvec4[0] = 0; value->fvec4[1] = 0; value->fvec4[2] = 0; value->fvec4[3] = 0; snprintf(fieldName, sizeof(fieldName), "%s[0]", field); _lookupFloatValue(description, name, fieldName, &value->fvec4[0]); snprintf(fieldName, sizeof(fieldName), "%s[1]", field); _lookupFloatValue(description, name, fieldName, &value->fvec4[1]); snprintf(fieldName, sizeof(fieldName), "%s[2]", field); _lookupFloatValue(description, name, fieldName, &value->fvec4[2]); snprintf(fieldName, sizeof(fieldName), "%s[3]", field); _lookupFloatValue(description, name, fieldName, &value->fvec4[3]); break; case GL_FLOAT_MAT2: value->fmat2x2[0] = 0; value->fmat2x2[1] = 0; value->fmat2x2[2] = 0; value->fmat2x2[3] = 0; snprintf(fieldName, sizeof(fieldName), "%s[0,0]", field); _lookupFloatValue(description, name, fieldName, &value->fmat2x2[0]); snprintf(fieldName, sizeof(fieldName), "%s[0,1]", field); _lookupFloatValue(description, name, fieldName, &value->fmat2x2[1]); snprintf(fieldName, sizeof(fieldName), "%s[1,0]", field); _lookupFloatValue(description, name, fieldName, &value->fmat2x2[2]); snprintf(fieldName, sizeof(fieldName), "%s[1,1]", field); _lookupFloatValue(description, name, fieldName, &value->fmat2x2[3]); break; case GL_FLOAT_MAT3: value->fmat3x3[0] = 0; value->fmat3x3[1] = 0; value->fmat3x3[2] = 0; value->fmat3x3[3] = 0; value->fmat3x3[4] = 0; value->fmat3x3[5] = 0; value->fmat3x3[6] = 0; value->fmat3x3[7] = 0; value->fmat3x3[8] = 0; snprintf(fieldName, sizeof(fieldName), "%s[0,0]", field); _lookupFloatValue(description, name, fieldName, &value->fmat3x3[0]); snprintf(fieldName, sizeof(fieldName), "%s[0,1]", field); _lookupFloatValue(description, name, fieldName, &value->fmat3x3[1]); snprintf(fieldName, sizeof(fieldName), "%s[0,2]", field); _lookupFloatValue(description, name, fieldName, &value->fmat3x3[2]); snprintf(fieldName, sizeof(fieldName), "%s[1,0]", field); _lookupFloatValue(description, name, fieldName, &value->fmat3x3[3]); snprintf(fieldName, sizeof(fieldName), "%s[1,1]", field); _lookupFloatValue(description, name, fieldName, &value->fmat3x3[4]); snprintf(fieldName, sizeof(fieldName), "%s[1,2]", field); _lookupFloatValue(description, name, fieldName, &value->fmat3x3[5]); snprintf(fieldName, sizeof(fieldName), "%s[2,0]", field); _lookupFloatValue(description, name, fieldName, &value->fmat3x3[6]); snprintf(fieldName, sizeof(fieldName), "%s[2,1]", field); _lookupFloatValue(description, name, fieldName, &value->fmat3x3[7]); snprintf(fieldName, sizeof(fieldName), "%s[2,2]", field); _lookupFloatValue(description, name, fieldName, &value->fmat3x3[8]); break; case GL_FLOAT_MAT4: value->fmat4x4[0] = 0; value->fmat4x4[1] = 0; value->fmat4x4[2] = 0; value->fmat4x4[3] = 0; value->fmat4x4[4] = 0; value->fmat4x4[5] = 0; value->fmat4x4[6] = 0; value->fmat4x4[7] = 0; value->fmat4x4[8] = 0; value->fmat4x4[9] = 0; value->fmat4x4[10] = 0; value->fmat4x4[11] = 0; value->fmat4x4[12] = 0; value->fmat4x4[13] = 0; value->fmat4x4[14] = 0; value->fmat4x4[15] = 0; snprintf(fieldName, sizeof(fieldName), "%s[0,0]", field); _lookupFloatValue(description, name, fieldName, &value->fmat4x4[0]); snprintf(fieldName, sizeof(fieldName), "%s[0,1]", field); _lookupFloatValue(description, name, fieldName, &value->fmat4x4[1]); snprintf(fieldName, sizeof(fieldName), "%s[0,2]", field); _lookupFloatValue(description, name, fieldName, &value->fmat4x4[2]); snprintf(fieldName, sizeof(fieldName), "%s[0,3]", field); _lookupFloatValue(description, name, fieldName, &value->fmat4x4[3]); snprintf(fieldName, sizeof(fieldName), "%s[1,0]", field); _lookupFloatValue(description, name, fieldName, &value->fmat4x4[4]); snprintf(fieldName, sizeof(fieldName), "%s[1,1]", field); _lookupFloatValue(description, name, fieldName, &value->fmat4x4[5]); snprintf(fieldName, sizeof(fieldName), "%s[1,2]", field); _lookupFloatValue(description, name, fieldName, &value->fmat4x4[6]); snprintf(fieldName, sizeof(fieldName), "%s[1,3]", field); _lookupFloatValue(description, name, fieldName, &value->fmat4x4[7]); snprintf(fieldName, sizeof(fieldName), "%s[2,0]", field); _lookupFloatValue(description, name, fieldName, &value->fmat4x4[8]); snprintf(fieldName, sizeof(fieldName), "%s[2,1]", field); _lookupFloatValue(description, name, fieldName, &value->fmat4x4[9]); snprintf(fieldName, sizeof(fieldName), "%s[2,2]", field); _lookupFloatValue(description, name, fieldName, &value->fmat4x4[10]); snprintf(fieldName, sizeof(fieldName), "%s[2,3]", field); _lookupFloatValue(description, name, fieldName, &value->fmat4x4[11]); snprintf(fieldName, sizeof(fieldName), "%s[3,0]", field); _lookupFloatValue(description, name, fieldName, &value->fmat4x4[12]); snprintf(fieldName, sizeof(fieldName), "%s[3,1]", field); _lookupFloatValue(description, name, fieldName, &value->fmat4x4[13]); snprintf(fieldName, sizeof(fieldName), "%s[3,2]", field); _lookupFloatValue(description, name, fieldName, &value->fmat4x4[14]); snprintf(fieldName, sizeof(fieldName), "%s[3,3]", field); _lookupFloatValue(description, name, fieldName, &value->fmat4x4[15]); break; case GL_INT: value->i = 0; _lookupIntValue(description, name, field, &value->i); break; case GL_INT_VEC2: value->ivec2[0] = 0; value->ivec2[1] = 0; snprintf(fieldName, sizeof(fieldName), "%s[0]", field); _lookupIntValue(description, name, fieldName, &value->ivec2[0]); snprintf(fieldName, sizeof(fieldName), "%s[1]", field); _lookupIntValue(description, name, fieldName, &value->ivec2[1]); break; case GL_INT_VEC3: value->ivec3[0] = 0; value->ivec3[1] = 0; value->ivec3[2] = 0; snprintf(fieldName, sizeof(fieldName), "%s[0]", field); _lookupIntValue(description, name, fieldName, &value->ivec3[0]); snprintf(fieldName, sizeof(fieldName), "%s[1]", field); _lookupIntValue(description, name, fieldName, &value->ivec3[1]); snprintf(fieldName, sizeof(fieldName), "%s[2]", field); _lookupIntValue(description, name, fieldName, &value->ivec3[2]); break; case GL_INT_VEC4: value->ivec4[0] = 0; value->ivec4[1] = 0; value->ivec4[2] = 0; value->ivec4[3] = 0; snprintf(fieldName, sizeof(fieldName), "%s[0]", field); _lookupIntValue(description, name, fieldName, &value->ivec4[0]); snprintf(fieldName, sizeof(fieldName), "%s[1]", field); _lookupIntValue(description, name, fieldName, &value->ivec4[1]); snprintf(fieldName, sizeof(fieldName), "%s[2]", field); _lookupIntValue(description, name, fieldName, &value->ivec4[2]); snprintf(fieldName, sizeof(fieldName), "%s[3]", field); _lookupIntValue(description, name, fieldName, &value->ivec4[3]); break; case GL_BOOL: value->b = 0; _lookupBoolValue(description, name, field, &value->b); break; case GL_BOOL_VEC2: value->bvec2[0] = 0; value->bvec2[1] = 0; snprintf(fieldName, sizeof(fieldName), "%s[0]", field); _lookupBoolValue(description, name, fieldName, &value->bvec2[0]); snprintf(fieldName, sizeof(fieldName), "%s[1]", field); _lookupBoolValue(description, name, fieldName, &value->bvec2[1]); break; case GL_BOOL_VEC3: value->bvec3[0] = 0; value->bvec3[1] = 0; value->bvec3[2] = 0; snprintf(fieldName, sizeof(fieldName), "%s[0]", field); _lookupBoolValue(description, name, fieldName, &value->bvec3[0]); snprintf(fieldName, sizeof(fieldName), "%s[1]", field); _lookupBoolValue(description, name, fieldName, &value->bvec3[1]); snprintf(fieldName, sizeof(fieldName), "%s[2]", field); _lookupBoolValue(description, name, fieldName, &value->bvec3[2]); break; case GL_BOOL_VEC4: value->bvec4[0] = 0; value->bvec4[1] = 0; value->bvec4[2] = 0; value->bvec4[3] = 0; snprintf(fieldName, sizeof(fieldName), "%s[0]", field); _lookupBoolValue(description, name, fieldName, &value->bvec4[0]); snprintf(fieldName, sizeof(fieldName), "%s[1]", field); _lookupBoolValue(description, name, fieldName, &value->bvec4[1]); snprintf(fieldName, sizeof(fieldName), "%s[2]", field); _lookupBoolValue(description, name, fieldName, &value->bvec4[2]); snprintf(fieldName, sizeof(fieldName), "%s[3]", field); _lookupBoolValue(description, name, fieldName, &value->bvec4[3]); break; } }