mupen64plus-oldsvn/main/mupenIniApi.c
Scott Knauert 6830f04a17 Save of WIP. Added support for Internal Name (extremely messly), cleaned up rcs CIC detection, so
its faster and uses less memory. Added initial Status support.
2008-05-31 08:02:22 +00:00

298 lines
8.4 KiB
C

/**
* Mupen64 - mupenIniApi.c
* Copyright (C) 2002 Hacktarux
*
* Mupen64 homepage: http://mupen64.emulation64.com
* email address: hacktarux@yahoo.fr
*
* If you want to contribute to the project please contact
* me first (maybe someone is already making what you are
* planning to do).
*
*
* This program is free software; you can redistribute it and/
* or modify it under the terms of the GNU General Public Li-
* cence as published by the Free Software Foundation; either
* version 2 of the Licence, or any later version.
*
* This program is distributed in the hope that it will be use-
* ful, but WITHOUT ANY WARRANTY; without even the implied war-
* ranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public Licence 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., 675 Mass Ave, Cambridge, MA 02139,
* USA.
*
**/
#include "mupenIniApi.h"
#include "main.h"
#include <stdio.h>
#include <zlib.h>
#include <string.h>
#include <stdlib.h>
typedef struct _romdatabase_search
{
mupenEntry entry;
struct _romdatabase_search* next_entry;
struct _romdatabase_search* next_crc;
struct _romdatabase_search* next_md5;
} romdatabase_search;
typedef struct
{
char *comment;
romdatabase_search* crc_lists[256];
romdatabase_search* md5_lists[256];
romdatabase_search* list;
} _romdatabase;
static _romdatabase romdatabase;
typedef mupenEntry romdatabase_entry;
romdatabase_entry emptyEntry;
static int split_property(char *s)
{
int i = 0;
while(s[i] != '=' && s[i] != 0) i++;
if (s[i] == 0) return -1;
s[i] = 0;
return i;
}
void ini_openFile()
{
gzFile gzfile;
char buf[256];
int i=0;
romdatabase_search *cur = NULL;
int free_buffer = 0;
if(romdatabase.comment!=NULL)
{ return; }
//Query config system and open romdatabase.
char *pathname = (char*)config_get_string("RomDatabaseFile", NULL);
if(pathname==NULL)
{
printf("[rcs] Database not in config.\n");
pathname = (char*)malloc(PATH_MAX*sizeof(char));
snprintf(pathname, PATH_MAX, "%s%s", get_configpath(), "mupen64plus.ini");
config_put_string("RomDatabaseFile", pathname);
free_buffer = 1;
}
//printf("Database file: %s \n", pathname);
gzfile = gzopen(pathname, "rb");
if(free_buffer)
{ free(pathname); }
if(gzfile==NULL)
{
printf("[rcs] Unable to open rom database.\n");
return;
}
//Move through opening comments, set romdatabase.comment to non-NULL
//to signal we have a database.
do
{
gzgets(gzfile, buf, 255);
if(buf[0]!='[')
{
i+= strlen(buf);
if(romdatabase.comment==NULL)
{
romdatabase.comment = (char*)malloc(i+1);
strcpy(romdatabase.comment, buf);
}
else
{
romdatabase.comment = (char*)realloc(romdatabase.comment, i+1);
strcat(romdatabase.comment, buf);
}
}
}
while (buf[0] != '[' && !gzeof(gzfile));
//Clear premade indices.
for ( i = 0; i < 255; ++i )
{ romdatabase.crc_lists[i] = NULL; }
for ( i = 0; i < 255; ++i )
{ romdatabase.md5_lists[i] = NULL; }
romdatabase.list = NULL;
do
{
if(buf[0]=='[')
{
if(romdatabase.list==NULL)
{
romdatabase.list = (romdatabase_search*)malloc(sizeof(romdatabase_search));
romdatabase.list->next_entry = NULL;
romdatabase.list->next_crc = NULL;
romdatabase.list->next_md5 = NULL;
cur = romdatabase.list;
}
else
{
cur->next_entry = (romdatabase_search*)malloc(sizeof(romdatabase_search));
cur = cur->next_entry;
cur->next_entry = NULL;
cur->next_crc = NULL;
cur->next_md5 = NULL;
}
i = strlen(buf);
while(buf[i] != ']') i--;
buf[i] = 0;
strncpy(cur->entry.md5, buf+1, 32);
cur->entry.md5[32] = '\0';
buf[3] = 0;
sscanf(buf+1, "%X", &i);
if(romdatabase.md5_lists[i]==NULL)
{ romdatabase.md5_lists[i] = cur; }
else
{
romdatabase_search *aux = romdatabase.md5_lists[i];
cur->next_md5 = aux;
romdatabase.md5_lists[i] = cur;
}
cur->entry.status=3;
cur->entry.eeprom16kb = 0;
strcpy(cur->entry.refmd5, "");
strcpy(cur->entry.comments, "");
}
else
{
i = split_property(buf);
if(i!=-1)
{
if(!strcmp(buf, "Good Name"))
{
if(buf[i+1+strlen(buf+i+1)-1]=='\n')
{ buf[i+1+strlen(buf+i+1)-1] = '\0'; }
if (buf[i+1+strlen(buf+i+1)-1]=='\r')
{ buf[i+1+strlen(buf+i+1)-1] = '\0'; }
strncpy(cur->entry.goodname, buf+i+1, 99);
}
else if(!strcmp(buf, "Header Code"))
{
strncpy(cur->entry.crc, buf+i+1, 21);
cur->entry.crc[21] = '\0';
buf[i+3] = 0;
sscanf(buf+i+1, "%X", &i);
if(romdatabase.crc_lists[i]==NULL)
{ romdatabase.crc_lists[i] = cur; }
else
{
romdatabase_search *aux = romdatabase.crc_lists[i];
cur->next_crc = aux;
romdatabase.crc_lists[i] = cur;
}
}
else if(!strcmp(buf, "Reference"))
{
strncpy(cur->entry.refmd5, buf+i+1, 32);
cur->entry.refmd5[32] = '\0';
}
else if(!strcmp(buf, "Eeprom"))
{
if(!strncmp(buf+i+1, "16k", 3))
{ cur->entry.eeprom16kb = 1;
}
}
}
}
gzgets(gzfile, buf, 255);
}
while (!gzeof(gzfile));
gzclose(gzfile);
}
void romdatabase_close()
{
if (romdatabase.comment == NULL)
{ return; }
free(romdatabase.comment);
while(romdatabase.list != NULL)
{
romdatabase_search *search = romdatabase.list->next_entry;
free(romdatabase.list);
romdatabase.list = search;
}
}
mupenEntry* ini_search_by_md5(const char *md5)
{
char buffer[3];
int i;
romdatabase_search *search;
//If no database, return empty.
if(romdatabase.comment==NULL)
{ return &emptyEntry; }
//Convert first 2 hex digits to search premade index.
buffer[0] = md5[0];
buffer[1] = md5[1];
buffer[2] = '\0';
sscanf(buffer, "%X", &i);
search = romdatabase.md5_lists[i];
while (search != NULL && strncmp(search->entry.md5, md5, 32))
{ search = search->next_md5; }
//If found return pointer, if not return empty.
if(search==NULL)
{ return &emptyEntry; }
else
{ return &(search->entry); }
}
mupenEntry* ini_search_by_crc(const char *crc)
{
char buffer[3];
int i;
romdatabase_search *search;
//If no database, return empty.
if(romdatabase.comment==NULL)
{ return &emptyEntry; }
//Convert first 2 hex digits to search premade index.
buffer[0] = crc[0];
buffer[1] = crc[1];
buffer[2] = '\0';
sscanf(buffer, "%X", &i);
search = romdatabase.crc_lists[i];
while (search != NULL && strncmp(search->entry.crc, crc, 21))
{ search = search->next_crc; }
if(search == NULL)
{ return &emptyEntry; }
//Return crc of reference rom if different.
if(strcmp(search->entry.refmd5, ""))
{
mupenEntry* temp = ini_search_by_md5(search->entry.refmd5);
if(strncmp(search->entry.crc, temp->crc, 21))
{ return &(search->entry); }
else
{ return temp; }
}
else
{ return &(search->entry); }
}