ScreenSaver/src/effects/plasma.cpp

86 lines
2.0 KiB
C++

#include "effects.h"
#include <cstring>
#include <cmath>
/********************************\
* PLASMA EFFECT - MODULE 1 *
* Specific data and structures *
\********************************/
static int aSin[512];
uint8_t index;
static uint16_t pos1 = 0, pos2 = 0, pos3 = 0, pos4 = 0, tpos1, tpos2, tpos3, tpos4;
uint16_t x;
void plasma_init( bopti_image_t *screen )
{
uint16_t palette[256];
size_t palette_size = 512;
for(int i=0; i<64; ++i)
{
palette[i] = C_RGB( i<<2, 255 - ((i << 2) + 1), 0 );
palette[i+64] = C_RGB( 255, (i << 2) + 1, 0 );
palette[i+128] = C_RGB( 255 - ((i << 2) + 1), 255 - ((i << 2) + 1), 0 );
palette[i+192] = C_RGB( 0, (i << 2) + 1, 0 );
}
memcpy(screen->palette, palette, palette_size);
for (int i = 0; i < 512; i++)
{
float rad = ((float)i * 0.703125) * 0.0174532; /* 360 / 512 * degree to rad, 360 degrees spread over 512 values to be able to use AND 512-1 instead of using modulo 360*/
aSin[i] = sin(rad) * 1024; /*using fixed point math with 1024 as base*/
}
}
void plasma_update( bopti_image_t *screen, [[Maybe_unused]] float dt )
{
uint8_t *image = (uint8_t *) screen->data;
tpos4 = pos4;
tpos3 = pos3;
for (int i = 0; i < MAXHEIGHT; ++i)
{
tpos1 = pos1 + 5;
tpos2 = pos2 + 3;
tpos3 &= 511;
tpos4 &= 511;
for (int j = 0; j < DWIDTH; ++j)
{
tpos1 &= 511;
tpos2 &= 511;
x = aSin[tpos1] + aSin[tpos2] + aSin[tpos3] + aSin[tpos4]; /*actual plasma calculation*/
index = 128 + (x >> 4); /*fixed point multiplication but optimized so basically it says (x * (64 * 1024) / (1024 * 1024)), x is already multiplied by 1024*/
*image++ = index;
tpos1 += 5;
tpos2 += 3;
}
tpos4 += 3;
tpos3 += 1;
}
pos1 +=9;
pos3 +=8;
}
void plasma_render( bopti_image_t *screen )
{
dimage(0,0,screen);
}
void plasma_deinit( bopti_image_t *screen )
{
}