/*
	Name:         make-ilda.c
	Author:       cLx - http://clx.freeshell.org/
	Description:  Routine to generate ILDA frames to a open FILE descriptor.
	Demo:         http://www.youtube.com/watch?v=Jmyr0XvRwfA (the firsts 30 seconds)
	Date:         2009-08-09
	Copyright:    CC-BY-NC-SA 3.0
*/

typedef struct {
    signed int x; signed int y; int blanking; unsigned int color;
} t_point;

int make_ilda_frame(FILE *fp, char *nomframe, unsigned int nbframes, unsigned int nbpoints, t_point point[]){
    unsigned int i, lastpoint;
    signed int a;
    unsigned int s;
    char nomframe2[8]={0,0,0,0,0,0,0,0};

    // Signature (1 to 4)
    fwrite("ILDA", 1, 4, fp); // 1 to 4

    // Not used (5 to 7)
    fputc(0, fp);
    fputc(0, fp);
    fputc(0, fp);

    // Format type (8) :
    fputc(1, fp); //0=3D ; 1=2D ; 2=palette

    // Name (9 to 16)
    for (i=0; i<sizeof(nomframe)&&i<7; i++){
        if (nomframe[i]){
            nomframe2[i]=nomframe[i];
        }
        else {
            break;
        }
    }
    fwrite(nomframe2, 1, 8, fp);

    // Company name (17 to 24)
    fwrite("cLxMkFrm", 1, 8, fp);

    // Total number of entries in data section (25 to 26)
    // (number of points/numbers of palette's entry)
    fputc(nbpoints/256, fp);
    fputc(nbpoints%256, fp);

    // Current frame number (27 to 28)
    // (from 0 to N-1)
    fputc(0, fp);
    fputc(0, fp);

    // Total number of frames (29 to 30)
    // (could be 0 to indicate the end of the ILDA file)
    fputc(nbframes/256, fp);
    fputc(nbframes%256, fp);

    // Scanner head (31)
    // (0 for default device)
    fputc(0, fp);

    // Not used (32)
    fputc(0, fp);

    // END OF HEADER, NOW COMES THE DATA !

    lastpoint = 0;
    for (i=0; i<nbpoints; i++){
        //x (signed 16 bits big indian) (bit de signe au debut)
        a = point[i].x;
        if (a > 32767) { a = 32737; }
        else if (a < -32768) { a = -32768; }
        s = 0x00; if (a < 0) { s = 0x80; }
        fputc((((a>>8)&0x7F))|s, fp);
        fputc(a%256, fp);

        //y (signed 16 bits big indian) (bit de signe au debut)
        a = point[i].y;
        if (a > 32767) { a = 32737; }
        else if (a < -32768) { a = -32768; }
        s = 0x00; if (a < 0) { s = 0x80; }
        fputc((((a>>8)&0x7F))|s, fp);
        fputc(a%256, fp);

        //z (signed 16 bits big indian but equal to 0 when 2D in 3D frame)
        //fputc(0, fp);
        //fputc(0, fp);

        //status (blanked if bit 6 (|0x40) is set and lastpoint is bit 7 (|0x80) is set)
        if (i==nbpoints-1) { lastpoint = 1; }
        fputc(0|(point[i].blanking?0x40:0x00)|(lastpoint?0x80:0x00), fp);

        //color
        fputc(point[i].color, fp);
    }

    return 0;
    /////// END OF THE WRITING ILDA FONCTION /////////////
}

// DEMO

#include <stdio.h>
#include <math.h>

#ifndef PI
#define PI 3.141592654
#endif

int main(void){
    FILE *fp;
    fp = fopen("out.ild", "wb");

    if (!fp){
       printf("Unable to open file for writing\n");
       sleep();
       return -1;
    }

    printf("File opened for writing. Creating variables...\n");
    {
    int n, nbpoints = 365; float xx, yy;
    t_point points[60000];
    memset(points, 0x00, sizeof(points));
    printf("OK\n");
    for (n=0; n<360; n+=1){
    printf("n = %d, ", n);
    
    {
        int i, x, y, t;
        int j=0;
        
        for (i=0; i<8; i++){
             = 32766 * (cos(PI+((float)n+(float)i*6.0/360)/180.0*PI)+1.5)/2.5;
            yy = 32766 * 0.9;//(cos(PI+((float)n+(float)i*6.0/360)/180.0*PI)+1.5)/2.5;
            for(t=0; t<3; t++){
                points[j].x = (-3.5+(float)i)*xx/4;
                points[j].y = 0;
                points[j].color = 1;
                points[j].blanking = t?0:1;
                j++;
            }
        }
           
        /*   
        {
        for (i=0; i<36; i+=5){
             = 32766 * 0.9;//(cos(PI+((float)n+(float)i*6.0/360)/180.0*PI)+1.5)/2.5;
            yy = 32766 * 0.9;//(cos(PI+((float)n+(float)i*6.0/360)/180.0*PI)+1.5)/2.5;
            points[j].x = xx*sin((float)(i+n)/(180.0/PI));
            points[j].y = yy*cos((float)(i+n)/(180.0/PI));
            points[j].color = 2;
            points[j].blanking = i==0?1:0;
            j++;
        }
        //points[j-1].blanking = 1;
        for (i=0; i<36; i+=5){
             = 32766 * 0.9;//(cos(PI+((float)n+(float)i*6.0/360)/180.0*PI)+1.5)/2.5;
            yy = 32766 * 0.9;//(cos(PI+((float)n+(float)i*6.0/360)/180.0*PI)+1.5)/2.5;
            points[j].x = -xx*sin((float)(i+n)/(180.0/PI));
            points[j].y = -yy*cos((float)(i+n)/(180.0/PI));
            points[j].color = 4;
            points[j].blanking = i==0?1:0;
            j++;
        }
        //points[j-1].blanking = 1;

        }
        */


        /*
        {
        int colors[]={2, 3, 2, 4};
        for (i=0; i<360; i+=5){
             = 32766 * (cos(PI+((float)n+(float)i*6.0/360)/180.0*PI)+1.5)/2.5;
            yy = 32766 * (cos(PI+((float)n+(float)i*6.0/360)/180.0*PI)+1.5)/2.5;
            points[j].x = xx*sin((float)(i+n)/(180.0/PI));
            points[j].y = yy*cos((float)(i+n)/(180.0/PI));
            points[j].color = colors[i%4];
            points[j].blanking = 0;
            j++;
        }
        }
        */ 
        
        /*
        for (i=0; i<=30000; i+=300){
            points[j].x = (i-15000)*2;
            points[j].y = 20000*sin(((float)i/50+n)/(180.0/PI))/2;
            //points[j].color = (int)(((2.0*60.0/256.0)*(float)n+((float)i/120.0)))%256;
            j++;
        }
        for (i=30000; i>0; i-=300){
            points[j].x = (i-15000)*2;
            points[j].y = 20000*sin(((float)i/50+n)/(180.0/PI))/2;
            //points[j].color = (int)(((2.0*60.0/256.0)*(float)n+((float)i/120.0)))%256;
            j++;
        }
        */
        
        
        
        make_ilda_frame(fp, "A", 360/6, j, points);
    }

    }
    }
    make_ilda_frame(fp, "END", 0, 0, NULL);

    fclose(fp);
    return 0;
}

 [PROGRAMME COMPLET] AutoExit (a sa propre page)
 [C] [Win32] Mouseloop : Ou comment faire des trucs stupides avec le pointeur de la souris
 [PHP] [INCLUDE] Récupérer des chaines quel que soit l'état de magicquotes.
 [C] [Win32] APM : Faire passer les moniteurs en green mode/locker le PC rapidement.
 [QBASIC] Lire par RS-232 les données du multimetre VC 670 et les enregistrer dans un CSV
 [C] [Portable] [Connerie] Un encodeur/décodeur ROT13 et pas que 13, en mode console.
 [mIRC] Ce client IRC n'est pas très convivial avec le mode "away". Voila qui est mieux.
 [C] [Win32] Un programme pour récupérer le nom de la chanson actuellement jouée.
 [Cµ] [PIC] [CCS] Le programme d'un chariot suiveur de ligne noire par caméra video.
10  [PROJET SOURCEFORGE] [C] Un client/passerelle en mode console pour les minichats (rmcgirr83.org) sur forums PhpBB
11  [C] [Win32] [NHC] "Workaround" d'un probleme avec le son de mon laptop lors du changement de frequence cpu
12  [C] Make-ILDA : a C routine to create ILDA files, for lasershows.