Difference between revisions of "psi2love"

(Created page with "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. <source lang="cpp"> // This code was...")
 
m (Added missing properties for the category page, also this isn't really a Löve-related snippet; (it'd be like me sharing my scream tracker module loader code (in lua even) because löve can be used as a module player.))
 
(3 intermediate revisions by 2 users not shown)
Line 2: Line 2:
  
 
<source lang="cpp">
 
<source lang="cpp">
// This code was written by Andre Leiradella and is in the public domain.
 
 
 
#include <stdio.h>
 
#include <stdio.h>
 
#include <stdint.h>
 
#include <stdint.h>
Line 56: Line 54:
 
int main( int argc, const char* argv[] )
 
int main( int argc, const char* argv[] )
 
{
 
{
if ( argc != 2 )
+
if ( argc != 5 )
 
{
 
{
fprintf( stderr, "USAGE: psi2love filename.psi\n" );
+
fprintf( stderr, "USAGE: psi2love filename.psi func_name image_name max_particles\n" );
 
return 1;
 
return 1;
 
}
 
}
Line 80: Line 78:
 
fclose( psi );
 
fclose( psi );
 
 
printf( "local function newParticleSystem()\n" );
+
printf( "local function %s()\n", argv[ 2 ] );
 
printf( "  -- created from %s\n", argv[ 1 ] );
 
printf( "  -- created from %s\n", argv[ 1 ] );
 
printf( "\n" );
 
printf( "\n" );
printf( "  -- make sure to change the line below to the correct image and maximum number of particles\n" );
+
printf( "  local ps = love.graphics.newParticleSystem( %s, %s )\n", argv[ 3 ], argv[ 4 ] );
printf( "  local ps = love.graphics.newParticleSystem( image, 128 )\n" );
 
 
printf( "\n" );
 
printf( "\n" );
 
 
Line 118: Line 115:
 
 
 
// fSizeStart, fSizeEnd, fSizeVar
 
// fSizeStart, fSizeEnd, fSizeVar
printf( "  ps:setSize( %g, %g, %g )\n", info.fSizeStart, info.fSizeEnd, info.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
 
// fSpinStart, fSpinEnd, fSpinVar
Line 148: Line 146:
 
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.
 
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.
+
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!
 
Have fun!
 
[[Category:Snippets]]
 
[[Category:Snippets]]
 +
{{#set:LOVE Version=any}}
 +
{{#set:Description=C++ program taking a HGE psi file and converting it to Lua source code to create an equivalent particle system in LÖVE.}}

Latest revision as of 00:38, 12 November 2016

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!