const char *S9xGetFilenameInc (const char *e, enum s9x_getdirtype dirtype) { static char filename [PATH_MAX + 1]; char dir [_MAX_DIR + 1]; char drive [_MAX_DRIVE + 1]; char fname [_MAX_FNAME + 1]; char ext [_MAX_EXT + 1]; unsigned int i=0; const char *d; _splitpath (Memory.ROMFilename, drive, dir, fname, ext); d=S9xGetDirectory(dirtype); do { _snprintf(filename, sizeof(filename), "%s\\%s%03d%s", d, fname, i, e); i++; } while(_taccess (_tFromChar(filename), 0) == 0 && i!=0); return (filename); }
bool CGLCG::LoadShader(const TCHAR *shaderFile) { CCGShader cgShader; TCHAR shaderPath[MAX_PATH]; TCHAR tempPath[MAX_PATH]; CGprofile vertexProfile, fragmentProfile; GLenum error; if(!fboFunctionsLoaded) { MessageBox(NULL, TEXT("Your OpenGL graphics driver does not support framebuffer objects.\nYou will not be able to use CG shaders in OpenGL mode."), TEXT("CG Error"), MB_OK|MB_ICONEXCLAMATION); return false; } vertexProfile = cgGLGetLatestProfile(CG_GL_VERTEX); fragmentProfile = cgGLGetLatestProfile(CG_GL_FRAGMENT); cgGLDisableProfile(vertexProfile); cgGLDisableProfile(fragmentProfile); ClearPasses(); if (shaderFile == NULL || *shaderFile==TEXT('\0')) return true; lstrcpy(shaderPath, shaderFile); ReduceToPath(shaderPath); SetCurrentDirectory(shaderPath); if(!cgShader.LoadShader(_tToChar(shaderFile))) return false; cgGLSetOptimalOptions(vertexProfile); cgGLSetOptimalOptions(fragmentProfile); /* insert dummy pass that will contain the original texture */ shaderPasses.push_back(shaderPass()); for(CCGShader::passVector::iterator it=cgShader.shaderPasses.begin(); it!=cgShader.shaderPasses.end();it++) { shaderPass pass; pass.scaleParams = it->scaleParams; /* if this is the last pass (the only one that can have CG_SCALE_NONE) and no filter has been set use the GUI setting */ if(pass.scaleParams.scaleTypeX==CG_SCALE_NONE && !it->filterSet) { pass.linearFilter = GUI.BilinearFilter; } else { pass.linearFilter = it->linearFilter; } pass.frameCounterMod = it->frameCounterMod; pass.floatFbo = it->floatFbo; // paths in the meta file can be relative _tfullpath(tempPath,_tFromChar(it->cgShaderFile),MAX_PATH); char *fileContents = ReadShaderFileContents(tempPath); if(!fileContents) return false; // individual shader might include files, these should be relative to shader ReduceToPath(tempPath); SetCurrentDirectory(tempPath); pass.cgVertexProgram = cgCreateProgram( cgContext, CG_SOURCE, fileContents, vertexProfile, "main_vertex", NULL); checkForCgError("Compiling vertex program"); pass.cgFragmentProgram = cgCreateProgram( cgContext, CG_SOURCE, fileContents, fragmentProfile, "main_fragment", NULL); checkForCgError("Compiling fragment program"); // set path back for next pass SetCurrentDirectory(shaderPath); delete [] fileContents; if(!pass.cgVertexProgram || !pass.cgFragmentProgram) { return false; } cgGLLoadProgram(pass.cgVertexProgram); cgGLLoadProgram(pass.cgFragmentProgram); /* generate framebuffer and texture for this pass and apply default texture settings */ glGenFramebuffers(1,&pass.fbo); glGenTextures(1,&pass.tex); glBindTexture(GL_TEXTURE_2D,pass.tex); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); shaderPasses.push_back(pass); } for(std::vector<CCGShader::lookupTexture>::iterator it=cgShader.lookupTextures.begin();it!=cgShader.lookupTextures.end();it++) { lookupTexture tex; strcpy(tex.id,it->id); /* generate texture for the lut and apply specified filter setting */ glGenTextures(1,&tex.tex); glBindTexture(GL_TEXTURE_2D,tex.tex); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, it->linearfilter?GL_LINEAR:GL_NEAREST); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, it->linearfilter?GL_LINEAR:GL_NEAREST); _tfullpath(tempPath,_tFromChar(it->texturePath),MAX_PATH); // simple file extension png/tga decision int strLen = strlen(it->texturePath); if(strLen>4) { if(!strcasecmp(&it->texturePath[strLen-4],".png")) { int width, height; bool hasAlpha; GLubyte *texData; if(loadPngImage(tempPath,width,height,hasAlpha,&texData)) { glPixelStorei(GL_UNPACK_ROW_LENGTH, width); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, hasAlpha ? GL_RGBA : GL_RGB, GL_UNSIGNED_BYTE, texData); free(texData); } } else if(!strcasecmp(&it->texturePath[strLen-4],".tga")) { STGA stga; if(loadTGA(tempPath,stga)) { glPixelStorei(GL_UNPACK_ROW_LENGTH, stga.width); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, stga.width, stga.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, stga.data); } } } lookupTextures.push_back(tex); } /* enable texture unit 1 for the lookup textures */ glClientActiveTexture(GL_TEXTURE1); glEnableClientState(GL_TEXTURE_COORD_ARRAY); glTexCoordPointer(2,GL_FLOAT,0,lut_coords); glClientActiveTexture(GL_TEXTURE0); /* generate textures and set default values for the pref-filled PREV deque. */ for(int i=0;i<prevPasses.size();i++) { glGenTextures(1,&prevPasses[i].tex); glBindTexture(GL_TEXTURE_2D,prevPasses[i].tex); glTexImage2D(GL_TEXTURE_2D,0,GL_RGB,512,512,0,GL_RGB,GL_UNSIGNED_SHORT_5_6_5,NULL); glBindTexture(GL_TEXTURE_2D,0); prevPasses[i].textureSize.x = prevPasses[i].textureSize.y = prevPasses[i].textureSize.x = prevPasses[i].textureSize.y = 0; memset(prevPasses[i].texCoords,0,sizeof(prevPasses[i].texCoords)); } shaderLoaded = true; return true; }
void Get(ConfigFile& conf) { switch(type) { case CIT_BOOL: case CIT_BOOLONOFF: if(size == 1) *(uint8 *)addr = (uint8) conf.GetBool(name, def!=0); if(size == 2) *(uint16*)addr = (uint16)conf.GetBool(name, def!=0); if(size == 4) *(uint32*)addr = (uint32)conf.GetBool(name, def!=0); if(size == 8) *(uint64*)addr = (uint64)conf.GetBool(name, def!=0); break; case CIT_INT: if(size == 1) *(uint8 *)addr = (uint8) conf.GetInt(name, reinterpret_cast<int32>(def)); if(size == 2) *(uint16*)addr = (uint16)conf.GetInt(name, reinterpret_cast<int32>(def)); if(size == 4) *(uint32*)addr = (uint32)conf.GetInt(name, reinterpret_cast<int32>(def)); if(size == 8) *(uint64*)addr = (uint64)conf.GetInt(name, reinterpret_cast<int32>(def)); break; case CIT_UINT: if(size == 1) *(uint8 *)addr = (uint8) conf.GetUInt(name, reinterpret_cast<uint32>(def)); if(size == 2) *(uint16*)addr = (uint16)conf.GetUInt(name, reinterpret_cast<uint32>(def)); if(size == 4) *(uint32*)addr = (uint32)conf.GetUInt(name, reinterpret_cast<uint32>(def)); if(size == 8) *(uint64*)addr = (uint64)conf.GetUInt(name, reinterpret_cast<uint32>(def)); break; case CIT_STRING: lstrcpyn((TCHAR*)addr, _tFromChar(conf.GetString(name, reinterpret_cast<const char*>(def))), size-1); ((TCHAR*)addr)[size-1] = TEXT('\0'); break; case CIT_INVBOOL: case CIT_INVBOOLONOFF: if(size == 1) *(uint8 *)addr = (uint8) !conf.GetBool(name, def!=0); if(size == 2) *(uint16*)addr = (uint16)!conf.GetBool(name, def!=0); if(size == 4) *(uint32*)addr = (uint32)!conf.GetBool(name, def!=0); if(size == 8) *(uint64*)addr = (uint64)!conf.GetBool(name, def!=0); break; case CIT_VKEY: { uint16 keyNum = (uint16)conf.GetUInt(name, reinterpret_cast<uint32>(def)); const char* keyStr = conf.GetString(name); if(keyStr) { for(int i=0;i<512;i++) { if(i<256) // keys { if(!strcasecmp(keyStr,keyToString[i]) || (*keyToAlternateString[i] && !strcasecmp(keyStr,keyToAlternateString[i]))) { keyNum = i; break; } } else // joystick: { char temp [128]; extern void TranslateKey(WORD keyz,char *out); TranslateKey(0x8000|(i-256),temp); if(strlen(keyStr)>3 && !strcasecmp(keyStr+3,temp+3)) { for(int j = 0 ; j < 16 ; j++) { if(keyStr[2]-'0' == j || keyStr[2]-'a' == j-10) { keyNum = 0x8000|(i-256)|(j<<8); i = 512; break; } } } } } } if(size == 1) *(uint8 *)addr = (uint8) keyNum; if(size == 2) *(uint16*)addr = (uint16)keyNum; if(size == 4) *(uint32*)addr = (uint32)keyNum; if(size == 8) *(uint64*)addr = (uint64)keyNum; } break; case CIT_VKEYMOD: { uint16 modNum = 0; const char* modStr = conf.GetString(name); if(modStr) { if(strstr(modStr, "ft") || strstr(modStr, "FT")) modNum |= CUSTKEY_SHIFT_MASK; if(strstr(modStr, "tr") || strstr(modStr, "TR")) modNum |= CUSTKEY_CTRL_MASK; if(strstr(modStr, "lt") || strstr(modStr, "LT")) modNum |= CUSTKEY_ALT_MASK; } if(!modNum && (!modStr || strcasecmp(modStr, "none"))) modNum = conf.GetUInt(name, reinterpret_cast<uint32>(def)); if(size == 1) *(uint8 *)addr = (uint8) modNum; if(size == 2) *(uint16*)addr = (uint16)modNum; if(size == 4) *(uint32*)addr = (uint32)modNum; if(size == 8) *(uint64*)addr = (uint64)modNum; } break; } // if it had a comment, override our own with it const char* newComment = conf.GetComment(name); if(newComment && *newComment) comment = newComment; }
const TCHAR *S9xGetDirectoryT (enum s9x_getdirtype dirtype) { if(!startDirectoryValid) { // directory of the executable's location: GetModuleFileName(NULL, startDirectory, PATH_MAX); for(int i=lstrlen(startDirectory); i>=0; i--){ if(IS_SLASH(startDirectory[i])){ startDirectory[i]=TEXT('\0'); break; } } startDirectoryValid = true; } SetCurrentDirectory(startDirectory); // makes sure relative paths are relative to the application's location const TCHAR* rv = startDirectory; switch(dirtype){ default: case DEFAULT_DIR: case HOME_DIR: break; case SCREENSHOT_DIR: rv = GUI.ScreensDir; break; case ROM_DIR: rv = GUI.RomDir; break; case SRAM_DIR: rv = GUI.SRAMFileDir; break; case BIOS_DIR: rv = GUI.BiosDir; break; case SPC_DIR: rv = GUI.SPCDir; break; case IPS_DIR: case CHEAT_DIR: rv = GUI.PatchDir; break; case SNAPSHOT_DIR: rv = GUI.FreezeFileDir; break; case ROMFILENAME_DIR: { static TCHAR filename [PATH_MAX]; lstrcpy(filename, _tFromChar(Memory.ROMFilename)); if(!filename[0]) rv = GUI.RomDir; for(int i=lstrlen(filename); i>=0; i--){ if(IS_SLASH(filename[i])){ filename[i]=TEXT('\0'); break; } } rv = filename; } break; } _tmkdir(rv); return rv; }
bool CD3DCG::LoadShader(const TCHAR *shaderFile) { CCGShader cgShader; TCHAR shaderPath[MAX_PATH]; TCHAR tempPath[MAX_PATH]; HRESULT hr; GLenum error; ClearPasses(); if (shaderFile == NULL || *shaderFile==TEXT('\0')) return true; lstrcpy(shaderPath,shaderFile); for(int i=lstrlen(shaderPath); i>=0; i--){ if(IS_SLASH(shaderPath[i])){ shaderPath[i]=TEXT('\0'); break; } } SetCurrentDirectory(shaderPath); if(!cgShader.LoadShader(_tToChar(shaderFile))) return false; CGprofile vertexProfile = cgD3D9GetLatestVertexProfile(); CGprofile pixelProfile = cgD3D9GetLatestPixelProfile(); const char** vertexOptions = cgD3D9GetOptimalOptions(vertexProfile); const char** pixelOptions = cgD3D9GetOptimalOptions(pixelProfile); shaderPasses.push_back(shaderPass()); for(CCGShader::passVector::iterator it=cgShader.shaderPasses.begin(); it!=cgShader.shaderPasses.end();it++) { shaderPass pass; pass.scaleParams = it->scaleParams; /* if this is the last pass (the only one that can have CG_SCALE_NONE) and no filter has been set use the GUI setting */ if(pass.scaleParams.scaleTypeX==CG_SCALE_NONE && !it->filterSet) { pass.linearFilter = GUI.BilinearFilter; } else { pass.linearFilter = it->linearFilter; } // paths in the meta file can be relative _tfullpath(tempPath,_tFromChar(it->cgShaderFile),MAX_PATH); char *fileContents = ReadShaderFileContents(tempPath); if(!fileContents) return false; pass.cgVertexProgram = cgCreateProgram( cgContext, CG_SOURCE, fileContents, vertexProfile, "main_vertex", vertexOptions); checkForCgError("Compiling vertex program"); pass.cgFragmentProgram = cgCreateProgram( cgContext, CG_SOURCE, fileContents, pixelProfile, "main_fragment", pixelOptions); checkForCgError("Compiling fragment program"); delete [] fileContents; if(!pass.cgVertexProgram || !pass.cgFragmentProgram) { return false; } if(pass.cgVertexProgram) { hr = cgD3D9LoadProgram(pass.cgVertexProgram,false,0); } checkForCgError("Loading vertex program"); if(pass.cgFragmentProgram) { hr = cgD3D9LoadProgram(pass.cgFragmentProgram,false,0); } checkForCgError("Loading fragment program"); /* generate vertex buffer */ hr = pDevice->CreateVertexBuffer(sizeof(VERTEX)*4,D3DUSAGE_WRITEONLY,0,D3DPOOL_MANAGED,&pass.vertexBuffer,NULL); if(FAILED(hr)) { pass.vertexBuffer = NULL; DXTRACE_ERR_MSGBOX(TEXT("Error creating vertex buffer"), hr); return false; } /* set up vertex declarations for the pass, this also creates the vertex declaration */ setupVertexDeclaration(pass); shaderPasses.push_back(pass); } for(std::vector<CCGShader::lookupTexture>::iterator it=cgShader.lookupTextures.begin();it!=cgShader.lookupTextures.end();it++) { lookupTexture tex; strcpy(tex.id,it->id); tex.linearFilter = it->linearfilter; _tfullpath(tempPath,_tFromChar(it->texturePath),MAX_PATH); hr = D3DXCreateTextureFromFileEx( pDevice, tempPath, D3DX_DEFAULT_NONPOW2, D3DX_DEFAULT_NONPOW2, 0, 0, D3DFMT_FROM_FILE, D3DPOOL_MANAGED, it->linearfilter?D3DX_FILTER_LINEAR:D3DX_FILTER_POINT, 0, 0, NULL, NULL, &tex.tex); if FAILED(hr){ tex.tex = NULL; } lookupTextures.push_back(tex); } shaderLoaded = true; return true; }