ScreenSaver/src/effects/firecube.cpp

175 lines
4.2 KiB
C++

#include "effects.h"
#include <num/num.h>
#include "../utilities/fast_trig.h"
#include "../utilities/3Dtransform.h"
#include "../utilities/utilities.h"
#include <cstring>
typedef struct
{
uint8_t p1;
uint8_t p2;
} Pairs;
#define NB_POINT_CUBE 8
#define NB_LINES_CUBE 12
Pairs Lines[NB_LINES_CUBE]= {{0,1},{1,2},{2,3},{3,0},
{4,5},{5,6},{6,7},{7,4},
{0,4},{1,5},{2,6},{3,7}};
Vertex3D Cube[NB_POINT_CUBE];
#define SCALE 80
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;
void firecube_init( bopti_image_t *screen )
{
eye = libnum::num32( 250 );
scale = libnum::num32( SCALE );
eyescale = eye*scale;
centerx = (DWIDTH / 2);
centery = (MAXHEIGHT / 2);
Cube[0].x=libnum::num32(-0.75); Cube[0].y=libnum::num32(-0.75); Cube[0].z=libnum::num32(-0.75);
Cube[1].x=libnum::num32(0.75); Cube[1].y=libnum::num32(-0.75); Cube[1].z=libnum::num32(-0.75);
Cube[2].x=libnum::num32(0.75); Cube[2].y=libnum::num32(0.75); Cube[2].z=libnum::num32(-0.75);
Cube[3].x=libnum::num32(-0.75); Cube[3].y=libnum::num32(0.75); Cube[3].z=libnum::num32(-0.75);
Cube[4].x=libnum::num32(-0.75); Cube[4].y=libnum::num32(-0.75); Cube[4].z=libnum::num32(0.75);
Cube[5].x=libnum::num32(0.75); Cube[5].y=libnum::num32(-0.75); Cube[5].z=libnum::num32(0.75);
Cube[6].x=libnum::num32(0.75); Cube[6].y=libnum::num32(0.75); Cube[6].z=libnum::num32(0.75);
Cube[7].x=libnum::num32(-0.75); Cube[7].y=libnum::num32(0.75); Cube[7].z=libnum::num32(0.75);
for(int u = 0; u<64; u++)
{
screen->palette[u] = C_RGB( 0, 0, 0 );
screen->palette[u+64] = C_RGB( u/2, 0, 0 );
screen->palette[u+128] = C_RGB( 31, u/2, 0 );
screen->palette[u+192] = C_RGB( 31, 31, u/2 );
}
image_fill( screen, -128 );
}
void firecube_update( bopti_image_t *screen, [[Maybe_unused]] float dt )
{
anglef += dt / 10000.0;
angle = (int) anglef;
for (int i = 0; i < NB_POINT_CUBE; i++)
{
RotateVertex(&Cube[i], 0, angle, angle);
ProjectVertex(&Cube[i]);
}
}
void drawline(bopti_image_t *screen, int x1, int y1, int x2, int y2, uint8_t color)
{
uint8_t *dest = (uint8_t *)screen->data;
/* Brensenham line drawing algorithm */
int i;
int x = x1;
int y = y1;
int cumul;
int dx = x2 - x1;
int dy = y2 - y1;
int sx = SGN(dx);
int sy = SGN(dy);
dx = (dx >= 0 ? dx : -dx);
dy = (dy >= 0 ? dy : -dy);
pixel(screen, x1, y1, color);
if(dx >= dy)
{
/* Start with a non-zero cumul to even the overdue between the
two ends of the line (for more regularity) */
cumul = dx >> 1;
for(i = 1; i < dx; i++)
{
x += sx;
cumul += dy;
if(cumul > dx) cumul -= dx, y += sy;
pixel(screen, x, y, color);
}
}
else
{
cumul = dy >> 1;
for(i = 1; i < dy; i++)
{
y += sy;
cumul += dx;
if(cumul > dy) cumul -= dy, x += sx;
pixel(screen, x, y, color);
}
}
pixel(screen, x2, y2, color);
}
void Blur( bopti_image_t *screen )
{
int8_t *dest = (int8_t *)screen->data;
int16_t temp;
uint32_t offset = (MAXHEIGHT - 1 ) * screen->stride; // pixel(x,y)
for( int index = 0; index < MAXHEIGHT-1; index++ )
{
for( int x = 1; x < screen->width - 1; x++ )
{
temp = dest[ offset + x - 1 ] + // pixel(x-1,y+1)
dest[ offset + x ] + // pixel(x,y+1)
dest[ offset + x + 1 ] + // pixel(x+1,y+1)
dest[ offset + x - screen->stride ]; // pixel(x,y+2)
dest[offset + x - screen->stride] = temp >> 2;
}
offset -= screen->stride;
}
}
void firecube_render( bopti_image_t *screen )
{
for (int j = 0; j < NB_LINES_CUBE; j++)
drawline( screen, Cube[ Lines[j].p1 ].sx, Cube[ Lines[j].p1 ].sy, Cube[ Lines[j].p2 ].sx, Cube[ Lines[j].p2 ].sy, 127 );
Blur( screen );
dimage( 0, 0, screen );
}
void firecube_deinit( bopti_image_t *screen )
{
}
char firecube_TextToRender[100] = "Mesmerizing Rotating & Burning Cube > _\0";
char *firecube_text( void )
{
return firecube_TextToRender;
}