RetroArch/console/rgl/ps3/cgbio.cpp
2012-05-06 03:47:35 +02:00

369 lines
8.5 KiB
C++

#include <string>
#include <cstddef>
#include <Cg/cgc.h>
#include <Cg/cgGL.h>
#include <Cg/cgBinary.h>
#include "cgbio.hpp"
using std::fill_n;
namespace cgc {
namespace bio {
bin_io* bin_io::instance_ = 0;
bin_io::bin_io()
{
}
bin_io::bin_io( const bin_io& )
{
}
const bin_io* bin_io::instance()
{
if ( 0 == instance_ )
{
instance_ = new bin_io;
}
return instance_;
}
void bin_io::delete_instance()
{
if ( 0 != instance_ )
{
delete instance_;
instance_ = 0;
}
}
CGBIO_ERROR bin_io::new_elf_reader( elf_reader** obj ) const
{
CGBIO_ERROR ret = CGBIO_ERROR_NO_ERROR;
*obj = new elf_reader_impl;
if ( 0 == *obj )
ret = CGBIO_ERROR_MEMORY;
return ret;
}
const char*
bin_io::error_string( CGBIO_ERROR error ) const
{
switch ( error )
{
case CGBIO_ERROR_NO_ERROR:
return "No error";
case CGBIO_ERROR_LOADED:
return "Binary file has been loaded earlier";
case CGBIO_ERROR_FILEIO:
return "File input output error";
case CGBIO_ERROR_FORMAT:
return "File format error";
case CGBIO_ERROR_INDEX:
return "Index is out of range";
case CGBIO_ERROR_MEMORY:
return "Can't allocate memory";
case CGBIO_ERROR_RELOC:
return "Relocation error";
case CGBIO_ERROR_SYMBOL:
return "Symbol error";
case CGBIO_ERROR_UNKNOWN_TYPE:
return "Uknown type";
default:
return "Unknown error";
}
return "Unknown error";
}
CGBIO_ERROR
bin_io::new_nvb_reader( nvb_reader** obj ) const
{
CGBIO_ERROR ret = CGBIO_ERROR_NO_ERROR;
*obj = new nvb_reader_impl;
if ( *obj == 0 )
ret = CGBIO_ERROR_MEMORY;
return ret;
}
nvb_reader_impl::nvb_reader_impl()
{
ref_count_ = 1;
offset_ = 0;
image_ = 0;
owner_ = false;
loaded_ = false;
endianness_ = host_endianness();
std::fill_n( reinterpret_cast<char*>( &header_ ), sizeof( header_ ), '\0' );
}
nvb_reader_impl::~nvb_reader_impl()
{
if ( image_ != 0 )
delete [] image_;
}
ptrdiff_t
nvb_reader_impl::reference() const
{
return ++ref_count_;
}
ptrdiff_t
nvb_reader_impl::release() const
{
ptrdiff_t ret = --ref_count_;
if ( ref_count_ == 0 )
delete this;
return ret;
}
CGBIO_ERROR
nvb_reader_impl::loadFromString( const char* source, size_t length)
{
if ( loaded_ )
{
return CGBIO_ERROR_LOADED;
}
CGBIO_ERROR ret = CGBIO_ERROR_NO_ERROR;
while (1)
{
if (length < sizeof( header_ ))
{
ret = CGBIO_ERROR_FORMAT;
break;
}
memcpy(&header_ ,source,sizeof( header_ ));
if ( CG_BINARY_FORMAT_REVISION != header_.binaryFormatRevision )
{
endianness_ = ( CGBIODATALSB == endianness_ ) ? CGBIODATAMSB : CGBIODATALSB;
int binaryRevision = convert_endianness( header_.binaryFormatRevision, endianness_ );
if ( CG_BINARY_FORMAT_REVISION != binaryRevision )
{
ret = CGBIO_ERROR_FORMAT;
break;
}
}
size_t sz = length;
image_ = new char[sz];
memcpy(image_,source,sz);
loaded_ = true;
ret = CGBIO_ERROR_NO_ERROR;
break;
}
return ret;
}
bool
nvb_reader_impl::is_loaded() const
{
return loaded_;
}
unsigned char
nvb_reader_impl::endianness() const
{
return endianness_;
}
CGprofile
nvb_reader_impl::profile() const
{
return (CGprofile) convert_endianness( (unsigned int) header_.profile, endianness() );
}
unsigned int
nvb_reader_impl::revision() const
{
return convert_endianness( header_.binaryFormatRevision, endianness() );
}
unsigned int nvb_reader_impl::size() const
{
return convert_endianness( header_.totalSize, endianness() );
}
unsigned int nvb_reader_impl::number_of_params() const
{
return convert_endianness( header_.parameterCount, endianness() );
}
unsigned int nvb_reader_impl::ucode_size() const
{
return convert_endianness( header_.ucodeSize, endianness() );
}
const char* nvb_reader_impl::ucode() const
{
if ( 0 == image_ || 0 == ucode_size() )
return 0;
return ( image_ + convert_endianness( header_.ucode, endianness() ) );
}
const CgBinaryFragmentProgram*
nvb_reader_impl::fragment_program() const
{
if ( 0 == image_ )
return 0;
return reinterpret_cast<CgBinaryFragmentProgram*>( &image_[convert_endianness( header_.program, endianness_ )] );
}
const CgBinaryVertexProgram* nvb_reader_impl::vertex_program() const
{
if ( 0 == image_ )
return 0;
return reinterpret_cast<CgBinaryVertexProgram*>( &image_[convert_endianness( header_.program, endianness_ )] );
}
CGBIO_ERROR nvb_reader_impl::get_param_name( unsigned int index, const char **name, bool& is_referenced ) const
{
if ( index >= number_of_params() )
return CGBIO_ERROR_INDEX;
if ( 0 == image_ )
return CGBIO_ERROR_NO_ERROR;
const CgBinaryParameter* params = reinterpret_cast<CgBinaryParameter*>( &image_[convert_endianness( header_.parameterArray, endianness_ )] );
const CgBinaryParameter& pp = params[index];
is_referenced = convert_endianness( pp.isReferenced, endianness() ) != 0;
CgBinaryStringOffset nm_offset = convert_endianness( pp.name,endianness() );
if ( nm_offset != 0 )
*name = &image_[nm_offset];
else
*name = "";
return CGBIO_ERROR_NO_ERROR;
}
CGBIO_ERROR
nvb_reader_impl::get_param( unsigned int index,
CGtype& type,
CGresource& resource,
CGenum& variability,
int& resource_index,
const char ** name,
STL_NAMESPACE vector<float>& default_value,
STL_NAMESPACE vector<unsigned int>& embedded_constants,
const char ** semantic,
int& paramno,
bool& is_referenced,
bool& is_shared ) const
{
if ( index >= number_of_params() )
return CGBIO_ERROR_INDEX;
if ( 0 == image_ )
return CGBIO_ERROR_NO_ERROR;
const CgBinaryParameter* params = reinterpret_cast<CgBinaryParameter*>( &image_[convert_endianness( header_.parameterArray, endianness_ )] );
const CgBinaryParameter& pp = params[index];
type = static_cast<CGtype>(convert_endianness( static_cast<unsigned int>( pp.type ), endianness() ) );
resource = static_cast<CGresource>(convert_endianness( static_cast<unsigned int>( pp.res ), endianness() ) );
variability = static_cast<CGenum>(convert_endianness( static_cast<unsigned int>( pp.var ),endianness() ) );
resource_index = convert_endianness( pp.resIndex,endianness() );
paramno = convert_endianness( pp.paramno, endianness() );
is_referenced = convert_endianness( pp.isReferenced,endianness() ) != 0;
is_shared = convert_endianness( pp.isShared,endianness() ) != 0;
CgBinaryStringOffset nm_offset = convert_endianness( pp.name,endianness() );
CgBinaryFloatOffset dv_offset = convert_endianness( pp.defaultValue,endianness() );
CgBinaryEmbeddedConstantOffset ec_offset = convert_endianness( pp.embeddedConst,endianness() );
CgBinaryStringOffset sm_offset = convert_endianness( pp.semantic,endianness() );
if ( 0 != nm_offset )
{
*name = &image_[nm_offset];
}
else
*name = "";
if ( 0 != sm_offset )
{
*semantic = &image_[sm_offset];
}
else
*semantic = "";
if ( 0 != dv_offset )
{
char *vp = &image_[dv_offset];
for (int ii = 0; ii < 4; ++ii)
{
int tmp;
memcpy(&tmp,vp+4*ii,4);
tmp = convert_endianness(tmp,endianness());
float tmp2;
memcpy(&tmp2,&tmp,4);
default_value.push_back( tmp2 );
}
}
if ( 0 != ec_offset )
{
void *vp = &image_[ec_offset];
CgBinaryEmbeddedConstant& ec = *(static_cast<CgBinaryEmbeddedConstant*>( vp ));
for (unsigned int ii = 0; ii < convert_endianness( ec.ucodeCount, endianness() ); ++ii)
{
unsigned int offset = convert_endianness( ec.ucodeOffset[ii], endianness() );
embedded_constants.push_back( offset );
}
}
return CGBIO_ERROR_NO_ERROR;
}
elf_reader_impl::elf_reader_impl()
{
ref_count_ = 1;
initialized_ = false;
fill_n( reinterpret_cast<char*>( &header_ ), sizeof( header_ ), '\0' );
}
elf_reader_impl::~elf_reader_impl()
{
}
CGBIO_ERROR
elf_reader_impl::load( const char* filename )
{
return CGBIO_ERROR_NO_ERROR;
}
CGBIO_ERROR
elf_reader_impl::load( std::istream* stream, int start )
{
return CGBIO_ERROR_NO_ERROR;
}
bool
elf_reader_impl::is_initialized() const
{
return initialized_;
}
ptrdiff_t
elf_reader_impl::reference() const
{
return ++ref_count_;
}
ptrdiff_t
elf_reader_impl::release() const
{
ptrdiff_t ret = --ref_count_;
if ( 0 == ref_count_ )
{
delete this;
}
return ret;
}
}
}