Shmup/src/starfieldshader.cpp

312 lines
9.4 KiB
C++

#include <azur/gint/render.h>
#include "MyAzurShaders.h"
#include <cstdlib>
#include <cstdio>
#include <gint/rtc.h>
#include <gint/usb.h>
#include <gint/usb-ff-bulk.h>
#include <vector>
#define DARKSKY 0x2106
#define BLUE1 0x39EE
#define BLUE2 0x3310
#define BLUE3 0x64DF
#define PINK1 0x4147
#define PINK2 0x7211
#define PINK3 0xD3D7
#define GREEN1 0x31E7
#define GREEN2 0x4245
#define GREEN3 0x34AD
#define ORANGE1 0x61C6
#define ORANGE2 0x8AA7
#define ORANGE3 0xDB83
#define WHITE1 0x31A6
#define WHITE2 0x9CD3
#define WHITE3 0xFFFF
uint8_t AZRP_SHADER_STARFIELD = -1;
struct particle
{
int x, y, s, c, frag, off;
particle( int _x, int _y, int _s, int _c, int _f, int _o ) : x(_x), y(_y), s(_s), c(_c), frag(_f), off(_o) {};
};
struct star
{
int x, y, s, n, t;
star( int _x, int _y, int _s, int _n, int _t ) : x(_x), y(_y), s(_s), n(_n), t(_t) {};
star() {};
};
std::vector<particle*> pixels;
std::vector<star*> starfield;
__attribute__((constructor))
static void register_shader(void)
{
extern azrp_shader_t azrp_shader_starfield;
AZRP_SHADER_STARFIELD = azrp_register_shader(azrp_shader_starfield);
}
void azrp_shader_starfield_configure(void)
{
azrp_set_uniforms(AZRP_SHADER_STARFIELD, (void *)azrp_width);
}
void azrp_starfield_USBDEBUG( uint8_t info )
{
char texttosend[1024];
int nbpixelcumulated = 0;
if (info==SHOW_PIXELS)
for(unsigned int i=0; i<pixels.size(); i++)
{
sprintf( texttosend, "Pixel %d : x=%d : y=%d : s=%d : f=%d : c=%d : o=%d\n", i, pixels[i]->x, pixels[i]->y, pixels[i]->s, pixels[i]->frag, pixels[i]->c, pixels[i]->off );
usb_fxlink_text(texttosend, 0);
}
else if (info==SHOW_STARS)
for(unsigned int i=0; i<starfield.size(); i++)
{
if (starfield[i]->n==1 || starfield[i]->n==2) nbpixelcumulated+=4;
else if (starfield[i]->n==3) nbpixelcumulated+=9;
else if (starfield[i]->n==4) nbpixelcumulated+=21;
sprintf( texttosend, "Star %d : x=%d : y=%d : s=%d : n=%d : t=%d : cumul=%d\n", i, starfield[i]->x, starfield[i]->y, starfield[i]->s, starfield[i]->n, starfield[i]->t, nbpixelcumulated );
usb_fxlink_text(texttosend, 0);
}
}
void azrp_starfield_init( uint8_t nbstars )
{
for(auto&s : starfield)
delete(s);
starfield.clear();
srand(rtc_ticks());
for(int i=0; i<nbstars; i++)
{
star *temp = new star();
temp->x = rand( ) % 394;
temp->y = rand( ) % 222;
temp->s = 1 + rand( ) % 3; // 1,2,3 : speed of the star
temp->n = 1 + rand( ) % 4; // 1,2,3,4 : size of the star
temp->t = 1 + rand( ) % 12; // 1..12 : colorcode of the star
starfield.push_back( temp );
}
for(auto& s : starfield)
{
uint16_t col1, col2, col3;
if (s->t==1 || s->t==2)
{
col1 = BLUE1;
col2 = BLUE2;
col3 = BLUE3;
}
else if (s->t==3 || s->t==4)
{
col1 = PINK1;
col2 = PINK2;
col3 = PINK3;
}
else if (s->t==5 || s->t==6)
{
col1 = GREEN1;
col2 = GREEN2;
col3 = GREEN3;
}
else if (s->t==7 || s->t==8)
{
col1 = ORANGE1;
col2 = ORANGE2;
col3 = ORANGE3;
}
else
{
col1 = WHITE1;
col2 = WHITE2;
col3 = WHITE3;
}
particle *ptemp;
if (s->n==1 || s->n==2)
{
ptemp = new particle( s->x, s->y, s->s, col2, s->y/16, s->y&15 );
pixels.push_back( ptemp );
ptemp = new particle( s->x+1, s->y, s->s, col2, s->y/16, s->y&15 );
pixels.push_back( ptemp );
ptemp = new particle( s->x, s->y+1, s->s, col2, (s->y+1)/16, (s->y+1)&15 );
pixels.push_back( ptemp );
ptemp = new particle( s->x+1, s->y+1, s->s, col2, (s->y+1)/16, (s->y+1)&15 );
pixels.push_back( ptemp );
}
else if (s->n==3)
{
ptemp = new particle( s->x, s->y, s->s, DARKSKY, s->y/16, s->y&15 );
pixels.push_back( ptemp );
ptemp = new particle( s->x+1, s->y, s->s, col3, s->y/16, s->y&15 );
pixels.push_back( ptemp );
ptemp = new particle( s->x+2, s->y, s->s, DARKSKY, s->y/16, s->y&15 );
pixels.push_back( ptemp );
ptemp = new particle( s->x, s->y+1, s->s, col3, (s->y+1)/16, (s->y+1)&15 );
pixels.push_back( ptemp );
ptemp = new particle( s->x+1, s->y+1, s->s, col2, (s->y+1)/16, (s->y+1)&15 );
pixels.push_back( ptemp );
ptemp = new particle( s->x+2, s->y+1, s->s, col3, (s->y+1)/16, (s->y+1)&15 );
pixels.push_back( ptemp );
ptemp = new particle( s->x, s->y+2, s->s, DARKSKY, (s->y+2)/16, (s->y+2)&15 );
pixels.push_back( ptemp );
ptemp = new particle( s->x+1, s->y+2, s->s, col3, (s->y+2)/16, (s->y+2)&15 );
pixels.push_back( ptemp );
ptemp = new particle( s->x+2, s->y+2, s->s, DARKSKY, (s->y+2)/16, (s->y+2)&15 );
pixels.push_back( ptemp );
}
else if (s->n==4)
{
ptemp = new particle( s->x+1, s->y, s->s, col1, s->y/16, s->y&15 );
pixels.push_back( ptemp );
ptemp = new particle( s->x+2, s->y, s->s, col1, s->y/16, s->y&15 );
pixels.push_back( ptemp );
ptemp = new particle( s->x+3, s->y, s->s, col1, s->y/16, s->y&15 );
pixels.push_back( ptemp );
ptemp = new particle( s->x, s->y+1, s->s, col1, (s->y+1)/16, (s->y+1)&15 );
pixels.push_back( ptemp );
ptemp = new particle( s->x+1, s->y+1, s->s, col2, (s->y+1)/16, (s->y+1)&15 );
pixels.push_back( ptemp );
ptemp = new particle( s->x+2, s->y+1, s->s, col2, (s->y+1)/16, (s->y+1)&15 );
pixels.push_back( ptemp );
ptemp = new particle( s->x+3, s->y+1, s->s, col2, (s->y+1)/16, (s->y+1)&15 );
pixels.push_back( ptemp );
ptemp = new particle( s->x+4, s->y+1, s->s, col1, (s->y+1)/16, (s->y+1)&15 );
pixels.push_back( ptemp );
ptemp = new particle( s->x, s->y+2, s->s, col1, (s->y+2)/16, (s->y+2)&15 );
pixels.push_back( ptemp );
ptemp = new particle( s->x+1, s->y+2, s->s, col2, (s->y+2)/16, (s->y+2)&15 );
pixels.push_back( ptemp );
ptemp = new particle( s->x+2, s->y+2, s->s, col3, (s->y+2)/16, (s->y+2)&15 );
pixels.push_back( ptemp );
ptemp = new particle( s->x+3, s->y+2, s->s, col2, (s->y+2)/16, (s->y+2)&15 );
pixels.push_back( ptemp );
ptemp = new particle( s->x+4, s->y+2, s->s, col1, (s->y+2)/16, (s->y+2)&15 );
pixels.push_back( ptemp );
ptemp = new particle( s->x, s->y+3, s->s, col1, (s->y+3)/16, (s->y+3)&15 );
pixels.push_back( ptemp );
ptemp = new particle( s->x+1, s->y+3, s->s, col2, (s->y+3)/16, (s->y+3)&15 );
pixels.push_back( ptemp );
ptemp = new particle( s->x+2, s->y+3, s->s, col2, (s->y+3)/16, (s->y+3)&15 );
pixels.push_back( ptemp );
ptemp = new particle( s->x+3, s->y+3, s->s, col2, (s->y+3)/16, (s->y+3)&15 );
pixels.push_back( ptemp );
ptemp = new particle( s->x+4, s->y+3, s->s, col1, (s->y+3)/16, (s->y+3)&15 );
pixels.push_back( ptemp );
ptemp = new particle( s->x+1, s->y+4, s->s, col1, (s->y+4)/16, (s->y+4)&15 );
pixels.push_back( ptemp );
ptemp = new particle( s->x+2, s->y+4, s->s, col1, (s->y+4)/16, (s->y+4)&15 );
pixels.push_back( ptemp );
ptemp = new particle( s->x+3, s->y+4, s->s, col1, (s->y+4)/16, (s->y+4)&15 );
pixels.push_back( ptemp );
}
// else
// {
// ptemp = new particle( s->x, s->y, s->s, col3, s->y/16, s->y&15 );
// pixels.push_back( ptemp );
// }
}
}
void azrp_starfield_close( void )
{
for(auto&p : pixels)
delete(p);
pixels.clear();
for(auto&s : starfield)
delete(s);
starfield.clear();
}
struct command {
uint8_t shader_id;
uint8_t current_frag;
uint8_t nbpixel;
particle **data;
};
void azrp_starfield( void )
{
prof_enter(azrp_perf_cmdgen);
struct command cmd;
cmd.shader_id = AZRP_SHADER_STARFIELD;
cmd.current_frag = 0;
cmd.nbpixel = pixels.size();
cmd.data = pixels.data();
for(unsigned int i=0; i<pixels.size(); i++)
{
pixels[i]->x = (pixels[i]->x - pixels[i]->s) % 396;
pixels[i]->frag = pixels[i]->y / 16;
pixels[i]->off = pixels[i]->y & 15;
}
int fragmin = 0;
int fragcount = (223 >> 4) + 1;
azrp_queue_command(&cmd, sizeof cmd, fragmin, fragcount);
prof_leave(azrp_perf_cmdgen);
}
void azrp_shader_starfield( void *uniforms, void *comnd, void *fragment )
{
struct command *cmd = (struct command *) comnd;
uint16_t *frag = (uint16_t *) fragment;
for(int i=0; i<cmd->nbpixel; i++)
{
particle *currentpart = cmd->data[i];
if (cmd->current_frag == currentpart->frag)
{
frag[azrp_width * currentpart->off + currentpart->x] = currentpart->c;
}
}
cmd->current_frag++;
}