psi2love
psi2love.cpp is a small C++ program which takes a HGE psi file and outputs Lua source code to create an equivalent particle system in LÖVE.
#include <stdio.h> #include <stdint.h> #include <errno.h> #include <string.h> #include <math.h> struct hgeColor { float r,g,b,a; }; struct hgeParticleSystemInfo { uint32_t sprite; // hgeSprite* sprite; // texture + blend mode int32_t nEmission; // int nEmission; // particles per sec float fLifetime; float fParticleLifeMin; float fParticleLifeMax; float fDirection; float fSpread; int32_t bRelative; // bool bRelative; float fSpeedMin; float fSpeedMax; float fGravityMin; float fGravityMax; float fRadialAccelMin; float fRadialAccelMax; float fTangentialAccelMin; float fTangentialAccelMax; float fSizeStart; float fSizeEnd; float fSizeVar; float fSpinStart; float fSpinEnd; float fSpinVar; hgeColor colColorStart; // + alpha hgeColor colColorEnd; float fColorVar; float fAlphaVar; }; int main( int argc, const char* argv[] ) { if ( argc != 5 ) { fprintf( stderr, "USAGE: psi2love filename.psi func_name image_name max_particles\n" ); return 1; } FILE* psi = fopen( argv[ 1 ], "rb" ); if ( psi == NULL ) { fprintf( stderr, "Error: %s\n", strerror( errno ) ); return 1; } hgeParticleSystemInfo info; if ( fread( &info, 1, sizeof( info ), psi ) != sizeof( info ) ) { fprintf( stderr, "Error: %s\n", strerror( errno ) ); fclose( psi ); return 1; } fclose( psi ); printf( "local function %s()\n", argv[ 2 ] ); printf( " -- created from %s\n", argv[ 1 ] ); printf( "\n" ); printf( " local ps = love.graphics.newParticleSystem( %s, %s )\n", argv[ 3 ], argv[ 4 ] ); printf( "\n" ); // nEmission printf( " ps:setEmissionRate( %d )\n", info.nEmission ); // fLifetime printf( " ps:setLifetime( %g )%s\n", info.fLifetime, info.fLifetime == -1.0 ? " -- forever" : "" ); // fParticleLifeMin, fParticleLifeMax printf( " ps:setParticleLife( %g, %g )\n", info.fParticleLifeMin, info.fParticleLifeMax ); // fDirection printf( " ps:setDirection( %g )\n", info.fDirection - M_PI / 2 ); // fSpread printf( " ps:setSpread( %g )\n", info.fSpread ); // bRelative printf( " -- ps:setRelative( %s )\n", info.bRelative ? "true" : "false" ); // fSpeedMin, fSpeedMax printf( " ps:setSpeed( %g, %g )\n", info.fSpeedMin, info.fSpeedMax ); // fGravityMin, fGravityMax printf( " ps:setGravity( %g, %g )\n", info.fGravityMin, info.fGravityMax ); // fRadialAccelMin, fRadialAccelMax printf( " ps:setRadialAcceleration( %g, %g )\n", info.fRadialAccelMin, info.fRadialAccelMax ); // fTangentialAccelMin, fTangentialAccelMax printf( " ps:setTangentialAcceleration( %g, %g )\n", info.fTangentialAccelMin, info.fTangentialAccelMax ); // fSizeStart, fSizeEnd, fSizeVar printf( " ps:setSize( %g, %g ) -- there's a bug in 0.7.1 that forces us to set the size variation using its own function\n", info.fSizeStart, info.fSizeEnd ); printf( " ps:setSizeVariation( %g )\n", info.fSizeVar ); // fSpinStart, fSpinEnd, fSpinVar printf( " ps:setSpin( %g, %g, %g )\n", info.fSpinStart, info.fSpinEnd, info.fSpinVar ); // colColorStart, colColorEnd printf( " ps:setColor( %d, %d, %d, %d, %d, %d, %d, %d )\n", (int)(info.colColorStart.r * 255), (int)(info.colColorStart.g * 255), (int)(info.colColorStart.b * 255), (int)(info.colColorStart.a * 255), (int)(info.colColorEnd.r * 255), (int)(info.colColorEnd.g * 255), (int)(info.colColorEnd.b * 255), (int)(info.colColorEnd.a * 255) ); // fColorVar printf( " -- ps:setColorVariation( %g )\n", info.fColorVar ); // fAlphaVar printf( " -- ps:setAlphaVariation( %g )\n", info.fAlphaVar ); printf( "\n" ); printf( " return ps\n" ); printf( "end\n" ); return 0; }
To compile with MinGW, just type "g++ -o psi2love psi2love.cpp" on the prompt.
The bRelative, fColorVar and fAlphaVar members of HGE's particle system structure don't have counterparts in LÖVE so I generate them in comments.
Just make sure to change the parameters to love.graphics.newParticleSystem in the generated function. I've tested with a couple of emitters created with HGE's particle editor and the results were satisfactory.
Have fun!