/* * Glide64 - Glide video plugin for Nintendo 64 emulators. * Copyright (c) 2002 Dave2001 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public * Licence along with this program; if not, write to the Free * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA */ //**************************************************************** // // Glide64 - Glide Plugin for Nintendo 64 emulators (tested mostly with Project64) // Project started on December 29th, 2001 // // To modify Glide64: // * Write your name and (optional)email, commented by your work, so I know who did it, and so that you can find which parts you modified when it comes time to send it to me. // * Do NOT send me the whole project or file that you modified. Take out your modified code sections, and tell me where to put them. If people sent the whole thing, I would have many different versions, but no idea how to combine them all. // // Official Glide64 development channel: #Glide64 on EFnet // // Original author: Dave2001 (Dave2999@hotmail.com) // Other authors: Gonetz, Gugaman // //**************************************************************** // INI code v1.1 #define M64P_PLUGIN_PROTOTYPES 1 #include "m64p_types.h" #include "m64p_plugin.h" #include "m64p_config.h" #include "m64p_vidext.h" #include "Ini.h" #include "Gfx1.3.h" #include #ifndef _WIN32 #include #include #include #include #endif // _WIN32 #include #ifndef _WIN32 #include #endif #ifdef _WIN32 #define PATH_MAX _MAX_PATH #endif /* PATH_MAX only may be defined by limits.h */ #ifndef PATH_MAX #define PATH_MAX 4096 #endif FILE *ini; int sectionstart; int last_line; // last good line int last_line_ret; // last line ended in return? WORD cr = 0x0A0D; static char configdir[PATH_MAX] = {0}; BOOL INI_Open () { // Get the path of the dll, ex: C:\Games\Project64\Plugin\Glide64.dll char path[PATH_MAX]; if(strlen(configdir) > 0) { strncpy(path, configdir, PATH_MAX); // make sure there's a trailing '/' //if(path[strlen(path)-1] != '/') // strncat(path, "/", PATH_MAX - strlen(path)); } else { #ifdef _WIN32 GetModuleFileName (hInstance, path, PATH_MAX); #else // _WIN32 # ifdef __FreeBSD__ int n = readlink("/proc/curproc/files", path, PATH_MAX); #else int n = readlink("/proc/self/exe", path, PATH_MAX); #endif if (n == -1) strcpy(path, "./"); else { char path2[PATH_MAX]; int i; path[n] = '\0'; strcpy(path2, path); for (i=strlen(path2)-1; i>0; i--) { if(path2[i] == '/') break; } if(i == 0) strcpy(path, "./"); else { DIR *dir; struct dirent *entry; int gooddir = 0; path2[i+1] = '\0'; dir = opendir(path2); while((entry = readdir(dir)) != NULL) { if(!strcmp(entry->d_name, "plugins")) gooddir = 1; } closedir(dir); if(!gooddir) strcpy(path, "./"); } } #endif // _WIN32 // Find the previous backslash int i; for (i=strlen(path)-1; i>0; i--) { #ifdef _WIN32 if (path[i] == '\\') #else // _WIN32 if (path[i] == '/') #endif // _WIN32 break; } if (path == 0) return FALSE; path[i+1] = 0; #ifndef _WIN32 strcat(path, "plugins/"); #endif // _WIN32 } //strncat (path, "Glide64.ini", PATH_MAX - strlen(path)); WriteLog(M64MSG_INFO, "opening %s\n", path); // Open the file ini = fopen (path, "rb"); if (ini == NULL) { WriteLog(M64MSG_ERROR, "Could not find Glide64.ini!"); return FALSE; /* ini = fopen (path, "w+b"); if (ini == NULL) { return FALSE; } */ } sectionstart = 0; last_line = 0; last_line_ret = 1; return TRUE; } void INI_Close () { //if (ini) // fclose(ini); } void INI_InsertSpace(int space) { // Since there is no good way to normally insert to or delete from a certain location in // a file, this function was added. It will insert (or delete) space bytes at the // current location. // note: negative count means delete char chunk[2048]; int len, file, start_pos, cur_pos; #ifdef _WIN32 file = _fileno(ini); #else // _WIN32 file = fileno(ini); #endif // _WIN32 start_pos = ftell(ini); fseek(ini,0,SEEK_END); // if adding, extend the file if (space > 0) #ifdef _WIN32 _chsize (file, _filelength(file)+space); #else // _WIN32 { int t1 = ftell(ini); fseek(ini, 0L, SEEK_END); int t2 = ftell(ini); fseek(ini, t1, SEEK_SET); ftruncate(file, t2+space); } #endif // _WIN32 while (1) { cur_pos = ftell(ini); len = cur_pos - start_pos; if (len == 0) break; if (len > 2048) len = 2048; fseek (ini,-len,SEEK_CUR); fread (chunk,1,len,ini); fseek (ini,-len+space,SEEK_CUR); fwrite (chunk,1,len,ini); fseek (ini,-len-space,SEEK_CUR); } // if deleted, make the file shorter if (space < 0) #ifdef _WIN32 _chsize (file, _filelength(file)+space); #else // _WIN32 { int t1 = ftell(ini); fseek(ini, 0L, SEEK_END); int t2 = ftell(ini); fseek(ini, t1, SEEK_SET); ftruncate(file, t2+space); } #endif // _WIN32 } BOOL INI_FindSection (const char *sectionname, BOOL create) { if (ini == NULL) return FALSE; char line[256], section[64]; char *p; int i, sectionfound, ret; rewind (ini); last_line = 0; sectionfound = 0; while(!feof(ini)) { ret = 0; *line=0; fgets(line,255,ini); // remove enter i=strlen(line); // ZIGGY there was a bug here if EOL was unix like on a short line (i.e. a line // with just EOL), it would write into line[-1] if(i>=1 && line[i-1]==0xa) { ret=1; line[i-1]=0; if (i>=2 && line[i-2]==0xd) line[i-2]=0; } // remove comments p=line; while(*p) { if (p[0]=='/' && p[1]=='/') { p[0]=0; break; } p++; } // skip starting space p=line; while(*p<=' ' && *p) p++; // empty line if(!*p) continue; last_line=ftell(ini); // where to add if not found last_line_ret = ret; if(*p!='[') continue; p++; for (i=0;i<63;i++) { if(*p==']' || !*p) break; section[i]=*p++; } section[i]=0; #ifdef _WIN32 if(!stricmp(section,sectionname)) #else // _WIN32 if (!strcasecmp(section,sectionname)) #endif // _WIN32 { sectionstart=ftell(ini); sectionfound=1; return TRUE; } } if (!sectionfound && create) { // create the section fseek(ini,last_line,SEEK_SET); INI_InsertSpace ((!last_line_ret) * 2 + 6 + strlen(sectionname)); if (!last_line_ret) fwrite (&cr, 1, 2, ini); fwrite (&cr, 1, 2, ini); sprintf (section, "[%s]", sectionname); fwrite (section, 1, strlen(section), ini); fwrite (&cr, 1, 2, ini); sectionstart = ftell(ini); last_line = sectionstart; last_line_ret = 1; return TRUE; } return FALSE; } // Reads the value of item 'itemname' as a string. const char *INI_ReadString (const char *itemname, char *value, const char *def_value, BOOL create) { char line[256], name[64]; char *p, *n; int ret, i; *value = 0; fseek(ini,sectionstart,SEEK_SET); while(!feof(ini)) { ret = 0; *line=0; fgets(line,255,ini); // remove enter i=strlen(line); // ZIGGY there was a bug here if EOL was unix like on a short line (i.e. a line // with just EOL), it would write into line[-1] // OLD CODE : if(line[i-1]=='\n') ret=1, line[i-2]=0; if(i>=1 && line[i-1]==0xa) { ret=1; line[i-1]=0; if (i>=2 && line[i-2]==0xd) line[i-2]=0; } // remove comments p=line; while(*p) { if (p[0]==';') { p[0]=0; break; } p++; } // skip starting space p=line; while(*p<=' ' && *p) p++; // empty line if(!*p) continue; // new section if(*p=='[') break; last_line=ftell(ini); // where to add if not found last_line_ret = ret; // read name n = name; while(*p && *p!='=' && *p>' ') *n++ = *p++; *n = 0; #ifdef _WIN32 if(!stricmp(name,itemname)) #else // _WIN32 if(!strcasecmp(name,itemname)) #endif // _WIN32 { // skip spaces/equal sign while(*p<=' ' || *p=='=') p++; // read value n = value; while(*p) *n++ = *p++; // remove trailing spaces while (*(n-1) == ' ') n--; *n=0; return value; } } // uh-oh, not found. we need to create if (create) { fseek(ini,last_line,SEEK_SET); INI_InsertSpace ((!last_line_ret) * 2 + strlen(itemname) + strlen(def_value) + 5); if (!last_line_ret) fwrite (&cr, 1, 2, ini); sprintf (line, "%s = %s", itemname, def_value); fwrite (line, 1, strlen(line), ini); fwrite (&cr, 1, 2, ini); last_line = ftell(ini); last_line_ret = 1; } strcpy (value, def_value); return value; } // Reads the value of item 'itemname' as a string. void INI_WriteString (const char *itemname, const char *value) { char line[256], name[64]; char *p, *n; int ret, i; fseek(ini,sectionstart,SEEK_SET); while(!feof(ini)) { ret = 0; *line=0; fgets(line,255,ini); // remove enter i=strlen(line); // ZIGGY there was a bug here if EOL was unix like on a short line (i.e. a line // with just EOL), it would write into line[-1] // OLD CODE : if(line[i-1]=='\n') ret=1, line[i-2]=0; if(i>=1 && line[i-1]==0xa) { ret=1; line[i-1]=0; if (i>=2 && line[i-2]==0xd) line[i-2]=0; } // remove comments p=line; while(*p) { if (p[0]=='/' && p[1]=='/') { p[0]=0; break; } p++; } // skip starting space p=line; while(*p<=' ' && *p) p++; // empty line if(!*p) continue; // new section if(*p=='[') break; last_line=ftell(ini); // where to add if not found last_line_ret = ret; // read name n = name; while(*p && *p!='=' && *p>' ') *n++ = *p++; *n = 0; #ifdef _WIN32 if(!stricmp(name,itemname)) #else // _WIN32 if(!strcasecmp(name,itemname)) #endif // _WIN32 { INI_InsertSpace (-i + (strlen(itemname) + strlen(value) + 5)); sprintf (line, "%s = %s", itemname, value); fseek (ini, -i, SEEK_CUR); fwrite (line, 1, strlen(line), ini); fwrite (&cr, 1, 2, ini); last_line = ftell(ini); last_line_ret = 1; return; } } // uh-oh, not found. we need to create fseek(ini,last_line,SEEK_SET); INI_InsertSpace ((!last_line_ret) * 2 + strlen(itemname) + strlen(value) + 5); if (!last_line_ret) fwrite (&cr, 1, 2, ini); sprintf (line, "%s = %s", itemname, value); fwrite (line, 1, strlen(line), ini); fwrite (&cr, 1, 2, ini); last_line = ftell(ini); last_line_ret = 1; return; } int INI_ReadInt (const char *itemname, int def_value, BOOL create) { if (ini == NULL) return def_value; char value[64], def[64]; #ifdef _WIN32 _itoa (def_value, def, 10); #else // _WIN32 sprintf(def, "%d", def_value); #endif // _WIN32 INI_ReadString (itemname, value, def, create); return atoi (value); } void INI_WriteInt (const char *itemname, int value) { char valstr[64]; #ifdef _WIN32 _itoa (value, valstr, 10); #else // _WIN32 sprintf(valstr, "%d", value); #endif // _WIN32 INI_WriteString (itemname, valstr); } void SetConfigDir( const char *configDir ) { strncpy(configdir, configDir, PATH_MAX); }