Shmup/src/starfieldshader.cpp

236 lines
6.9 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>
uint8_t AZRP_SHADER_STARFIELD = -1;
#define NBPARTS 100
struct particle
{
int x, y, s, c, frag, off;
};
struct star
{
int x, y, s, n, t;
};
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);
}
struct command {
uint8_t shader_id;
uint8_t current_frag;
uint8_t nbpixel;
particle *data;
};
#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
void azrp_starfield_init( uint8_t nbstars )
{
srand(rtc_ticks());
star temp;
for(int i=0; i<nbstars; i++)
{
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 );
}
particle ptemp;
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 = 0xFFFF;
col2 = 0XFFFF;
col3 = 0XFFFF;
}
if (s.n==2)
{
ptemp = { s.x, s.y, s.s, col2, s.y/16, s.y&15 }; pixels.push_back( ptemp );
ptemp = { s.x+1, s.y, s.s, col2, s.y/16, s.y&15 }; pixels.push_back( ptemp );
ptemp = { s.x, s.y+1, s.s, col2, (s.y+1)/16, (s.y+1)&15 }; pixels.push_back( ptemp );
ptemp = { 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 = { s.x, s.y, s.s, DARKSKY, s.y/16, s.y&15 }; pixels.push_back( ptemp );
ptemp = { s.x+1, s.y, s.s, col3, s.y/16, s.y&15 }; pixels.push_back( ptemp );
ptemp = { s.x+2, s.y, s.s, DARKSKY, s.y/16, s.y&15 }; pixels.push_back( ptemp );
ptemp = { s.x, s.y+1, s.s, col3, (s.y+1)/16, (s.y+1)&15 }; pixels.push_back( ptemp );
ptemp = { s.x+1, s.y+1, s.s, col2, (s.y+1)/16, (s.y+1)&15 }; pixels.push_back( ptemp );
ptemp = { s.x+2, s.y+1, s.s, col3, (s.y+1)/16, (s.y+1)&15 }; pixels.push_back( ptemp );
ptemp = { s.x, s.y+2, s.s, DARKSKY, (s.y+2)/16, (s.y+2)&15 }; pixels.push_back( ptemp );
ptemp = { s.x+1, s.y+2, s.s, col3, (s.y+2)/16, (s.y+2)&15 }; pixels.push_back( ptemp );
ptemp = { 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 = { s.x+1, s.y, s.s, col1, s.y/16, s.y&15 }; pixels.push_back( ptemp );
ptemp = { s.x+2, s.y, s.s, col1, s.y/16, s.y&15 }; pixels.push_back( ptemp );
ptemp = { s.x+3, s.y, s.s, col1, s.y/16, s.y&15 }; pixels.push_back( ptemp );
ptemp = { s.x, s.y+1, s.s, col1, (s.y+1)/16, (s.y+1)&15 }; pixels.push_back( ptemp );
ptemp = { s.x+1, s.y+1, s.s, col2, (s.y+1)/16, (s.y+1)&15 }; pixels.push_back( ptemp );
ptemp = { s.x+2, s.y+1, s.s, col2, (s.y+1)/16, (s.y+1)&15 }; pixels.push_back( ptemp );
ptemp = { s.x+3, s.y+1, s.s, col2, (s.y+1)/16, (s.y+1)&15 }; pixels.push_back( ptemp );
ptemp = { s.x+4, s.y+1, s.s, col1, (s.y+1)/16, (s.y+1)&15 }; pixels.push_back( ptemp );
ptemp = { s.x, s.y+2, s.s, col1, (s.y+2)/16, (s.y+2)&15 }; pixels.push_back( ptemp );
ptemp = { s.x+1, s.y+2, s.s, col2, (s.y+2)/16, (s.y+2)&15 }; pixels.push_back( ptemp );
ptemp = { s.x+2, s.y+2, s.s, col3, (s.y+2)/16, (s.y+2)&15 }; pixels.push_back( ptemp );
ptemp = { s.x+3, s.y+2, s.s, col2, (s.y+2)/16, (s.y+2)&15 }; pixels.push_back( ptemp );
ptemp = { s.x+4, s.y+2, s.s, col1, (s.y+2)/16, (s.y+2)&15 }; pixels.push_back( ptemp );
ptemp = { s.x, s.y+3, s.s, col1, (s.y+3)/16, (s.y+3)&15 }; pixels.push_back( ptemp );
ptemp = { s.x+1, s.y+3, s.s, col2, (s.y+3)/16, (s.y+3)&15 }; pixels.push_back( ptemp );
ptemp = { s.x+2, s.y+3, s.s, col2, (s.y+3)/16, (s.y+3)&15 }; pixels.push_back( ptemp );
ptemp = { s.x+3, s.y+3, s.s, col2, (s.y+3)/16, (s.y+3)&15 }; pixels.push_back( ptemp );
ptemp = { s.x+4, s.y+3, s.s, col1, (s.y+3)/16, (s.y+3)&15 }; pixels.push_back( ptemp );
ptemp = { s.x+1, s.y+4, s.s, col1, (s.y+4)/16, (s.y+4)&15 }; pixels.push_back( ptemp );
ptemp = { s.x+2, s.y+4, s.s, col1, (s.y+4)/16, (s.y+4)&15 }; pixels.push_back( ptemp );
ptemp = { s.x+3, s.y+4, s.s, col1, (s.y+4)/16, (s.y+4)&15 }; pixels.push_back( ptemp );
}
else
{
ptemp = { s.x, s.y, s.s, col3, s.y/16, s.y&15 }; pixels.push_back( ptemp );
}
}
starfield.clear();
}
void azrp_starfield_close( void )
{
pixels.clear();
starfield.clear();
}
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(int i=0; i<pixels.size(); i++)
{
pixels[i].y = (pixels[i].y + pixels[i].s) % 224;
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;
particle *data = cmd->data;
for(int i=0; i<cmd->nbpixel; i++)
if (cmd->current_frag == data[i].frag)
{
frag[azrp_width * data[i].off + data[i].x] = data[i].c;
}
cmd->current_frag++;
}