Soyez le premier à donner votre avis sur cette source.
Vue 8 256 fois - Téléchargée 254 fois
#include <assert.h> #include <conio.h> #include <dpmi.h> #include <go32.h> #include <math.h> #include <pc.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/farptr.h> #include <sys/movedata.h> #include <unistd.h> #define BLACK 0 #define RED 1 #define WHITE 2 #define ENTER 13 #define ESCAPE 27 #define SPACE 32 //////////////////////////////////////////////////////////////////////////////////////////////////// typedef struct VERTEX { double x; double y; struct VERTEX* n; } VERTEX; //////////////////////////////////////////////////////////////////////////////////////////////////// char ascii[2048]; char* buffer; double SIN[360]; double COS[360]; __dpmi_regs regs; VERTEX* f; VERTEX* fh; VERTEX* m; VERTEX* mh; //////////////////////////////////////////////////////////////////////////////////////////////////// int mouse(int* cx,int* cy,int lx,int ly); int build(VERTEX* v); void display(); void draw(VERTEX* v,char color); void erase(); void free_fractal(); void generation(); void initVESA(); void line(int fx,int fy,int lx,int ly,char color); void pcx(); void stopVESA(); void text(char* t,int c,int x,int y); //////////////////////////////////////////////////////////////////////////////////////////////////// int main() { char key; char segs[30]; int i; int fi; int mi; initVESA(); mi=build(m); if (mi==-1) { stopVESA(); return 0; } fi=build(f); if (fi==-1) { stopVESA(); return 0; } draw(f,BLACK); i=0; while (1) { sprintf(segs,"%d segments ",(int)(fi*pow(mi,i++))); text(segs,WHITE,1,10); display(); do key=getch(); while ((key!=ENTER)&&(key!='P')&&(key!=ESCAPE)); if (key==ESCAPE) break; else if (key=='P') pcx(); erase(); generation(); }; stopVESA(); return 0; } //////////////////////////////////////////////////////////////////////////////////////////////////// int mouse(int* cx,int* cy,int lx,int ly) { int button=0; do { regs.x.ax=0x03; // MOV AX,00h __dpmi_int(0x33,®s); // INT 33h button=(button&2)|(regs.x.bx&1); if (button==1) { (*cx)+=regs.x.cx-lx; // augmente cx du nombre de pixel dont la souris a bouge (*cy)-=regs.x.dx-ly; // diminue cy du nombre de pixel dont la souris a bouge button|=2; } } while (button&1); // continue tant qu'un bouton est presse if (!button) { (*cx)+=regs.x.cx-lx; // augmente cx du nombre de pixel dont la souris a bouge (*cy)-=regs.x.dx-ly; // diminue cy du nombre de pixel dont la souris a bouge } if ((*cx)>350) (*cx)=350; // pour eviter les debordements else if ((*cx)<-349) (*cx)=-349; if ((*cy)>350) (*cy)=350; // pour eviter les debordements else if ((*cy)<-349) (*cy)=-349; regs.x.ax=0x04; // MOV AX,00h regs.x.cx=lx; // MOV CX,[lx] regs.x.dx=ly; // MOV DX,[ly] __dpmi_int(0x33,®s); // INT 33h return button; } //////////////////////////////////////////////////////////////////////////////////////////////////// int build(VERTEX* v) { int cx=0; int cy=0; int lx; int ly; int i=1; char key; char pos[5]; double deg; VERTEX* p; VERTEX* h; text("X : ",WHITE,1,10); text("Y : ",WHITE,1,11); text("angle : ",WHITE,1,12); regs.x.ax=0x03; // MOV AX,00h __dpmi_int(0x33,®s); // INT 33h lx=regs.x.cx; // position X actuelle de la souris ly=regs.x.dx; // position Y actuelle de la souris h=v; // sauve l'adresse du debut de la liste if (v->n==NULL) // si l'utilisateur doit choisir le premier et le dernier vertex { while (1) // boucle infinie { // efface l'ancien curseur if (cy==350) buffer[cx+510+((382-cy)<<10)]=BLACK; else buffer[cx+510+((382-cy)<<10)]=WHITE; if (cx==350) buffer[cx+511+((383-cy)<<10)]=BLACK; else buffer[cx+511+((383-cy)<<10)]=WHITE; if (cy==-349) buffer[cx+510+((384-cy)<<10)]=BLACK; else buffer[cx+510+((384-cy)<<10)]=WHITE; if (cx==-349) buffer[cx+509+((383-cy)<<10)]=BLACK; else buffer[cx+509+((383-cy)<<10)]=WHITE; buffer[cx+510+((383-cy)<<10)]=WHITE; if (mouse(&cx,&cy,lx,ly)) { v->x=(double)cx; v->y=(double)cy; if (v->n==NULL) // si l'utilisateur a choisi le premier vertex { v->n=(VERTEX*)malloc(sizeof(VERTEX)); v=v->n; v->n=(VERTEX*)1; // flag } else break; // quitte la boucle infinie si le dernier vertex a ete choisi } // gestion du clavier if (kbhit()) { key=getch(); if (key==ESCAPE) { v->n=NULL; return -1; } } // affiche la position du curseur sprintf(pos,"%4d",cx); text(pos,WHITE,5,10); sprintf(pos,"%4d",cy); text(pos,WHITE,5,11); // dessine le nouveau curseur buffer[cx+510+((382-cy)<<10)]=RED; buffer[cx+511+((383-cy)<<10)]=RED; buffer[cx+510+((384-cy)<<10)]=RED; buffer[cx+509+((383-cy)<<10)]=RED; buffer[cx+510+((383-cy)<<10)]=RED; // si le premier vertex est deja choisi if (v->n) { line(h->x,h->y,cx,cy,BLACK); buffer[(int)h->x+510+((int)(382-h->y)<<10)]=BLACK; buffer[(int)h->x+511+((int)(383-h->y)<<10)]=BLACK; buffer[(int)h->x+510+((int)(384-h->y)<<10)]=BLACK; buffer[(int)h->x+509+((int)(383-h->y)<<10)]=BLACK; buffer[(int)h->x+510+((int)(383-h->y)<<10)]=BLACK; // affiche l'amplitude if ((cx-h->x==0.0)&&(cy-h->y>=0.0)) deg=90.0; else if ((cx-h->x==0.0)&&(cy-h->y<=0.0)) deg=270.0; else if ((cx-h->x>=0.0)&&(cy-h->y>=0.0)) deg=180.0/PI*atan((cy-h->y)/(cx-h->x)); else if ((cx-h->x<=0.0)&&(cy-h->y>=0.0)) deg=180.0-180.0/PI*atan(-(cy-h->y)/(cx-h->x)); else if ((cx-h->x<=0.0)&&(cy-h->y<=0.0)) deg=180.0+180.0/PI*atan((cy-h->y)/(cx-h->x)); else deg=360.0-180.0/PI*atan(-(cy-h->y)/(cx-h->x)); sprintf(pos,"%3.0f",deg); text(pos,WHITE,9,12); } display(); line(h->x,h->y,cx,cy,WHITE); } v->n=NULL; // ferme la liste chainee v=h; // revient au debut de la liste chainee // efface le premier vertex if (h->y==350) buffer[(int)h->x+510+((int)(382-h->y)<<10)]=BLACK; else buffer[(int)h->x+510+((int)(382-h->y)<<10)]=WHITE; if (cx==350) buffer[(int)h->x+511+((int)(383-h->y)<<10)]=BLACK; else buffer[(int)h->x+511+((int)(383-h->y)<<10)]=WHITE; if (h->y==-349) buffer[(int)h->x+510+((int)(384-h->y)<<10)]=BLACK; else buffer[(int)h->x+510+((int)(384-h->y)<<10)]=WHITE; if (cx==-349) buffer[(int)h->x+509+((int)(383-h->y)<<10)]=BLACK; else buffer[(int)h->x+509+((int)(383-h->y)<<10)]=WHITE; buffer[(int)h->x+510+((int)(383-h->y)<<10)]=WHITE; } p=v->n; // sauve l'adresse de l'element suivant v->n=(VERTEX*)malloc(sizeof(VERTEX)); // nouvel element suivant v->n->n=p; // positionne le nouvel element juste avant l'ancien element p=v; // sauve l'adresse de l'element actuel v=v->n; do { while (!kbhit()) // tant qu'aucune touche n'est pressee { // efface l'ancien curseur if (cy==350) buffer[cx+510+((382-cy)<<10)]=BLACK; else buffer[cx+510+((382-cy)<<10)]=WHITE; if (cx==350) buffer[cx+511+((383-cy)<<10)]=BLACK; else buffer[cx+511+((383-cy)<<10)]=WHITE; if (cy==-349) buffer[cx+510+((384-cy)<<10)]=BLACK; else buffer[cx+510+((384-cy)<<10)]=WHITE; if (cx==-349) buffer[cx+509+((383-cy)<<10)]=BLACK; else buffer[cx+509+((383-cy)<<10)]=WHITE; buffer[cx+510+((383-cy)<<10)]=WHITE; if (mouse(&cx,&cy,lx,ly)) { i++; // augmente le nombre de segments erase(); v->x=(double)cx; v->y=(double)cy; p=v->n; v->n=(VERTEX*)malloc(sizeof(VERTEX)); v->n->n=p; p=v; v=v->n; // le nouveau vertex est maintenant enregistre // et on passe au vertex suivant } else erase(); // efface l'ancien fractal v->x=(double)cx; // nouvelle position X du point v->y=(double)cy; // nouvelle position Y du point draw(h,RED); // dessine le nouveau fractal // affiche la position du curseur sprintf(pos,"%4d",cx); text(pos,WHITE,5,10); sprintf(pos,"%4d",cy); text(pos,WHITE,5,11); // affiche l'amplitude if ((cx-p->x==0.0)&&(cy-p->y>=0.0)) deg=90.0; else if ((cx-p->x==0.0)&&(cy-p->y<=0.0)) deg=270.0; else if ((cx-p->x>=0.0)&&(cy-p->y>=0.0)) deg=180.0/PI*atan((cy-p->y)/(cx-p->x)); else if ((cx-p->x<=0.0)&&(cy-p->y>=0.0)) deg=180.0-180.0/PI*atan(-(cy-p->y)/(cx-p->x)); else if ((cx-p->x<=0.0)&&(cy-p->y<=0.0)) deg=180.0+180.0/PI*atan((cy-p->y)/(cx-p->x)); else deg=360.0-180.0/PI*atan(-(cy-p->y)/(cx-p->x)); sprintf(pos,"%3.0f",deg); text(pos,WHITE,9,12); // dessine le nouveau curseur buffer[cx+510+((382-cy)<<10)]=BLACK; buffer[cx+511+((383-cy)<<10)]=BLACK; buffer[cx+510+((384-cy)<<10)]=BLACK; buffer[cx+509+((383-cy)<<10)]=BLACK; buffer[cx+510+((383-cy)<<10)]=BLACK; display(); // affichage } // gestion du clavier key=getch(); if (key==ESCAPE) { v->n=NULL; return -1; } } while (key!=ENTER); // recommence si ENTER n'a pas ete presse erase(); // efface le fractal text(" ",WHITE,1,10); text(" ",WHITE,1,11); text(" ",WHITE,1,12); display(); v=h; while (v->n->n) // cherche l'avant-dernier vertex { p=v; // sauve l'adresse de l'element actuel v=v->n; // et passe a l'element suivant } p->n=v->n; // efface l'element actuel free(v); // libere la memoire return i; // renvoie le nombre de segments } //////////////////////////////////////////////////////////////////////////////////////////////////// void display() { int bank; while (!(inportw(0x03DA)&8)); // synchronisation avec l'ecran while (inportw(0x03DA)&8); for (bank=0 ; bank<12 ; bank++) // 12 banques { regs.x.ax=0x4F05; // fonction 4F05h regs.x.bx=0; // fenetre A regs.x.dx=bank; // numero de la banque __dpmi_int(0x10,®s); // INT 10h dosmemput(buffer+(bank<<16),65536L,0xA0000); // affichage } } //////////////////////////////////////////////////////////////////////////////////////////////////// void draw(VERTEX* v,char color) { while (v->n) { line(v->x,v->y,v->n->x,v->n->y,color); v=v->n; } } //////////////////////////////////////////////////////////////////////////////////////////////////// void erase() { unsigned long i; i=161+33*1024; // position 161:33 while (i<=860+732*1024) // tant qu'on est pas a la position 860:732 { buffer[i]=WHITE; // pixel blanc i++; // augmente i if ((i%1024)>860) i+=163+161; // si X > 860 } // on vient d'effacer le carre blanc de 700x700 pixels } //////////////////////////////////////////////////////////////////////////////////////////////////// void free_fractal() { f=fh; // revient au debut de la liste while (f->n) // on efface chaque element jusqu'a ce { // qu'on soit arrive au dernier element fh=f; // on retient l'adresse de l'element actuel f=f->n; // on va a l'element suivant free(fh); // et on efface l'element de l'adresse retenue } // on recommence tant qu'il reste des elements free(f); // et on efface le tout dernier element m=mh; // on fait exactement la meme chose pour l'autre liste chainee while (m->n) { mh=m; m=m->n; free(mh); } free(m); } //////////////////////////////////////////////////////////////////////////////////////////////////// void generation() { double deg; double fl; double fx; double fy; double fdeg; double ml; double mx; double my; double mdeg; VERTEX* p; f=fh; draw(f,BLACK); display(); while (f->n) { // calcule l'amplitude et la longueur du segment fx=f->n->x-f->x; fy=f->n->y-f->y; fl=sqrt(fx*fx+fy*fy); if ((fx==0.0)&&(fy>=0.0)) fdeg=90.0; else if ((fx==0.0)&&(fy<=0.0)) fdeg=270.0; else if ((fx>=0.0)&&(fy>=0.0)) fdeg=180.0/PI*atan(fy/fx); else if ((fx<=0.0)&&(fy>=0.0)) fdeg=180.0-180.0/PI*atan(-fy/fx); else if ((fx<=0.0)&&(fy<=0.0)) fdeg=180.0+180.0/PI*atan(fy/fx); else fdeg=360.0-180.0/PI*atan(-fy/fx); m=mh; while (m->n->n) { // efface l'ancien segment line(f->x,f->y,f->n->x,f->n->y,WHITE); // calcule l'amplitude et la longueur du segment mx=m->n->x-m->x; my=m->n->y-m->y; ml=sqrt(mx*mx+my*my); if ((mx==0.0)&&(my>=0.0)) mdeg=90.0; else if ((mx==0.0)&&(my<=0.0)) mdeg=270.0; else if ((mx>=0.0)&&(my>=0.0)) mdeg=180.0/PI*atan(my/mx); else if ((mx<=0.0)&&(my>=0.0)) mdeg=180.0-180.0/PI*atan(-my/mx); else if ((mx<=0.0)&&(my<=0.0)) mdeg=180.0+180.0/PI*atan(my/mx); else mdeg=360.0-180.0/PI*atan(-my/mx); // insere un nouveau vertex p=f->n; f->n=(VERTEX*)malloc(sizeof(VERTEX)); f->n->n=p; p=f; f=f->n; // positionne le nouveau vertex deg=fdeg+mdeg; if (deg>=360.0) deg-=360.0; ml=fl*ml/700.0; f->x=p->x+COS[(int)deg]*ml; f->y=p->y+SIN[(int)deg]*ml; // affiche le nouveau segment en rouge line(p->x,p->y,f->x,f->y,RED); display(); m=m->n; } line(f->x,f->y,f->n->x,f->n->y,RED); f=f->n; } m=mh; f=fh; erase(); draw(f,BLACK); display(); } //////////////////////////////////////////////////////////////////////////////////////////////////// void initVESA() { unsigned long i; regs.x.ax=0x4F02; // fonction 4F02h regs.x.bx=0x105; // mode 105h - 1024x768 256 couleurs __dpmi_int(0x10,®s); // INT 10h buffer=(char*)malloc(1024*768); // alloue de la memoire pour le buffer outportb(0x03C8,BLACK); // noir outportb(0x03C9,0); outportb(0x03C9,0); outportb(0x03C9,0); outportb(0x03C8,RED); // rouge outportb(0x03C9,63); outportb(0x03C9,0); outportb(0x03C9,0); outportb(0x03C8,WHITE); // blanc outportb(0x03C9,63); outportb(0x03C9,63); outportb(0x03C9,63); for (i=0 ; i<1024*768 ; i++) buffer[i]=BLACK; // ecran noir erase(); // dessine un carre blanc de 700x700 pixels f=(VERTEX*)malloc(sizeof(VERTEX)); // creation du premier element fh=f; // sauve l'adresse du debut f->n=NULL; // on ferme la liste chainee m=(VERTEX*)malloc(sizeof(VERTEX)); // creation des deux premiers vertex mh=m; // sauve l'adresse du debut m->x=-349.0; // premier vertex au centre m->y=0.0; // et tout a gauche m->n=(VERTEX*)malloc(sizeof(VERTEX)); // vertex suivant m=m->n; m->x=350.0; // second vertex au centre m->y=0.0; // et tout a droite m->n=NULL; // on ferme la liste chainee m=mh; // on revient au debut de la liste chainee // initialisation de la souris regs.x.ax=0x00; // MOV AX,00h __dpmi_int(0x33,®s); // INT 33h regs.x.ax=0x02; // MOV AX,02h __dpmi_int(0x33,®s); // INT 33h // precalcul des nombres trigonometriques for (i=0 ; i<360 ; i++) { SIN[i]=sin(i*PI/180.0); COS[i]=cos(i*PI/180.0); } // initialisation texte dosmemget(0x000FFA6E,2048L,ascii); text("GENERATEUR DE FRACTAL - par Boes Olivier\r\n",RED,41,1); } //////////////////////////////////////////////////////////////////////////////////////////////////// void line(int fx,int fy,int lx,int ly,char color) { int x1; int y1; int x2; int y2; int dx; int dy; int sub; int remain; int error; int inc1; int inc2; fx+=510; fy=383-fy; lx+=510; ly=383-ly; if (fx>lx) { x1=lx; x2=fx; y1=ly; y2=fy; } else { x1=fx; x2=lx; y1=fy; y2=ly; } dx=x2-x1; dy=y2-y1; if ((!dx)&&(!dy)) return; if (dy<0) { dy=-dy; inc1=-1; inc2=1; } else { inc1=1; inc2=1; } if (dx>dy) { sub=dx-dy; error=dy-(dx>>1); remain=(dx+1)>>1; do { if ((x1>160)&&(x1<861)&&(y1>32)&&(y1<733)) buffer[x1+(y1<<10)]=color; if ((x2>160)&&(x2<861)&&(y2>32)&&(y2<733)) buffer[x2+(y2<<10)]=color; x1+=inc2; x2-=inc2; if (error>=0) { y1+=inc1; y2-=inc1; error-=sub; } else error+=dy; } while (--remain>0); if ((!(dx&1))&&((x1>160)&&(x1<861)&&(y1>32)&&(y1<733))) buffer[x1+(y1<<10)]=color; } else { sub=dy-dx; error=dx-(dy>>1); remain=(dy+1)>>1; do { if ((x1>160)&&(x1<861)&&(y1>32)&&(y1<733)) buffer[x1+(y1<<10)]=color; if ((x2>160)&&(x2<861)&&(y2>32)&&(y2<733)) buffer[x2+(y2<<10)]=color; y1+=inc1; y2-=inc1; if (error>=0) { x1+=inc2; x2-=inc2; error-=sub; } else error+=dx; } while (--remain>0); if ((!(dy&1))&&((x1>160)&&(x1<861)&&(y1>32)&&(y1<733))) buffer[x1+(y1<<10)]=color; } } //////////////////////////////////////////////////////////////////////////////////////////////////// void pcx() { char header[128]; char c; char n; char name[11]; char* img; FILE* file; unsigned char pal[768]; unsigned int width=(700+(700&1)); unsigned long max=700*700; unsigned long i; unsigned long i2; /* --- CREATION DU PCX --- */ strcpy(name,"ecran0.pcx"); while ((__file_exists(name))&&(name[5]<='9')) name[5]++; if (name[5]>'9') return; file=fopen(name,"wb"); img=(char*)malloc(700*700*sizeof(char)); i=161+33*1024; // position 161:33 i2=0; while (i<=860+732*1024) // tant qu'on est pas a la position 860:732 { img[i2++]=buffer[i]; i++; // augmente i if ((i%1024)>860) i+=163+161; // si X > 860 } /* --- EN-TETE --- */ header[0]=10; /* octet PCX */ header[1]=5; /* version de PCX */ header[2]=1; /* RLE active */ header[3]=8; /* 8 bits pour un pixel */ header[4]=0; /* Xmin */ header[5]=0; /* Xmin */ header[6]=0; /* Ymin */ header[7]=0; /* Ymin */ header[8]=(700-1)&0x00FF; /* Xmax */ header[9]=((700-1)&0xFF00)>>8; /* Xmax */ header[10]=(700-1)&0x00FF; /* Ymax */ header[11]=((700-1)&0xFF00)>>8; /* Ymax */ header[12]=72; /* resolution horizontale */ header[13]=0; /* resolution horizontale */ header[14]=72; /* resolution verticale */ header[15]=0; /* resolution verticale */ for (i=0 ; i<16 ; i++) /* palette 16 couleurs */ { header[i*3+16]=15-i; header[i*3+17]=15-i; header[i*3+18]=15-i; } header[64]=0; /* toujours 0 */ header[65]=1; /* toujours 1 */ header[66]=width&0x00FF; /* largeur, doit etre un nombre pair */ header[67]=(width&0xFF00)>>8; /* largeur, doit etre un nombre pair */ header[68]=1; /* 1 = couleurs, 2 = noir et blanc */ for (i=69 ; i<128 ; i++) header[i]=0; /* tout le reste c'est 0 */ fwrite(header,sizeof(char),128,file); /* on ecrit l'en-tete */ /* --- IMAGE --- */ i=0; do { c=img[i]; i++; n=1; if (i!=max) while (img[i]==c) { if ((n<63)&&(i%700)) n++; else break; i++; if (i==max) break; } if ((n==1)&&((c&0xC0)!=0xC0)) fwrite(&c,sizeof(char),1,file); else { if ((i%700==0)&&(700!=width)&&(c==(char)(255))) { n++; width=0; } n|=0xC0; fwrite(&n,sizeof(char),1,file); fwrite(&c,sizeof(char),1,file); } if (!width) width=700+1; else if ((i%700==0)&&(700!=width)) fwrite("\xC1\xFF",sizeof(char),2,file); } while (i!=max); /* --- PALETTE --- */ c=12; fwrite(&c,sizeof(char),1,file); pal[0]=0; pal[1]=0; pal[2]=0; pal[3]=255; pal[4]=0; pal[5]=0; pal[6]=255; pal[7]=255; pal[8]=255; for (i=9 ; i<768 ; i++) pal[i]=0; fwrite(pal,sizeof(char),768,file); fclose(file); free(img); } //////////////////////////////////////////////////////////////////////////////////////////////////// void stopVESA() { regs.h.ah=0x00; // fonction 00h regs.h.al=0x03; // mode 03h - mode texte normal __dpmi_int(0x10,®s); // INT 10h free(buffer); // on libere la memoire du buffer free_fractal(); // on libere la memoire des listes chainees } //////////////////////////////////////////////////////////////////////////////////////////////////// void text(char* t,int c,int x,int y) { unsigned int i; unsigned int i2; unsigned int pos1; unsigned int pos2; pos1=(x<<3)+(y<<13); // convertit les positions for (i=0 ; t[i] ; i++) // tant que le texte n'est pas fini { if (t[i]=='\n') // passe une ligne { pos1+=1024*8; continue; } if (t[i]=='\r') // retour a gauche { pos1=(pos1&0xFFC00)+(x<<3); continue; } pos2=t[i]<<3; // va au caractere demande for (i2=0 ; i2<8 ; i2++) // 8 lignes par caracteres { if (ascii[pos2]&0x80) buffer[pos1++]=c&0x00FF; else buffer[pos1++]=(c&0xFF00)>>8; if (ascii[pos2]&0x40) buffer[pos1++]=c&0x00FF; else buffer[pos1++]=(c&0xFF00)>>8; if (ascii[pos2]&0x20) buffer[pos1++]=c&0x00FF; else buffer[pos1++]=(c&0xFF00)>>8; if (ascii[pos2]&0x10) buffer[pos1++]=c&0x00FF; else buffer[pos1++]=(c&0xFF00)>>8; if (ascii[pos2]&0x08) buffer[pos1++]=c&0x00FF; else buffer[pos1++]=(c&0xFF00)>>8; if (ascii[pos2]&0x04) buffer[pos1++]=c&0x00FF; else buffer[pos1++]=(c&0xFF00)>>8; if (ascii[pos2]&0x02) buffer[pos1++]=c&0x00FF; else buffer[pos1++]=(c&0xFF00)>>8; if (ascii[pos2]&0x01) buffer[pos1++]=c&0x00FF; else buffer[pos1++]=(c&0xFF00)>>8; pos1+=1024-8; pos2++; } pos1-=1024*8-8; } } #include <assert.h> #include <conio.h> #include <dpmi.h> #include <go32.h> #include <math.h> #include <pc.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/farptr.h> #include <sys/movedata.h> #include <unistd.h> #define BLACK 0 #define RED 1 #define WHITE 2 #define ENTER 13 #define ESCAPE 27 #define SPACE 32 //////////////////////////////////////////////////////////////////////////////////////////////////// typedef struct VERTEX { double x; double y; struct VERTEX* n; } VERTEX; //////////////////////////////////////////////////////////////////////////////////////////////////// char ascii[2048]; char* buffer; double SIN[360]; double COS[360]; __dpmi_regs regs; VERTEX* f; VERTEX* fh; VERTEX* m; VERTEX* mh; //////////////////////////////////////////////////////////////////////////////////////////////////// int mouse(int* cx,int* cy,int lx,int ly); int build(VERTEX* v); void display(); void draw(VERTEX* v,char color); void erase(); void free_fractal(); void generation(); void initVESA(); void line(int fx,int fy,int lx,int ly,char color); void pcx(); void stopVESA(); void text(char* t,int c,int x,int y); //////////////////////////////////////////////////////////////////////////////////////////////////// int main() { char key; char segs[30]; int i; int fi; int mi; initVESA(); mi=build(m); if (mi==-1) { stopVESA(); return 0; } fi=build(f); if (fi==-1) { stopVESA(); return 0; } draw(f,BLACK); i=0; while (1) { sprintf(segs,"%d segments ",(int)(fi*pow(mi,i++))); text(segs,WHITE,1,10); display(); do key=getch(); while ((key!=ENTER)&&(key!='P')&&(key!=ESCAPE)); if (key==ESCAPE) break; else if (key=='P') pcx(); erase(); generation(); }; stopVESA(); return 0; } //////////////////////////////////////////////////////////////////////////////////////////////////// int mouse(int* cx,int* cy,int lx,int ly) { int button=0; do { regs.x.ax=0x03; // MOV AX,00h __dpmi_int(0x33,®s); // INT 33h button=(button&2)|(regs.x.bx&1); if (button==1) { (*cx)+=regs.x.cx-lx; // augmente cx du nombre de pixel dont la souris a bouge (*cy)-=regs.x.dx-ly; // diminue cy du nombre de pixel dont la souris a bouge button|=2; } } while (button&1); // continue tant qu'un bouton est presse if (!button) { (*cx)+=regs.x.cx-lx; // augmente cx du nombre de pixel dont la souris a bouge (*cy)-=regs.x.dx-ly; // diminue cy du nombre de pixel dont la souris a bouge } if ((*cx)>350) (*cx)=350; // pour eviter les debordements else if ((*cx)<-349) (*cx)=-349; if ((*cy)>350) (*cy)=350; // pour eviter les debordements else if ((*cy)<-349) (*cy)=-349; regs.x.ax=0x04; // MOV AX,00h regs.x.cx=lx; // MOV CX,[lx] regs.x.dx=ly; // MOV DX,[ly] __dpmi_int(0x33,®s); // INT 33h return button; } //////////////////////////////////////////////////////////////////////////////////////////////////// int build(VERTEX* v) { int cx=0; int cy=0; int lx; int ly; int i=1; char key; char pos[5]; double deg; VERTEX* p; VERTEX* h; text("X : ",WHITE,1,10); text("Y : ",WHITE,1,11); text("angle : ",WHITE,1,12); regs.x.ax=0x03; // MOV AX,00h __dpmi_int(0x33,®s); // INT 33h lx=regs.x.cx; // position X actuelle de la souris ly=regs.x.dx; // position Y actuelle de la souris h=v; // sauve l'adresse du debut de la liste if (v->n==NULL) // si l'utilisateur doit choisir le premier et le dernier vertex { while (1) // boucle infinie { // efface l'ancien curseur if (cy==350) buffer[cx+510+((382-cy)<<10)]=BLACK; else buffer[cx+510+((382-cy)<<10)]=WHITE; if (cx==350) buffer[cx+511+((383-cy)<<10)]=BLACK; else buffer[cx+511+((383-cy)<<10)]=WHITE; if (cy==-349) buffer[cx+510+((384-cy)<<10)]=BLACK; else buffer[cx+510+((384-cy)<<10)]=WHITE; if (cx==-349) buffer[cx+509+((383-cy)<<10)]=BLACK; else buffer[cx+509+((383-cy)<<10)]=WHITE; buffer[cx+510+((383-cy)<<10)]=WHITE; if (mouse(&cx,&cy,lx,ly)) { v->x=(double)cx; v->y=(double)cy; if (v->n==NULL) // si l'utilisateur a choisi le premier vertex { v->n=(VERTEX*)malloc(sizeof(VERTEX)); v=v->n; v->n=(VERTEX*)1; // flag } else break; // quitte la boucle infinie si le dernier vertex a ete choisi } // gestion du clavier if (kbhit()) { key=getch(); if (key==ESCAPE) { v->n=NULL; return -1; } } // affiche la position du curseur sprintf(pos,"%4d",cx); text(pos,WHITE,5,10); sprintf(pos,"%4d",cy); text(pos,WHITE,5,11); // dessine le nouveau curseur buffer[cx+510+((382-cy)<<10)]=RED; buffer[cx+511+((383-cy)<<10)]=RED; buffer[cx+510+((384-cy)<<10)]=RED; buffer[cx+509+((383-cy)<<10)]=RED; buffer[cx+510+((383-cy)<<10)]=RED; // si le premier vertex est deja choisi if (v->n) { line(h->x,h->y,cx,cy,BLACK); buffer[(int)h->x+510+((int)(382-h->y)<<10)]=BLACK; buffer[(int)h->x+511+((int)(383-h->y)<<10)]=BLACK; buffer[(int)h->x+510+((int)(384-h->y)<<10)]=BLACK; buffer[(int)h->x+509+((int)(383-h->y)<<10)]=BLACK; buffer[(int)h->x+510+((int)(383-h->y)<<10)]=BLACK; // affiche l'amplitude if ((cx-h->x==0.0)&&(cy-h->y>=0.0)) deg=90.0; else if ((cx-h->x==0.0)&&(cy-h->y<=0.0)) deg=270.0; else if ((cx-h->x>=0.0)&&(cy-h->y>=0.0)) deg=180.0/PI*atan((cy-h->y)/(cx-h->x)); else if ((cx-h->x<=0.0)&&(cy-h->y>=0.0)) deg=180.0-180.0/PI*atan(-(cy-h->y)/(cx-h->x)); else if ((cx-h->x<=0.0)&&(cy-h->y<=0.0)) deg=180.0+180.0/PI*atan((cy-h->y)/(cx-h->x)); else deg=360.0-180.0/PI*atan(-(cy-h->y)/(cx-h->x)); sprintf(pos,"%3.0f",deg); text(pos,WHITE,9,12); } display(); line(h->x,h->y,cx,cy,WHITE); } v->n=NULL; // ferme la liste chainee v=h; // revient au debut de la liste chainee // efface le premier vertex if (h->y==350) buffer[(int)h->x+510+((int)(382-h->y)<<10)]=BLACK; else buffer[(int)h->x+510+((int)(382-h->y)<<10)]=WHITE; if (cx==350) buffer[(int)h->x+511+((int)(383-h->y)<<10)]=BLACK; else buffer[(int)h->x+511+((int)(383-h->y)<<10)]=WHITE; if (h->y==-349) buffer[(int)h->x+510+((int)(384-h->y)<<10)]=BLACK; else buffer[(int)h->x+510+((int)(384-h->y)<<10)]=WHITE; if (cx==-349) buffer[(int)h->x+509+((int)(383-h->y)<<10)]=BLACK; else buffer[(int)h->x+509+((int)(383-h->y)<<10)]=WHITE; buffer[(int)h->x+510+((int)(383-h->y)<<10)]=WHITE; } p=v->n; // sauve l'adresse de l'element suivant v->n=(VERTEX*)malloc(sizeof(VERTEX)); // nouvel element suivant v->n->n=p; // positionne le nouvel element juste avant l'ancien element p=v; // sauve l'adresse de l'element actuel v=v->n; do { while (!kbhit()) // tant qu'aucune touche n'est pressee { // efface l'ancien curseur if (cy==350) buffer[cx+510+((382-cy)<<10)]=BLACK; else buffer[cx+510+((382-cy)<<10)]=WHITE; if (cx==350) buffer[cx+511+((383-cy)<<10)]=BLACK; else buffer[cx+511+((383-cy)<<10)]=WHITE; if (cy==-349) buffer[cx+510+((384-cy)<<10)]=BLACK; else buffer[cx+510+((384-cy)<<10)]=WHITE; if (cx==-349) buffer[cx+509+((383-cy)<<10)]=BLACK; else buffer[cx+509+((383-cy)<<10)]=WHITE; buffer[cx+510+((383-cy)<<10)]=WHITE; if (mouse(&cx,&cy,lx,ly)) { i++; // augmente le nombre de segments erase(); v->x=(double)cx; v->y=(double)cy; p=v->n; v->n=(VERTEX*)malloc(sizeof(VERTEX)); v->n->n=p; p=v; v=v->n; // le nouveau vertex est maintenant enregistre // et on passe au vertex suivant } else erase(); // efface l'ancien fractal v->x=(double)cx; // nouvelle position X du point v->y=(double)cy; // nouvelle position Y du point draw(h,RED); // dessine le nouveau fractal // affiche la position du curseur sprintf(pos,"%4d",cx); text(pos,WHITE,5,10); sprintf(pos,"%4d",cy); text(pos,WHITE,5,11); // affiche l'amplitude if ((cx-p->x==0.0)&&(cy-p->y>=0.0)) deg=90.0; else if ((cx-p->x==0.0)&&(cy-p->y<=0.0)) deg=270.0; else if ((cx-p->x>=0.0)&&(cy-p->y>=0.0)) deg=180.0/PI*atan((cy-p->y)/(cx-p->x)); else if ((cx-p->x<=0.0)&&(cy-p->y>=0.0)) deg=180.0-180.0/PI*atan(-(cy-p->y)/(cx-p->x)); else if ((cx-p->x<=0.0)&&(cy-p->y<=0.0)) deg=180.0+180.0/PI*atan((cy-p->y)/(cx-p->x)); else deg=360.0-180.0/PI*atan(-(cy-p->y)/(cx-p->x)); sprintf(pos,"%3.0f",deg); text(pos,WHITE,9,12); // dessine le nouveau curseur buffer[cx+510+((382-cy)<<10)]=BLACK; buffer[cx+511+((383-cy)<<10)]=BLACK; buffer[cx+510+((384-cy)<<10)]=BLACK; buffer[cx+509+((383-cy)<<10)]=BLACK; buffer[cx+510+((383-cy)<<10)]=BLACK; display(); // affichage } // gestion du clavier key=getch(); if (key==ESCAPE) { v->n=NULL; return -1; } } while (key!=ENTER); // recommence si ENTER n'a pas ete presse erase(); // efface le fractal text(" ",WHITE,1,10); text(" ",WHITE,1,11); text(" ",WHITE,1,12); display(); v=h; while (v->n->n) // cherche l'avant-dernier vertex { p=v; // sauve l'adresse de l'element actuel v=v->n; // et passe a l'element suivant } p->n=v->n; // efface l'element actuel free(v); // libere la memoire return i; // renvoie le nombre de segments } //////////////////////////////////////////////////////////////////////////////////////////////////// void display() { int bank; while (!(inportw(0x03DA)&8)); // synchronisation avec l'ecran while (inportw(0x03DA)&8); for (bank=0 ; bank<12 ; bank++) // 12 banques { regs.x.ax=0x4F05; // fonction 4F05h regs.x.bx=0; // fenetre A regs.x.dx=bank; // numero de la banque __dpmi_int(0x10,®s); // INT 10h dosmemput(buffer+(bank<<16),65536L,0xA0000); // affichage } } //////////////////////////////////////////////////////////////////////////////////////////////////// void draw(VERTEX* v,char color) { while (v->n) { line(v->x,v->y,v->n->x,v->n->y,color); v=v->n; } } //////////////////////////////////////////////////////////////////////////////////////////////////// void erase() { unsigned long i; i=161+33*1024; // position 161:33 while (i<=860+732*1024) // tant qu'on est pas a la position 860:732 { buffer[i]=WHITE; // pixel blanc i++; // augmente i if ((i%1024)>860) i+=163+161; // si X > 860 } // on vient d'effacer le carre blanc de 700x700 pixels } //////////////////////////////////////////////////////////////////////////////////////////////////// void free_fractal() { f=fh; // revient au debut de la liste while (f->n) // on efface chaque element jusqu'a ce { // qu'on soit arrive au dernier element fh=f; // on retient l'adresse de l'element actuel f=f->n; // on va a l'element suivant free(fh); // et on efface l'element de l'adresse retenue } // on recommence tant qu'il reste des elements free(f); // et on efface le tout dernier element m=mh; // on fait exactement la meme chose pour l'autre liste chainee while (m->n) { mh=m; m=m->n; free(mh); } free(m); } //////////////////////////////////////////////////////////////////////////////////////////////////// void generation() { double deg; double fl; double fx; double fy; double fdeg; double ml; double mx; double my; double mdeg; VERTEX* p; f=fh; draw(f,BLACK); display(); while (f->n) { // calcule l'amplitude et la longueur du segment fx=f->n->x-f->x; fy=f->n->y-f->y; fl=sqrt(fx*fx+fy*fy); if ((fx==0.0)&&(fy>=0.0)) fdeg=90.0; else if ((fx==0.0)&&(fy<=0.0)) fdeg=270.0; else if ((fx>=0.0)&&(fy>=0.0)) fdeg=180.0/PI*atan(fy/fx); else if ((fx<=0.0)&&(fy>=0.0)) fdeg=180.0-180.0/PI*atan(-fy/fx); else if ((fx<=0.0)&&(fy<=0.0)) fdeg=180.0+180.0/PI*atan(fy/fx); else fdeg=360.0-180.0/PI*atan(-fy/fx); m=mh; while (m->n->n) { // efface l'ancien segment line(f->x,f->y,f->n->x,f->n->y,WHITE); // calcule l'amplitude et la longueur du segment mx=m->n->x-m->x; my=m->n->y-m->y; ml=sqrt(mx*mx+my*my); if ((mx==0.0)&&(my>=0.0)) mdeg=90.0; else if ((mx==0.0)&&(my<=0.0)) mdeg=270.0; else if ((mx>=0.0)&&(my>=0.0)) mdeg=180.0/PI*atan(my/mx); else if ((mx<=0.0)&&(my>=0.0)) mdeg=180.0-180.0/PI*atan(-my/mx); else if ((mx<=0.0)&&(my<=0.0)) mdeg=180.0+180.0/PI*atan(my/mx); else mdeg=360.0-180.0/PI*atan(-my/mx); // insere un nouveau vertex p=f->n; f->n=(VERTEX*)malloc(sizeof(VERTEX)); f->n->n=p; p=f; f=f->n; // positionne le nouveau vertex deg=fdeg+mdeg; if (deg>=360.0) deg-=360.0; ml=fl*ml/700.0; f->x=p->x+COS[(int)deg]*ml; f->y=p->y+SIN[(int)deg]*ml; // affiche le nouveau segment en rouge line(p->x,p->y,f->x,f->y,RED); display(); m=m->n; } line(f->x,f->y,f->n->x,f->n->y,RED); f=f->n; } m=mh; f=fh; erase(); draw(f,BLACK); display(); } //////////////////////////////////////////////////////////////////////////////////////////////////// void initVESA() { unsigned long i; regs.x.ax=0x4F02; // fonction 4F02h regs.x.bx=0x105; // mode 105h - 1024x768 256 couleurs __dpmi_int(0x10,®s); // INT 10h buffer=(char*)malloc(1024*768); // alloue de la memoire pour le buffer outportb(0x03C8,BLACK); // noir outportb(0x03C9,0); outportb(0x03C9,0); outportb(0x03C9,0); outportb(0x03C8,RED); // rouge outportb(0x03C9,63); outportb(0x03C9,0); outportb(0x03C9,0); outportb(0x03C8,WHITE); // blanc outportb(0x03C9,63); outportb(0x03C9,63); outportb(0x03C9,63); for (i=0 ; i<1024*768 ; i++) buffer[i]=BLACK; // ecran noir erase(); // dessine un carre blanc de 700x700 pixels f=(VERTEX*)malloc(sizeof(VERTEX)); // creation du premier element fh=f; // sauve l'adresse du debut f->n=NULL; // on ferme la liste chainee m=(VERTEX*)malloc(sizeof(VERTEX)); // creation des deux premiers vertex mh=m; // sauve l'adresse du debut m->x=-349.0; // premier vertex au centre m->y=0.0; // et tout a gauche m->n=(VERTEX*)malloc(sizeof(VERTEX)); // vertex suivant m=m->n; m->x=350.0; // second vertex au centre m->y=0.0; // et tout a droite m->n=NULL; // on ferme la liste chainee m=mh; // on revient au debut de la liste chainee // initialisation de la souris regs.x.ax=0x00; // MOV AX,00h __dpmi_int(0x33,®s); // INT 33h regs.x.ax=0x02; // MOV AX,02h __dpmi_int(0x33,®s); // INT 33h // precalcul des nombres trigonometriques for (i=0 ; i<360 ; i++) { SIN[i]=sin(i*PI/180.0); COS[i]=cos(i*PI/180.0); } // initialisation texte dosmemget(0x000FFA6E,2048L,ascii); text("GENERATEUR DE FRACTAL - par Boes Olivier\r\n",RED,41,1); } //////////////////////////////////////////////////////////////////////////////////////////////////// void line(int fx,int fy,int lx,int ly,char color) { int x1; int y1; int x2; int y2; int dx; int dy; int sub; int remain; int error; int inc1; int inc2; fx+=510; fy=383-fy; lx+=510; ly=383-ly; if (fx>lx) { x1=lx; x2=fx; y1=ly; y2=fy; } else { x1=fx; x2=lx; y1=fy; y2=ly; } dx=x2-x1; dy=y2-y1; if ((!dx)&&(!dy)) return; if (dy<0) { dy=-dy; inc1=-1; inc2=1; } else { inc1=1; inc2=1; } if (dx>dy) { sub=dx-dy; error=dy-(dx>>1); remain=(dx+1)>>1; do { if ((x1>160)&&(x1<861)&&(y1>32)&&(y1<733)) buffer[x1+(y1<<10)]=color; if ((x2>160)&&(x2<861)&&(y2>32)&&(y2<733)) buffer[x2+(y2<<10)]=color; x1+=inc2; x2-=inc2; if (error>=0) { y1+=inc1; y2-=inc1; error-=sub; } else error+=dy; } while (--remain>0); if ((!(dx&1))&&((x1>160)&&(x1<861)&&(y1>32)&&(y1<733))) buffer[x1+(y1<<10)]=color; } else { sub=dy-dx; error=dx-(dy>>1); remain=(dy+1)>>1; do { if ((x1>160)&&(x1<861)&&(y1>32)&&(y1<733)) buffer[x1+(y1<<10)]=color; if ((x2>160)&&(x2<861)&&(y2>32)&&(y2<733)) buffer[x2+(y2<<10)]=color; y1+=inc1; y2-=inc1; if (error>=0) { x1+=inc2; x2-=inc2; error-=sub; } else error+=dx; } while (--remain>0); if ((!(dy&1))&&((x1>160)&&(x1<861)&&(y1>32)&&(y1<733))) buffer[x1+(y1<<10)]=color; } } //////////////////////////////////////////////////////////////////////////////////////////////////// void pcx() { char header[128]; char c; char n; char name[11]; char* img; FILE* file; unsigned char pal[768]; unsigned int width=(700+(700&1)); unsigned long max=700*700; unsigned long i; unsigned long i2; /* --- CREATION DU PCX --- */ strcpy(name,"ecran0.pcx"); while ((__file_exists(name))&&(name[5]<='9')) name[5]++; if (name[5]>'9') return; file=fopen(name,"wb"); img=(char*)malloc(700*700*sizeof(char)); i=161+33*1024; // position 161:33 i2=0; while (i<=860+732*1024) // tant qu'on est pas a la position 860:732 { img[i2++]=buffer[i]; i++; // augmente i if ((i%1024)>860) i+=163+161; // si X > 860 } /* --- EN-TETE --- */ header[0]=10; /* octet PCX */ header[1]=5; /* version de PCX */ header[2]=1; /* RLE active */ header[3]=8; /* 8 bits pour un pixel */ header[4]=0; /* Xmin */ header[5]=0; /* Xmin */ header[6]=0; /* Ymin */ header[7]=0; /* Ymin */ header[8]=(700-1)&0x00FF; /* Xmax */ header[9]=((700-1)&0xFF00)>>8; /* Xmax */ header[10]=(700-1)&0x00FF; /* Ymax */ header[11]=((700-1)&0xFF00)>>8; /* Ymax */ header[12]=72; /* resolution horizontale */ header[13]=0; /* resolution horizontale */ header[14]=72; /* resolution verticale */ header[15]=0; /* resolution verticale */ for (i=0 ; i<16 ; i++) /* palette 16 couleurs */ { header[i*3+16]=15-i; header[i*3+17]=15-i; header[i*3+18]=15-i; } header[64]=0; /* toujours 0 */ header[65]=1; /* toujours 1 */ header[66]=width&0x00FF; /* largeur, doit etre un nombre pair */ header[67]=(width&0xFF00)>>8; /* largeur, doit etre un nombre pair */ header[68]=1; /* 1 = couleurs, 2 = noir et blanc */ for (i=69 ; i<128 ; i++) header[i]=0; /* tout le reste c'est 0 */ fwrite(header,sizeof(char),128,file); /* on ecrit l'en-tete */ /* --- IMAGE --- */ i=0; do { c=img[i]; i++; n=1; if (i!=max) while (img[i]==c) { if ((n<63)&&(i%700)) n++; else break; i++; if (i==max) break; } if ((n==1)&&((c&0xC0)!=0xC0)) fwrite(&c,sizeof(char),1,file); else { if ((i%700==0)&&(700!=width)&&(c==(char)(255))) { n++; width=0; } n|=0xC0; fwrite(&n,sizeof(char),1,file); fwrite(&c,sizeof(char),1,file); } if (!width) width=700+1; else if ((i%700==0)&&(700!=width)) fwrite("\xC1\xFF",sizeof(char),2,file); } while (i!=max); /* --- PALETTE --- */ c=12; fwrite(&c,sizeof(char),1,file); pal[0]=0; pal[1]=0; pal[2]=0; pal[3]=255; pal[4]=0; pal[5]=0; pal[6]=255; pal[7]=255; pal[8]=255; for (i=9 ; i<768 ; i++) pal[i]=0; fwrite(pal,sizeof(char),768,file); fclose(file); free(img); } //////////////////////////////////////////////////////////////////////////////////////////////////// void stopVESA() { regs.h.ah=0x00; // fonction 00h regs.h.al=0x03; // mode 03h - mode texte normal __dpmi_int(0x10,®s); // INT 10h free(buffer); // on libere la memoire du buffer free_fractal(); // on libere la memoire des listes chainees } //////////////////////////////////////////////////////////////////////////////////////////////////// void text(char* t,int c,int x,int y) { unsigned int i; unsigned int i2; unsigned int pos1; unsigned int pos2; pos1=(x<<3)+(y<<13); // convertit les positions for (i=0 ; t[i] ; i++) // tant que le texte n'est pas fini { if (t[i]=='\n') // passe une ligne { pos1+=1024*8; continue; } if (t[i]=='\r') // retour a gauche { pos1=(pos1&0xFFC00)+(x<<3); continue; } pos2=t[i]<<3; // va au caractere demande for (i2=0 ; i2<8 ; i2++) // 8 lignes par caracteres { if (ascii[pos2]&0x80) buffer[pos1++]=c&0x00FF; else buffer[pos1++]=(c&0xFF00)>>8; if (ascii[pos2]&0x40) buffer[pos1++]=c&0x00FF; else buffer[pos1++]=(c&0xFF00)>>8; if (ascii[pos2]&0x20) buffer[pos1++]=c&0x00FF; else buffer[pos1++]=(c&0xFF00)>>8; if (ascii[pos2]&0x10) buffer[pos1++]=c&0x00FF; else buffer[pos1++]=(c&0xFF00)>>8; if (ascii[pos2]&0x08) buffer[pos1++]=c&0x00FF; else buffer[pos1++]=(c&0xFF00)>>8; if (ascii[pos2]&0x04) buffer[pos1++]=c&0x00FF; else buffer[pos1++]=(c&0xFF00)>>8; if (ascii[pos2]&0x02) buffer[pos1++]=c&0x00FF; else buffer[pos1++]=(c&0xFF00)>>8; if (ascii[pos2]&0x01) buffer[pos1++]=c&0x00FF; else buffer[pos1++]=(c&0xFF00)>>8; pos1+=1024-8; pos2++; } pos1-=1024*8-8; } }
5 juil. 2011 à 10:31
27 août 2004 à 21:35
9 août 2004 à 20:26
D'où tire-tu toutes ces idées de programme ???
9 août 2004 à 14:10
9 août 2004 à 13:53
je comprend pas pourquoi ça ne marche pas, chez moi sur WinXP ya aucun probleme
Vous n'êtes pas encore membre ?
inscrivez-vous, c'est gratuit et ça prend moins d'une minute !
Les membres obtiennent plus de réponses que les utilisateurs anonymes.
Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.
Le fait d'être membre vous permet d'avoir des options supplémentaires.