AxibugEmuOnline/References/VirtuaNESex_src_191105/NES/ROM.cpp
2024-08-05 17:58:53 +08:00

720 lines
18 KiB
C++
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//////////////////////////////////////////////////////////////////////////
// //
// NES ROM Cartridge class //
// Norix //
// written 2001/02/20 //
// last modify ----/--/-- //
//////////////////////////////////////////////////////////////////////////
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <mbstring.h>
#include "typedef.h"
#include "macro.h"
#include "VirtuaNESres.h"
#include "DebugOut.h"
#include "App.h"
#include "Plugin.h"
#include "Pathlib.h"
#include "Crclib.h"
#include "Archive.h"
#include "rom.h"
#include "romdb.h"
#include "mmu.h"
#include "mapper.h"
const char* img_fname; //for bbk
BOOL g_bSan2;
unsigned char pFont[256*1024];
INT g_UnfTVMode = -1;
#define MKID(a) ((unsigned long) \
(((a) >> 24) & 0x000000FF) | \
(((a) >> 8) & 0x0000FF00) | \
(((a) << 8) & 0x00FF0000) | \
(((a) << 24) & 0xFF000000))
//
// ƒRƒ“ƒXƒgƒ‰ƒNƒ^
//
ROM::ROM( const char* fname )
{
FILE *fp = NULL;
LPBYTE temp = NULL;
LPBYTE bios = NULL;
LONG FileSize;
g_bSan2 = FALSE;
ZEROMEMORY( &header, sizeof(header) );
ZEROMEMORY( path, sizeof(path) );
ZEROMEMORY( name, sizeof(name) );
bPAL = FALSE;
bNSF = FALSE;
NSF_PAGE_SIZE = 0;
board = 0;
bUnif = FALSE;
g_UnfTVMode = -1;
lpPRG = lpCHR = lpTrainer = lpDiskBios = lpDisk = NULL;
crc = crcall = 0;
mapper = 0;
diskno = 0;
try {
//for bbk-------------------------------------------------------------------------
if( !(fp = ::fopen( fname, "rb" )) ) {
LPCSTR szErrStr = CApp::GetErrorString( IDS_ERROR_OPEN );
::wsprintf( szErrorString, szErrStr, fname );
throw szErrorString;
}
::fseek( fp, 0, SEEK_END );
FileSize = ::ftell( fp );
::fseek( fp, 0, SEEK_SET );
if( !(temp = (LPBYTE)::malloc( FileSize )) ) {
throw CApp::GetErrorString( IDS_ERROR_OUTOFMEMORY );
}
if( ::fread( temp, FileSize, 1, fp ) != 1 ) {
throw CApp::GetErrorString( IDS_ERROR_READ );
}
FCLOSE( fp );
::memcpy( &header, temp, sizeof(NESHEADER) );
if( header.ID[0] == 0xEB && header.ID[1] == 0x3C
&& header.ID[2] == 0x90 && header.ID[3] == 0x53 ) {
img_fname = fname;
// DEBUGOUT( "img_fname: %s\n", img_fname );
fname = "bbk_bios10.rom";
} else {
FREE( temp );
}
//--------------------------------------------------------------------------------
if( !(fp = ::fopen( fname, "rb" )) ) {
// xxx ƒtƒ@ƒCƒðŠJ¯Ü¹ñ
LPCSTR szErrStr = CApp::GetErrorString( IDS_ERROR_OPEN );
::wsprintf( szErrorString, szErrStr, fname );
throw szErrorString;
}
// ƒtƒ@ƒCƒƒTƒCƒYŽæ“¾
::fseek( fp, 0, SEEK_END );
FileSize = ::ftell( fp );
::fseek( fp, 0, SEEK_SET );
// ƒtƒ@ƒCƒƒTƒCƒYƒ`ƒFƒbƒN(NESƒwƒbƒ_+1ƒoƒCƒgˆÈ<CB86>ã©<E2809A>H)
if( FileSize < 17 ) {
// ƒtƒ@ƒCƒƒTƒCƒYª<E2809A>¬³·¬Ü·
throw CApp::GetErrorString( IDS_ERROR_SMALLFILE );
}
// ƒeƒ“ƒ|ƒ‰ƒŠƒ<C5A0>ƒƒŠŠm•Û
if( !(temp = (LPBYTE)::malloc( FileSize )) ) {
// ƒ<>ƒƒŠðŠm•Û<E280A2>o—ˆÜ¹ñ
throw CApp::GetErrorString( IDS_ERROR_OUTOFMEMORY );
}
// ƒTƒCƒY•ª“ÇÝ<E2809A>žÝ
if( ::fread( temp, FileSize, 1, fp ) != 1 ) {
// ƒtƒ@ƒCƒÌ“ÇÝ<E2809A>žÝÉŽ¸”sµÜµ½
throw CApp::GetErrorString( IDS_ERROR_READ );
}
FCLOSE( fp );
// ƒwƒbƒ_ƒRƒs<C692>[
::memcpy( &header, temp, sizeof(NESHEADER) );
header.CHR_PAGE_SIZE = header.CHR_PAGE_SIZE_old;
header.PRG_PAGE_SIZE = header.PRG_PAGE_SIZE_old;
if( header.ID[0] == 'N' && header.ID[1] == 'E'
&& header.ID[2] == 'S' && header.ID[3] == 0x1A ) {
// ƒwƒbƒ_ƒRƒs<C692>[
memcpy( &header, temp, sizeof(NESHEADER) );
header.CHR_PAGE_SIZE = header.CHR_PAGE_SIZE_old;
header.PRG_PAGE_SIZE = header.PRG_PAGE_SIZE_old;
} else if( header.ID[0] == 'F' && header.ID[1] == 'D'
&& header.ID[2] == 'S' && header.ID[3] == 0x1A ) {
// ƒwƒbƒ_ƒRƒs<C692>[
memcpy( &header, temp, sizeof(NESHEADER) );
header.CHR_PAGE_SIZE = header.CHR_PAGE_SIZE_old;
header.PRG_PAGE_SIZE = header.PRG_PAGE_SIZE_old;
} else if( header.ID[0] == 'N' && header.ID[1] == 'E'
&& header.ID[2] == 'S' && header.ID[3] == 'M') {
// ƒwƒbƒ_ƒRƒs<C692>[
memcpy( &header, temp, sizeof(NESHEADER) );
header.CHR_PAGE_SIZE = header.CHR_PAGE_SIZE_old;
header.PRG_PAGE_SIZE = header.PRG_PAGE_SIZE_old;
} else if( header.ID[0] == 'U' && header.ID[1] == 'N'
&& header.ID[2] == 'I' && header.ID[3] == 'F') {
//´¦ÀíUnif ROM
} else {
FREE( temp );
if( !UnCompress( fname, &temp, (LPDWORD)&FileSize ) ) {
// –¢‘ΉžŒ`Ž®‚Å‚·
throw CApp::GetErrorString( IDS_ERROR_UNSUPPORTFORMAT );
}
// ƒwƒbƒ_ƒRƒs<C692>[
::memcpy( &header, temp, sizeof(NESHEADER) );
header.CHR_PAGE_SIZE = header.CHR_PAGE_SIZE_old;
header.PRG_PAGE_SIZE = header.PRG_PAGE_SIZE_old;
}
DWORD PRGoffset, CHRoffset;
LONG PRGsize, CHRsize;
BYTE *pUnif = temp;
DWORD filesize = FileSize;
if( header.ID[0] == 'N' && header.ID[1] == 'E'
&& header.ID[2] == 'S' && header.ID[3] == 0x1A ) {
// •<>ÊÌNESƒtƒ@ƒCƒ
PRGsize = (LONG)header.PRG_PAGE_SIZE*0x4000;
CHRsize = (LONG)header.CHR_PAGE_SIZE*0x2000;
PRGoffset = sizeof(NESHEADER);
CHRoffset = PRGoffset + PRGsize;
//for Game Star - Smart Genius (Unl)
if(header.PRG_PAGE_SIZE==0xff)
PRGsize = (LONG)(header.PRG_PAGE_SIZE+1)*0x4000;
if( IsTRAINER() ) {
PRGoffset += 512;
CHRoffset += 512;
}
if( PRGsize <= 0 || (PRGsize+CHRsize) > FileSize ) {
// NESƒwƒbƒ_ªˆÙ<CB86>íÅ·
throw CApp::GetErrorString( IDS_ERROR_INVALIDNESHEADER );
}
// PRG BANK
if( !(lpPRG = (LPBYTE)malloc( PRGsize )) ) {
// ƒ<>ƒƒŠðŠm•Û<E280A2>o—ˆÜ¹ñ
throw CApp::GetErrorString( IDS_ERROR_OUTOFMEMORY );
}
::memcpy( lpPRG, temp+PRGoffset, PRGsize );
// CHR BANK
if( CHRsize > 0 ) {
if( !(lpCHR = (LPBYTE)malloc( CHRsize )) ) {
// ƒ<>ƒƒŠðŠm•Û<E280A2>o—ˆÜ¹ñ
throw CApp::GetErrorString( IDS_ERROR_OUTOFMEMORY );
}
if( FileSize >= CHRoffset+CHRsize ) {
memcpy( lpCHR, temp+CHRoffset, CHRsize );
} else {
// CHRƒoƒ“ƒN<C692>­È¢<E2809A>c
CHRsize -= (CHRoffset+CHRsize - FileSize);
memcpy( lpCHR, temp+CHRoffset, CHRsize );
}
} else {
lpCHR = NULL;
}
// Trainer
if( IsTRAINER() ) {
if( !(lpTrainer = (LPBYTE)malloc( 512 )) ) {
// ƒ<>ƒƒŠðŠm•Û<E280A2>o—ˆÜ¹ñ
throw CApp::GetErrorString( IDS_ERROR_OUTOFMEMORY );
}
memcpy( lpTrainer, temp+sizeof(NESHEADER), 512 );
} else {
lpTrainer = NULL;
}
} else if( header.ID[0] == 'U' && header.ID[1] == 'N'
&& header.ID[2] == 'I' && header.ID[3] == 'F' ) {
DWORD Signature, BlockLen;
DWORD ipos =0x20;//Ìø¹ýUNIFÍ·
BYTE id,i;
BYTE *tPRG[0x10], *tCHR[0x10];
DWORD sizePRG[0x10],sizeCHR[0x10];
//char info[100];
//char name[100];
PRGsize = 0x00;
CHRsize = 0x00;
header.ID[0] = 'N';
header.ID[1] = 'E';
header.ID[2] = 'S';
header.ID[3] = 0x1A;
board = 0;
bUnif = TRUE;
// header.PRG_PAGE_SIZE = (BYTE)diskno*4;
// header.CHR_PAGE_SIZE = 0;
// header.control1 = 0x40;
// header.control2 = 0x10;
header.control1 = 0;
header.control2 = 0;
for (i = 0; i < 0x10; i++)
{
tPRG[i] = tCHR[i] = 0;
}
//filesize
while(ipos<filesize)
{
id = 0;
memcpy(&Signature,&pUnif[ipos],4);ipos+=4;
memcpy(&BlockLen,&pUnif[ipos],4);ipos+=4;
switch(Signature)
{
case MKID('MAPR')://boardÃû×Ö
memcpy( pboardname, &pUnif[ipos], BlockLen);
pboardname[BlockLen]=0;
//memcpy( info, &pUnif[ipos], BlockLen);
//fl.info = info;
ipos+=BlockLen; break;
case MKID('NAME'):
//memcpy( pboardname, &pUnif[ipos], BlockLen);
//fl.title = name;
ipos+=BlockLen; break;
case MKID('TVCI')://µçÊÓÖÆʽ
g_UnfTVMode = pUnif[ipos];
ipos+=BlockLen; break;
case MKID('BATR')://ʹÓõç³Ø¼ÇÒä
header.control1 |=2;
ipos+=BlockLen; break;
case MKID('FONT')://×Ö¿â
// memcpy( pFont, &pUnif[ipos], BlockLen>65536?65536:BlockLen );
memcpy( pFont, &pUnif[ipos], BlockLen );
ipos+=BlockLen; break;
case MKID('MIRR'):
if (pUnif[ipos]==0)
header.control1 &=14;
else if (pUnif[ipos]==1)
header.control1 |=1;
ipos+=BlockLen;
break;
case MKID('PRGF'): id++;
case MKID('PRGE'): id++;
case MKID('PRGD'): id++;
case MKID('PRGC'): id++;
case MKID('PRGB'): id++;
case MKID('PRGA'): id++;
case MKID('PRG9'): id++;
case MKID('PRG8'): id++;
case MKID('PRG7'): id++;
case MKID('PRG6'): id++;
case MKID('PRG5'): id++;
case MKID('PRG4'): id++;
case MKID('PRG3'): id++;
case MKID('PRG2'): id++;
case MKID('PRG1'): id++;
case MKID('PRG0'):
sizePRG[id] = BlockLen;
tPRG[id] = (BYTE*)malloc(BlockLen);
memcpy( tPRG[id], &pUnif[ipos], BlockLen );
ipos+=BlockLen;
PRGsize += BlockLen;
break;
case MKID('CHRF'): id++;
case MKID('CHRE'): id++;
case MKID('CHRD'): id++;
case MKID('CHRC'): id++;
case MKID('CHRB'): id++;
case MKID('CHRA'): id++;
case MKID('CHR9'): id++;
case MKID('CHR8'): id++;
case MKID('CHR7'): id++;
case MKID('CHR6'): id++;
case MKID('CHR5'): id++;
case MKID('CHR4'): id++;
case MKID('CHR3'): id++;
case MKID('CHR2'): id++;
case MKID('CHR1'): id++;
case MKID('CHR0'):
sizeCHR[id] = BlockLen;
tCHR[id] = (BYTE*)malloc(BlockLen);
memcpy( tCHR[id], &pUnif[ipos], BlockLen );
ipos+=BlockLen;
CHRsize += BlockLen;
break;
default:
ipos+=BlockLen; break;
}
}
//fl.mapper = 0;
//fl.prg_size = 0;
//fl.chr_size = 0;
board = NES_ROM_get_unifBoardID(pboardname);
header.PRG_PAGE_SIZE = PRGsize/(16*1024);
header.CHR_PAGE_SIZE = CHRsize/(8*1024);
DWORD LenPRG=0,LenCHR=0;
if(PRGsize)
lpPRG = (LPBYTE)malloc( PRGsize );
if(CHRsize)
lpCHR = (LPBYTE)malloc( CHRsize );
for (i = 0; i < 16; i++)
{
if (tPRG[i])
{
memcpy(&lpPRG[LenPRG], tPRG[i], sizePRG[i]);
LenPRG += sizePRG[i];
//fl.prg_size += sizePRG[i]>>14;
//PRGsize = PRGsize+LenPRG;
free(tPRG[i]);
}
if (tCHR[i])
{
memcpy(&lpCHR[LenCHR], tCHR[i], sizeCHR[i]);
LenCHR += sizeCHR[i];
//fl.chr_size = (fl.chr_size)+(sizeCHR[i]>>13);
//CHRsize = CHRsize+LenCHR;
free(tCHR[i]);
}
}
} else if( header.ID[0] == 'F' && header.ID[1] == 'D'
&& header.ID[2] == 'S' && header.ID[3] == 0x1A ) {
// FDS(Nintendo Disk System)
// ƒfƒBƒXƒNƒTƒCƒY
diskno = header.PRG_PAGE_SIZE;
if( FileSize < (16+65500*diskno) ) {
// ƒfƒBƒXƒNƒTƒCƒYªˆÙ<CB86>íÅ·
throw CApp::GetErrorString( IDS_ERROR_ILLEGALDISKSIZE );
}
if( diskno > 4 ) {
// 4Êæè½¢ƒfƒBƒXƒNÍΉžµÄ¢Ü¹ñ
throw CApp::GetErrorString( IDS_ERROR_UNSUPPORTDISK );
}
ZEROMEMORY( &header, sizeof(NESHEADER) );
// ƒ_ƒ~<7E>[ƒwƒbƒ_ð<E2809A>ìé
header.ID[0] = 'N';
header.ID[1] = 'E';
header.ID[2] = 'S';
header.ID[3] = 0x1A;
header.PRG_PAGE_SIZE = (BYTE)diskno*4;
header.CHR_PAGE_SIZE = 0;
header.control1 = 0x40;
header.control2 = 0x10;
PRGsize = sizeof(NESHEADER)+65500*(LONG)diskno;
// PRG BANK
if( !(lpPRG = (LPBYTE)malloc( PRGsize )) ) {
// ƒ<>ƒƒŠðŠm•Û<E280A2>o—ˆÜ¹ñ
throw CApp::GetErrorString( IDS_ERROR_OUTOFMEMORY );
}
// ƒf<C692>[ƒ^̃oƒbƒNƒAƒbƒv—p
if( !(lpDisk = (LPBYTE)malloc( PRGsize )) ) {
// ƒ<>ƒƒŠðŠm•Û<E280A2>o—ˆÜ¹ñ
throw CApp::GetErrorString( IDS_ERROR_OUTOFMEMORY );
}
// CHR BANK
lpCHR = NULL;
::memcpy( lpPRG, &header, sizeof(NESHEADER) );
::memcpy( lpPRG+sizeof(NESHEADER), temp+sizeof(NESHEADER), 65500*(LONG)diskno );
// ƒf<C692>[ƒ^Ì<E2809A>«Š·¦<E2809A>ê<EFBFBD>Š“Áè—p
ZEROMEMORY( lpDisk, PRGsize );
// memcpy( lpDisk, &header, sizeof(NESHEADER) );
// memcpy( lpDisk+sizeof(NESHEADER), temp+sizeof(NESHEADER), PRGsize-sizeof(NESHEADER) );
lpPRG[0] = 'F';
lpPRG[1] = 'D';
lpPRG[2] = 'S';
lpPRG[3] = 0x1A;
lpPRG[4] = (BYTE)diskno;
// DISKSYSTEM BIOS̃<C38C><C692>[ƒh
string Path = CPathlib::MakePathExt( CApp::GetModulePath(), "DISKSYS", "ROM" );
if( !(fp = fopen( Path.c_str(), "rb" )) ) {
// DISKSYS.ROMª èܹñ
throw CApp::GetErrorString( IDS_ERROR_NODISKBIOS );
}
::fseek( fp, 0, SEEK_END );
FileSize = ::ftell( fp );
::fseek( fp, 0, SEEK_SET );
if( FileSize < 17 ) {
// ƒtƒ@ƒCƒƒTƒCƒYª<E2809A>¬³·¬Ü·
throw CApp::GetErrorString( IDS_ERROR_SMALLFILE );
}
if( !(bios = (LPBYTE)malloc( FileSize )) ) {
// ƒ<>ƒƒŠðŠm•Û<E280A2>o—ˆÜ¹ñ
throw CApp::GetErrorString( IDS_ERROR_OUTOFMEMORY );
}
if( fread( bios, FileSize, 1, fp ) != 1 ) {
// ƒtƒ@ƒCƒÌ“ÇÝ<E2809A>žÝÉŽ¸”sµÜµ½
throw CApp::GetErrorString( IDS_ERROR_READ );
}
FCLOSE( fp );
if( !(lpDiskBios = (LPBYTE)malloc( 8*1024 )) ) {
// ƒ<>ƒƒŠðŠm•Û<E280A2>o—ˆÜ¹ñ
throw CApp::GetErrorString( IDS_ERROR_OUTOFMEMORY );
}
if( bios[0] == 'N' && bios[1] == 'E' && bios[2] == 'S' && bios[3] == 0x1A ) {
// NESŒ`Ž®BIOS
::memcpy( lpDiskBios, bios+0x6010, 8*1024 );
} else {
// <20>¶BIOS
::memcpy( lpDiskBios, bios, 8*1024 );
}
FREE( bios );
} else if( header.ID[0] == 'N' && header.ID[1] == 'E'
&& header.ID[2] == 'S' && header.ID[3] == 'M') {
// NSF
bNSF = TRUE;
ZEROMEMORY( &header, sizeof(NESHEADER) );
// ƒwƒbƒ_ƒRƒs<C692>[
memcpy( &nsfheader, temp, sizeof(NSFHEADER) );
PRGsize = FileSize-sizeof(NSFHEADER);
//DEBUGOUT( "PRGSIZE:%d\n", PRGsize );
PRGsize = (PRGsize+0x0FFF)&~0x0FFF;
//DEBUGOUT( "PRGSIZE:%d\n", PRGsize );
if( !(lpPRG = (LPBYTE)malloc( PRGsize )) ) {
// ƒ<>ƒƒŠðŠm•Û<E280A2>o—ˆÜ¹ñ
throw CApp::GetErrorString( IDS_ERROR_OUTOFMEMORY );
throw szErrorString;
}
ZEROMEMORY( lpPRG, PRGsize );
memcpy( lpPRG, temp+sizeof(NSFHEADER), FileSize-sizeof(NSFHEADER) );
NSF_PAGE_SIZE = PRGsize>>12;
//DEBUGOUT( "PAGESIZE:%d\n", NSF_PAGE_SIZE );
} else {
// –¢‘ΉžŒ`Ž®‚Å‚·
throw CApp::GetErrorString( IDS_ERROR_UNSUPPORTFORMAT );
}
// ƒpƒX/ƒtƒ@ƒCƒ¼Žæ“¾
{
string tempstr;
tempstr = CPathlib::SplitPath( fname );
::strcpy( path, tempstr.c_str() );
tempstr = CPathlib::SplitFname( fname );
::strcpy( name, tempstr.c_str() );
// ƒIƒŠƒWƒiƒƒtƒ@ƒCƒ¼(ƒtƒƒpƒX)
::strcpy( fullpath, fname );
}
// ƒ}ƒbƒp<C692>Ýè
if( !bNSF ) {
mapper = (header.control1>>4)|(header.control2&0xF0);
crc = crcall = crcvrom = 0;
if( mapper != 20 ) {
// PRG crcÌŒvŽZ(NesToyÌPRG CRCÆ“¯¶)
if( IsTRAINER() ) {
crcall = CRC::CrcRev( 512+PRGsize+CHRsize, temp+sizeof(NESHEADER) );
crc = CRC::CrcRev( 512+PRGsize, temp+sizeof(NESHEADER) );
if( CHRsize )
crcvrom = CRC::CrcRev( CHRsize, temp+PRGsize+512+sizeof(NESHEADER) );
} else {
crcall = CRC::CrcRev( PRGsize+CHRsize, temp+sizeof(NESHEADER) );
crc = CRC::CrcRev( PRGsize, temp+sizeof(NESHEADER) );
if( CHRsize )
crcvrom = CRC::CrcRev( CHRsize, temp+PRGsize+sizeof(NESHEADER) );
}
FilenameCheck( name );
romdatabase.HeaderCorrect( header, crcall, crc );
#include "ROM_Patch.cpp"
fdsmakerID = fdsgameID = 0;
} else {
crc = crcall = crcvrom = 0;
fdsmakerID = lpPRG[0x1F];
fdsgameID = (lpPRG[0x20]<<24)|(lpPRG[0x21]<<16)|(lpPRG[0x22]<<8)|(lpPRG[0x23]<<0);
}
if(bUnif){
mapper = board;
crc = CRC::CrcRev( PRGsize, lpPRG );
if( CHRsize )
crcvrom = CRC::CrcRev( CHRsize, lpCHR );
}
} else {
// NSF
mapper = 0x0100; // Private mapper
crc = crcall = crcvrom = 0;
fdsmakerID = fdsgameID = 0;
}
FREE( temp );
} catch( CHAR* str ) {
// Œ´ˆöªí©ÁÄ¢éƒGƒ‰<C692>[<5B>ˆ<CB86>
FCLOSE( fp );
FREE( temp );
FREE( bios );
FREE( lpPRG );
FREE( lpCHR );
FREE( lpTrainer );
FREE( lpDiskBios );
FREE( lpDisk );
throw str;
#ifndef _DEBUG
} catch(...) {
// ˆê”Ê•ÛŒìƒGƒ‰<C692>[Æ©<E2809A>oµ½­³¢ÌÅ...(^^;
FCLOSE( fp );
FREE( temp );
FREE( bios );
FREE( lpPRG );
FREE( lpCHR );
FREE( lpTrainer );
FREE( lpDiskBios );
FREE( lpDisk );
#ifdef _DATATRACE
// For dis...
FREE( PROM_ACCESS );
#endif
// •s¾ÈƒGƒ‰<C692>[ª”­<E2809D>µÜµ½
throw CApp::GetErrorString( IDS_ERROR_UNKNOWN );
#endif // !_DEBUG
}
}
//
// ƒfƒXƒgƒ‰ƒNƒ^
//
ROM::~ROM()
{
FREE( lpPRG );
FREE( lpCHR );
FREE( lpTrainer );
FREE( lpDiskBios );
FREE( lpDisk );
}
//
// ROMƒtƒ@ƒCƒƒ`ƒFƒbƒN
//
INT ROM::IsRomFile( const char* fname )
{
FILE* fp = NULL;
NESHEADER header;
if( !(fp = fopen( fname, "rb" )) )
return IDS_ERROR_OPEN;
// ƒTƒCƒY•ª“ÇÝ<E2809A>žÝ
if( fread( &header, sizeof(header), 1, fp ) != 1 ) {
FCLOSE( fp );
return IDS_ERROR_READ;
}
FCLOSE( fp );
if( header.ID[0] == 'N' && header.ID[1] == 'E'
&& header.ID[2] == 'S' && header.ID[3] == 0x1A ) {
for( INT i = 0; i < 4; i++ ) {
if( header.reserved[i] )
return IDS_ERROR_ILLEGALHEADER;
}
return 0;
} else if( header.ID[0] == 'F' && header.ID[1] == 'D'
&& header.ID[2] == 'S' && header.ID[3] == 0x1A ) {
return 0;
} else if( header.ID[0] == 'U' && header.ID[1] == 'N'
&& header.ID[2] == 'I' && header.ID[3] == 'F' ) {
return 0;
} else if( header.ID[0] == 'N' && header.ID[1] == 'E'
&& header.ID[2] == 'S' && header.ID[3] == 'M' ) {
return 0;
} else if( header.ID[0] == 0xEB && header.ID[1] == 0x3C //BBK
&& header.ID[2] == 0x90 && header.ID[3] == 0x53 ) {
return 0;
} else {
LPBYTE temp = NULL;
LONG size;
if( !UnCompress( fname, &temp, (LPDWORD)&size ) )
return IDS_ERROR_UNSUPPORTFORMAT;
memcpy( &header, temp, sizeof(NESHEADER) );
header.CHR_PAGE_SIZE = header.CHR_PAGE_SIZE_old;
header.PRG_PAGE_SIZE = header.PRG_PAGE_SIZE_old;
FREE( temp );
if( header.ID[0] == 'N' && header.ID[1] == 'E'
&& header.ID[2] == 'S' && header.ID[3] == 0x1A ) {
for( INT i = 0; i < 4; i++ ) {
if( header.reserved[i] )
return IDS_ERROR_ILLEGALHEADER;
}
return 0;
} else if( header.ID[0] == 'U' && header.ID[1] == 'N'
&& header.ID[2] == 'I' && header.ID[3] == 'F' ) {
return 0;
} else if( header.ID[0] == 'F' && header.ID[1] == 'D'
&& header.ID[2] == 'S' && header.ID[3] == 0x1A ) {
return 0;
} else if( header.ID[0] == 'N' && header.ID[1] == 'E'
&& header.ID[2] == 'S' && header.ID[3] == 'M') {
return 0;
} else if( header.ID[0] == 0xEB && header.ID[1] == 0x3C //BBK
&& header.ID[2] == 0x90 && header.ID[3] == 0x53 ) {
return 0;
}
}
return IDS_ERROR_UNSUPPORTFORMAT;
}
//
// ROMƒtƒ@ƒCƒ¼Ìƒ`ƒFƒbƒN(PALðŽ©“®”»•Ê)
//
void ROM::FilenameCheck( const char* fname )
{
unsigned char* p = (unsigned char*)fname;
while( *p != (unsigned char)'\0' ) {
if( *p == (unsigned char)'(' ) {
if( _mbsnbicmp( p, (unsigned char*)"(E)", 3 ) == 0 ) {
bPAL = TRUE;
return;
}
}
p = _mbsinc(p);
}
}