mirror of
https://github.com/RaySollium99/picodrive.git
synced 2025-09-05 15:27:46 -04:00
143 lines
2.7 KiB
C++
143 lines
2.7 KiB
C++
|
|
#include "app.h"
|
|
#include "Unzip.h"
|
|
|
|
unsigned char *RomData=NULL;
|
|
int RomLen=0;
|
|
char RomName[260]="";
|
|
|
|
|
|
static int Byteswap(unsigned char *data,int len)
|
|
{
|
|
int i=0;
|
|
|
|
if (len<2) return 1; // Too short
|
|
|
|
do
|
|
{
|
|
unsigned short *pd=(unsigned short *)(data+i);
|
|
int word=*pd; // Get word
|
|
|
|
word=(word<<8)|(word>>8); // Byteswap it
|
|
*pd=(unsigned short)word; // Put word
|
|
i+=2;
|
|
}
|
|
while (i+2<=len);
|
|
|
|
return 0;
|
|
}
|
|
|
|
// Interleve a 16k block and byteswap
|
|
static int InterleveBlock(unsigned char *dest,unsigned char *src)
|
|
{
|
|
int i=0;
|
|
for (i=0;i<0x2000;i++) dest[(i<<1) ]=src[ i]; // Odd
|
|
for (i=0;i<0x2000;i++) dest[(i<<1)+1]=src[0x2000+i]; // Even
|
|
return 0;
|
|
}
|
|
|
|
// Decode a SMD file
|
|
static int DecodeSmd(unsigned char *data,int len)
|
|
{
|
|
unsigned char *temp=NULL;
|
|
int i=0;
|
|
|
|
temp=(unsigned char *)malloc(0x4000);
|
|
if (temp==NULL) return 1;
|
|
memset(temp,0,0x4000);
|
|
|
|
// Interleve each 16k block and shift down by 0x200:
|
|
for (i=0; i+0x4200<=len; i+=0x4000)
|
|
{
|
|
InterleveBlock(temp,data+0x200+i); // Interleve 16k to temporary buffer
|
|
memcpy(data+i,temp,0x4000); // Copy back in
|
|
}
|
|
|
|
free(temp);
|
|
return 0;
|
|
}
|
|
|
|
int RomLoad()
|
|
{
|
|
FILE *file=NULL;
|
|
char *name=NULL;
|
|
int nameLen=0;
|
|
int fileLen=0,space=0;
|
|
Unzip unzip;
|
|
|
|
name=RomName;
|
|
|
|
file=fopen(name,"rb"); if (file==NULL) return 1;
|
|
|
|
nameLen=strlen(name);
|
|
if (stricmp(name+nameLen-4,".zip")==0) unzip.file=file; // Open as zip file
|
|
|
|
if (unzip.file)
|
|
{
|
|
int ret=0;
|
|
|
|
ret=unzip.fileOpen(); // Get first entry
|
|
if (ret==0)
|
|
{
|
|
fileLen=unzip.dataLen; // Length of file
|
|
// Switch to using the name in the zip file:
|
|
name=unzip.name; nameLen=strlen(name);
|
|
}
|
|
else
|
|
{
|
|
unzip.file=NULL;
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
// Find out the length of the file:
|
|
fseek(file,0,SEEK_END); fileLen=ftell(file);
|
|
fseek(file,0,SEEK_SET);
|
|
}
|
|
|
|
// Allocate space for it:
|
|
space=(fileLen+0x3fff)&~0x3fff;
|
|
|
|
RomData=(unsigned char *)malloc(space);
|
|
if (RomData==NULL) { fclose(file); return 1; }
|
|
memset(RomData,0,space);
|
|
|
|
// Read in file:
|
|
if (unzip.file) unzip.fileDecode(RomData);
|
|
else fread(RomData,1,fileLen,file);
|
|
|
|
unzip.fileClose();
|
|
|
|
fclose(file);
|
|
unzip.file=file=NULL;
|
|
|
|
RomLen=fileLen;
|
|
|
|
// Check for SMD:
|
|
if ((fileLen&0x3fff)==0x200)
|
|
{
|
|
// Decode and byteswap:
|
|
DecodeSmd(RomData,RomLen);
|
|
RomLen-=0x200;
|
|
}
|
|
else
|
|
{
|
|
// Just byteswap:
|
|
Byteswap(RomData,RomLen);
|
|
}
|
|
|
|
PicoCartInsert(RomData,RomLen);
|
|
|
|
return 0;
|
|
}
|
|
|
|
void RomFree()
|
|
{
|
|
// PicoCartInsert(NULL,0); // Unplug rom
|
|
|
|
if (RomData) free(RomData);
|
|
RomData=NULL; RomLen=0;
|
|
memset(RomName,0,sizeof(RomName));
|
|
}
|
|
|