daedalus/Source/Utility/ROMFile.cpp
2019-02-27 17:04:51 +11:00

159 lines
3.6 KiB
C++

/*
Copyright (C) 2006 StrmnNrmn
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "stdafx.h"
#include "ROMFile.h"
#include "ROMFileCompressed.h"
#include "ROMFileUncompressed.h"
#include "Debug/DBGConsole.h"
#include "Utility/Stream.h"
#include "Utility/IO.h"
#include <algorithm>
#include <string.h>
bool IsRomfilename( const char * rom_filename )
{
const char * last_period( strrchr( rom_filename, '.' ) );
if(last_period == NULL)
return false;
return (_strcmpi(last_period, ".v64") == 0 ||
_strcmpi(last_period, ".z64") == 0 ||
_strcmpi(last_period, ".n64") == 0 ||
_strcmpi(last_period, ".rom") == 0 ||
_strcmpi(last_period, ".bin") == 0 ||
_strcmpi(last_period, ".jap") == 0 ||
_strcmpi(last_period, ".pal") == 0 ||
_strcmpi(last_period, ".usa") == 0 ||
_strcmpi(last_period, ".zip") == 0);
}
ROMFile * ROMFile::Create( const char * filename )
{
const char * ext = IO::Path::FindExtension( filename );
if (ext && _strcmpi(ext, ".zip") == 0)
{
#ifdef DAEDALUS_COMPRESSED_ROM_SUPPORT
return new ROMFileCompressed( filename );
#else
return NULL;
#endif
}
else
{
return new ROMFileUncompressed( filename );
}
}
ROMFile::ROMFile( const char * filename )
: mHeaderMagic( 0 )
{
IO::Path::Assign( mFilename, filename );
}
ROMFile::~ROMFile()
{
}
bool ROMFile::LoadData( u32 bytes_to_read, u8 *p_bytes, COutputStream & messages )
{
if( !LoadRawData( bytes_to_read, p_bytes, messages ) )
{
messages << "Unable to get rom info from '" << mFilename << "'";
return false;
}
return true;
}
bool ROMFile::RequiresSwapping() const
{
DAEDALUS_ASSERT( mHeaderMagic != 0, "The header magic hasn't been set" );
return mHeaderMagic != 0x80371240;
}
bool ROMFile::SetHeaderMagic( u32 magic )
{
mHeaderMagic = magic;
#ifdef DAEDALUS_DEBUG_CONSOLE
switch (mHeaderMagic)
{
case 0x80371240:
case 0x40123780:
case 0x12408037:
break;
default:
DAEDALUS_ERROR( "Unhandled swapping mode %08x for %s", magic, mFilename );
DBGConsole_Msg(0, "[CUnknown ROM format for %s: 0x%08x", mFilename, magic);
return false;
}
#endif
return true;
}
void ROMFile::CorrectSwap( u8 * p_bytes, u32 length )
{
switch (mHeaderMagic)
{
case 0x80371240:
// Pre byteswapped - no need to do anything
break;
case 0x40123780:
ByteSwap_3210( p_bytes, length );
break;
case 0x12408037:
ByteSwap_2301( p_bytes, length );
break;
default:
DAEDALUS_ERROR( "Unhandled swapping mode: %08x", mHeaderMagic );
break;
}
}
// Swap bytes from 37 80 40 12
// to 40 12 37 80
void ROMFile::ByteSwap_2301( void * p_bytes, u32 length )
{
u32* p = (u32*)p_bytes;
u32* maxp = (u32*)((u8*)p_bytes + length);
for(; p < maxp; p++)
{
std::swap(((u16*)p)[0], ((u16*)p)[1]);
}
}
// Swap bytes from 80 37 12 40
// to 40 12 37 80
void ROMFile::ByteSwap_3210( void * p_bytes, u32 length )
{
u8* p = (u8*)p_bytes;
u8* maxp = (u8*)(p + length);
for(; p < maxp; p+=4)
{
std::swap(p[0], p[3]);
std::swap(p[1], p[2]);
}
}