Subversion Repositories ps3ware

Compare Revisions

Ignore whitespace Rev 202 → Rev 203

/trunk/libps3rsx/tools/common/XMLUtils.h
New file
0,0 → 1,273
#pragma once
 
struct SStrng
{
const xmlChar *ptr;
SStrng( xmlChar const *_ptr = 0 ) : ptr( _ptr )
{
if( ptr && *ptr == '#' )++ptr;
};
bool operator < (const SStrng & str ) const
{
return xmlStrcmp ( ptr, str.ptr ) < 0;
};
};
 
 
template<typename T> class CAutoContainer
{
static std::map< SStrng, T*> container;
static std::map< SStrng, T*> containersid;
static std::vector<T*> arrayContainer;
 
 
const xmlChar *myId;
public:
void SetId( const xmlChar *id )
{
myId = id;
}
 
static void Addsid( const xmlChar * id, T *obj )
{
if( obj == 0 || id == 0 )
{
return;
}
containersid[SStrng(id)] = obj;
};
static void Add( const xmlChar * id, T *obj )
{
if( obj == 0 )
{
return;
};
arrayContainer.push_back( obj );
if( id == 0 )
{
return;
}
container[SStrng(id)] = obj;
};
 
static const std::vector<T*> &GetArrayContainer()
{
return arrayContainer;
}
 
static T *Get( const xmlChar * id )
{
class std::map<SStrng, T*>::iterator it = container.find( id );
if( it != container.end() )
return it->second;
return 0;
 
};
 
static T *Getsid( const xmlChar * id )
{
class std::map<SStrng, T*>::iterator it = containersid.find( id );
if( it != containersid.end() )
return it->second;
return 0;
 
};
 
static void Clear()
{
for( class std::map< SStrng, T*>::iterator it = container.begin();
it != container.end();
++it)
{
delete it->second;
}
 
container.clear();
arrayContainer.clear();
}
};
 
#define _X (const xmlChar *)
 
inline const xmlAttr *Find( const xmlAttr *root, const xmlChar *name )
{
for( const xmlAttr *node = root; node; node = node->next )
{
if( !xmlStrcmp( name, node->name ) )
{
return node;
}
}
return 0;
};
 
inline const xmlNode *Find( const xmlNode * root, const xmlChar *name )
{
for ( ;root ;root = root->next )
{
if( !xmlStrcmp( name, root->name ) )
{
return root;
}
}
return 0;
};
 
inline const xmlChar *LoadStrAttr( const xmlNode * root, const xmlChar *name )
{
const xmlAttr *node = Find( root->properties, name );
if( !node )
{
return 0;
}
return node->children->content;
};
 
 
bool inline IsSpace( xmlChar v )
{
return ( v == ' ' ) || ( v == '\n' );
}
 
template<typename T> class CXMLLoader
{
public:
~CXMLLoader()
{
T::Clear();
}
 
void Load( xmlNode *root, bool recursive, bool silent = true )
{
xmlNode *node = root;
for( ;node ;node = node->next )
{
if( xmlStrcmp( T::GetName(), node->name ) )
{
Load( node->children, recursive, silent );
}
else
{
T *result = T::CreateInstance( node );
if( result )
{
const xmlChar *id = LoadStrAttr( node, _X"id" );
const xmlChar *sid = LoadStrAttr( node, _X"sid" );
result->SetId( id );
 
 
if( !silent )
{
printf( "%s %s\n", id, typeid( T ).name() );
}
T::Add( id, result );
T::Addsid( sid, result );
 
}
 
if( recursive )
{
Load( node->children, recursive, silent );
}
}
}
}
};
 
struct itbl
{
int table[256];
itbl()
{
for( int i = 0; i < 256; ++i )
{
char c = i;
int res = -1;
switch( c )
{
case('0'):res = 0;break;
case('1'):res = 1;break;
case('2'):res = 2;break;
case('3'):res = 3;break;
case('4'):res = 4;break;
case('5'):res = 5;break;
case('6'):res = 6;break;
case('7'):res = 7;break;
case('8'):res = 8;break;
case('9'):res = 9;break;
};
table[i] = res;
};
};
};
 
inline int parse_fake_int( const xmlChar *&ptr )
{
static itbl trans;
char last = 0;
while( trans.table[*ptr] ==-1 )
{
last = *ptr;
++ptr;
}
int res = 0, curr;
while(1)
{
curr = trans.table[*ptr];
if( curr == -1 )return last == '-' ? -res - 1 : res;
++ptr;
res = res * 10 + curr;
}
};
 
inline int parse_int( const xmlChar *&ptr )
{
int res = parse_fake_int( ptr );
return res < 0 ? res + 1 : res;
};
 
inline float parse_flt( const xmlChar *&ptr )
{
static itbl trans;
int res = 0, curr;
float f = 1.0f;
while(1)
{
curr = trans.table[*ptr];
if( curr == -1 )return res * f;
++ptr;
res = res * 10 + curr;
f *= 0.1f;
}
};
 
inline float parse_float( const xmlChar *&ptr )
{
float end = 0.0f;
int beg = parse_fake_int( ptr );
if( *ptr == '.' )end = parse_flt( ++ptr );
float f = beg < 0 ? beg - end + 1.0f: beg + end;
return f;
};
 
inline void flush_str( const xmlChar *&ptr )
{
while( ( *ptr == '\n' ) || ( *ptr == ' ' ) )
{
xmlChar *fuck = const_cast<xmlChar *>( ptr );
*fuck = 0;
ptr++;
}
}
 
inline void parse_str( const xmlChar *&ptr )
{
while( *(++ptr) != '\n' );
//return res < 0 ? res + 1 : res;
};
 
template< class T > std::map<SStrng, T*> CAutoContainer<T>::container;
template< class T > std::map<SStrng, T*> CAutoContainer<T>::containersid;
template< class T > std::vector<T*> CAutoContainer<T>::arrayContainer;
 
 
Property changes:
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: trunk/libps3rsx/tools/common/conv.h
===================================================================
--- trunk/libps3rsx/tools/common/conv.h (revision 0)
+++ trunk/libps3rsx/tools/common/conv.h (revision 203)
@@ -0,0 +1,49 @@
+#pragma once
+/** Converts float in uint32 format to a a half in uint16 format*/
+static inline uint16 floatToHalfI(uint32 i)
+{
+ register int s = (i >> 16) & 0x00008000;
+ register int e = ((i >> 23) & 0x000000ff) - (127 - 15);
+ register int m = i & 0x007fffff;
+
+ if (e <= 0)
+ {
+ if (e < -10)
+ {
+ return 0;
+ }
+ m = (m | 0x00800000) >> (1 - e);
+
+ return s | (m >> 13);
+ }
+ else if (e == 0xff - (127 - 15))
+ {
+ if (m == 0) // Inf
+ {
+ return s | 0x7c00;
+ }
+ else // NAN
+ {
+ m >>= 13;
+ return s | 0x7c00 | m | (m == 0);
+ }
+ }
+ else
+ {
+ if (e > 30) // Overflow
+ {
+ return s | 0x7c00;
+ }
+
+ return s | (e << 10) | (m >> 13);
+ }
+}
+
+
+static inline uint16 floatToHalf(float i)
+{
+ union { float f; uint32 i; } v;
+ v.f = i;
+ return floatToHalfI(v.i);
+}
+
Index: trunk/libps3rsx/tools/toolgeometry/collada/ColladaEffect.h
===================================================================
--- trunk/libps3rsx/tools/toolgeometry/collada/ColladaEffect.h (revision 202)
+++ trunk/libps3rsx/tools/toolgeometry/collada/ColladaEffect.h (revision 203)
@@ -1,5 +1,5 @@
#pragma once
-#include "XMLUtils.h"
+#include "../../common/XMLUtils.h"
class CColladaEffect : public CAutoContainer<CColladaEffect>
{
/trunk/libps3rsx/tools/toolgeometry/collada/ColladaSource.h
1,6 → 1,6
#pragma once
 
#include "XMLUtils.h"
#include "../../common/XMLUtils.h"
class CColladaFloatArray;
class CColladaIDREFArray;
 
/trunk/libps3rsx/tools/toolgeometry/collada/Makefile
1,4 → 1,4
CPPFLAGS=-Wall -g -I/usr/include/libxml2
CPPFLAGS=-Wall -O3 -g -I/usr/include/libxml2
 
SOURCE= colladatool.cpp ColladaNode.cpp ColladaSource.cpp ColladaTriangles.cpp ColladaVertices.cpp ColladaAnimation.cpp ColladaMaterial.cpp ColladaBindMaterial.cpp ColladaController.cpp ColladaEffect.cpp ColladaFloatArray.cpp ColladaGeometry.cpp ColladaImage.cpp ColladaIDREFArray.cpp
 
/trunk/libps3rsx/tools/toolgeometry/collada/colladatool.cpp
1,6 → 1,9
#include "StdAfx.h"
 
#include "XMLUtils.h"
#include "../../common/XMLUtils.h"
#include "../../common/conv.h"
 
 
#include "ColladaTriangles.h"
#include "ColladaImage.h"
#include "ColladaEffect.h"
17,12 → 20,12
 
#include "../../../src/geometry/geometry.h"
#include "../../../src/geometry/model.h"
 
 
struct cache_opt_t
{
uint16 entries[4 + 3];
 
cache_opt_t( )
 
cache_opt_t( )
{
entries[0] = 0xffff;
entries[1] = 0xffff;
49,7 → 52,7
 
entries[ptr++] = trn[j];
 
skip:;
skip:;
}
 
ptr -= 4;
86,8 → 89,11
}
 
};
 
 
 
 
 
 
 
void re_arrange( const std::vector<uint16> &_indices, std::vector<uint16> &dst )
{
if( _indices.empty() )
131,205 → 137,202
}
}
 
 
misses = 3.0f * misses / (float)indices.size();
printf( "cache misses per tri %f \n", misses );
 
}
 
 
#define CHUNK 64
 
 
struct MeshHeader
{
}
 
struct MatrixAffector
{
uint8 bone;
uint8 geomChunks[3];
uint8 weights[3][4];
MatrixAffector();
MatrixAffector( uint8 _bone, uint8 chunk, uint8 *_weights ) : bone( _bone )
{
 
geomChunks[0] = 0xff;
geomChunks[1] = 0xff;
geomChunks[2] = 0xff;
SetChunk( bone, chunk, _weights );
}
bool SetChunk( uint8 _bone, uint8 chunk, uint8 *_weights )
{
 
if( bone != _bone )
{
return false;
}
for( size_t i = 0; i < 3; ++i )
{
if( geomChunks[i] == 0xff )
{
geomChunks[i] = chunk;
memcpy( weights[i], weights, 4 );
return true;
}
}
return false;
}
};
 
 
void AddMatrix( size_t lastMark, std::vector<MatrixAffector> &chunks, uint8 bone, uint8 chunk, uint8 *weights )
{
for( size_t i = lastMark; i < chunks.size(); ++i )
{
if( chunks[i].SetChunk( bone, chunk, weights ) )
{
return;
}
}
chunks.push_back( MatrixAffector( bone, chunk, weights ) );
}
 
void remap_vertices( std::vector<SFatVertex> &vertices, std::vector<uint16> &indices )
{
uint16 beg = 0;
std::vector<uint16> remap;
remap.resize( vertices.size(), 0xffff );
std::vector<SFatVertex> tempVertices( vertices.size() );
std::vector<uint16> tempIndices( indices.size() );
for( size_t i = 0; i < indices.size(); ++i )
{
uint16 ind = indices[i];
if( remap[ind] == 0xffff )
{
remap[ind] = beg++;
}
tempIndices[i] = remap[ind];
tempVertices[remap[ind]] = vertices[ind];
}
vertices = tempVertices;
indices = tempIndices;
uint8 table[256];
uint8 value[256][4];
memset( table, 0, sizeof( table ) );
memset( value, 0, sizeof( value ) );
float matrices = 0.0f;
float clusters = 0.0001f + vertices.size();
std::vector<MatrixAffector> chunks;
std::vector<size_t> marks;
size_t lastChunk = 0;
size_t lastMark = 0;
for( size_t i = 0; i < vertices.size(); i += 4 )
{
uint8 ptr = 0;
uint8 weights[16][4];
uint8 indices[16];
for( size_t j = 0; j < 4 && ( i + j < vertices.size() ); ++j )
{
for( size_t k = 0; k < 4; ++k )
{
uint8 ind = vertices[i + j].indices[k];
value[ind][0] = 0;
value[ind][1] = 0;
value[ind][2] = 0;
value[ind][3] = 0;
table[ind] = 0;
}
}
for( size_t j = 0; j < 4 && ( i + j < vertices.size() ); ++j )
{
for( size_t k = 0; k < 4; ++k )
{
uint8 ind = vertices[i + j].indices[k];
uint8 w = vertices[i + j].weights[k];
table[ind] += w > 0 ? 1 : 0;
value[ind][j] += w;
}
}
for( size_t j = 0; j < 4 && ( i + j < vertices.size() ); ++j )
{
for( size_t k = 0; k < 4; ++k )
{
uint8 ind = vertices[i + j].indices[k];
if( table[ind] > 0 )
{
//printf( "%3d ", ind );
for( size_t l = 0; l < 4; ++l )
{
//printf( "%3d ", value[ind][l] );
weights[ptr][l] = value[ind][l];
}
indices[ptr] = ind;
table[ind] = 0;
++ptr;
//printf( "\n" );
}
}
//printf( "%d matrices \n", ptr );
}
for( size_t j = 0; j < 4 && ( i + j < vertices.size() ); ++j )
{
uint8 w = 0;
for( size_t l = 0; l < ptr; ++l )
{
w += weights[l][j];
}
}
for( size_t l = 0; l < ptr; ++l )
{
AddMatrix( lastMark, chunks, table[l], i, &weights[l][0] );
}
//matrices += ptr;
if( ( i - lastChunk >= CHUNK - 4 ) || ( i + 4 >= vertices.size() ) )
{
marks.push_back( lastMark );
size_t s = chunks.size() - lastMark;
//lastChunk = i;
matrices += 3.0f * 4.0f * s;
//printf( "chunk with %2d vertices and 3x %2d matrices \n", i - lastChunk + 4, s );
lastMark = chunks.size();
lastChunk = i;
}
}
printf( "%d matrix groups in %d chunks \n", chunks.size(), marks.size() );
printf( "%f matrices per vertex \n", matrices / clusters );
}
 
 
 
#define CHUNK 64
 
 
 
struct MatrixAffector
{
uint8 bone;
uint8 geomChunks[3];
uint8 weights[3][4];
MatrixAffector();
MatrixAffector( uint8 _bone, uint8 chunk, uint8 *_weights ) : bone( _bone )
{
 
geomChunks[0] = 0xff;
geomChunks[1] = 0xff;
geomChunks[2] = 0xff;
SetChunk( bone, chunk, _weights );
}
bool SetChunk( uint8 _bone, uint8 chunk, uint8 *_weights )
{
 
if( bone != _bone )
{
return false;
}
for( size_t i = 0; i < 3; ++i )
{
if( geomChunks[i] == 0xff )
{
geomChunks[i] = chunk;
memcpy( weights[i], weights, 4 );
return true;
}
}
return false;
}
};
 
 
void AddMatrix( size_t lastMark, std::vector<MatrixAffector> &chunks, uint8 bone, uint8 chunk, uint8 *weights )
{
for( size_t i = lastMark; i < chunks.size(); ++i )
{
if( chunks[i].SetChunk( bone, chunk, weights ) )
{
return;
}
}
chunks.push_back( MatrixAffector( bone, chunk, weights ) );
}
 
void remap_vertices( std::vector<SFatVertex> &vertices, std::vector<uint16> &indices )
{
uint16 beg = 0;
std::vector<uint16> remap;
remap.resize( vertices.size(), 0xffff );
std::vector<SFatVertex> tempVertices( vertices.size() );
std::vector<uint16> tempIndices( indices.size() );
for( size_t i = 0; i < indices.size(); ++i )
{
uint16 ind = indices[i];
if( remap[ind] == 0xffff )
{
remap[ind] = beg++;
}
tempIndices[i] = remap[ind];
tempVertices[remap[ind]] = vertices[ind];
}
vertices = tempVertices;
indices = tempIndices;
uint8 table[256];
uint8 value[256][4];
memset( table, 0, sizeof( table ) );
memset( value, 0, sizeof( value ) );
float matrices = 0.0f;
float clusters = 0.0001f + vertices.size();
std::vector<MatrixAffector> chunks;
std::vector<size_t> marks;
size_t lastChunk = 0;
size_t lastMark = 0;
for( size_t i = 0; i < vertices.size(); i += 4 )
{
uint8 ptr = 0;
uint8 weights[16][4];
uint8 indices[16];
for( size_t j = 0; j < 4 && ( i + j < vertices.size() ); ++j )
{
for( size_t k = 0; k < 4; ++k )
{
uint8 ind = vertices[i + j].indices[k];
value[ind][0] = 0;
value[ind][1] = 0;
value[ind][2] = 0;
value[ind][3] = 0;
table[ind] = 0;
}
}
for( size_t j = 0; j < 4 && ( i + j < vertices.size() ); ++j )
{
for( size_t k = 0; k < 4; ++k )
{
uint8 ind = vertices[i + j].indices[k];
uint8 w = vertices[i + j].weights[k];
table[ind] += w > 0 ? 1 : 0;
value[ind][j] += w;
}
}
for( size_t j = 0; j < 4 && ( i + j < vertices.size() ); ++j )
{
for( size_t k = 0; k < 4; ++k )
{
uint8 ind = vertices[i + j].indices[k];
if( table[ind] > 0 )
{
//printf( "%3d ", ind );
for( size_t l = 0; l < 4; ++l )
{
//printf( "%3d ", value[ind][l] );
weights[ptr][l] = value[ind][l];
}
indices[ptr] = ind;
table[ind] = 0;
++ptr;
//printf( "\n" );
}
}
//printf( "%d matrices \n", ptr );
}
for( size_t j = 0; j < 4 && ( i + j < vertices.size() ); ++j )
{
uint8 w = 0;
for( size_t l = 0; l < ptr; ++l )
{
w += weights[l][j];
}
}
for( size_t l = 0; l < ptr; ++l )
{
AddMatrix( lastMark, chunks, table[l], i, &weights[l][0] );
}
//matrices += ptr;
if( ( i - lastChunk >= CHUNK - 4 ) || ( i + 4 >= vertices.size() ) )
{
marks.push_back( lastMark );
size_t s = chunks.size() - lastMark;
//lastChunk = i;
matrices += 3.0f * 4.0f * s;
//printf( "chunk with %2d vertices and 3x %2d matrices \n", i - lastChunk + 4, s );
lastMark = chunks.size();
lastChunk = i;
}
}
printf( "%d matrix groups in %d chunks \n", chunks.size(), marks.size() );
printf( "%f matrices per vertex \n", matrices / clusters );
}
 
struct FOpen
{
FILE *fp;
346,12 → 349,27
 
struct local_vertex_t
{
float coo[3];
float tex[2];
uint16 coo[3];
uint16 tex[2];
};
 
uint16 f2us( float f )
{
int v = (int) ( f * 4096.0f + ( 1 << 15 ) );
if( v < 0 )
{
v = 0;
}
if( v > 65535 )
{
v = 65535;
}
return (uint16)v;
}
;
 
 
void convert_model( const char *fileNameOut, const char *fileNameIn )
{
xmlDoc *doc = NULL;
403,9 → 421,9
std::vector<uint16> indices;
 
triangles[i]->GetFatVertices( &vertices, &indices );
re_arrange( indices, indices );
remap_vertices( vertices, indices );
re_arrange( indices, indices );
remap_vertices( vertices, indices );
printf( "%s %i %i\n", triangles[i]->GetEffect()->GetDiffuse()->GetFileName().ptr, vertices.size(), indices.size() );
 
 
420,16 → 438,16
FOpen fp( buff, false );
if( fp.fp )
{
model.position.format = FLOAT;
model.position.format = HALF;
model.position.type = POS0;
model.position.components = 3;
model.position.offset = 0;
model.position.stride = sizeof( local_vertex_t );
 
model.texcoord.format = FLOAT;
model.texcoord.format = HALF;
model.texcoord.type = TEX0;
model.texcoord.components = 2;
model.texcoord.offset = 12;
model.texcoord.offset = 6;
model.texcoord.stride = sizeof( local_vertex_t );
 
model.indices = TRIANGLES;
455,11 → 473,11
lvertices.resize( vertices.size() );
for( size_t j = 0; j < vertices.size(); ++j )
{
lvertices[j].coo[0] = vertices[j].coo[0];
lvertices[j].coo[1] = vertices[j].coo[1];
lvertices[j].coo[2] = vertices[j].coo[2];
lvertices[j].tex[0] = vertices[j].tx0[0];
lvertices[j].tex[1] = 1.0f - vertices[j].tx0[1];
lvertices[j].coo[0] = floatToHalf( vertices[j].coo[0] );
lvertices[j].coo[1] = floatToHalf( vertices[j].coo[1] );
lvertices[j].coo[2] = floatToHalf( vertices[j].coo[2] );
lvertices[j].tex[0] = floatToHalf( vertices[j].tx0[0] );
lvertices[j].tex[1] = floatToHalf( 1.0f - vertices[j].tx0[1] );
 
 
}
/trunk/libps3rsx/tools/toolgeometry/collada/ColladaController.h
1,6 → 1,6
#pragma once
 
#include "XMLUtils.h"
#include "../../common/XMLUtils.h"
#include "vec3.h"
 
class CColladaFloatArray;
/trunk/libps3rsx/tools/toolgeometry/collada/ColladaIDREFArray.h
1,6 → 1,6
#pragma once
 
#include "XMLUtils.h"
#include "../../common/XMLUtils.h"
 
class CColladaIDREFArray : public CAutoContainer<CColladaIDREFArray>
{
/trunk/libps3rsx/tools/toolgeometry/collada/ColladaGeometry.h
1,5 → 1,5
#pragma once
#include "XMLUtils.h"
#include "../../common/XMLUtils.h"
 
 
class CColladaTriangles;
/trunk/libps3rsx/tools/toolgeometry/collada/ColladaBindMaterial.h
1,6 → 1,6
#pragma once
 
#include "XMLUtils.h"
#include "../../common/XMLUtils.h"
 
class CColladaEffect;
 
/trunk/libps3rsx/tools/toolgeometry/collada/ColladaFloatArray.h
1,6 → 1,6
#pragma once
 
#include "XMLUtils.h"
#include "../../common/XMLUtils.h"
 
class CColladaFloatArray : public CAutoContainer<CColladaFloatArray>
{
/trunk/libps3rsx/tools/toolgeometry/collada/ColladaAnimation.h
1,5 → 1,5
#pragma once
#include "XMLUtils.h"
#include "../../common/XMLUtils.h"
 
class CColladaSource;
 
/trunk/libps3rsx/tools/toolgeometry/collada/ColladaImage.h
1,6 → 1,6
#pragma once
 
#include "XMLUtils.h"
#include "../../common/XMLUtils.h"
 
class CColladaImage : public CAutoContainer<CColladaImage>
{
/trunk/libps3rsx/tools/toolgeometry/collada/ColladaTriangles.cpp
1,5 → 1,5
#include "StdAfx.h"
#include "XMLUtils.h"
#include "../../common/XMLUtils.h"
#include "ColladaTriangles.h"
#include "ColladaSource.h"
#include "ColladaVertices.h"
/trunk/libps3rsx/tools/toolgeometry/collada/ColladaVertices.h
1,5 → 1,5
#pragma once
#include "XMLUtils.h"
#include "../../common/XMLUtils.h"
 
class CColladaSource;
 
/trunk/libps3rsx/tools/toolgeometry/collada/ColladaNode.h
1,5 → 1,5
#pragma once
#include "XMLUtils.h"
#include "../../common/XMLUtils.h"
#include "vec3.h"
 
class CColladaSource;
/trunk/libps3rsx/tools/toolgeometry/collada/ColladaMaterial.cpp
1,5 → 1,5
#include "StdAfx.h"
#include "XMLUtils.h"
#include "../../common/XMLUtils.h"
#include "ColladaMaterial.h"
#include "ColladaImage.h"
#include "ColladaEffect.h"
/trunk/libps3rsx/tools/toolshaderf/compile.sh
1,2 → 1,2
make
./a.out ../../data/custom.pixel < shader
./a.out ../../data/particle.pixel < shader
/trunk/libps3rsx/tools/toolshaderf/shader
1,3 → 1,6
!!FP1.0
TEXH H0, f[TEX0], TEX0, 2D;
MULH H0, f[COL0], H0;
MULH H0, H0.wwww, H0;
 
END
/trunk/libps3rsx/tools/toolshaderv/crc.y
221,7 → 221,7
 
void clean()
{
vp_inst[0] = 0x401f9c6c;
vp_inst[0] = 0x00001c6c;
vp_inst[1] = 0x0000000d;
vp_inst[2] = 0x8106c083;
vp_inst[3] = 0x60401f80;
/trunk/libps3rsx/tools/toolshaderv/y.tab.c
236,7 → 236,7
 
void clean()
{
vp_inst[0] = 0x401f9c6c;
vp_inst[0] = 0x00001c6c;
vp_inst[1] = 0x0000000d;
vp_inst[2] = 0x8106c083;
vp_inst[3] = 0x60401f80;
/trunk/libps3rsx/tools/toolshaderv/compile.sh
1,2 → 1,2
make
./a.out ../../data/mvp.vertex < shader
./a.out ../../data/particle.vertex < shader
/trunk/libps3rsx/tools/toolshaderv/shader
4,6 → 4,8
DP4 o[HPOS].y, c[1], v[OPOS];
DP4 o[HPOS].z, c[2], v[OPOS];
DP4 o[HPOS].w, c[3], v[OPOS];
MOV o[COL0], v[COL0];
MOV o[TEX0], v[TEX0];
 
MOV o[TEX0], v[TEX0];
 
END
/trunk/libps3rsx/tools/toolfx/res
New file
0,0 → 1,1851
g++ -Wall -O3 -lxml2 -I/usr/include/libxml2 toolfx.cpp -o toolfx
1
1
1
24
1
24
24
1
1
1
1
1
1
1
9
1
9
9
6
6
6
1
1
1
1
9
1
9
9
6
6
4
1
1
1
1
9
1
9
9
6
6
3
1
1
1
1
9
1
9
9
7
7
5
1
1
1
1
9
1
9
9
6
6
4
1
1
1
1
9
1
9
9
7
7
6
1
1
1
1
9
1
9
9
6
6
3
1
1
1
1
9
1
9
9
7
7
5
1
1
1
1
9
1
9
9
7
7
4
1
1
1
1
9
1
9
9
6
6
4
1
1
1
1
9
1
9
9
6
6
6
1
1
1
1
9
1
9
9
7
7
4
1
1
1
1
9
1
9
9
7
7
5
1
1
1
1
9
1
9
9
6
6
6
1
1
1
1
9
1
9
9
7
7
3
1
1
1
1
9
1
9
9
6
6
7
1
1
1
1
9
1
9
9
7
7
3
1
1
1
1
9
1
9
9
6
6
5
1
1
1
1
9
1
9
9
6
6
6
1
1
1
1
9
1
9
9
6
6
6
1
1
1
1
9
1
9
9
6
6
6
1
1
1
1
9
1
9
9
7
7
1
1
1
1
1
9
1
9
9
7
7
1
1
1
1
1
9
1
9
9
7
7
1
1
1
1
1
9
1
9
9
7
7
1
1
1
1
1
9
1
9
9
7
7
1
1
1
1
1
9
1
9
9
7
7
1
1
1
1
1
9
1
9
9
7
7
1
1
1
1
1
9
1
9
9
7
7
1
1
1
1
1
9
1
9
9
7
7
1
1
1
1
1
9
1
9
9
7
7
1
1
1
1
1
9
1
9
9
7
7
1
1
1
1
1
9
1
9
9
7
7
1
1
1
1
1
9
1
9
9
7
7
1
1
1
1
1
9
1
9
9
7
7
1
1
1
1
1
9
1
9
9
7
7
1
1
5
5
1
6
6
5
6
4
4
1
1
4
5
1
6
6
6
6
4
4
1
1
4
7
1
9
9
9
9
5
5
1
1
5
4
1
6
6
6
6
4
4
1
1
4
4
1
5
5
5
5
4
4
1
1
5
5
1
7
7
7
7
4
4
1
1
6
6
1
8
9
8
9
5
5
1
1
5
5
1
5
5
5
5
4
4
1
1
4
6
1
8
8
7
8
5
5
1
1
6
3
1
8
8
7
8
5
5
1
1
6
6
1
8
8
8
8
5
5
1
1
1
6
1
8
8
7
8
5
5
1
1
4
5
1
6
6
6
6
4
4
1
1
6
5
1
8
8
7
8
5
5
1
1
5
4
1
6
6
6
6
4
4
1
1
3
7
1
8
8
8
8
5
5
1
1
6
7
1
9
9
9
9
5
5
1
1
5
5
1
6
6
6
6
4
4
1
1
5
4
1
7
7
7
7
4
4
1
1
5
4
1
6
6
6
6
4
4
1
1
2
6
1
9
9
9
9
5
5
1
1
5
4
1
6
6
5
6
4
4
1
1
7
4
1
9
9
9
9
5
5
1
1
5
5
1
6
6
5
6
4
4
1
1
1
5
1
5
5
5
5
4
4
1
1
6
4
1
7
7
7
7
5
5
1
1
5
5
1
5
5
5
5
3
3
1
1
6
6
1
6
6
6
6
4
4
1
1
4
4
1
4
4
4
4
3
3
1
1
5
1
1
5
5
5
5
4
4
1
1
4
4
1
4
4
4
4
3
3
1
1
6
6
3
6
6
6
6
4
4
1
1
5
4
1
5
5
5
5
4
4
1
1
6
5
1
6
6
6
6
4
4
1
1
5
5
1
6
6
6
6
4
4
1
1
6
5
3
6
6
6
6
4
4
1
1
6
6
1
6
6
6
6
4
4
1
1
6
6
3
6
6
6
6
4
4
1
1
6
6
1
6
6
6
6
4
4
1
1
4
4
1
4
4
4
4
3
3
1
1
4
4
1
4
4
4
4
3
3
1
1
4
4
1
4
4
4
4
3
3
1
1
6
6
2
6
6
6
6
4
4
1
1
1
4
1
4
4
4
4
3
3
1
1
5
1
1
5
5
5
4
3
3
1
1
4
5
1
5
5
5
5
3
3
1
1
5
5
1
5
5
5
5
4
4
1
1
4
4
1
4
4
4
4
3
3
1
1
5
5
1
5
5
4
5
3
3
1
1
5
3
1
5
5
5
5
4
4
1
1
3
6
2
6
6
6
6
4
4
1
1
5
6
1
6
6
6
6
4
4
1
1
4
5
3
5
5
5
5
4
4
1
1
5
4
1
5
5
5
5
3
3
1
1
4
5
1
5
5
5
5
4
4
1
1
5
6
2
6
6
6
6
4
4
1
1
3
6
1
6
6
6
6
4
4
1
1
5
5
2
5
5
5
5
4
4
1
1
5
4
1
5
5
5
5
4
4
1
1
5
5
1
5
5
5
5
4
4
1
1
5
4
2
5
5
5
4
3
3
1
1
5
3
2
5
5
4
5
3
3
1
1
4
6
3
6
6
6
6
4
4
1
1
5
5
1
5
5
4
5
3
3
1
1
4
5
1
5
5
5
5
4
4
1
1
1
4
1
4
4
4
4
3
3
1
1
4
6
1
6
6
6
6
4
4
1
1
5
4
1
5
5
5
5
4
4
1
1
6
3
3
6
6
6
6
4
4
1
1
5
6
1
6
6
6
6
4
4
1
1
4
4
1
4
4
4
4
3
3
1
1
5
5
1
5
5
5
5
3
3
1
1
5
5
1
5
5
5
5
4
4
1
1
5
5
1
5
5
5
5
4
4
1
1
5
3
1
5
5
5
5
3
3
1
1
6
5
1
6
6
6
6
4
4
1
1
5
6
1
6
6
6
6
4
4
1
1
5
3
1
4
5
5
5
3
3
1
1
5
6
3
6
6
6
6
4
4
1
1
4
5
1
5
5
4
5
3
3
1
1
6
5
1
6
6
6
6
4
4
1
1
5
1
1
5
5
5
5
4
4
1
1
6
5
2
6
6
6
6
4
4
1
1
6
6
1
6
6
6
6
4
4
1
1
3
4
1
4
4
4
4
3
3
1
1
5
5
1
5
5
5
5
4
4
1
1
3
6
1
6
6
6
6
4
4
1
1
4
1
1
4
4
4
4
3
3
1
1
5
3
2
5
5
5
5
3
3
1
1
5
4
2
5
5
5
5
3
3
1
1
5
4
2
5
5
5
5
4
4
1
1
5
3
2
5
5
5
5
4
4
1
1
6
4
2
6
6
6
6
4
4
1
1
6
6
1
6
6
6
6
4
4
1
1
1
5
1
5
5
5
5
4
4
1
1
4
5
1
5
5
5
5
3
3
1
1
5
4
3
5
5
5
5
4
4
1
1
5
5
1
5
5
5
4
3
3
1
1
5
6
2
6
6
6
6
4
4
1
1
6
6
3
6
6
6
6
4
4
1
1
3
5
1
5
5
5
5
4
4
1
1
4
5
1
5
5
5
5
3
3
1
1
6
3
2
6
6
6
6
4
4
1
1
4
5
1
5
5
5
5
4
4
1
1
3
5
2
5
5
5
5
4
4
1
1
4
5
1
5
5
5
5
4
4
1
1
6
6
3
6
6
6
6
4
4
1
1
5
6
2
6
6
6
6
4
4
1
1
5
6
1
6
6
6
6
4
4
1
1
4
5
1
5
5
4
5
3
3
1
1
5
6
1
6
6
6
6
4
4
1
1
4
6
1
6
6
6
6
4
4
1
1
4
6
1
6
6
6
6
4
4
1
1
1
5
3
5
5
5
5
3
3
1
1
6
5
2
6
6
6
6
4
4
1
1
4
5
1
5
5
5
5
3
3
1
1
5
5
1
5
5
5
5
4
4
1
1
5
5
1
4
5
5
5
3
3
1
1
5
5
1
5
5
5
5
4
4
1
1
5
6
1
6
6
6
6
4
4
1
1
5
5
1
5
5
5
5
4
4
1
1
4
5
1
5
5
5
5
4
4
1
1
6
5
3
6
6
6
6
4
4
1
1
6
6
1
6
6
6
6
4
4
1
1
5
4
1
4
5
5
5
3
3
1
1
5
4
1
5
5
5
5
4
4
1
1
5
6
1
6
6
6
6
4
4
1
1
5
4
1
5
5
5
5
4
4
1
1
5
6
1
6
6
6
6
4
4
1
1
5
6
3
6
6
6
6
4
4
1
1
4
6
1
6
6
6
6
4
4
1
1
particles 168 pack size 28512
file dumped
/trunk/libps3rsx/tools/toolfx/toolfx
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/trunk/libps3rsx/tools/toolfx/toolfx
New file
Property changes:
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: trunk/libps3rsx/tools/toolfx/toolfx.cpp
===================================================================
--- trunk/libps3rsx/tools/toolfx/toolfx.cpp (revision 0)
+++ trunk/libps3rsx/tools/toolfx/toolfx.cpp (revision 203)
@@ -0,0 +1,413 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <math.h>
+#include <vector>
+#include <map>
+#include "StdAfx.h"
+#include "../common/XMLUtils.h"
+#include "../common/conv.h"
+#include "../../src/hilevel/fx.h"
+
+template<class T> void BinDump( const T &value, std::vector<uint8> &data )
+{
+ for( size_t i = 0; i < sizeof( T ); ++i )
+ {
+ data.push_back( ((uint8 *)&value)[i] );
+ }
+}
+
+typedef std::pair<float, uint16> Pair;
+
+enum Type
+{
+ FLOAT,
+ UINT8
+};
+
+
+
+
+uint8 saturateub( float v )
+{
+ int iv = int( v * 255.0f );
+ if( iv < 0 )
+ {
+ return 0;
+ }
+ if( iv > 255 )
+ {
+ return 255;
+ }
+ return uint8(iv);
+}
+
+struct CTrack
+{
+
+ std::vector<Pair> pairs;
+
+ void DumpBinary( std::vector<uint8> &data, Type type )
+ {
+ uint16 size = (uint16)pairs.size();
+
+ printf( "%d \n", size );
+
+ BinDump( size, data );
+ for( size_t i = 1; i + 1 < pairs.size(); ++i )
+ {
+ BinDump( pairs[i].second, data );
+ }
+ for( size_t i = 0; i < pairs.size(); ++i )
+ {
+ if( type == FLOAT )
+ {
+
+ BinDump( floatToHalf (pairs[i].first ), data );
+ }
+ if( type == UINT8 )
+ {
+ BinDump( saturateub( pairs[i].first ), data );
+ }
+ }
+ }
+
+ void Add( float value, uint16 key )
+ {
+ pairs.push_back( Pair( value, key ) );
+ }
+
+ void Out( const char * name )
+ {
+ printf( "%s ", name );
+ for( size_t i = 0; i < pairs.size(); ++i )
+ {
+ printf( "%2.4f:%d ", pairs[i].first, pairs[i].second );
+ }
+ printf( "\n" );
+ }
+
+ void Compress( float delta, CTrack &out )
+ {
+ uint16 first = 0;
+ uint16 last = 2;
+
+
+ float start = pairs[0].first;
+ out.pairs.push_back( pairs[0] );
+
+
+ bool ret = true;
+ for( size_t i = 0; i < pairs.size(); ++i )
+ {
+ if( fabs( start - pairs[i].first ) > delta )
+ {
+ ret = false;
+ break;
+ }
+
+ }
+
+ if( ret )
+ {
+ return;
+ }
+
+ while( 1 )
+ {
+ ++last;
+ if( last >= pairs.size() )
+ {
+ out.pairs.push_back( pairs.back() );
+ return;
+ }
+
+ float firstValue = pairs[first].first;
+ float lastValue = pairs[last].first;
+ float dist = 1.0f / ( last - first );
+ bool dump = false;
+
+ for( uint16 n = first + 1; n + 1 < last; ++n )
+ {
+
+ if( fabs( pairs[n].first - firstValue * ( n - first ) * dist - lastValue * ( last - n ) * dist ) > delta )
+ {
+ dump = true;
+ break;
+ }
+
+ }
+
+ if( dump )
+ {
+ out.pairs.push_back( pairs[last - 1] );
+ first = last;
+ last = first + 2;
+ }
+ }
+ }
+};
+
+
+enum Mode
+{
+ XYZ, RGBA, SCALE, ANGLE, SPRITE,
+};
+
+
+
+struct ParticleTrack
+{
+ CTrack data[11];
+ CTrack optimized[11];
+ std::vector<uint8> bin;
+
+ uint16 startFrame;
+ uint16 endFrame;
+
+
+ void Out()
+ {
+
+ int local = 0;
+ static float deltas[11] = { 0.01f, 0.01f, 0.01f, 0.01f, 0.01f, 0.01f, 0.01f, 0.01f, 0.01f, 0.01f, 0.01f };
+ Type types[11] = { FLOAT, FLOAT, FLOAT, FLOAT, FLOAT, FLOAT, FLOAT, FLOAT, FLOAT, FLOAT, FLOAT };
+ for( size_t i = 0; i < 11; ++i )
+ {
+ data[i].Compress( deltas[i], optimized[i] );
+ optimized[i].DumpBinary( bin, types[i] );
+ }
+
+ local = bin.size();
+ if( local & 15 )
+ {
+ local += ( 16 - local & 15 );
+ }
+ bin.resize( local, 0 );
+ }
+
+
+
+ void ParseXYZ(const xmlNode *xmlKey, uint16 ind )
+ {
+ data[0].Add( atof( (const char *)LoadStrAttr( xmlKey, _X"x" ) ), ind );
+ data[1].Add( atof( (const char *)LoadStrAttr( xmlKey, _X"y" ) ), ind );
+ data[2].Add( atof( (const char *)LoadStrAttr( xmlKey, _X"z" ) ), ind );
+ }
+
+ void ParseRGBA(const xmlNode *xmlKey, uint16 ind )
+ {
+
+ data[3].Add( atof( (const char *)LoadStrAttr( xmlKey, _X"r" ) ), ind );
+ data[4].Add( atof( (const char *)LoadStrAttr( xmlKey, _X"g" ) ), ind );
+ data[5].Add( atof( (const char *)LoadStrAttr( xmlKey, _X"b" ) ), ind );
+ data[6].Add( atof( (const char *)LoadStrAttr( xmlKey, _X"a" ) ), ind );
+ }
+
+ void ParseScale(const xmlNode *xmlKey, uint16 ind )
+ {
+ data[7].Add( atof( (const char *)LoadStrAttr( xmlKey, _X"x" ) ) * 0.5f, ind );
+ data[8].Add( atof( (const char *)LoadStrAttr( xmlKey, _X"y" ) ) * 0.5f, ind );
+ }
+
+
+ void ParseAngle(const xmlNode *xmlKey, uint16 ind )
+ {
+ data[9].Add( atof( (const char *)LoadStrAttr( xmlKey, _X"value" ) ) / 6.28318531f, ind );
+ }
+
+ void ParseSprite(const xmlNode *xmlKey, uint16 ind )
+ {
+ data[10].Add( (float)atoi( (const char *)LoadStrAttr( xmlKey, _X"value" ) ) + 0.5f, ind );
+ }
+
+ void Parse( const xmlNode *xmlTrack, Mode mode )
+ {
+
+ for ( xmlNode *xmlKey = xmlTrack->children; xmlKey; xmlKey = xmlKey->next )
+ {
+ if ( xmlStrcmp( xmlKey->name, _X"key" ) != 0 )
+ continue;
+
+ int time = atoi( (const char *)LoadStrAttr( xmlKey, _X"time" ) );
+
+ if( mode == XYZ )
+ {
+ ParseXYZ( xmlKey, (uint16)time );
+ }
+ else if( mode == RGBA )
+ {
+ ParseRGBA( xmlKey, (uint16)time );
+ }
+ else if( mode == SCALE )
+ {
+ ParseScale( xmlKey, (uint16)time );
+ }
+ else if( mode == ANGLE )
+ {
+ ParseAngle( xmlKey, (uint16)time );
+ }
+ if( mode == SPRITE )
+ {
+ ParseSprite( xmlKey, (uint16)time );
+ }
+
+ }
+ }
+
+ void ParseInfo( xmlNode *xmlParticle )
+ {
+ startFrame = atoi( (const char *)LoadStrAttr( xmlParticle, _X"startFrame" ) );
+ endFrame = atoi( (const char *)LoadStrAttr( xmlParticle, _X"endFrame" ) );
+
+ }
+
+
+ void Parse( xmlNode *xmlParticle )
+ {
+ Parse( Find( xmlParticle->children, _X"position" ), XYZ );
+ Parse( Find( xmlParticle->children, _X"color" ), RGBA );
+ Parse( Find( xmlParticle->children, _X"scale" ), SCALE );
+ Parse( Find( xmlParticle->children, _X"rotation" ), ANGLE );
+ Parse( Find( xmlParticle->children, _X"sprite" ), SPRITE );
+
+ }
+
+};
+
+
+
+
+struct FOpen
+{
+ FILE *fp;
+ FOpen( const char *file, bool read )
+ {
+ fp = fopen( file, read ? "rb" : "wb" );
+ }
+ ~FOpen()
+ {
+ if( fp == 0 )
+ {
+ return;
+ }
+ fclose( fp );
+ }
+};
+
+
+bool LoadParticleTemplate( const xmlNode *root, const char *fileDump, int loop )
+{
+
+
+ const xmlNode *particlesSet = Find( root->children, _X"particles" );
+ //int numFrames = atoi( (const char *)LoadStrAttr( particlesSet, _X"frames" ) );
+ //int numTracks = atoi( (const char *)LoadStrAttr( particlesSet, _X"tracks" ) );
+
+ std::vector<BinaryParticle> particles;
+ std::vector<uint8> bin;
+
+ for ( ; particlesSet; particlesSet = particlesSet->next )
+ {
+ for( xmlNode *xmlParticle = particlesSet->children; xmlParticle; xmlParticle = xmlParticle->next )
+ {
+ if ( xmlStrcmp( xmlParticle->name, _X"particle" ) != 0 )
+ continue;
+
+
+ ParticleTrack track;
+
+ track.ParseInfo( xmlParticle );
+
+ if( track.startFrame <= loop )
+ {
+
+ uint16 length = bin.size();
+ bin.swap( track.bin );
+ track.Parse( xmlParticle );
+
+ track.Out();
+ BinaryParticle bp;
+ bp.startFrame = track.startFrame;
+ bp.endFrame = track.endFrame;
+ bp.qwordOffset = length;
+ bp.qwordSize = track.bin.size() - length;
+
+ assert( ( bp.qwordSize & 15 ) == 0 );
+ assert( ( bp.qwordOffset & 15 ) == 0 );
+
+ bp.qwordSize /= 16;
+ bp.qwordOffset /= 16;
+
+ particles.push_back( bp );
+ bin.swap( track.bin );
+ }
+ }
+ }
+
+ printf( "particles %d pack size %d \n", particles.size(), bin.size() );
+
+ uint32 length = particles.size();
+ if( length & 1 )
+ {
+ particles.resize( length + 1 );
+ }
+
+ ParticleHeader header;
+ header.particles = (uint16)length;
+ header.loopFrame = loop;
+ header.trackSize = bin.size();
+ header.particleOffset = sizeof( header );
+ header.trackOffset = sizeof( header) + sizeof( particles[0] ) * particles.size();
+
+ FOpen fp( fileDump, false );
+
+ if( fp.fp == 0 )
+ {
+ printf( "file %s can not be opened \n", fileDump );
+ return false;
+ }
+
+ fwrite( &header, 1, sizeof( header ), fp.fp );
+ fwrite( &particles[0], particles.size(), sizeof( particles[0] ), fp.fp );
+ fwrite( &bin[0], 1, bin.size(), fp.fp );
+ return true;
+}
+
+
+
+
+
+int main( int argc, const char *argv[2] )
+{
+ if( argc != 4 )
+ {
+ printf( "params: infile outfile loopFrame \n" );
+ return -1;
+ }
+
+ xmlDoc *doc = NULL;
+ xmlNode *root = NULL;
+
+ int loop = atoi( argv[3] );
+
+ doc = xmlReadFile( argv[1], NULL, 0 );
+
+ if (doc == NULL)
+ {
+ printf( "error: could not parse file %s", argv[1] );
+ return -1;
+ }
+
+ //printf( "%d \n", size );
+ root = xmlDocGetRootElement(doc);
+ if( LoadParticleTemplate( root, argv[2], loop ) )
+ {
+ printf( "file dumped \n" );
+ }
+
+ return 0;
+
+}
Index: trunk/libps3rsx/tools/toolfx/Makefile
===================================================================
--- trunk/libps3rsx/tools/toolfx/Makefile (revision 0)
+++ trunk/libps3rsx/tools/toolfx/Makefile (revision 203)
@@ -0,0 +1,11 @@
+CPPFLAGS= -Wall -O3 -lxml2 -I/usr/include/libxml2
+
+all:toolfx
+
+
+toolfx: toolfx.cpp
+ $(CXX) $(CPPFLAGS) toolfx.cpp -o toolfx
+
+
+clean:
+ $(RM) *.o $(OBJSQ) toolfx
Index: trunk/libps3rsx/tools/toolfx/StdAfx.h
===================================================================
--- trunk/libps3rsx/tools/toolfx/StdAfx.h (revision 0)
+++ trunk/libps3rsx/tools/toolfx/StdAfx.h (revision 203)
@@ -0,0 +1,48 @@
+// stdafx.h : include file for standard system include files,
+// or project specific include files that are used frequently, but
+// are changed infrequently
+//
+
+#pragma once
+
+#include <stdio.h>
+#include <libxml/parser.h>
+#include <libxml/tree.h>
+#include <math.h>
+#include <float.h>
+#include <map>
+#include <vector>
+#include <string>
+#include <assert.h>
+#include <algorithm>
+#include <typeinfo>
+#include <time.h>
+
+
+typedef unsigned char uint8;
+typedef signed char sint8;
+
+typedef unsigned short uint16;
+typedef signed short sint16;
+
+typedef unsigned int uint32;
+typedef signed int sint32;
+
+typedef unsigned long long uint64;
+typedef signed long long sint64;
+
+
+typedef unsigned char uint8_t;
+typedef signed char sint8_t;
+
+typedef unsigned short uint16_t;
+typedef signed short sint16_t;
+
+typedef unsigned int uint32_t;
+typedef signed int sint32_T;
+
+typedef unsigned long long uint64_t;
+typedef signed long long sint64_t;
+
+#define LENGTH(X) (sizeof(X)/sizeof(X[0]))
+
Index: trunk/libps3rsx/tools/toolfx/compress!!.sh
===================================================================
--- trunk/libps3rsx/tools/toolfx/compress!!.sh (revision 0)
+++ trunk/libps3rsx/tools/toolfx/compress!!.sh (revision 203)
@@ -0,0 +1,3 @@
+make
+./toolfx ../../art/licensed/SpellIce.xml ../../data/spell 160
+
/trunk/libps3rsx/tools/toolfx/compress!!.sh
Property changes:
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: trunk/libps3rsx/tools/tooldxt/compress!!.sh
===================================================================
--- trunk/libps3rsx/tools/tooldxt/compress!!.sh (revision 202)
+++ trunk/libps3rsx/tools/tooldxt/compress!!.sh (revision 203)
@@ -1,2 +1,2 @@
make
-./tooldxt -dxt3 10 ../../art/licensed/TrollWhite.tga ../../data/troll.dxt3
+./tooldxt -dxt5 10 ../../art/licensed/Glow05Blue.tga ../../art/licensed/Rays18Blue.tga ../../art/licensed/Rays01Blue.tga ../../art/licensed/Spark01Blue.tga ../../data/spell.dxt3
Index: trunk/libps3rsx/tools/tooldxt/tooldxt
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: trunk/libps3rsx/tools/tooldxt/tooldxt.cpp
===================================================================
--- trunk/libps3rsx/tools/tooldxt/tooldxt.cpp (revision 202)
+++ trunk/libps3rsx/tools/tooldxt/tooldxt.cpp (revision 203)
@@ -5,20 +5,24 @@
#include <stdlib.h>
#include <stdint.h>
#include <math.h>
+#include <vector>
+#include <string>
+#include <algorithm>
#include "../../src/types.h"
#include "../../src/textures/textures.h"
+#include "../common/conv.h"
enum ETGAImageType
{
- TGAIT_NOIMAGEDATA = 0,
- TGAIT_COLOR_MAPPED = 1,
- TGAIT_TRUE_COLOR = 2,
- TGAIT_BLACK_WHITE = 3,
- TGAIT_RLE_COLOR_MAPPED = 9,
- TGAIT_RLE_TRUE_COLOR = 10,
- TGAIT_RLE_BLACK_WHITE = 11
+ TGAIT_NOIMAGEDATA = 0,
+ TGAIT_COLOR_MAPPED = 1,
+ TGAIT_TRUE_COLOR = 2,
+ TGAIT_BLACK_WHITE = 3,
+ TGAIT_RLE_COLOR_MAPPED = 9,
+ TGAIT_RLE_TRUE_COLOR = 10,
+ TGAIT_RLE_BLACK_WHITE = 11
};
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -26,17 +30,17 @@
// describe the color map (if any) used for the image
struct SColorMapSpecification
{
- uint16 wFirstEntryIndex;// Index of the first color map entry. Index refers to the starting entry in loading the color map.
- uint16 wColorMapLength; // Total number of color map entries included
- uint8 cColorMapEntrySize;// Establishes the number of bits per entry. Typically 15, 16, 24 or 32-bit values are used
+ uint16 wFirstEntryIndex;// Index of the first color map entry. Index refers to the starting entry in loading the color map.
+ uint16 wColorMapLength; // Total number of color map entries included
+ uint8 cColorMapEntrySize;// Establishes the number of bits per entry. Typically 15, 16, 24 or 32-bit values are used
};
//
struct SImageDescriptor
{
-uint8 cAlphaChannelBits : 4; // the number of attribute bits per pixel
-uint8 cLeftToRightOrder : 1; // left-to-right ordering
-uint8 cTopToBottomOrder : 1; // top-to-bottom ordering
-uint8 cUnused : 2; // Must be zero to insure future compatibility
+ uint8 cAlphaChannelBits : 4; // the number of attribute bits per pixel
+ uint8 cLeftToRightOrder : 1; // left-to-right ordering
+ uint8 cTopToBottomOrder : 1; // top-to-bottom ordering
+ uint8 cUnused : 2; // Must be zero to insure future compatibility
};
// describe the image screen location, size and pixel depth
@@ -43,355 +47,565 @@
struct SImageSpecification
{
- uint16 wXOrigin; // absolute horizontal coordinate for the lower left corner of the image as it is positioned on a display device having an origin at the lower left of the screen
- uint16 wYOrigin; // absolute vertical coordinate for the lower left corner of the image as it is positioned on a display device having an origin at the lower left of the screen
- uint16 wImageWidth; // width of the image in pixels
- uint16 wImageHeight; // height of the image in pixels
- uint8 cPixelDepth; // number of bits per pixel. This number includes the Attribute or Alpha channel bits. Common values are 8, 16, 24 and 32 but other pixel depths could be used.
- SImageDescriptor descriptor; //
+ uint16 wXOrigin; // absolute horizontal coordinate for the lower left corner of the image as it is positioned on a display device having an origin at the lower left of the screen
+ uint16 wYOrigin; // absolute vertical coordinate for the lower left corner of the image as it is positioned on a display device having an origin at the lower left of the screen
+ uint16 wImageWidth; // width of the image in pixels
+ uint16 wImageHeight; // height of the image in pixels
+ uint8 cPixelDepth; // number of bits per pixel. This number includes the Attribute or Alpha channel bits. Common values are 8, 16, 24 and 32 but other pixel depths could be used.
+ SImageDescriptor descriptor; //
};
struct STGAFileHeader
{
- uint8 cIDLength; // identifies the number of bytes contained in Field 6, the Image ID Field
- uint8 cColorMapType; // indicates the type of color map (if any) included with the image
- uint8 cImageType; // TGA File Format can be used to store Pseudo-Color, True-Color and Direct-Color images of various pixel depths
- SColorMapSpecification colormap; //
- SImageSpecification imagespec; //
+ uint8 cIDLength; // identifies the number of bytes contained in Field 6, the Image ID Field
+ uint8 cColorMapType; // indicates the type of color map (if any) included with the image
+ uint8 cImageType; // TGA File Format can be used to store Pseudo-Color, True-Color and Direct-Color images of various pixel depths
+ SColorMapSpecification colormap; //
+ SImageSpecification imagespec; //
};
struct STGAFileFooter
{
- uint32 dwExtensionAreaOffset; // offset from the beginning of the file to the start of the Extension Area
- uint32 dwDeveloperDirectoryOffset;
- // offset from the beginning of the file to the start of the Developer Directory
- uint8 cSignature[16]; // "TRUEVISION-XFILE"
- uint8 cReservedCharacter; // must be '.'
- uint8 cBinaryZeroStringTerminator; // '\0'
+ uint32 dwExtensionAreaOffset; // offset from the beginning of the file to the start of the Extension Area
+ uint32 dwDeveloperDirectoryOffset;
+ // offset from the beginning of the file to the start of the Developer Directory
+ uint8 cSignature[16]; // "TRUEVISION-XFILE"
+ uint8 cReservedCharacter; // must be '.'
+ uint8 cBinaryZeroStringTerminator; // '\0'
};
#pragma pack()
+struct Rectangle
+{
+ size_t width;
+ size_t height;
+ size_t x;
+ size_t y;
+};
+struct SortR
+{
+ size_t price;
+ size_t order;
+ bool operator < ( const SortR &s ) const
+ {
+ return price > s.price;
+ }
+};
+
+void Sort( const Rectangle *rects, size_t size, size_t *order )
+{
+ std::vector<SortR> sorts( size );
+
+ for( size_t i = 0; i < size; ++i )
+ {
+ order[i] = i;
+ const Rectangle &rect = rects[i];
+ sorts[i].price = ( rect.width << 16 ) + rect.height;
+ sorts[i].order = i;
+ }
+
+ std::sort( sorts.begin(), sorts.end() );
+
+ for( size_t i = 0; i < size; ++i )
+ {
+ order[i] = sorts[i].order;
+ }
+}
+
+bool Pack( Rectangle *rects, size_t size, const size_t *order, size_t width, size_t height )
+{
+ std::vector<size_t> line( width, 0 );
+
+ for( size_t i = 0; i < size; ++i )
+ {
+ Rectangle &rect = !order ? rects[i] : rects[order[i]];
+
+ size_t minMaxHeight = height;
+ size_t minMaxIndex = 0;
+
+ for( size_t k = 0; k + rect.width <= width; ++k )
+ {
+ size_t maxHeight = 0;
+ for( size_t j = k; j < k + rect.width; ++j )
+ {
+ if( maxHeight < line[j] )
+ {
+ maxHeight = line[j];
+ }
+ }
+ if( minMaxHeight > maxHeight )
+ {
+ minMaxHeight = maxHeight;
+ minMaxIndex = k;
+ }
+ }
+
+ if( minMaxHeight + rect.height > height )
+ {
+ return false;
+ }
+
+ rect.y = minMaxHeight;
+ rect.x = minMaxIndex;
+
+ for( size_t j = minMaxIndex; j < minMaxIndex + rect.width; ++j )
+ {
+ line[j] = minMaxHeight + rect.height;
+ }
+ }
+
+ printf( "%d %d\n", width, height );
+ for( size_t i = 0; i < size; ++i )
+ {
+ Rectangle &rect = !order ? rects[i] : rects[order[i]];
+ printf( "w = %d h = %d x = %d y = %d \n", rect.width, rect.height, rect.x, rect.y );
+ }
+
+ return true;
+}
+
struct FOpen
{
- FILE *fp;
- FOpen( const char *file, bool read )
- {
- fp = fopen( file, read ? "rb" : "wb" );
- }
- ~FOpen()
- {
- fclose( fp );
- }
+ FILE *fp;
+ FOpen( const char *file, bool read )
+ {
+ fp = fopen( file, read ? "rb" : "wb" );
+ }
+ ~FOpen()
+ {
+ fclose( fp );
+ }
};
struct Notifier
{
- virtual void Length( int add ) = 0;
- virtual void Mip() = 0;
+ virtual void Length( int add ) = 0;
+ virtual void Mip() = 0;
};
-void convert_texture_2D( const texture_desc_t *desc, const uint8_t *user_rgba, uint8_t *out, float gamma, Notifier *note )
+uint8 noise( uint8 v )
{
- uint8 pixels[4][4][4]; // 16 pixels of input
- uint8 dxt[16]; // 8-16 bytes of output
+ return v;
+}
- if( desc->mips == 0 )
- {
- return;
- }
+void ConvertTexture2D( const texture_desc_t *desc, const uint8_t *user_rgba, uint8_t *out, float gamma, Notifier *note )
+{
+ uint8 pixels[4][4][4]; // 16 pixels of input
+ uint8 dxt[16]; // 8-16 bytes of output
- note->Mip();
+ if( desc->mips == 0 )
+ {
+ return;
+ }
- int block = -1;
- int comp = -1;
+ note->Mip();
- if( desc->format == DXT1 )
- {
- block = 8;
- comp = squish::kDxt1;
- }
- if( desc->format == DXT3 )
- {
- block = 16;
- comp = squish::kDxt3;
- }
- if( desc->format == DXT5 )
- {
- block = 16;
- comp = squish::kDxt5;
- }
-
+ int block = -1;
+ int comp = -1;
- for( int i = 0; i < desc->height; i += 4 )
- {
- for( int j = 0; j < desc->width; j += 4 )
- {
+ if( desc->format == DXT1 )
+ {
+ block = 8;
+ comp = squish::kDxt1;
+ }
+ if( desc->format == DXT3 )
+ {
+ printf( "3" );
+ block = 16;
+ comp = squish::kDxt3;
+ }
+ if( desc->format == DXT5 )
+ {
+ printf( "5" );
+ block = 16;
+ comp = squish::kDxt5;
+ }
- if( user_rgba )
- {
- for( int i1 = 0; i1 < 4; ++i1 )
- {
- for( int j1 = 0; j1 < 4; ++j1 )
- {
- int offset = ( ( j + j1 ) + ( i + i1 ) * desc->width ) * 4;
- pixels[i1][j1][0] = user_rgba[offset + 2];
- pixels[i1][j1][1] = user_rgba[offset + 1];
- pixels[i1][j1][2] = user_rgba[offset + 0];
- pixels[i1][j1][3] = user_rgba[offset + 3];
- }
- }
- squish::Compress( &pixels[0][0][0], dxt, comp );
- memcpy( out, dxt, block );
- out += block;
- }
- note->Length( block );
- }
- }
+ for( int i = 0; i < desc->height; i += 4 )
+ {
+ for( int j = 0; j < desc->width; j += 4 )
+ {
- if( desc->height > 4 && desc->width > 4 )
- {
+ if( user_rgba )
+ {
+ for( int i1 = 0; i1 < 4; ++i1 )
+ {
+ for( int j1 = 0; j1 < 4; ++j1 )
+ {
+ int offset = ( ( j + j1 ) + ( i + i1 ) * desc->width ) * 4;
+
+ pixels[i1][j1][0] = noise( user_rgba[offset + 2] );
+ pixels[i1][j1][1] = noise( user_rgba[offset + 1] );
+ pixels[i1][j1][2] = noise( user_rgba[offset + 0] );
+ pixels[i1][j1][3] = noise( user_rgba[offset + 3] );
- uint8_t *newData = 0;
+ }
+ }
+ squish::Compress( &pixels[0][0][0], dxt, comp );
+ memcpy( out, dxt, block );
+ out += block;
+ }
+ note->Length( block );
+ }
+ }
- if( user_rgba )
- {
- newData = new uint8_t[ desc->width * desc->height ];
+ if( desc->height > 4 && desc->width > 4 )
+ {
- float inv = 1.0f / gamma;
- for( int i = 0; i < desc->height; i += 2 )
- {
- for( int j = 0; j < desc->width; j += 2 )
- {
- float r = 0.0f;
- float g = 0.0f;
- float b = 0.0f;
- float a = 0.0f;
+ std::vector<uint8_t> newData;
- for( int i1 = 0; i1 < 2; ++i1 )
- {
- for( int j1 = 0; j1 < 2; ++j1 )
- {
- int offset = ( ( j + j1 ) + ( i + i1 ) * desc->width ) * 4;
- r += 0.25f * pow( user_rgba[offset + 0], gamma );
- g += 0.25f * pow( user_rgba[offset + 1], gamma );
- b += 0.25f * pow( user_rgba[offset + 2], gamma );
- a += 0.25f * pow( user_rgba[offset + 3], gamma );
+ if( user_rgba )
+ {
+
+ newData.resize( desc->width * desc->height );
+ float inv = 1.0f / gamma;
+ for( int i = 0; i < desc->height; i += 2 )
+ {
+ for( int j = 0; j < desc->width; j += 2 )
+ {
+ float r = 0.0f;
+ float g = 0.0f;
+ float b = 0.0f;
+ float a = 0.0f;
- }
- }
+ for( int i1 = 0; i1 < 2; ++i1 )
+ {
+ for( int j1 = 0; j1 < 2; ++j1 )
+ {
+ int offset = ( ( j + j1 ) + ( i + i1 ) * desc->width ) * 4;
+ r += 0.25f * pow( user_rgba[offset + 0], gamma );
+ g += 0.25f * pow( user_rgba[offset + 1], gamma );
+ b += 0.25f * pow( user_rgba[offset + 2], gamma );
+ a += 0.25f * pow( user_rgba[offset + 3], gamma );
- int offset = ( j * 2 + i * desc->width );
- newData[offset + 0] = (uint8_t)pow ( r, inv );
- newData[offset + 1] = (uint8_t)pow ( g, inv );
- newData[offset + 2] = (uint8_t)pow ( b, inv );
- newData[offset + 3] = (uint8_t)pow ( a, inv );
+ }
+ }
- }
- }
- }
- texture_desc_t newDesc = *desc;
- newDesc.width /= 2;
- newDesc.height /= 2;
- newDesc.mips--;
- convert_texture_2D( &newDesc, newData, out, gamma, note );
- delete[] newData;
+ int offset = ( j * 2 + i * desc->width );
+ newData[offset + 0] = (uint8_t)pow ( r, inv );
+ newData[offset + 1] = (uint8_t)pow ( g, inv );
+ newData[offset + 2] = (uint8_t)pow ( b, inv );
+ newData[offset + 3] = (uint8_t)pow ( a, inv );
- }
+ }
+ }
+ }
+ texture_desc_t newDesc = *desc;
+ newDesc.width /= 2;
+ newDesc.height /= 2;
+ newDesc.mips--;
+ ConvertTexture2D( &newDesc, user_rgba ? &newData[0] : 0, out, gamma, note );
+
+ }
}
struct LengthMips : public Notifier
{
- int length;
- int mips;
+ int length;
+ int mips;
- LengthMips() : length ( 0 ), mips( 0 ){};
+ LengthMips() : length ( 0 ), mips( 0 ){};
- void Length( int add )
- {
- length += add;
- }
- void Mip()
- {
- ++mips;
- }
+ void Length( int add )
+ {
+ length += add;
+ }
+ void Mip()
+ {
+ ++mips;
+ }
};
struct Counter : public Notifier
{
- int mips;
- int length;
- int total;
- int percent;
+ int mips;
+ int length;
+ int total;
+ int percent;
- Counter() : length ( 0 ), mips( 0 ), percent( -1 ) {};
+ Counter() : length ( 0 ), mips( 0 ), percent( -1 ) {};
- void Length( int add )
- {
-
- length += add;
- int newPercent = ( length * 10 ) / total;
- if( newPercent != percent )
- {
- printf( "percent = %d \n", newPercent * 10 );
- percent = newPercent;
- }
+ void Length( int add )
+ {
- }
- void Mip()
- {
- }
-};
+ length += add;
+ int newPercent = ( length * 10 ) / total;
+ if( newPercent != percent )
+ {
+ printf( "percent = %d \n", newPercent * 10 );
+ percent = newPercent;
+ }
+ }
+ void Mip()
+ {}
+}
+;
+
uint16 endian( uint16 a )
{
return ( a >> 8 ) | ( ( a & 0xff ) << 8 );
}
-int main( int argc, const char *argv[2] )
+
+struct TgaFile
{
- texture_desc_t desc;
- if( argc < 4 )
- {
- printf( "params: [-dxt1:-dxt3:-dxt5] [mips num] infile outfile\n" );
+ std::vector<uint8> data;
+ int width;
+ int height;
- return -1;
+ uint8 *GetPixel( size_t i, size_t j )
+ {
+ return &data[ ( i * width + j ) * 4 ];
- }
+ }
+ void SetSize( size_t size )
+ {
+ width = height = size;
+ data.resize( width * height * 4, 255 );
+ }
+ void Pack( size_t i, size_t j, TgaFile &src )
+ {
+ for( size_t ii = 0; ii < src.width; ++ii )
+ {
+
+ for( size_t jj = 0; jj < src.height; ++jj )
+ {
+ const uint8 *from = src.GetPixel( ii, jj );
+ uint8 *to = GetPixel( ii + i, jj + j );
+ to[0] = from[0];
+ to[1] = from[1];
+ to[2] = from[2];
+ to[3] = from[3];
+
+ }
+ }
+ }
+ bool Init( const char *file )
+ {
+ std::vector<uint8> scan;
- int mode = -1;
+ FOpen fp( file, true );
- if( !strcmp( argv[1], "-dxt1" ) )
- {
- mode = 1;
- desc.format = DXT1;
- }
+ if( !fp.fp )
+ {
+ printf( "can not open file %s \n", file );
+ return false;
+ }
- if( !strcmp( argv[1], "-dxt3" ) )
- {
- mode = 3;
- desc.format = DXT3;
- }
+ STGAFileHeader hdr;
- if( !strcmp( argv[1], "-dxt5" ) )
- {
- mode = 5;
- desc.format = DXT5;
- }
+ if( !fread( &hdr, sizeof( hdr ), 1, fp.fp ) )
+ {
+ printf( "cannot read tga header from file %s \n", file );
+ return false;
+ }
- if( mode ==- 1 )
- {
- printf( "specify [-dxt1:-dxt3:-dxt5]\n" );
- return -1;
- }
+ if( hdr.cImageType != TGAIT_TRUE_COLOR )
+ {
+ printf( "not TGAIT_TRUE_COLOR file %s \n", file );
+ return file;
+ }
- int mips = atoi( argv[2] );
+ int bpp = -1;
- FOpen fp( argv[3], true );
- FOpen out_file( argv[4], false );
-
+ if( hdr.imagespec.cPixelDepth == 24 )
+ {
+ bpp = 3;
+ }
- if( !fp.fp )
- {
- printf( "cannot open file %s \n", argv[3] );
- return -1;
- }
+ if( hdr.imagespec.cPixelDepth == 32 )
+ {
+ bpp = 4;
+ }
- STGAFileHeader hdr;
+ if( bpp == -1 )
+ {
+ printf( "not 24 or 32 image depth for file %s \n", file );
+ return -1;
+ }
- if( !fread( &hdr, sizeof( hdr ), 1, fp.fp ) )
- {
- printf( "cannot read tga header from file %s \n", argv[3] );
- return -1;
- }
- //fseek( fp.fp, hdr.cIDLength, SEEK_CUR );
- if( hdr.cImageType != TGAIT_TRUE_COLOR )
- {
- printf( "not TGAIT_TRUE_COLOR file %s \n", argv[3] );
- return -1;
- }
+ width = endian( hdr.imagespec.wImageWidth );
+ height = endian( hdr.imagespec.wImageHeight );
+ scan.resize( width * 4 );
+ data.resize( width * height * 4, 255 );
- int bpp = -1;
+ printf( "file %s width %d height %d bpp %d\n", file, width, height, bpp );
- if( hdr.imagespec.cPixelDepth == 24 )
- {
- bpp = 3;
- }
+ for( int i = 0; i < height; ++i )
+ {
- if( hdr.imagespec.cPixelDepth == 32 )
- {
- bpp = 4;
- }
+ memset( &scan[0], 255, width * 4 );
+ fread( &scan[0], width * bpp, 1, fp.fp );
+ int ioff = hdr.imagespec.descriptor.cTopToBottomOrder ? height - 1 - i : i;
+ ioff = ioff * width * 4;
- if( bpp == -1 )
- {
- printf( "not 24 or 32 image depth for file %s \n", argv[3] );
- return -1;
- }
+ for( int j = 0; j < width; ++j )
+ {
+ int off = hdr.imagespec.descriptor.cLeftToRightOrder ? j : width - 1 - j;
+ off = ioff + off * 4;
+ for( int k = 0; k < bpp; ++k )
+ {
+ data[off + k] = scan[j * bpp + k];
+ }
+ }
+ }
+ return true;
+ }
+};
- int width = endian( hdr.imagespec.wImageWidth );
- int height = endian( hdr.imagespec.wImageHeight );
- uint8 *scan = new uint8[ width * 4 ];
- uint8 *data = new uint8[ width * height * 4 ];
- memset( data, 255, width * height * 4 );
+int main( int argc, const char *argv[] )
+{
+ texture_desc_t desc;
+ if( argc < 5 )
+ {
+ printf( "params: [-dxt1:-dxt3:-dxt5] [mips num] infile outfile\n" );
- printf( "file %s width %d height %d bpp %d\n", argv[3], width, height, bpp );
+ return -1;
- for( int i = 0; i < height; ++i )
- {
+ }
- memset( scan, 255, width * 4 );
- fread( scan, width * bpp, 1, fp.fp );
- int ioff = hdr.imagespec.descriptor.cTopToBottomOrder ? height - 1 - i : i;
- ioff = ioff * width * 4;
+ int mode = -1;
- for( int j = 0; j < width; ++j )
- {
- int off = hdr.imagespec.descriptor.cLeftToRightOrder ? j : width - 1 - j;
- off = ioff + off * 4;
- for( int k = 0; k < bpp; ++k )
- {
- data[off + k] = scan[j * bpp + k];
- }
- }
- }
+ if( !strcmp( argv[1], "-dxt1" ) )
+ {
+ mode = 1;
+ desc.format = DXT1;
+ }
+ if( !strcmp( argv[1], "-dxt3" ) )
+ {
+ mode = 3;
+ desc.format = DXT3;
+ }
- LengthMips lm;
- Counter cnt;
- desc.width = width;
- desc.mips = mips;
- desc.height = height;
-
+ if( !strcmp( argv[1], "-dxt5" ) )
+ {
+ mode = 5;
+ desc.format = DXT5;
+ }
- convert_texture_2D( &desc, 0, 0, 1.2f, &lm );
-
- desc.length = lm.length;
- uint8 *out = new uint8[lm.length];
- cnt.total = lm.length;
-
+ if( mode ==- 1 )
+ {
+ printf( "specify [-dxt1:-dxt3:-dxt5]\n" );
+ return -1;
+ }
- convert_texture_2D( &desc, data, out, 1.2f, &cnt );
-
- printf( "result mips %d result size = %d \n", lm.mips, lm.length );
-
- desc.mips = lm.mips;
-
- fwrite( &desc, sizeof( desc ), 1, out_file.fp );
- fwrite( out, lm.length, 1, out_file.fp );
-
+ FOpen out_file( argv[argc - 1], false );
+ TgaFile tf;
- delete out;
- delete data;
- delete scan;
- return 0;
+ if( argc == 5 )
+ {
+ if( !tf.Init( argv[3] ) )
+ {
+ return -1;
+ }
+ }
+ else
+ {
+ std::vector<TgaFile> files;
+ files.resize( argc - 4 );
+
+ for( size_t i = 0; i < files.size(); ++i )
+ {
+ if( !files[i].Init( argv[3 + i] ) )
+ {
+ return -1;
+ }
+ }
+
+ std::vector<Rectangle> rects;
+ std::vector<size_t> order;
+ order.resize( files.size() );
+ rects.resize( files.size() );
+ for( size_t i = 0; i < files.size(); ++i )
+ {
+ rects[i].width = files[i].width;
+ rects[i].height = files[i].height;
+ }
+ Sort( &rects[0], files.size(), &order[0] );
+
+ size_t size = 0;
+ for( size_t j = 0; j < 16; ++j )
+ {
+ if( Pack( &rects[0], files.size(), &order[0], 1 << j, 1 << j ) )
+ {
+
+ FOpen out_atlas( ( std::string( argv[argc - 1 ] ) + ".atlas" ).c_str(), false );
+ size = 1 << j;
+ tf.SetSize( size );
+ float mul = 1.0f / (float)size;
+ for( size_t i = 0; i < files.size(); ++i )
+ {
+ uint16 v[8];
+
+
+ float x = ( rects[i].x + 1.0f ) * mul;
+ float y = ( rects[i].y + 1.0f ) * mul;
+ float dx = ( rects[i].width - 2.0f ) * mul;
+ float dy = ( rects[i].height - 2.0f ) * mul;
+
+
+ v[1] = floatToHalf( x );
+ v[0] = floatToHalf( y );
+ v[3] = floatToHalf( x + dx );
+ v[2] = floatToHalf( y );
+ v[5] = floatToHalf( x + dx );
+ v[4] = floatToHalf( y + dy );
+ v[7] = floatToHalf( x );
+ v[6] = floatToHalf( y + dy );
+
+ fwrite( v, 16, 1, out_atlas.fp );
+ tf.Pack( rects[i].x, rects[i].y, files[i] );
+ }
+ break;
+ }
+ }
+ if( size == 0 )
+ {
+ printf( "too big atlas \n" );
+ return -1;
+ }
+
+ }
+
+ printf( "packing...\n" );
+
+ int mips = atoi( argv[2] );
+ LengthMips lm;
+ Counter cnt;
+ desc.width = tf.width;
+ desc.mips = mips;
+ desc.height = tf.height;
+
+
+ ConvertTexture2D( &desc, 0, 0, 1.2f, &lm );
+
+ desc.length = lm.length;
+ std::vector<uint8> out( lm.length );
+ cnt.total = lm.length;
+
+
+ ConvertTexture2D( &desc, &tf.data[0], &out[0], 1.2f, &cnt );
+
+ printf( "result mips %d result size = %d \n", lm.mips, lm.length );
+
+ desc.mips = lm.mips;
+
+ fwrite( &desc, sizeof( desc ), 1, out_file.fp );
+ fwrite( &out[0], out.size(), 1, out_file.fp );
+
+
+ return 0;
+
}