174 lines
4.8 KiB
C++
174 lines
4.8 KiB
C++
#include "effects.h"
|
|
|
|
#include <num/num.h>
|
|
#include "../utilities/fast_trig.h"
|
|
#include "../utilities/3Dtransform.h"
|
|
|
|
#include <cstring>
|
|
|
|
/********************************\
|
|
* MOPRHING EFFECT - MODULE 2 *
|
|
* Specific data and structures *
|
|
\********************************/
|
|
|
|
|
|
|
|
#define NB_POINTS 1024
|
|
#define SCALE 80
|
|
|
|
extern Vertex3D Sphere[NB_POINTS];
|
|
extern Vertex3D Torus[NB_POINTS];
|
|
extern Vertex3D Cylinder[NB_POINTS];
|
|
extern Vertex3D Morph[NB_POINTS];
|
|
|
|
extern libnum::num32 scale;
|
|
extern libnum::num32 eye;
|
|
extern libnum::num32 eyescale;
|
|
extern int centerx, centery;
|
|
|
|
static float anglef = 0.0;
|
|
static int angle = 0;
|
|
|
|
static double frame_counter = 0;
|
|
|
|
|
|
void morphfire_init( bopti_image_t *screen )
|
|
{
|
|
eye = libnum::num32( 250 );
|
|
scale = libnum::num32( SCALE );
|
|
eyescale = eye*scale;
|
|
|
|
centerx = (DWIDTH / 2);
|
|
centery = (MAXHEIGHT / 2);
|
|
|
|
// Create Sphere
|
|
for (int i = 0; i < NB_POINTS; i++)
|
|
{
|
|
int theta = rand() % 360;
|
|
int phi = rand() % 360 ;
|
|
Sphere[i].x = FastCosInt(phi) * FastSinInt(theta);
|
|
Sphere[i].y = FastSinInt(phi) * FastSinInt(theta);
|
|
Sphere[i].z = FastCosInt(theta);
|
|
}
|
|
|
|
// Create torus
|
|
for (int i = 0; i < NB_POINTS; i++)
|
|
{
|
|
int theta = rand() % 360;
|
|
int phi = rand() % 360 ;
|
|
Torus[i].x = (libnum::num32(0.8) + libnum::num32(0.4) * FastCosInt(theta)) * FastCosInt(phi);
|
|
Torus[i].y = (libnum::num32(0.8) + libnum::num32(0.4) * FastCosInt(theta)) * FastSinInt(phi);
|
|
Torus[i].z = libnum::num32(0.4) * FastSinInt(theta);
|
|
}
|
|
|
|
// Create cylinder
|
|
for (int i = 0; i < NB_POINTS; i++)
|
|
{
|
|
int theta = rand() % 360;
|
|
int height = rand() % 800;
|
|
Cylinder[i].x = libnum::num32(0.75) * FastCosInt(theta);
|
|
Cylinder[i].y = libnum::num32(0.75) * FastSinInt(theta);
|
|
Cylinder[i].z = libnum::num32( ((float) height - 400.0f) / 500.0f );
|
|
}
|
|
|
|
for(int u = 0; u<64; u++)
|
|
{
|
|
screen->palette[u] = C_RGB( 0, 0, 0 );
|
|
screen->palette[u+64] = C_RGB( 0, 0, u/2 );
|
|
screen->palette[u+128] = C_RGB( 0, u/2, 31 );
|
|
screen->palette[u+192] = C_RGB( u/2, 31, 31 );
|
|
}
|
|
|
|
image_fill( screen, -128 );
|
|
}
|
|
|
|
|
|
void morphfire_update( bopti_image_t *screen, [[Maybe_unused]] float dt )
|
|
{
|
|
anglef += dt / 10000.0;
|
|
angle = (int) anglef;
|
|
|
|
frame_counter += dt / 10000.0;
|
|
int frame = (int)frame_counter % 1536;
|
|
|
|
// Transform the torus into a sphere
|
|
if (frame >= 0 && frame < 256) {
|
|
int key = frame;
|
|
for (int i = 0; i < NB_POINTS; i++) {
|
|
Morph[i].x = (libnum::num32(key) * Sphere[i].x + libnum::num32(256 - key) * Torus[i].x) / libnum::num32(256);
|
|
Morph[i].y = (libnum::num32(key) * Sphere[i].y + libnum::num32(256 - key) * Torus[i].y) / libnum::num32(256);
|
|
Morph[i].z = (libnum::num32(key) * Sphere[i].z + libnum::num32(256 - key) * Torus[i].z) / libnum::num32(256);
|
|
}
|
|
}
|
|
|
|
// Transform the sphere into a torus
|
|
if (frame >= 512 && frame <768 ) {
|
|
int key = frame - 512;
|
|
for (int i = 0; i < NB_POINTS; i++) {
|
|
Morph[i].x = (libnum::num32(key) * Cylinder[i].x + libnum::num32(256 - key) * Sphere[i].x) / libnum::num32(256);
|
|
Morph[i].y = (libnum::num32(key) * Cylinder[i].y + libnum::num32(256 - key) * Sphere[i].y) / libnum::num32(256);
|
|
Morph[i].z = (libnum::num32(key) * Cylinder[i].z + libnum::num32(256 - key) * Sphere[i].z) / libnum::num32(256);
|
|
}
|
|
}
|
|
|
|
// Transform the sphere into a torus
|
|
if (frame >= 1024 && frame <1280 ) {
|
|
int key = frame - 1024;
|
|
for (int i = 0; i < NB_POINTS; i++) {
|
|
Morph[i].x = (libnum::num32(key) * Torus[i].x + libnum::num32(256 - key) * Cylinder[i].x) / libnum::num32(256);
|
|
Morph[i].y = (libnum::num32(key) * Torus[i].y + libnum::num32(256 - key) * Cylinder[i].y) / libnum::num32(256);
|
|
Morph[i].z = (libnum::num32(key) * Torus[i].z + libnum::num32(256 - key) * Cylinder[i].z) / libnum::num32(256);
|
|
}
|
|
}
|
|
|
|
// Rotate the vertex in world coordinates and then project them on screen
|
|
for (int i = 0; i < NB_POINTS; i++)
|
|
{
|
|
RotateVertex(&Morph[i], 0, angle, angle);
|
|
ProjectVertex(&Morph[i]);
|
|
}
|
|
}
|
|
|
|
void pixel( bopti_image_t *screen, uint16_t sx, uint16_t sy, int8_t color )
|
|
{
|
|
if (sx<0 || sx>DWIDTH || sy<0 || sy> MAXHEIGHT ) return;
|
|
|
|
int8_t *image = (int8_t *)screen->data;
|
|
|
|
image[ sx + sy * screen->stride ] = color;
|
|
}
|
|
|
|
|
|
void morphfire_render( bopti_image_t *screen )
|
|
{
|
|
//image_fill( screen, -128 );
|
|
|
|
int8_t *image = (int8_t *)screen->data;
|
|
|
|
for (int i = 0; i < NB_POINTS; i++)
|
|
{
|
|
pixel( screen, Morph[i].sx-1, Morph[i].sy, 127 );
|
|
pixel( screen, Morph[i].sx, Morph[i].sy, 127 );
|
|
pixel( screen, Morph[i].sx+1, Morph[i].sy, 127 );
|
|
pixel( screen, Morph[i].sx, Morph[i].sy-1, 127 );
|
|
pixel( screen, Morph[i].sx, Morph[i].sy+1, 127 );
|
|
}
|
|
|
|
Blur( screen );
|
|
Blur( screen );
|
|
|
|
dimage( 0, 0, screen );
|
|
}
|
|
|
|
void morphfire_deinit( bopti_image_t *screen )
|
|
{
|
|
|
|
}
|
|
|
|
|
|
char morphfire_TextToRender[100] = "Morphing & Blur > _\0";
|
|
|
|
char *morphfire_text( void )
|
|
{
|
|
return morphfire_TextToRender;
|
|
} |