Fixes, tweaks, cleanup.
This commit is contained in:
@@ -3,18 +3,88 @@
|
||||
#include <stdlib.h>
|
||||
#include <sys/stat.h>
|
||||
#include <dirent.h>
|
||||
#include <ctype.h>
|
||||
|
||||
|
||||
#include "sxmlc.h"
|
||||
|
||||
#include "../../sxmlc.h"
|
||||
#include "../../user_io.h"
|
||||
#include "../../file_io.h"
|
||||
#include "../../menu.h"
|
||||
#include "../../fpga_io.h"
|
||||
#include "../../lib/md5/md5.h"
|
||||
|
||||
#include "buffer.h"
|
||||
|
||||
#define DEBUG_ROM_BINARY 0
|
||||
#if DEBUG_ROM_BINARY
|
||||
FILE *rombinary;
|
||||
#endif
|
||||
|
||||
static int file_tx_start(unsigned char index)
|
||||
{
|
||||
// set index byte (0=bios rom, 1-n=OSD entry index)
|
||||
user_io_set_index(index);
|
||||
|
||||
// prepare transmission of new file
|
||||
user_io_set_download(1);
|
||||
|
||||
#if DEBUG_ROM_BINARY
|
||||
rombinary = fopen("/media/fat/this.rom", "wb");
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int file_tx_body(const uint8_t *buf, uint16_t chunk, struct MD5Context *md5context)
|
||||
{
|
||||
EnableFpga();
|
||||
spi8(UIO_FILE_TX_DAT);
|
||||
|
||||
spi_write(buf, chunk, user_io_get_width());
|
||||
DisableFpga();
|
||||
|
||||
if (md5context) MD5Update(md5context, buf, chunk);
|
||||
#if DEBUG_ROM_BINARY
|
||||
fwrite(buf, 1, chunk, rombinary);
|
||||
#endif
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int file_tx_body_filepart(const char *name, int start, int len, struct MD5Context *md5context)
|
||||
{
|
||||
char mute = 0;
|
||||
fileTYPE f = {};
|
||||
static uint8_t buf[4096];
|
||||
if (!FileOpen(&f, name, mute)) return 0;
|
||||
if (start) FileSeek(&f, start, SEEK_SET);
|
||||
unsigned long bytes2send = f.size;
|
||||
if (len > 0 && len < (int)bytes2send) bytes2send = len;
|
||||
/* transmit the entire file using one transfer */
|
||||
printf("Selected file %s with %lu bytes to send \n", name, bytes2send);
|
||||
while (bytes2send)
|
||||
{
|
||||
uint16_t chunk = (bytes2send > sizeof(buf)) ? sizeof(buf) : bytes2send;
|
||||
|
||||
FileReadAdv(&f, buf, chunk);
|
||||
file_tx_body(buf, chunk, md5context);
|
||||
|
||||
bytes2send -= chunk;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int file_tx_finish()
|
||||
{
|
||||
printf("\n");
|
||||
#if DEBUG_ROM_BINARY
|
||||
fclose(rombinary);
|
||||
#endif
|
||||
|
||||
// signal end of transmission
|
||||
user_io_set_download(0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
#include "md5.h"
|
||||
/*
|
||||
* adapted from https://gist.github.com/xsleonard/7341172
|
||||
*
|
||||
@@ -32,44 +102,35 @@
|
||||
* */
|
||||
unsigned char* hexstr_to_char(const char* hexstr, size_t *out_len)
|
||||
{
|
||||
size_t len = strlen(hexstr);
|
||||
unsigned char* chrs = (unsigned char*)malloc((len+1) * sizeof(*chrs));
|
||||
int dest=0;
|
||||
// point to the beginning of the array
|
||||
const char *ptr = hexstr;
|
||||
while (*ptr) {
|
||||
// check to see if we have a space
|
||||
while (*ptr=='\n' || *ptr=='\r' || *ptr==' ' || *ptr=='\t' || *ptr==9 /*horiz tab*/) ptr++;
|
||||
if (*ptr==0) break;
|
||||
size_t len = strlen(hexstr);
|
||||
unsigned char* chrs = (unsigned char*)malloc((len + 1) * sizeof(*chrs));
|
||||
int dest = 0;
|
||||
// point to the beginning of the array
|
||||
const char *ptr = hexstr;
|
||||
while (*ptr) {
|
||||
// check to see if we have a space
|
||||
while (*ptr == '\n' || *ptr == '\r' || *ptr == ' ' || *ptr == '\t' || *ptr == 9 /*horiz tab*/) ptr++;
|
||||
if (*ptr == 0) break;
|
||||
|
||||
// pull two characters off
|
||||
int val1= (*ptr % 32 + 9) % 25 * 16;
|
||||
ptr++;
|
||||
/* check to odd numbers of characters*/
|
||||
if (*ptr==0) {
|
||||
int val= (ptr[-1] % 32 + 9) % 25;
|
||||
chrs[dest++] = val;
|
||||
break;
|
||||
}
|
||||
int val2= (*ptr % 32 + 9) % 25;
|
||||
ptr++;
|
||||
chrs[dest++] = val1+val2;
|
||||
}
|
||||
chrs[dest]=0;
|
||||
*out_len = dest; /* dest is 0 based, so we don't need to subtract 1*/
|
||||
return chrs;
|
||||
// pull two characters off
|
||||
int val1 = (*ptr % 32 + 9) % 25 * 16;
|
||||
ptr++;
|
||||
/* check to odd numbers of characters*/
|
||||
if (*ptr == 0) {
|
||||
int val = (ptr[-1] % 32 + 9) % 25;
|
||||
chrs[dest++] = val;
|
||||
break;
|
||||
}
|
||||
int val2 = (*ptr % 32 + 9) % 25;
|
||||
ptr++;
|
||||
chrs[dest++] = val1 + val2;
|
||||
}
|
||||
chrs[dest] = 0;
|
||||
*out_len = dest; /* dest is 0 based, so we don't need to subtract 1*/
|
||||
return chrs;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
user_io.h:int user_io_file_tx_start(const char *name,unsigned char index=0);
|
||||
user_io.h:int user_io_file_tx_body(const uint8_t *buf,uint16_t chunk);
|
||||
user_io.h:int user_io_file_tx_body_filepart(const char *name,int start=0, int len=0);
|
||||
user_io.h:int user_io_file_tx_finish();
|
||||
*/
|
||||
|
||||
|
||||
#define kBigTextSize 4096
|
||||
#define kBigTextSize 1024
|
||||
struct arc_struct {
|
||||
char md5[kBigTextSize];
|
||||
char zipname[kBigTextSize];
|
||||
@@ -84,7 +145,7 @@ struct arc_struct {
|
||||
int insiderom;
|
||||
int validrom0;
|
||||
buffer_data *data;
|
||||
struct MD5Context context;
|
||||
struct MD5Context context;
|
||||
};
|
||||
|
||||
char global_error_msg[kBigTextSize];
|
||||
@@ -100,100 +161,98 @@ char global_error_msg[kBigTextSize];
|
||||
static int xml_send_rom(XMLEvent evt, const XMLNode* node, SXML_CHAR* text, const int n, SAX_Data* sd)
|
||||
{
|
||||
struct arc_struct *arc_info = (struct arc_struct *)sd->user;
|
||||
(void)(sd);
|
||||
(void)(sd);
|
||||
|
||||
switch (evt)
|
||||
{
|
||||
case XML_EVENT_START_NODE:
|
||||
switch (evt)
|
||||
{
|
||||
case XML_EVENT_START_NODE:
|
||||
|
||||
/* initialization */
|
||||
|
||||
|
||||
// initialize things for each tag (node):
|
||||
buffer_destroy(arc_info->data);
|
||||
arc_info->data=buffer_init(kBigTextSize);
|
||||
arc_info->partname[0]=0;
|
||||
arc_info->offset=0;
|
||||
arc_info->length=-1;
|
||||
arc_info->repeat=1;
|
||||
arc_info->data = buffer_init(kBigTextSize);
|
||||
arc_info->partname[0] = 0;
|
||||
arc_info->offset = 0;
|
||||
arc_info->length = -1;
|
||||
arc_info->repeat = 1;
|
||||
|
||||
/* on the beginning of a rom tag, we need to reset the state*/
|
||||
if (!strcasecmp(node->tag,"rom"))
|
||||
if (!strcasecmp(node->tag, "rom"))
|
||||
{
|
||||
arc_info->insiderom=1;
|
||||
arc_info->romname[0]=0;
|
||||
arc_info->romindex=0;
|
||||
arc_info->md5[0]=0;
|
||||
MD5Init (&arc_info->context);
|
||||
arc_info->insiderom = 1;
|
||||
arc_info->romname[0] = 0;
|
||||
arc_info->romindex = 0;
|
||||
arc_info->md5[0] = 0;
|
||||
MD5Init(&arc_info->context);
|
||||
}
|
||||
|
||||
// for each part tag, we clear the partzipname since it is optional and may not appear in the part tag
|
||||
if (!strcasecmp(node->tag,"part"))
|
||||
arc_info->partzipname[0]=0;
|
||||
if (!strcasecmp(node->tag, "part"))
|
||||
arc_info->partzipname[0] = 0;
|
||||
|
||||
|
||||
//printf("XML_EVENT_START_NODE: tag [%s]\n",node->tag);
|
||||
// walk the attributes and save them in the data structure as appropriate
|
||||
for (int i = 0; i < node->n_attributes; i++)
|
||||
{
|
||||
//printf("attribute %d name [%s] value [%s]\n",i,node->attributes[i].name,node->attributes[i].value);
|
||||
if (!strcasecmp(node->attributes[i].name,"zip") && !strcasecmp(node->tag,"rom"))
|
||||
{
|
||||
strcpy(arc_info->zipname,node->attributes[i].value);
|
||||
}
|
||||
if (!strcasecmp(node->attributes[i].name,"name") && !strcasecmp(node->tag,"rom"))
|
||||
{
|
||||
strcpy(arc_info->romname,node->attributes[i].value);
|
||||
}
|
||||
if (!strcasecmp(node->attributes[i].name,"md5") && !strcasecmp(node->tag,"rom"))
|
||||
{
|
||||
strcpy(arc_info->md5,node->attributes[i].value);
|
||||
}
|
||||
if (!strcasecmp(node->attributes[i].name,"index") && !strcasecmp(node->tag,"rom"))
|
||||
{
|
||||
arc_info->romindex=atoi(node->attributes[i].value);
|
||||
}
|
||||
/* these only exist if we are inside the rom tag, and in a part tag*/
|
||||
if (arc_info->insiderom) {
|
||||
if (!strcasecmp(node->attributes[i].name,"zip") && !strcasecmp(node->tag,"part"))
|
||||
{
|
||||
strcpy(arc_info->partzipname,node->attributes[i].value);
|
||||
}
|
||||
if (!strcasecmp(node->attributes[i].name,"name") && !strcasecmp(node->tag,"part"))
|
||||
{
|
||||
strcpy(arc_info->partname,node->attributes[i].value);
|
||||
}
|
||||
if (!strcasecmp(node->attributes[i].name,"offset") && !strcasecmp(node->tag,"part"))
|
||||
{
|
||||
arc_info->offset=atoi(node->attributes[i].value);
|
||||
}
|
||||
if (!strcasecmp(node->attributes[i].name,"length") && !strcasecmp(node->tag,"part"))
|
||||
{
|
||||
arc_info->length=atoi(node->attributes[i].value);
|
||||
}
|
||||
if (!strcasecmp(node->attributes[i].name,"repeat") && !strcasecmp(node->tag,"part"))
|
||||
{
|
||||
arc_info->repeat=atoi(node->attributes[i].value);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < node->n_attributes; i++)
|
||||
{
|
||||
//printf("attribute %d name [%s] value [%s]\n",i,node->attributes[i].name,node->attributes[i].value);
|
||||
if (!strcasecmp(node->attributes[i].name, "zip") && !strcasecmp(node->tag, "rom"))
|
||||
{
|
||||
strcpy(arc_info->zipname, node->attributes[i].value);
|
||||
}
|
||||
if (!strcasecmp(node->attributes[i].name, "name") && !strcasecmp(node->tag, "rom"))
|
||||
{
|
||||
strcpy(arc_info->romname, node->attributes[i].value);
|
||||
}
|
||||
if (!strcasecmp(node->attributes[i].name, "md5") && !strcasecmp(node->tag, "rom"))
|
||||
{
|
||||
strcpy(arc_info->md5, node->attributes[i].value);
|
||||
}
|
||||
if (!strcasecmp(node->attributes[i].name, "index") && !strcasecmp(node->tag, "rom"))
|
||||
{
|
||||
arc_info->romindex = atoi(node->attributes[i].value);
|
||||
}
|
||||
/* these only exist if we are inside the rom tag, and in a part tag*/
|
||||
if (arc_info->insiderom) {
|
||||
if (!strcasecmp(node->attributes[i].name, "zip") && !strcasecmp(node->tag, "part"))
|
||||
{
|
||||
strcpy(arc_info->partzipname, node->attributes[i].value);
|
||||
}
|
||||
if (!strcasecmp(node->attributes[i].name, "name") && !strcasecmp(node->tag, "part"))
|
||||
{
|
||||
strcpy(arc_info->partname, node->attributes[i].value);
|
||||
}
|
||||
if (!strcasecmp(node->attributes[i].name, "offset") && !strcasecmp(node->tag, "part"))
|
||||
{
|
||||
arc_info->offset = atoi(node->attributes[i].value);
|
||||
}
|
||||
if (!strcasecmp(node->attributes[i].name, "length") && !strcasecmp(node->tag, "part"))
|
||||
{
|
||||
arc_info->length = atoi(node->attributes[i].value);
|
||||
}
|
||||
if (!strcasecmp(node->attributes[i].name, "repeat") && !strcasecmp(node->tag, "part"))
|
||||
{
|
||||
arc_info->repeat = atoi(node->attributes[i].value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* at the beginning of each rom - tell the user_io to start a new message */
|
||||
if (!strcasecmp(node->tag,"rom"))
|
||||
if (!strcasecmp(node->tag, "rom"))
|
||||
{
|
||||
|
||||
// clear an error message if we have a second rom0
|
||||
// this is kind of a problem - you will never see the
|
||||
// error from the first rom0?
|
||||
//
|
||||
if (arc_info->romindex==0 && strlen(arc_info->zipname))
|
||||
arc_info->error_msg[0]=0;
|
||||
// clear an error message if we have a second rom0
|
||||
// this is kind of a problem - you will never see the
|
||||
// error from the first rom0?
|
||||
//
|
||||
if (arc_info->romindex == 0 && strlen(arc_info->zipname))
|
||||
arc_info->error_msg[0] = 0;
|
||||
|
||||
user_io_file_tx_start(arc_info->romname,arc_info->romindex);
|
||||
file_tx_start(arc_info->romindex);
|
||||
}
|
||||
break;
|
||||
break;
|
||||
|
||||
case XML_EVENT_TEXT:
|
||||
case XML_EVENT_TEXT:
|
||||
/* the text node is the data between tags, ie: <part>this text</part>
|
||||
*
|
||||
* the buffer_append is part of a buffer library that will realloc automatically
|
||||
@@ -201,67 +260,68 @@ static int xml_send_rom(XMLEvent evt, const XMLNode* node, SXML_CHAR* text, cons
|
||||
buffer_append(arc_info->data, text);
|
||||
//printf("XML_EVENT_TEXT: text [%s]\n",text);
|
||||
break;
|
||||
case XML_EVENT_END_NODE:
|
||||
|
||||
case XML_EVENT_END_NODE:
|
||||
//printf("XML_EVENT_END_NODE: tag [%s]\n",node->tag );
|
||||
|
||||
|
||||
// At the end of a rom node (when it is closed) we need to calculate hash values and clean up
|
||||
if (!strcasecmp(node->tag,"rom")) {
|
||||
if (arc_info->insiderom)
|
||||
if (!strcasecmp(node->tag, "rom")) {
|
||||
if (arc_info->insiderom)
|
||||
{
|
||||
unsigned char checksum[16];
|
||||
int checksumsame=1;
|
||||
char *md5=arc_info->md5;
|
||||
user_io_file_tx_finish();
|
||||
MD5Final (checksum, &arc_info->context);
|
||||
printf("md5[%s]\n",arc_info->md5);
|
||||
unsigned char checksum[16];
|
||||
int checksumsame = 1;
|
||||
char *md5 = arc_info->md5;
|
||||
file_tx_finish();
|
||||
MD5Final(checksum, &arc_info->context);
|
||||
printf("md5[%s]\n", arc_info->md5);
|
||||
printf("md5-calc[");
|
||||
for (int i = 0; i < 16; i++)
|
||||
{
|
||||
for (int i = 0; i < 16; i++)
|
||||
{
|
||||
char hex[10];
|
||||
snprintf(hex,10,"%02x", (unsigned int) checksum[i]);
|
||||
printf ("%02x", (unsigned int) checksum[i]);
|
||||
if (md5[0]!=hex[0] || md5[1]!=hex[1]) {
|
||||
checksumsame=0;
|
||||
snprintf(hex, 10, "%02x", (unsigned int)checksum[i]);
|
||||
printf("%02x", (unsigned int)checksum[i]);
|
||||
if (md5[0] != hex[0] || md5[1] != hex[1]) {
|
||||
checksumsame = 0;
|
||||
}
|
||||
md5+=2;
|
||||
}
|
||||
printf ("]\n");
|
||||
if (checksumsame==0)
|
||||
md5 += 2;
|
||||
}
|
||||
printf("]\n");
|
||||
if (checksumsame == 0)
|
||||
{
|
||||
printf("mismatch\n");
|
||||
if (!strlen(arc_info->error_msg))
|
||||
snprintf(arc_info->error_msg,kBigTextSize,"md5 mismatch for rom %d",arc_info->romindex);
|
||||
snprintf(arc_info->error_msg, kBigTextSize, "md5 mismatch for rom %d", arc_info->romindex);
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
// this code sets the validerom0 and clears the message
|
||||
// if a rom with index 0 has a correct md5. It supresses
|
||||
// if a rom with index 0 has a correct md5. It supresses
|
||||
// sending any further rom0 messages
|
||||
if (arc_info->romindex==0)
|
||||
if (arc_info->romindex == 0)
|
||||
{
|
||||
arc_info->validrom0=1;
|
||||
arc_info->error_msg[0]=0;
|
||||
arc_info->validrom0 = 1;
|
||||
arc_info->error_msg[0] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
arc_info->insiderom=0;
|
||||
arc_info->insiderom = 0;
|
||||
}
|
||||
|
||||
// At the end of a part node, send the rom part if we are inside a rom tag
|
||||
//int user_io_file_tx_body_filepart(const char *name,int start, int len)
|
||||
if (!strcasecmp(node->tag,"part") && arc_info->insiderom)
|
||||
if (!strcasecmp(node->tag, "part") && arc_info->insiderom)
|
||||
{
|
||||
// suppress rom0 if we already sent a valid one
|
||||
// this is useful for merged rom sets - if the first one was valid, use it
|
||||
// the second might not be
|
||||
if (arc_info->romindex==0 && arc_info->validrom0==1)
|
||||
if (arc_info->romindex == 0 && arc_info->validrom0 == 1)
|
||||
break;
|
||||
char fname[kBigTextSize*2+16];
|
||||
int start,length,repeat;
|
||||
repeat=arc_info->repeat;
|
||||
start=arc_info->offset;
|
||||
length=0;
|
||||
if (arc_info->length>0) length = arc_info->length;
|
||||
char fname[kBigTextSize * 2 + 16];
|
||||
int start, length, repeat;
|
||||
repeat = arc_info->repeat;
|
||||
start = arc_info->offset;
|
||||
length = 0;
|
||||
if (arc_info->length > 0) length = arc_info->length;
|
||||
//printf("partname[%s]\n",arc_info->partname);
|
||||
//printf("zipname [%s]\n",arc_info->zipname);
|
||||
//printf("offset[%d]\n",arc_info->offset);
|
||||
@@ -270,207 +330,216 @@ static int xml_send_rom(XMLEvent evt, const XMLNode* node, SXML_CHAR* text, cons
|
||||
//
|
||||
if (strlen(arc_info->partzipname))
|
||||
{
|
||||
if (arc_info->partzipname[0]=='/')
|
||||
sprintf(fname,"arcade%s/%s",arc_info->partzipname,arc_info->partname);
|
||||
if (arc_info->partzipname[0] == '/')
|
||||
sprintf(fname, "arcade%s/%s", arc_info->partzipname, arc_info->partname);
|
||||
else
|
||||
sprintf(fname,"arcade/mame/%s/%s",arc_info->partzipname,arc_info->partname);
|
||||
sprintf(fname, "arcade/mame/%s/%s", arc_info->partzipname, arc_info->partname);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (arc_info->zipname[0]=='/')
|
||||
sprintf(fname,"arcade%s/%s",arc_info->zipname,arc_info->partname);
|
||||
if (arc_info->zipname[0] == '/')
|
||||
sprintf(fname, "arcade%s/%s", arc_info->zipname, arc_info->partname);
|
||||
else
|
||||
sprintf(fname,"arcade/mame/%s/%s",arc_info->zipname,arc_info->partname);
|
||||
sprintf(fname, "arcade/mame/%s/%s", arc_info->zipname, arc_info->partname);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//user_io_file_tx_body_filepart(getFullPath(fname),0,0);
|
||||
if (strlen(arc_info->partname)) {
|
||||
printf("user_io_file_tx_body_filepart(const char *name[%s],int start[%d], int len[%d])\n",fname,start,length);
|
||||
for (int i=0;i<repeat;i++) {
|
||||
int result=user_io_file_tx_body_filepart(fname,start,length,&arc_info->context);
|
||||
printf("user_io_file_tx_body_filepart(const char *name[%s],int start[%d], int len[%d])\n", fname, start, length);
|
||||
for (int i = 0; i < repeat; i++) {
|
||||
int result = file_tx_body_filepart(fname, start, length, &arc_info->context);
|
||||
// we should check file not found error for the zip
|
||||
if (result==0)
|
||||
if (result == 0)
|
||||
{
|
||||
int skip=0;
|
||||
if (!strncasecmp(fname,"arcade/mame/",strlen("arcade/mame/")))
|
||||
skip=strlen("arcade/mame/");
|
||||
printf("%s does not exist\n",fname);
|
||||
snprintf(arc_info->error_msg,kBigTextSize,"%s\n"
|
||||
"\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\n"
|
||||
"File Not Found",fname+skip);
|
||||
int skip = 0;
|
||||
if (!strncasecmp(fname, "arcade/mame/", strlen("arcade/mame/")))
|
||||
skip = strlen("arcade/mame/");
|
||||
printf("%s does not exist\n", fname);
|
||||
snprintf(arc_info->error_msg, kBigTextSize, "%s\n"
|
||||
"\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\n"
|
||||
"File Not Found", fname + skip);
|
||||
}
|
||||
}
|
||||
}
|
||||
else // we have binary data?
|
||||
{
|
||||
//printf("we have bin.hex data [%s]\n",arc_info->data->content);
|
||||
size_t len=0;
|
||||
unsigned char* binary=hexstr_to_char(arc_info->data->content,&len);
|
||||
//printf("len %d:\n",len);
|
||||
//for (size_t i=0;i<len;i++) {
|
||||
// printf(" %d ",binary[i]);
|
||||
//}
|
||||
//printf("\n");
|
||||
for (int i=0;i<repeat;i++) {
|
||||
user_io_file_tx_body(binary,len,&arc_info->context);
|
||||
}
|
||||
if (binary) free(binary);
|
||||
//printf("we have bin.hex data [%s]\n",arc_info->data->content);
|
||||
size_t len = 0;
|
||||
unsigned char* binary = hexstr_to_char(arc_info->data->content, &len);
|
||||
//printf("len %d:\n",len);
|
||||
//for (size_t i=0;i<len;i++) {
|
||||
// printf(" %d ",binary[i]);
|
||||
//}
|
||||
//printf("\n");
|
||||
for (int i = 0; i < repeat; i++) {
|
||||
file_tx_body(binary, len, &arc_info->context);
|
||||
}
|
||||
if (binary) free(binary);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
break;
|
||||
break;
|
||||
|
||||
case XML_EVENT_ERROR:
|
||||
printf("XML parse: %s: ERROR %d\n", text, n);
|
||||
snprintf(arc_info->error_msg,kBigTextSize,"XML parse: %s: ERROR %d\n", text, n);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
case XML_EVENT_ERROR:
|
||||
printf("XML parse: %s: ERROR %d\n", text, n);
|
||||
snprintf(arc_info->error_msg, kBigTextSize, "XML parse: %s: ERROR %d\n", text, n);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
static int xml_scan_rbf(XMLEvent evt, const XMLNode* node, SXML_CHAR* text, const int n, SAX_Data* sd)
|
||||
{
|
||||
static int insiderbf=0;
|
||||
static int insiderbf = 0;
|
||||
char bigtext[kBigTextSize];
|
||||
char *rbf = (char *)sd->user;
|
||||
|
||||
switch (evt)
|
||||
{
|
||||
case XML_EVENT_START_NODE:
|
||||
bigtext[0]=0;
|
||||
if (!strcasecmp(node->tag,"rbf")) {
|
||||
insiderbf=1;
|
||||
switch (evt)
|
||||
{
|
||||
case XML_EVENT_START_NODE:
|
||||
bigtext[0] = 0;
|
||||
if (!strcasecmp(node->tag, "rbf")) {
|
||||
insiderbf = 1;
|
||||
}
|
||||
printf("XML_EVENT_START_NODE: tag [%s]\n", node->tag);
|
||||
for (int i = 0; i < node->n_attributes; i++)
|
||||
{
|
||||
printf("attribute %d name [%s] value [%s]\n", i, node->attributes[i].name, node->attributes[i].value);
|
||||
}
|
||||
printf("XML_EVENT_START_NODE: tag [%s]\n",node->tag);
|
||||
for (int i = 0; i < node->n_attributes; i++)
|
||||
{
|
||||
printf("attribute %d name [%s] value [%s]\n",i,node->attributes[i].name,node->attributes[i].value);
|
||||
}
|
||||
|
||||
break;
|
||||
case XML_EVENT_TEXT:
|
||||
break;
|
||||
case XML_EVENT_TEXT:
|
||||
if (insiderbf) {
|
||||
strncat(bigtext,text,kBigTextSize-strlen(bigtext)-1);
|
||||
printf("XML_EVENT_TEXT: text [%s]\n",text);
|
||||
strncat(bigtext, text, kBigTextSize - strlen(bigtext) - 1);
|
||||
printf("XML_EVENT_TEXT: text [%s]\n", text);
|
||||
}
|
||||
break;
|
||||
case XML_EVENT_END_NODE:
|
||||
if (!strcasecmp(node->tag,"rbf"))
|
||||
case XML_EVENT_END_NODE:
|
||||
if (!strcasecmp(node->tag, "rbf"))
|
||||
{
|
||||
insiderbf=0;
|
||||
insiderbf = 0;
|
||||
//printf("bigtext [%s]\n",bigtext);
|
||||
strncpy(rbf,bigtext,kBigTextSize);
|
||||
strncpy(rbf, bigtext, kBigTextSize);
|
||||
//printf("got rbf tag [%s]\n",rbf);
|
||||
}
|
||||
printf("XML_EVENT_END_NODE: tag [%s]\n",node->tag );
|
||||
break;
|
||||
printf("XML_EVENT_END_NODE: tag [%s]\n", node->tag);
|
||||
break;
|
||||
|
||||
case XML_EVENT_ERROR:
|
||||
printf("XML parse: %s: ERROR %d\n", text, n);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
case XML_EVENT_ERROR:
|
||||
printf("XML parse: %s: ERROR %d\n", text, n);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
int arcade_send_rom(const char *xml)
|
||||
{
|
||||
SAX_Callbacks sax;
|
||||
SAX_Callbacks_init(&sax);
|
||||
SAX_Callbacks sax;
|
||||
SAX_Callbacks_init(&sax);
|
||||
|
||||
sax.all_event = xml_send_rom;
|
||||
sax.all_event = xml_send_rom;
|
||||
|
||||
// create the structure we use for the XML parser
|
||||
struct arc_struct arc_info;
|
||||
arc_info.data=buffer_init(kBigTextSize);
|
||||
arc_info.error_msg[0]=0;
|
||||
arc_info.validrom0=0;
|
||||
arc_info.data = buffer_init(kBigTextSize);
|
||||
arc_info.error_msg[0] = 0;
|
||||
arc_info.validrom0 = 0;
|
||||
|
||||
// parse
|
||||
XMLDoc_parse_file_SAX(xml, &sax, &arc_info);
|
||||
if (arc_info.validrom0==0 && strlen(arc_info.error_msg))
|
||||
XMLDoc_parse_file_SAX(xml, &sax, &arc_info);
|
||||
if (arc_info.validrom0 == 0 && strlen(arc_info.error_msg))
|
||||
{
|
||||
strcpy(global_error_msg,arc_info.error_msg);
|
||||
printf("arcade_send_rom: pretty error: [%s]\n",global_error_msg);
|
||||
strcpy(global_error_msg, arc_info.error_msg);
|
||||
printf("arcade_send_rom: pretty error: [%s]\n", global_error_msg);
|
||||
}
|
||||
buffer_destroy(arc_info.data);
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CheckArcadeError(void)
|
||||
int arcade_check_error(void)
|
||||
{
|
||||
if (global_error_msg[0]!=0) {
|
||||
printf("ERROR: [%s]\n",global_error_msg);
|
||||
Info(global_error_msg,1000*30);
|
||||
global_error_msg[0]=0;
|
||||
if (global_error_msg[0] != 0) {
|
||||
printf("ERROR: [%s]\n", global_error_msg);
|
||||
Info(global_error_msg, 1000 * 30);
|
||||
global_error_msg[0] = 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int arcade_scan_xml_for_rbf(const char *xml,char *rbfname)
|
||||
int arcade_load(const char *xml)
|
||||
{
|
||||
char rbfname_fragment[kBigTextSize];
|
||||
rbfname_fragment[0]=0;
|
||||
rbfname[0]=0;
|
||||
SAX_Callbacks sax;
|
||||
SAX_Callbacks_init(&sax);
|
||||
MenuHide();
|
||||
|
||||
sax.all_event = xml_scan_rbf;
|
||||
XMLDoc_parse_file_SAX(xml, &sax, rbfname_fragment);
|
||||
strcpy(rbfname,rbfname_fragment);
|
||||
char rbfname[kBigTextSize];
|
||||
char xmlname[kBigTextSize];
|
||||
|
||||
//printf("arcade_scan_xml_for_rbf [%s]\n",xml);
|
||||
strcpy(xmlname, xml);
|
||||
|
||||
rbfname[0] = 0;
|
||||
SAX_Callbacks sax;
|
||||
SAX_Callbacks_init(&sax);
|
||||
|
||||
sax.all_event = xml_scan_rbf;
|
||||
XMLDoc_parse_file_SAX(xmlname, &sax, rbfname);
|
||||
|
||||
printf("arcade_scan_xml_for_rbf [%s]\n", xmlname);
|
||||
/* once we have the rbfname fragment from the MRA xml file
|
||||
* search the arcade folder for the match */
|
||||
struct dirent *entry;
|
||||
DIR *dir=NULL;
|
||||
struct dirent *entry;
|
||||
DIR *dir = NULL;
|
||||
//printf("opendir(%s)\n",getFullPath("arcade"));
|
||||
if (!(dir = opendir(getFullPath("arcade"))))
|
||||
{
|
||||
if (!(dir = opendir(getFullPath("arcade"))))
|
||||
{
|
||||
printf("arcade directory not found\n");
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
while ((entry = readdir(dir)) != NULL) {
|
||||
if (entry->d_type == DT_DIR) {
|
||||
}
|
||||
else {
|
||||
int found = 0;
|
||||
int len;
|
||||
while ((entry = readdir(dir)) != NULL)
|
||||
{
|
||||
if (entry->d_type != DT_DIR)
|
||||
{
|
||||
char newstring[kBigTextSize];
|
||||
//printf("entry name: %s\n",entry->d_name);
|
||||
snprintf(newstring,kBigTextSize,"Arcade-%s_",rbfname_fragment);
|
||||
if (!strncasecmp(newstring,entry->d_name,strlen(newstring))) {
|
||||
closedir(dir);
|
||||
strcpy(rbfname,entry->d_name);
|
||||
return 0;
|
||||
|
||||
}
|
||||
snprintf(newstring,kBigTextSize,"%s_",rbfname_fragment);
|
||||
if (!strncasecmp(newstring,entry->d_name,strlen(newstring))) {
|
||||
closedir(dir);
|
||||
strcpy(rbfname,entry->d_name);
|
||||
return 0;
|
||||
}
|
||||
snprintf(newstring,kBigTextSize,"%s.",rbfname_fragment);
|
||||
if (!strncasecmp(newstring,entry->d_name,strlen(newstring))) {
|
||||
closedir(dir);
|
||||
strcpy(rbfname,entry->d_name);
|
||||
return 0;
|
||||
snprintf(newstring, kBigTextSize, "Arcade-%s", rbfname);
|
||||
len = strlen(newstring);
|
||||
if (!strncasecmp(newstring, entry->d_name, len) && (entry->d_name[len] == '.' || entry->d_name[len] == '_'))
|
||||
{
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
snprintf(newstring, kBigTextSize, "%s", rbfname);
|
||||
len = strlen(newstring);
|
||||
if (!strncasecmp(newstring, entry->d_name, len) && (entry->d_name[len] == '.' || entry->d_name[len] == '_'))
|
||||
{
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (dir) closedir(dir);
|
||||
strcpy(rbfname,rbfname_fragment);
|
||||
return 0;
|
||||
if (found) sprintf(rbfname, "%s/arcade/%s", getRootDir(), entry->d_name);
|
||||
closedir(dir);
|
||||
|
||||
if (found)
|
||||
{
|
||||
printf("MRA: %s, RBF: %s\n", xmlname, rbfname);
|
||||
fpga_load_rbf(rbfname, NULL, xmlname);
|
||||
}
|
||||
else
|
||||
{
|
||||
Info("No core found!");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user