/****************************************************************************** libx42 - skinned vertex animation library Copyright (C) 2007 HermitWorks Entertainment Corporation 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. 51 Franklin Street, Fifth Floor Boston, MA 02110-1301, USA. ******************************************************************************/ #include "local.h" NOGLOBALALIAS bool x42name_eq( const x42data_t *x42, x42NameIndex_t a, x42NameIndex_t b ) { const char *sa; const char *sb; if( a == b ) return true; sa = x42->strings + a; sb = x42->strings + b; while( *sa && *sb ) { if( *sa++ != *sb++ ) return false; } return !*sa && !*sb; } NOGLOBALALIAS bool x42name_eq2( const x42data_t *x42, x42NameIndex_t a, const char *b ) { const char *sa; sa = x42->strings + a; if( sa == b ) return true; while( *sa && *b ) { if( *sa++ != *b++ ) return false; } return !*sa && !*b; } X42_EXPORT uint X42_CALL x42_ConvertPrimsToElems( uint primType, uint numPrims ) { switch( primType ) { case X42_PT_POINT_LIST: return numPrims; case X42_PT_LINE_LIST: return numPrims * 2; case X42_PT_LINE_STRIP: return numPrims ? numPrims + 1 : 0; case X42_PT_TRIANGLE_LIST: return numPrims * 3; case X42_PT_TRIANGLE_STRIP: case X42_PT_TRIANGLE_FAN: return numPrims ? numPrims + 2 : 0; default: fail_rz( X42_ERR_BADPARAMS, "invalid primType" ); } } X42_EXPORT uint X42_CALL x42_ConvertElemsToPrims( uint primType, uint numElems ) { switch( primType ) { case X42_PT_POINT_LIST: return numElems; case X42_PT_LINE_LIST: return numElems / 2; case X42_PT_LINE_STRIP: return numElems >= 2 ? numElems - 1 : 0; case X42_PT_TRIANGLE_LIST: return numElems / 3; case X42_PT_TRIANGLE_STRIP: case X42_PT_TRIANGLE_FAN: return numElems >= 3 ? numElems - 2 : 0; default: fail_rz( X42_ERR_BADPARAMS, "invalid primType" ); } } X42_EXPORT bool X42_CALL x42_CopyStreamToStream( x42memStream_t *dest, x42memStream_t *src, size_t elemSize, uint numElems, x42opts_t *opts ) { #ifndef LIBX42_NO_PARAM_VALIDATION demand_rf( dest != NULL && dest->pStreamZero != NULL, X42_ERR_BADPTR, "dest is null" ); demand_rf( src != NULL && src->pStreamZero != NULL, X42_ERR_BADPTR, "src is null" ); demand_rf( elemSize > 0 && elemSize % sizeof( int ) == 0, X42_ERR_BADPARAMS, "elemSize is not a multiple of sizeof( int )" ); #endif //see if we can just memcpy if( src->stride - src->scratchBytes == elemSize && dest->stride - dest->scratchBytes == elemSize ) { memcpy( dest->pStreamZero, src->pStreamZero, elemSize * numElems ); return true; } if( opts ) { bool applied_opts = x42_ApplyOpts( opts ); bool did_copy = opt_CopyStreamToStream( dest, src, elemSize, numElems, opts ); if( applied_opts ) x42_RemoveOpts( opts ); if( did_copy ) return true; } if( elemSize % sizeof( intptr_t ) <= src->scratchBytes && elemSize % sizeof( intptr_t ) <= dest->scratchBytes ) { //copy in system-native chunks size_t i, j; size_t is = src->stride; size_t os = dest->stride; const intptr_t * RESTRICT pi = (intptr_t*)src->pStreamZero; intptr_t * RESTRICT po = (intptr_t*)dest->pStreamZero; size_t nWordsPerElem = elemSize / sizeof( intptr_t ); if( nWordsPerElem * sizeof( intptr_t ) < elemSize ) nWordsPerElem += 1; for( i = 0; i < numElems; i++ ) { const intptr_t * RESTRICT cpi = pi; intptr_t * RESTRICT cpo = po; for( j = 0; j < nWordsPerElem; j++ ) *(cpo++) = *(cpi++); pi = (intptr_t*)((byte*)pi + is); po = (intptr_t*)((byte*)po + os); } } else { //copy in integer chunks size_t i, j; size_t is = src->stride; size_t os = dest->stride; const int *pi = (int*)src->pStreamZero; int *po = (int*)dest->pStreamZero; size_t nWordsPerElem = elemSize / sizeof( int ); if( nWordsPerElem * sizeof( int ) < elemSize ) nWordsPerElem += 1; for( i = 0; i < numElems; i++ ) { const int * RESTRICT cpi = pi; int * RESTRICT cpo = po; for( j = 0; j < nWordsPerElem; j++ ) *(cpo++) = *(cpi++); pi = (int*)((byte*)pi + is); po = (int*)((byte*)po + os); } } return true; }