mirror of
https://github.com/mupen64plus/mupen64plus-oldsvn.git
synced 2025-04-02 10:52:35 -04:00
298 lines
8.4 KiB
C
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); }
|
|
}
|