F5OEO-rpidatv/src/gui/tcanim.c

459 wiersze
8.3 KiB
C

#define VERSION "tcanim1v16"
// particles.c - Simple particles example using the OpenVG Testbed
// via Nick Williams (github.com/nilliams)
// https://gist.githubusercontent.com/nilliams/7705819/raw/9cbb5a1298d6eef858639095148ede2c33cb6d40/particles.c
//
// Modified by Brian Jordan, G4EWJ, 2016
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <time.h>
#include <sys/time.h>
#include "VG/openvg.h"
#include "VG/vgu.h"
#include "shapes.h"
#include <dirent.h>
#include <fnmatch.h>
#include <libgen.h>
#define NUM_PARTICLES 100
#define CYCLEFIELDS 0
int angle ;
int np ;
int changes ;
struct timeval now ;
int cycles ;
int activecount ;
int xoffset ;
int yoffset ;
char balloontext [6] ;
char filename [1024] ;
char filename2 [1024] ;
char dir [1024] ;
char base [1024] ;
int frames ;
int banneractive ;
int bannertoggle ;
int balloonsactive ;
char bannertext [65005] ;
int counter1, counter2 ;
int w, h ;
#define MAXNAMES 1000
VGImage save [MAXNAMES] ;
struct dirent **namelist ;
int namecount ;
int nameindex ;
int nameseconds ;
int namefields ;
typedef struct particle
{
int active ;
double x, y;
double vx, vy;
int r, g, b;
double radius;
int cycles ;
} particle_t;
particle_t particles[NUM_PARTICLES];
int showTrails = 0;
int directionRTL = 1 ;
int alternate = 1;
double gravity = 0.4 ;
int scan (void) ;
int filter (const struct dirent *) ;
// Initialize _all_ the particles
void initParticles(int w, int h) {
int i;
for (i = 0; i < NUM_PARTICLES; i++)
{
particle_t *p = &particles[i];
p->active = 0 ;
p->x = 0;
p->y = 0;
p->vx = (rand() % 10) + 11;
p->vy = (rand() % 17) + 20 ;
p->vy = 1 ;
// p->vx /= 2 ;
// p->vy /= 2 ;
p->r = rand() % 256;
p->g = rand() % 256;
p->b = rand() % 256;
p->radius = (rand() % 40) + 80;
if (directionRTL)
{
p->vx *= -1;
p->x = w;
}
p->cycles = 1 ;
}
}
void draw(int w, int h) {
int i;
particle_t *p;
double fontsize ;
double tempf ;
int temp ;
vgSetPixels (0,0,save[nameindex],0,0,w,h) ;
activecount = 0 ;
for (i = 0; i < NUM_PARTICLES ; i++)
{
p = &particles[i];
if (p->active)
{
activecount++ ;
Fill(p->r, p->g, p->b, 1.0);
Circle(p->x, p->y, p->radius);
tempf = 0.299 * (float)p->r + 0.587 * (float)p->g + 0.114 * (float)p->b ;
if (tempf >= 128)
{
Fill (0,0,0,1) ;
}
else
{
Fill (255,255,255,1) ;
}
fontsize = (14+2*strlen(balloontext)) * p->radius / TextWidth(balloontext,SansTypeface,25) ;
TextMid (p->x,p->y-fontsize/2,balloontext,SansTypeface,fontsize) ;
// Apply the velocity
p->x += p->vx / 4 ;
p->y += p->vy / 4 ;
// p->vx *= 0.98;
// if (p->vy > 0) p->vy *= 0.97;
// Gravity
p->vy -= gravity / 1.25 ;
// Stop particles leaving the canvas
if (p->x < -50) p->x = w + 50;
if (p->x > w + 50) p->x = -50;
// When particle reaches the bottom of screen reset velocity & start posn
if (p->y < -50)
{
p->cycles++ ;
p->x = 0;
p->y = 0;
p->vx = (rand() % 20) + 10;
p->vy = (rand() % 15) + 25;
if (directionRTL) {
p->vx *= -1;
p->x = w;
}
rand() ;
p->r = rand() % 256;
p->g = rand() % 256;
p->b = rand() % 256;
p->radius = (rand() % 35) + 35 ;
if (CYCLEFIELDS && cycles >= CYCLEFIELDS && banneractive == 2)
{
p->active = 0 ;
}
}
if (p->y > h + 50) p->y = -50;
}
}
if (banneractive == 1)
{
Fill (0,0,0,1) ;
Rect (0,0,720,54) ;
if (bannertoggle & 1)
{
Fill (128,0,192,1) ;
}
else
{
Fill (128,0,192,1) ;
}
Rect (0,20,720,34) ;
Fill (255,255,255,1) ;
Text (w-frames*2,28,bannertext,SansTypeface,19) ;
frames+=20 ;
temp = TextWidth (bannertext,SansTypeface,19) ;
if (temp - frames * 2 < -720)
{
frames = 0 ;
bannertoggle++ ;
if (CYCLEFIELDS && cycles >= CYCLEFIELDS)
{
banneractive = 2 ;
}
}
}
}
void makeImage ()
{
for (nameindex = 0 ; nameindex < namecount ; nameindex++)
{
Start(w, h);
save [nameindex] = vgCreateImage (VG_lRGBX_8888,w,h,VG_IMAGE_QUALITY_NONANTIALIASED) ;
Fill (0,0,0,1);
Rect (0, 0, w, h);
sprintf (filename2,"%s/%s",dir,namelist[nameindex]->d_name) ;
Image (xoffset,yoffset,720-xoffset,576-yoffset,filename2) ;
vgFinish() ;
vgGetPixels (save[nameindex],0,0,0,0,w,h) ;
// End() ;
// SaveEnd ("png.png") ;
}
}
// Display Options
// -t show trails
// -g[value] gravity
//
// Direction (alternates by default)
// -r right-to-left
// -l left-to-right
int main(int argc, char **argv)
{
int i ;
int x ;
int temp ;
int errors ;
char *p ;
counter1 = 0 ; counter2 = 0 ;
errors = 0 ;
if (argc != 6)
{
errors++ ;
}
else
{
strncpy (filename,argv[1],sizeof(filename)-5) ;
p = strchr (filename,'*') ;
if (p)
{
nameseconds = atoi (p+1) ;
if (nameseconds == 0)
{
nameseconds = 1 ;
}
*p = 0 ;
p = strstr (filename,".jpg") ;
if (p)
{
*p = 0 ;
}
strcat (filename,"*.jpg") ;
}
p = strstr (filename,".jpg") ;
if (p == 0)
{
strcat (filename,".jpg") ;
}
strcpy (dir,filename) ;
strcpy (dir,dirname(dir)) ;
strcpy (base,filename) ;
strcpy (base,basename(base)) ;
namecount = scan() ;
if (namecount <= 0)
{
printf ("Cannot find %s\n\n",filename) ;
exit (3) ;
}
if (namecount > MAXNAMES)
{
namecount = MAXNAMES ;
}
xoffset = atoi (argv[2]) ;
if (abs(xoffset) > 720)
{
errors++ ;
}
yoffset = atoi (argv[3]) ;
if (abs(yoffset) > 576)
{
errors++ ;
}
strncpy (balloontext,argv[4],sizeof(balloontext)-1) ;
strncpy (bannertext,argv[5],sizeof(bannertext)-5) ;
if (strlen(bannertext))
{
strcat (bannertext," ") ;
}
}
printf ("\n") ;
if (errors)
{
printf ("Usage: %s \"FILENAME(S)\" XOFFSET YOFFSET \"BALLOONTEXT\" \"BANNERTEXT\" \n",VERSION) ;
printf (" +/-720 +/-576 Max 5 Max 65000 \n") ;
printf ("FILENAME(S) may be a single file or FILENAMES*n - it is not necessary to specify the .jpg extension\n") ;
printf ("FILENAMES*n displays all files that start with FILENAMES in alpha order changing every n seconds\n") ;
printf ("FILENAME(S) should be enclosed in double quotes\n") ;
printf ("\n") ;
exit (2) ;
}
printf ("\n%s: Test Card Animator\n",VERSION) ;
if (namecount > 0)
{
printf ("Using image files in this order: \n") ;
for (nameindex = 0 ; nameindex < namecount ; nameindex++)
{
printf ("%s/%s\n",dir,namelist[nameindex]->d_name) ;
}
}
printf ("\n") ;
init (&w, &h);
//w = 720 ; h = 576 ;
makeImage() ;
Start (w,h) ;
vgSetPixels (0,0,save[0],0,0,w,h) ;
End() ;
namefields = 0 ;
nameindex = 0 ;
while (1)
{
counter1++ ;
memset (particles,0,sizeof(particles)) ;
frames = 0 ;
cycles = 0 ;
changes = 0 ;
angle = 0 ;
directionRTL = 1 ;
alternate = 1 ;
if (strlen(balloontext) > 0 )
{
np = 7 ;
}
else
{
np = 0 ;
}
srand(time(NULL));
initParticles(w, h);
for (x = 0 ; x < np ; x++)
{
particles[x].active = 1 ;
}
usleep (1000000) ;
if (strlen(bannertext) > 0)
{
banneractive = 0 ;
}
else
{
banneractive = 2 ;
}
balloonsactive = 0 ;
while (1)
{
Start (w, h);
counter2++ ;
draw(w, h);
End() ;
usleep(400000);
cycles++ ;
namefields++ ;
if (namefields >= nameseconds * 5)
{
nameindex++ ;
namefields = 0 ;
}
if (nameindex >= namecount)
{
nameindex = 0 ;
}
if (activecount == 0 && CYCLEFIELDS && cycles >= CYCLEFIELDS && frames == 0)
{
banneractive = 2 ;
Start (w, h);
counter2++ ;
draw(w, h);
End() ;
break ;
}
temp = 1 ;
for (x = 0 ; x < np ; x++)
{
temp &= particles[x].cycles ;
}
if (temp && banneractive == 0 && strlen(bannertext))
{
frames = 0 ;
banneractive = 1 ;
}
gettimeofday (&now,0) ;
x = now.tv_sec * 1000 + now.tv_usec / 1000 ;
// Change launch direction every 25 draws
i++;
if (alternate && i == 25)
{
changes++ ;
directionRTL = directionRTL ? 0 : 1;
i = 0;
}
}
// finish() ;
}
}
int filter (const struct dirent *sdx)
{
if (fnmatch(base,sdx->d_name,0)==0)
{
return (1) ;
}
else
{
return (0) ;
}
}
int scan()
{
int n ;
n = scandir(dir, &namelist, filter, alphasort) ;
if (n < 0)
{
// perror("scandir") ;
}
return (n) ;
}