// C Source File // Created 21/02/2002; 18:19:37 (ça nous rajeunit pas tout ça...) #define CHAINE_VERSION "Fast Reader X 2.0 by Brunni" #define USE_TI89 // Produce .89z File #define USE_TI92PLUS // Produce .9xz File #define OPTIMIZE_ROM_CALLS // Use ROM Call Optimization #define SAVE_SCREEN // Save/Restore LCD Contents #include // Include All Header Files #include "Fichier.h" #include "Langues.h" //valeurs de font et font2 pour FastChar #define PETITE_POLICE 6,18 #define POLICE_NORMALE 8,10 #define GRANDE_POLICE 10,0 #define CAR_ENTER 13 unsigned char* charset=NULL; //Images des caracères pour FastChar unsigned char* charwidth=NULL; //Largeur des caractères en petite police static inline void SetupCharSet(void) { unsigned short i; //Ch'tite fonte FontSetSys(F_4x6); memset(charset,0,6*256+8*256+10*256); PortSet(charset+10*256+8*256,7,6*256-1); for (i=0;i<256;i++) { charwidth[i] = FontCharWidth(i); DrawChar(0,i*6+(i==103),i,A_REPLACE); //on baisse le g } // Fonte moyenne FontSetSys(F_6x8); PortSet(charset+10*256,7,8*256-1); for (i=0;i<256;i++) DrawChar(0,i<<3,i,A_REPLACE); // Grosse fonte FontSetSys(F_8x10); PortSet(charset,7,10*256-1); for (i=0;i<256;i++) DrawChar(0,i*10,i,A_REPLACE); FontSetSys(F_6x8); PortRestore(); //On restore l'adresse de l'écran } void FastChar(short x,short y,unsigned char c,void *plane,short font,short font2) { unsigned char* sprite=&charset[font2*256+((short)c)*font]; long addr = ((long)plane)+(y<<5)-(y<<1)+((x>>3)&0xfffe); unsigned short cnt = 25-(x&15); // unrolled loop for more speed ... *(long*)addr^=(long)(*sprite++)<>3)&0x1e); register unsigned short cnt = 24-(x&15); for (;h;h--,addr+=30) *dest++ = (unsigned char)(((*(unsigned long*)addr)>>cnt) & 0xffL); } void Sprite8_OR(short x,short y,short h,unsigned char* sprite,void* dest) { register long addr = (long)dest+(y<<5)-(y<<1)+((x>>3)&0x1e); register unsigned short cnt = 24-(x&15); for (;h;h--,addr+=30) *(long*)addr|=(long)(*sprite++)<>3)&0x1e); register unsigned short cnt = 24-(x&15); for (;h;h--,addr+=30) *(long*)addr&=~((long)(~(*sprite++)&0xff)<x2) { short tmp = x1; x1 = x2; x2 = tmp; } p = (unsigned short*)(plane+(y<<5)-(y<<1)+((x1>>3)&0x1e)); dx = x2-x1+1; sx = x1 & 0x000f; if (dx<16) { unsigned long val = (ASM_SWAP(table2[dx])) >> sx; *(unsigned long*)p ^= val; return; } if (sx) { *p++ ^= table1[sx]; dx -= (16-sx); } while (dx >= 16) { *p++ ^= 0xffff; dx-=16; } if (dx) *p ^= table2[dx]; } //Routines de FLIB, merci François Leiber! char *mk_nam(char *str) { static char name[19] = {0} ; short len = strlen(str) ; if (len > 17) return NULL ; return strcpy(name+1, str)+len ; } char *get_ptr(SYM_ENTRY *entry) { if (entry == NULL || entry->handle == H_NULL) return NULL ; return (char*)HeapDeref(entry->handle) ; } SYM_ENTRY *get_entry(char *str) { char *nom = mk_nam(str) ; return SymFindPtr(nom, 0) ; } //Donne la longueur d'un caractère en fonction de sa police static inline short LONGCHAR(short c,short font) { if (font==0) return charwidth[c]; else return 4+2*font; } //STRICTEMENT INUTILE /*int gblX, gblY; CALLBACK void DessCar (char c, void *nul) { int x=gblX; gblX+=FontCharWidth(c); if (gblX>=240) return; DrawChar (x, gblY, c, 4); } void printf_truc(int x, int y, const char *format, ...) { va_list arg_ptr; va_start(arg_ptr, format); gblX=x, gblY=y; vcbprintf ((vcbprintf_Callback_t)DessCar,NULL,format,arg_ptr); va_end(arg_ptr); }*/ //FIN STRICTEMENT INUTILE void VerifPrintf(char *texte) { while(*texte) { if (*texte=='%') { texte++; while (!((*texte>='A' && *texte<='Z') || (*texte>='a' && *texte<='z')) && *texte) texte++; if (*texte) *texte='i'; } texte++; } } /*void DessTexte(int x, int y, char *texte, int attr) { int xx; while (1) { xx=x; x+=FontCharWidth(*texte); if (x>=240) break; DrawChar(x,y,*texte,attr); } }*/ void Debug(const char *format, ...) { char vbuf[100]; va_list arg_ptr; va_start(arg_ptr, format); vsprintf(vbuf, format, arg_ptr); PortRestore(); ClrScr(); DrawStr (0,0,vbuf,4); while(!ngetchx()); } static unsigned char and[]={0,0,0,0,0,0,0,0,0,0,0,0}; //Carré blanc pour ITALIQUE static unsigned char sur[]={ //Surlignage standard 0b01010101, 0b00000000, 0b01010101, 0b00000000, 0b01010101, 0b00000000, 0b01010101, 0b00000000, 0b01010101, 0b00000000}; static unsigned char gray[]={ //Surlignage charbon :-) 0b01010101, 0b10101010, 0b01010101, 0b10101010, 0b01010101, 0b10101010, 0b01010101, 0b10101010, 0b01010101, 0b10101010}; //Déinitialiser au besoin underwas, hau, haut, b_sauv, page_sauve //Centrage marche pas dans fenêtres multiples (num_fenster>0) car num_fenster pas sauvé (à chaque ligne)!!! //Possible de réduire à fond la taille du code en remplaçant les variables entières de type (unsigned) char par short (essayer avec la variable cc!) void _main(void) { unsigned char *bloc; unsigned char (*tfen)[16]; unsigned char (*namsaves)[4]; void * ScrTemp=NULL; //L'écran standard unsigned char *buffer; unsigned char c, cc, syncmode, lastchar; short a, aa, d, aApres; short b, bsav; unsigned char paraheight, indent; unsigned short args[7]; //arguments pour les fonctions spéciales short font, font2, gras, italic, under, color, underwas=0, k, align; short hau=0, haut=0; //Hauteur courante et max de la ligne unsigned char *(*tl); //, *savePtr=malloc(8); unsigned char *base; unsigned char* tf, *tg, *ti, *tu, *tc, *th, *tlc, *ta; unsigned char string[310]; //Chaine de caractères temporaire unsigned short pages, page; //Nombre de pages max/courant static unsigned short pagsaav=1; #ifndef PC unsigned char name_var[20]; //Pour la variable à lire #endif register unsigned char *nam; unsigned char *namdepart=namdepart; //Pointeur sur le fichier (Merci FL!) unsigned char *namsav[4]; //Sauvegarde pour le pointeur... unsigned char *nam2, *nam3; //Pointeur temporaire pour WordWrap static unsigned char wordwrap, LENT; //Modes spéciaux short z,zz; short i, espacement, espacemenh; //Variables "standardes" pour le cadrage d'images unsigned char flag, flague=0; short arg1,arg2,arg3,arg4,arg5; //Args analysés par range SCR_RECT FullScr={{0,0,239,127}}; //Plein écran. Remplacé par {{0,0,239,127}} pour une TI-92+ unsigned char pg[11]; unsigned short pgm=0; short num_fenster, num_obj; short objet[31][5]; //Les fameux objets: Images, Expr2D... short errcode; short tabul; short OSD_x,OSD_y; SCR_RECT Ecran; char ZoneEcran; unsigned char (*liens)[20]; unsigned short lienk[25], lienp[25], signet[25], mode_signet; short n_liens, ctrlh, ctrlb, gos, ctrlp,ctrlr, signets, recherchesignet, rechargepage; unsigned char *vars[12]; //Les styles. Allocation suffisante pour éviter le dépassement unsigned char mode_prelecture, debut_ligne, b_sauv=0, page_sauve=1, condbase; unsigned char call_sauve, align_sauve; unsigned char *premFois; char *chnePage, *chneSignet; #ifndef PC void *kbq=kbd_queue(); //Utilisation de OSdequeue. #endif //Initialisation unsigned char fen[4][4]; //Les fenestres :-) unsigned char *(*argsav); unsigned char styles[10][7]; //Les styles. Allocation suffisante pour éviter le dépassement #ifndef PC int HEIGHT=LCD_HEIGHT, WIDTH=LCD_WIDTH; #endif const unsigned long taille1= //Taille mémoire (zone 1) 16 *302+ //tfen 4*4 *302+ //namsaves 8 *302; //base (tableaux) const unsigned long taille2= (10*256+8*256+6*256+256)+ LCD_SIZE+120; //Ecrans const unsigned long taille3= 400+ //buffer sizeof(void*)*302+ //tl sizeof(void*)*302+ //argsav 25*20; //liens const unsigned long taille4= 302+ //chnePage 302; //chneSignet #define tailleTot (taille1+taille2+taille3+taille4) /* Debug("Stack: %lu",sizeof(bloc)+sizeof(tfen)+sizeof(namsaves)+sizeof(ScrTemp)+sizeof(buffer)+ 4*sizeof(c)+4*sizeof(a)+2*sizeof(b)+2*sizeof(paraheight)+sizeof(args)+9*sizeof(font)+ 2*sizeof(hau)+sizeof(tl)+sizeof(base)+8*sizeof(tf)+sizeof(string)+2*sizeof(page)+sizeof(pagsaav)+ sizeof(name_var)+sizeof(nam)+sizeof(namdepart)+sizeof(namsav)+2*sizeof(nam2)+2*sizeof(wordwrap)+ 2*sizeof(z)+3*sizeof(i)+2*sizeof(flag)+5*sizeof(arg1)+sizeof(myScr)+sizeof(FullScr)+sizeof(pg)+ sizeof(pgm)+2*sizeof(num_fenster)+sizeof(objet)+4*sizeof(errcode)+sizeof(Ecran)+sizeof(ZoneEcran)+ sizeof(liens)+sizeof(lienk)+sizeof(lienp)+sizeof(signet)+sizeof(mode_signet)+9*sizeof(n_liens)+ sizeof(vars)+5*sizeof(mode_prelecture)+2*sizeof(call_sauve)+sizeof(premFois)+sizeof(chnePage)+ sizeof(chneSignet)+sizeof(kbq)+sizeof(fen)+sizeof(argsav)+sizeof(styles)); Debug("RAM: %lu",tailleTot);*/ ST_showHelp(EN_COURS); //Chargement: mais c'est ce qu'on va faire... bloc = (unsigned char*)malloc (tailleTot); if (!bloc) return; memset(bloc,0,tailleTot); tfen = (unsigned char (*)[16])(bloc); namsaves = (unsigned char (*)[4])((char*)bloc+302*16); base=(u8*)bloc+302*(16+4*4); tf=base, tg=base+1*302, ti=base+2*302, tu=base+3*302, tc=base+4*302, th=base+5*302, tlc=base+6*302, ta=base+7*302; charset=(u8*)bloc+taille1; ScrTemp=(char*)charset+(10*256+8*256+6*256+256); buffer=bloc+taille1+taille2; tl=(unsigned char**)((unsigned char*)buffer+400); argsav=(unsigned char**)((unsigned char*)tl+sizeof(void*)*302); liens=(unsigned char (*)[20])((unsigned char*)argsav+sizeof(void*)*302); chnePage=(char*)bloc+taille1+taille2+taille3; chneSignet=chnePage+302; ctrlp=ctrlr=1; n_liens=recherchesignet=rechargepage=0; strcpy(chnePage,"Page %02i"); strcpy(chneSignet,"Signet %i"); LENT=0; #ifndef PC //Sur TI: récupération des arguments ESI argptr=top_estack; if(GetArgType(argptr)==45) { //Variable à éditer: Bien une chaine? strcpy(name_var,GetStrnArg(argptr)); } else goto frii; #endif memset(lienk,0,sizeof(lienk)); //Supprimer si optimisation charwidth = (unsigned char *)((void *)(charset+10*256+8*256+6*256)); SetupCharSet(); //dessine les caractères #ifndef PC DeskTop->Clip.xy.y0 = 0; DeskTop->Clip.xy.y1 = 127; #endif debut: a=b=bsav=pages=paraheight=indent=gras=italic=under=syncmode=lastchar=espacemenh=flag=ZoneEcran=c=num_obj=errcode=OSD_x=align=align_sauve=0; mode_prelecture=0; font=color=page=wordwrap=ctrlh=ctrlb=1; condbase=1; premFois=NULL; espacement=4, gos=0; signets=1; mode_signet=0; tabul=20; OSD_y=HEIGHT-5; short condition=FALSE, redo=FALSE; //ATTENTION: Si vous adaptez ce passage à la TI-92+, ne remplacez pas 160 par 240, mais 239! Et 100 par 127, impératif ou ce sera le plantage!!! for (num_fenster=0;num_fenster<=3;num_fenster++) { fen[num_fenster][0]=0; fen[num_fenster][1]=0; fen[num_fenster][2]=WIDTH-(num_fenster>0?WIDTH:0); fen[num_fenster][3]=HEIGHT-6; } num_fenster=0; //Une fenestre au départ, l'écran complet memset(styles,0,sizeof(styles)); unsigned short stack_ptr=0; short varnum=0, varsaves[302]; memset(signet,0,sizeof(signet)); // memset(ScrTemp,0,LCD_SIZE); #ifndef PC PortSet(ScrTemp,239,127); #else EffaceEcran(255); #endif memset(vars,0,sizeof(vars)); #ifndef PC nam = get_ptr(get_entry(name_var)); if (!nam) goto frii2; nam+=5; #else if (*name_var) { gblConverti=(char *)malloc(65536); FILE *f; f=fopen((const char*)name_var,"r"); i=fread(gblConverti,1,65536,f); gblConvertiTaille=i; gblConverti[i]=0; } nam=(unsigned char*)gblConverti; //Prélecture requise if (gblConvType) { flague=1; pgm=300; gos=1; mode_prelecture=0; } Output_DebutTexte(name_var); #endif memset(namsav,0,sizeof(namsav)); namsaves[0][4]=0; debu: if (align!=0) mode_prelecture=1; else mode_prelecture=0; if (mode_prelecture && condbase) { debut_ligne=1; page_sauve=page; } else debut_ligne=3; if (pages>0) goto religne; debu2: // Debug("%i %i %i",debut_ligne,a,b); if (pages==0) pages=1; call_sauve=1; goto sauve_param; religne: //Pas sûr d'avoir besoin... // if ((!align && mode_prelecture) || (align && !mode_prelecture)) // goto debu; if (debut_ligne==3) { a=fen[num_fenster][0]; } else if (debut_ligne==2) { page=page_sauve; b_sauv=b; debut_ligne=0; } else if (debut_ligne==1) { a=fen[num_fenster][0]; debut_ligne=2; page_sauve=page; page=301; goto debu2; } else if (debut_ligne==0) { if (align==1) a=(fen[num_fenster][2]+fen[num_fenster][0]-(a-fen[num_fenster][0]))>>1; else if (align==2) a=(fen[num_fenster][2]-a)+fen[num_fenster][0]; else Debug("ERREUR %i",align); b=b_sauv; // a=a_sauv, b=b_sauv; debut_ligne=1; page_sauve=page; page=301; goto restore_etat; } religne2: // a=fen[num_fenster][0]; if (lastchar==CAR_ENTER && indent) a+=tabul; #ifndef PC //Mode de synchronisation fluide. Inutile et non-supporté sur PC. if (b>bsav && !syncmode && b<128 && condition) memcpy(LCD_MEM+30*bsav,ScrTemp+30*bsav,(b-bsav)*30); #endif bsav=b; haut=6+(2*font)+(gras>>1); underwas=under>2? under-2: under; hau=haut; while(1) { redo: redo=FALSE; namdepart=nam; c=*nam++; //Permet d'aérer avec des espaces sans que ceux-ci soient pris en compte en cas de commentaire en milieu de ligne if (*(nam-2)==CAR_ENTER && c==32) c=*nam++; //Enlève un espace éventuel en début de ligne (dans le format texte standard, après le caracètre 13 vient celui-là) // if (c==32 && *nam==215) goto redo; //Commentaire -> on saute toute la partie du code jusqu'à la balise fermante ou la fin du fichier if (c==215) { while (*nam!=0 && *nam++!=215); //Enter après ça = fini if (*nam==CAR_ENTER) nam++; goto redo; } //Condition à remplir pour pouvoir afficher les infos à l'écran condbase=(pgm<=0 || page==pgm || page==1) && flague==0 && !rechargepage; condition=condbase && debut_ligne; //Fin du fichier if (c==0) goto pgbrk; //Entrée if (c==CAR_ENTER) { #ifdef PC Output_Caractere(CAR_ENTER,font,gras,italic,under,color); #endif lastchar=CAR_ENTER; break; } //Code de format © if (c==169) goto format; //Commande spéciale (i des nombres complexes) if (c==151) goto special; //Point virgule, séparateur d'argument if (c==59 && varnum==10) { vars[10]=nam; z=12; varnum=15; goto handler; } if (c==12 && signets<25) { //page break (12) -> pose un signet. mode_signet=1; for (i=1;i bloque le début du texte ici. // nam++; // if (page==1) goto debu; nam++; call_sauve=1; goto sauve_param; } /* if (*nam==42 && signets<25) { //$* -> pose un signet. mode_signet=1; nam++; for (i=1;i11)) { if (stack_ptr>0) { nam=namsav[--stack_ptr]; varnum=stack_ptr; if (z==11) goto apres_handler; goto redo; } else { nam--; goto pas_macro; } } if (varnum>=0 && varnum<=11) { if (*nam=='=') { //Stockage dans une macro vars[varnum]=++nam; reessaye: while (*(nam++)!=36 && *nam); if (*nam>=49 && *nam<=58) goto reessaye; if (varnum==11 && premFois!=nam) { premFois=nam; memset(ScrTemp,0,LCD_SIZE); goto here; } varnum=0; } else if (vars[varnum]) { //Collage macro (si elle existe) if (*nam==';') { vars[10]=++nam; while (*nam++!=36 && *nam); } here: namsav[stack_ptr++]=nam; nam=vars[varnum]; //Transfère la lecture sur la macro //Workaround pour le système d'alignement!!! if (varnum==11) goto debu; /*if (*nam==';') { while ((*++nam)!=';' && *nam) string[i++]=*nam; string[i]=3; if (b+atoi(string)>fen[num_fenster][3]) { nam=namsav[--stack_ptr]; varnum=stack_ptr; c=32; goto pgbrk; } }*/ } else varnum=0; } goto redo; } pas_macro: //Style (shift) //Spécialité: aucune if (c==27) { arg1=(*nam++)-48; //Numéro de style if (arg1==CAR_ENTER) { //Un égal -> stocke le style arg1=(*nam++)-48; //Le numéro se trouve après ;) if (arg1>=0 && arg1<=9) { //Ajoute au style arg1 le format courant styles[arg1][0]=font; styles[arg1][1]=gras; styles[arg1][2]=italic; styles[arg1][3]=under; styles[arg1][4]=color; styles[arg1][5]=hau+2*under; styles[arg1][6]=1; //Le style est bien valide (1) } goto redo; } else { if (arg1>=0 && arg1<=9 && styles[arg1][6]==1) { //signifie que le style est "valide". Très important! font=styles[arg1][0]; gras=styles[arg1][1]; italic=styles[arg1][2]; under=styles[arg1][3]; color=styles[arg1][4]; hau=styles[arg1][5]-2*under; goto parse; } } goto redo; } //Slash //Spécialités: \t, \\, \enter, \p, \xxx if (c==92) { i=0; if (*nam=='t') { //Tabulation a/=tabul; a++; //Arrondir a à la tabulation la plus proche par division entière et passer à la prochaine a*=tabul; *nam++; redo=TRUE; goto fi; } else if (*nam==CAR_ENTER) { //Retour à la ligne, saute une ligne sans la prendre en compte nam++; //L'espace qui vient ensuite... goto redo; } else if (*nam=='\\') { //Second slash -> imprime un seul slash c='\\'; *nam++; goto fi; } else if (*nam=='p') { //Saut de page *nam++; goto pgbrk; } else { while (*nam>=48 && *nam<=57 && i<3) //Un nombre -> imprime le caractère correspondant au code fourni string[i++]=*nam++; string[i]=0; if (i==0) c='\\'; //Pas un code de touche, ou code inconnu -> imprime un slash. else c=atoi((s8*)string); } } //Label over-bien nommé qui définit la fin d'une gestion de slash. fi: //Anticipation de la valeur de a si on y ajoute la largeur de caractère. aApres=a+LONGCHAR(c,font); //Vérification pour tous les objets si le texte se trouve au-dessus. for (i=1;i<=num_obj;i++) { if (aApres>objet[i][1] && a<=objet[i][3] && b+haut+2*underwas-2>=objet[i][2] && b+2<=objet[i][4]) { a=objet[i][3]+1; nam=namdepart; //a-=LONGCHAR(32,font); c=32; goto redo; } } if (b+haut+(underwas<<1)-1>=fen[num_fenster][3]) { nam=namdepart; goto pgbrk; } if (aApres>fen[num_fenster][2]) { nam=namdepart; break; } if (redo) goto redo; #ifdef PC //Conversion requise -> word wrap à zéro! if (gblConvType) wordwrap=0; #endif if (wordwrap && c==32) { //Le wordwrap va agir sur les espaces s'il est activé nam2=nam; aa=aApres; font2=font; while (1) { z=*nam2; if (z==32 || z==36 || z==CAR_ENTER || z==59) //Les seules manières "légales" de terminer le word wrap... (espace/retour à la ligne) break; if (font2==0) aa+=charwidth[z]; else aa+=4+2*font2; if (aa>fen[num_fenster][2]) goto brea; if (z==169) { //Un break dans le word wrap signifie qu'on ne gère pas ce cas. Cela créera des "bugs" de word wrapping dus à sa limitation, mais de toutes façons, il n'est pas très judicieux de changer la fonte en plein milieu d'un mot... break; //Décommentez les lignes suivantes (et commentez donc le break ci-dessus, cela va de soi) pour activer le support du wordwrap avec des mots en fonte multiple (un peu inutile) /* if (*(++nam2)=='F') { if (*(++nam2)<'3') font2=(*(nam2)-48); } else *nam2++; *nam2++; continue;*/ } //Support pour les styles. En fait, je me rends compte que c'est quasiment inutile vu que des tas de choses peuvent changer après cette commande -> commenté! if (z==27) { break; /* nam2++; if (*nam2=='=') nam2++; nam2++; continue;*/ } //Je n'ai pas implémenté de véritable support pour les slashs. Il ne vaut donc mieux pas décommenter les lignes ci-dessous... if (z==92) { break; /* nam2++; if (*nam2=='t' || *nam2=='p') break; else { while (*nam2>=48 && *nam2<=57) *nam2++; nam2--; } z='n';*/ } //Support pour les commandes. A nouveau, c'est quasiment inutile -> poubelle if (z==151) { break; /* *nam2++; while(*nam2!=151 && *nam2) *nam2++; *nam2++; continue;*/ } //Tiens donc, c'est quoi ça 215? Ah oui, le commentaire. Ca je laisse. if (z==215) { *nam2++; while(*nam2!=215 && *nam2) *nam2++; *nam2++; continue; } *nam2++; // if (aa+LONGCHAR(*nam2,font2)>fen[num_fenster][2]) goto brea; } } #ifdef PC Output_Caractere(c,font,gras,italic,under,color); #endif //Condition -> on a bien envie d'afficher quelque chose. C'est utile pour accélérer l'affichage des pages if (c!=32 && condition) { #ifndef PC if (italic && gras) Sprite8_AND(a,b,hau,and,ScrTemp); if (font==0) FastChar(a,b,c,ScrTemp,6,18); else if (font==1) FastChar(a,b,c,ScrTemp,8,10); else FastChar(a,b,c,ScrTemp,10,0); if (gras) { Sprite8Get(a,b,hau,ScrTemp,buffer); if (gras==1) Sprite8_OR(a+1,b,hau,buffer,ScrTemp); else if (gras==2) Sprite8_OR(a,b+1,hau,buffer,ScrTemp); else Sprite8_OR(a+1,b+1,hau,buffer,ScrTemp); } if (c!=32) { if (italic) { //Support pour mettre plus en italique la fonte deux que les autres... mais ça prend trop de place... // if (font!=2) { Sprite8Get(a,b,hau>>1,ScrTemp,buffer); Sprite8_AND(a,b,hau>>1,and,ScrTemp); Sprite8_OR(a+1,b,hau>>1,buffer,ScrTemp); /* } else { Sprite8Get(a,b,hau/3,ScrTemp,buffer); Sprite8_AND(a,b,hau/3,and,ScrTemp); Sprite8_OR(a+2,b,hau/3,buffer,ScrTemp); Sprite8Get(a,b+hau/3,hau/3,ScrTemp,buffer); Sprite8_AND(a,b+hau/3,hau/3,and,ScrTemp); Sprite8_OR(a+1,b+hau/3,hau/3,buffer,ScrTemp); }*/ } } #else //Le code pour PC est plus simple! :p DessCar(a,b,c,font,gras,italic); #endif } d=a; a=aApres; lastchar=c; if (condition) { if (under) { if (under<3 || c!=32) { FastDrawHLine(ScrTemp,d,a-1,b+hau); if (under==2 || (under==4 && c!=32)) FastDrawHLine(ScrTemp,d,a-1,b+hau+2); } } //Dessine le surlignage. Il doit y avoir de meilleures méthodes. Heu pardon, il y A de meilleures méthodes (j'y pense maintenant mais j'ai la flemme, et ça doit prendre plus de place). %) if (color==0) { for (z=b;z 0 num_obj=0; //A p'us d'objet! FontSetSys(0); //Pour dessiner l'indicateur de page. ici: if (debut_ligne==0) //La condition ne pouvait pas être fausse condition=condbase; if (page on revient à la première gos=2; //Houlà, je ne sais plus ce que ça signifie ça... #ifdef PC //Conversion terminée if (gblConvType) { Output_FinTexte(); goto debut; // goto fin; } #endif } goto key; } //Sur TI, il faut afficher l'écran avant l'indicateur, sur PC c'est l'inverse #ifndef PC if (condition) { LCD_restore(ScrTemp); //Affiche le contenu de notre écran... } #endif //Placer dans le if (condition) pour accélérer (pas mal à gagner) PortRestore(); #ifndef PC if (OSD_y<=123) //L'indicateur n'est pas disposé trop bas? printf_xy(OSD_x,OSD_y,chnePage,page); #else if (OSD_y<=123) //L'indicateur n'est pas disposé trop bas? DrawPetiteStrAvecFond_xy(OSD_x,OSD_y,0,0,0,chnePage,page); #endif //Sur PC, il faut afficher l'écran avec l'indicateur, sur TI ça doit être fait avant #ifdef PC // if (condition) // AfficheEcran(); #endif /*Alors là... flague = cacher le texte (pendant le chargement) rechargepage = si on cherche un signet par exemple, il faudra recharger la page courante. pgm = page recherchée (si l'utilisateur tape un numéro de page) */ if (flague==0 && !rechargepage && (page==pgm || pgm<=0 || (c==0 && pgm>page) || page>=300)) { k=keywait(); //Attente d'une touche #ifdef PC if (k==32766) { //Signal de menu if (SignalMenu==1 && SignalObjet==0) { //Fichier -> Ouvrir char nom[MAX_PATH]; memset(nom,0,sizeof(nom)); if (OuvreFichier(nom,ctChneOuverture)) { strcpy(gblFichierAOuvrir,nom); gblReturnValue=1; goto fin; } } else if (SignalMenu==1 && SignalObjet==1) { //Fichier -> Fermer gblReturnValue=1; goto fin; } else if (SignalMenu==1 && SignalObjet==2) //Fichier -> Quitter k=T_ESCAPE; else if (SignalMenu==2 && SignalObjet==0) { //Convertir -> RTF gblConvType = CVT_RTF; goto debut; } else if (SignalMenu==2 && SignalObjet==1) { //Convertir -> HTML gblConvType = CVT_HTML; goto debut; } else if (SignalMenu==2 && SignalObjet==2) { //Convertir -> Texte gblConvType = CVT_TXT; goto debut; } else if (SignalMenu==2 && SignalObjet==3) { //Convertir -> TXT / 89T if (*name_var) { char *ext, nomTemp[MAX_PATH]; char *charge, *converti; FILE *f; strcpy(nomTemp,name_var); ext=strstr(nomTemp,"."); if (ext) strcpy(ext,ReadRegistryString("ExtensionTI",".89t")); //Conversion directe en 89T charge = (char*)malloc(MAX_TEXTE); converti = (char*)malloc(MAX_TEXTE); //Conversion en txt f=fopen(name_var,"rb"); _in_set (charge, fread(charge,1,MAX_TEXTE,f)); fclose(f); _out_set (converti, MAX_TEXTE); IOConvTxtTo89t("main",nomTemp); f = fopen(nomTemp,"w"); fwrite (converti,1,_out_cur_size,f); fclose(f); free(charge); free(converti); } else { char *ext, nomTemp[MAX_PATH]; FILE *f; strcpy(nomTemp,gblFichier); ext=strstr(nomTemp,"."); if (ext) strcpy(ext,".txt"); //Conversion en txt f = fopen(nomTemp,"w"); if (f) { fwrite (gblConverti,1,gblConvertiTaille,f); fclose(f); } } } else if (SignalMenu==3 && SignalObjet==0) //TI-89 (2x) SetWindowPos(hConsole,HWND_TOP,0,0,tailleX+160,tailleY+100,SWP_NOZORDER|SWP_NOMOVE); else if (SignalMenu==3 && SignalObjet==1) //TI-92+ (2x) SetWindowPos(hConsole,HWND_TOP,0,0,tailleX+80+240,tailleY+28+128,SWP_NOZORDER|SWP_NOMOVE); else if (SignalMenu==3 && SignalObjet==2) //TI-89 (1x) SetWindowPos(hConsole,HWND_TOP,0,0,tailleX,tailleY,SWP_NOZORDER|SWP_NOMOVE); else if (SignalMenu==3 && SignalObjet==3) //TI-92+ (1x) SetWindowPos(hConsole,HWND_TOP,0,0,tailleX+80,tailleY+28,SWP_NOZORDER|SWP_NOMOVE); //Redimensionnement if (SignalMenu==3) { if (SignalObjet<2) scaling_fen=2; else scaling_fen=1; //TI-92+ if (SignalObjet%2) { ECRAN *ecrTemp; ecrTemp=CreeEcran(240,128); WIDTH=240; HEIGHT=128; ChoisitEcran(ecrTemp); } //TI-89 else { ECRAN *ecrTemp; ecrTemp=CreeEcran(160,100); WIDTH=160; HEIGHT=100; ChoisitEcran(ecrTemp); } goto debut; } } #endif pgm=0; //Cela signifie qu'on a trouvé la page que l'on recherchait } else { rechargepage=0; //Pas besoin de recharger la page courante k=0; //Prendre en compte la touche appuyée flague=0; if (!ctrlr) goto noctrlr; if (pgm<=pages) page=pgm; else if (pgm>pages && page!=pages) page=pages; else { noctrlr: if (page quitte if (k==T_BACKSPACE) { DrawStr(0,HEIGHT-5,CHAINE_VERSION,4); k=keywait(); } //Il faut vérifier si l'utilisateur a appuyé sur l'un des liens... //Nouveau: il est maintenant possible d'identifier un signet ET un texte dans le même lien! Exemple: //iK1,2,main\textei -> la touche 1 ouvrira main\texte et cherchera le deuxième signet. for (z=0;z0 && i<25) { //On recherche un signet? if (signet[i]) //Il existe? pgm=signet[i]; //Alors on place sur ce signet else { //Le signet n'a pas encore été trouvé pgm=300; //On le recherche sur les 300 pages du document recherchesignet=i; } } goto ici; //Cas #1: Ce n'est pas bon, redonnez une touche... Cas #2: Relancer la procédure de recherche de page (comme si l'utilisateur avait tapé un numéro de page à accéder) } } if (k==T_APPS) { //APPS: Restaure la dernière page visitée (pour autant que le programme ne soit pas archivé) pgm=pagsaav; //Ouah le nom! Ah, ce n'était pas le Gaamsaav dans Outcast ou un truc du style? goto pgmx; } //L'utilisateur veut accéder à une page car il a tapé un nombre if (k>='0' && k<='9' && ctrlp) { z=0; memset(pg,0,9); if (mode_signet) strcpy((s8*)string,chneSignet); else strcpy((s8*)string,chnePage); strcat((s8*)string," "); while (k>47 && k<58 && z<3) { pg[z++]=k; pgm=atoi((s8*)pg); #ifndef PC if (OSD_y<=123) printf_xy(OSD_x,OSD_y,(s8*)string,pgm); #else if (OSD_y<=123) DrawPetiteStrAvecFond_xy(OSD_x,OSD_y,0,0,0,(s8*)string,pgm); #endif if (z<3) k=keywait(); } //pgm=atoi(pg); pgmx: if (mode_signet) { i=pgm; goto chercheSignet; } else goto ici; //flague=1; //if (pgm>300) pgm=300; } //Gestion des touches utilisateur key: //OSSetSR(0x0700); //Haut if (k==T_HAUT && page>1 && (ctrlh || !condition)) page--; //Bas if (k==T_BAS && c>0 && page<300 && (ctrlb || !condition)) page++; if (page>pages) { //La page n'existe pas encore -> on sauvegarde l'état du texte pour pouvoir le restaurer (revenir en arrière) pages++; call_sauve=0; sauve_param: tl[page]=nam; tf[page]=font; tg[page]=gras; ti[page]=italic; tu[page]=under; tc[page]=color; th[page]=paraheight+(indent<<7); tlc[page]=lastchar; ta[page]=align; memcpy(tfen[page],fen,16); memcpy(namsaves[page],namsav,sizeof (*namsaves)); argsav[page]=vars[10]; varsaves[page]=stack_ptr; if (call_sauve) { goto religne; } } else { //Elle existe déjà -> on restaure l'état du texte à ce moment-là. restore_etat: nam=tl[page]; font=tf[page]; gras=tg[page]; italic=ti[page]; under=tu[page]; color=tc[page]; lastchar=tlc[page]; align=ta[page]; indent=th[page]>>7; paraheight=th[page]&127; memcpy(fen,tfen[page],16); memcpy(namsav,namsaves[page],sizeof (*namsaves)); vars[10]=argsav[page]; varnum=stack_ptr=varsaves[page]; if (debut_ligne==1) { page=page_sauve; goto religne2; } } //LCD_restore(ScrTemp); //Ceci n'est pas obligatoire, il affiche juste un écran blanc lors des chargements. PortSet(ScrTemp,239,127); //On remet notre écran temporaire. ctrlh=ctrlb=1; //Contrôles à nouveau actifs. if (!ZoneEcran) { //Si aucune zone écran n'a été définie, alors on efface l'écran entier #ifndef PC memset(ScrTemp,0,LCD_SIZE); #else EffaceEcran(255); #endif } else //Sinon uniquement la zone concernée ScrRectFill(&Ecran,&FullScr,0); a=fen[num_fenster][0]; //Replace le curseur dans le coin haut-gauche de la fenêtre courante (qui est la première à ce moment) b=fen[num_fenster][1]; bsav=0; z=varnum; //Sauvegarde la variable active varnum=11; //On passe à la onzième (macro $; auto-exécutée à chaque page) align_sauve=align; align=0; if (vars[11]) //Si la macro existe goto handler; //On va la gérer (en fait on agit comme si l'utilisateur venait de taper "$;") apres_handler: varnum=z; //On restaure la macro active align=align_sauve; goto debu; //Et c'est reparti pour la boucle principale! //Gestion des formats. Un beau goto nous amènera par là. C'est moche, mais au moins c'est rapide et ça permet de partager les variables. Rapide+Petit+Moche = Je_prends format: c=*nam++; //Propriété (alpha) à modifier cc=*nam++; //Valeur (numérique) à affecter if (cc>='0') { cc-='0'; //Nombre ASCII -> nombre if (c=='F' && cc<=2) font=cc; //©F0-©F2 : Modifie la fonte courante else if (c=='G' && cc<=3) gras=cc; //©G0-©G3 : Modifie l'effet (gras) du texte else if (c=='I' && cc<=1) italic=cc; //©I0-©I1 : Modifie l'italique du texte else if (c=='S' && cc<=4) under=cc; //©S0-©S4 : Modifie le soulignement du texte else if (c=='C' && cc<=4) color=cc; //©C0-©C4 : Modifie la couleur et/ou le surlignage. ©C1 par défaut else if (c=='A' && cc<=2) { align=cc; mode_prelecture=cc; goto debu; } else if (c=='W' && cc<=5) { //©W0-©W5 : Modifie le word wrapping ainsi que d'autres paramètres. Pair=pas de word wrapping, Impair=oui. 0=mode synchrone (l'écran est affiché une fois qu'il a terminé de charger), 2=(par défaut) Mode asynchrone (met à jour l'écran par parties), 4=Mode RPG (affiche caractère par caractère) wordwrap=cc&1; //cc modulo 2 if (cc>=4) { LENT=1; syncmode=0; } else if (cc>=2) syncmode=0; else syncmode=1; } } hau=6+(2*font)+(gras>>1); //On recalcule la hauteur parse: //Alors ce bout-là, je ne me rappelle vraiment plus à quoi il sert... (je vais essayer de commenter) z=(a==fen[num_fenster][0]+(indent?tabul:0)); //Détecte si on est au début d'une ligne if (under>2? under-2: under>underwas || z) underwas=under>2? under-2: under; //Heu... ah oui, underwas indique si le soulignement a au moins été activé une fois dans la ligne. Il s'agit d'une méthode bourrin. if (hau>haut || z) haut=hau; //La hauteur calculée est plus grande que la hauteur de la ligne -> on aggrandit la ligne goto redo; //On repasse dans la boucle principale. //Caractère de commandes (i) special: nam2=nam-1; special2: c=*nam++; //deb: zz=0; memset(args,255,sizeof(args)); //Remplit les arguments de 255 (?) //J'ai hésité à me programmer un indenteur pour l'occasion. Résultat: j'aurais mieux fait de le faire, ça m'aurait pris moins de temps! :D do { memset(string,0,299); aa=0; if (*nam=='-') { //L'utilisateur va rentrer un argument relatif à la position du curseur aa=-1; nam++; } if (*nam=='+') { aa=1; nam++; } z=0; //Longueur de la chaîne de l'argument while (*nam>=48 && *nam<=57) //Tant que c'est bien des nombres string[z++]=*nam++; if (z) //Au moins un chiffre? args[zz]=atoi((cs8*)string); //Chaîne -> entier pour l'argument en cours... else //Pas d'argument fourni -> position du curseur prise à la place args[zz]=500; //500 = centre (+0) if (aa!=0) args[zz]=500+args[zz]*aa; //Position relative +x ou -x zz++; //Un argument de plus fourni } while (*nam++==44 && zz<5); //Tant qu'une virgule est disponible (séparatrice d'arguments) //Un flag pour plus tard, voir plus bas. if (zz>1) flag=0; else flag=1; //Le prochain argument est une chaîne memset(string,0,299); z=0; if (*(nam-1)!=' ') *nam--; while (*nam!=151 && (*nam!=124 || (c=='E' || c=='e')) && z<299) { //Maximum 300 caractères string[z++]=*nam++; //On remplit la chaîne } *nam++; //Saute un caractère (celui de fermeture) /* Commande: 'k' Paramètres: aucun Alias: Keylink (minuscule pour la destruction) Efface tous les liens enregistrés, ceux-ci subsistant même si on passe d'un texte à l'autre (pratique) */ if (c=='k') n_liens=0; /* Commande: 'K' Paramètres: touche [,signet] [,nom_fichier] Alias: Keylink (majuscule pour la création) Crée un lien vers un fichier ou vers un signet et/ou un fichier (vous pouvez fournir l'un des deux arguments ou les deux, au choix) et l'associe à la touche spécifiée (il s'agit d'un code TI-BASIC GetKey ou d'un nombre de 0 à 9) */ if (c=='K') { if (args[0]<=9) args[0]+=48; //Touches numériques 0-9 zz=n_liens; //Sauvegarde du nombre de liens for (z=0;z=25) args[1]=0; //Max: 25 signets (donc -> 0 si un nombre plus grand a été choisi) lienp[zz]=args[1]; //Enregistrement du signet memcpy(liens[zz],string,17); //Copie le nom du fichier en question if (n_liens<24 && zz==n_liens) n_liens++; //Incrémente le nombre de liens } //Les quatre premiers arguments sont gérés de manière à pouvoir être relatifs ou absolus avec comme maximum et minimum 0 et 240/128 et comme défaut a/b. arg1=range(args[0],0,240,a); arg2=range(args[1],0,128,b); arg3=range(args[2],0,240,a); arg4=range(args[3],0,128,b); //Pour le cinquième, cela dépend, si on identifie une fenêtre ou non if (c=='w' || c=='W' || c=='F') arg5=range(args[4],0,3,num_fenster); //Si oui, alors le min/max est 0 à 3, et par défaut c'est la fenêtre courante else arg5=range(args[4],0,254,2); //Sinon c'est un attribut graphique -> entre 0 et 254 // if (arg1==a && arg2==b) //Aux positions courantes? Utilisé pour un objet (expr/image): si oui, on laisse un espace selon les dimensions de l'objet en question, sinon on n'en tient pas compte (il sera placé comme "arrière-plan") // flag=1; //C'est donc "flag" qui gère cela /* Commande: 'C' Paramètres: [x [,y]] Alias: Curseur / Cursor Modifie la position du curseur. L'analyseur d'arguments est souple, par exemple, vous pouvez faire ceci: iC0i, iC+10i, iC,-10i, iC40,15i, etc. */ if (c=='C') { a=arg1; b=arg2; } /* Commandes: flèches haut/bas/gauche/droite Paramètres: 1/0 (activé/désctivé) Alias: Aucun, cela parle de soi. Haut/Bas: Autorise ou non l'utilisation des touches de navigation (haut/bas donc). Le concept est bien entendu prévu pour pouvoir bloquer l'utilisateur dans une certaine zone de pages. Droite: Autorise l'accès à une page donnée en la tapant au fond (si on veut se cantonner à l'utilisation des liens) Gauche: Autorise l'accès rapide aux pages déjà affichées (par exemple vous allez à la page 100, alors l'accès aux autres pages en dessous (ex. 50) sera plus rapide, ceci permet de désactiver cette optimisation, en cas de workaround) */ if (c==21) ctrlr=arg1; if (c==22) ctrlp=arg1; if (c==23) ctrlh=arg1; if (c==24) ctrlb=arg1; if (condition) { //Routines graphiques dont l'exécution n'est pas vitale /* Commande: 'A' Paramètres: temps (vingtièmes de seconde) Alias: Attend Attend un moment (pour le mode lent) et une touche si zéro comme temps. */ if (LENT && c=='A' && pgm<=0) { LCD_restore(ScrTemp); wait(arg1); } /* Commande: 'B' Paramètres: x0,y0,x1,y1 [,mode] Alias: Boîte / Box Dessine une boîte pleine sur l'écran en utilisant les coordonnées fournies et le mode allant de 0 à 2. */ if (c=='B') { //Dessine une boîte pleine #ifndef PC ScrRectFill (&(SCR_RECT){{arg1, arg2, arg3, arg4}}, &FullScr, arg5); #else //Ma version de MSVC++ (6.0) ne supporte pas cette construction, en revanche GCC oui (mais y a pas de quoi troller...) SCR_RECT scrRect={{arg1, arg2, arg3, arg4}}; ScrRectFill (&scrRect, &FullScr, arg5); #endif } /* Commande: 'R' Paramètres: x0,y0,x1,y1 [,mode] Alias: Rectangle Dessine un rectangle (dont l'intérieur est vide) sur l'écran en utilisant les coordonnées fournies et le mode allant de 0 à 254. */ if (c=='R') { //Dessine un rectangle DrawClipRect(MakeWinRect(arg1,arg2,arg3,arg4),&FullScr,arg5); } /* Commande: 'L' Paramètres: x0,y0,x1,y1 [,mode] Alias: Ligne / Line Dessine une ligne partant de x0,y0 vers x1,y1 sur l'écran avec le mode allant de 0 à ?. */ if (c=='L') //Dessine une ligne DrawLine(arg1,arg2,arg3,arg4,arg5); /* Commande: '/' Paramètres: 0/1 (blanc/noir) Alias: / (barre l'écran) Efface l'écran en le remplissant de blanc ou de noir et remet le curseur au coin gauche. */ if (c=='/') { a=0; b=0; memset(ScrTemp,255*arg1,LCD_SIZE); } } /* Commande: 'G' Paramètres: aucun Alias: Goto (va à la fin du texte et revient, mauvais nom car autre chose à la base) Ceci a pour effet d'afficher toutes les pages du début à la fin. La navigation est ensuite très rapide. Généralement, ce n'est pas utile, mais si vous voulez faire un document interactif, ça peut être pratique. */ if (c=='G' && gos==0) { //GOTO flague=1; pgm=300; gos=1; mode_prelecture=0; } /* Commande: 'i' Paramètres: nom du fichier Alias: inclure / include Cela n'effectue malheureusement pas un #include mais passe sur un autre fichier. Généralement ce n'est pas utile, mais vous pourriez compléter un texte par un autre fichier dans lequel vous insérez des liens ou une table des matières, puis ajoutez le fichier de base (comprenne qui pourra :D). */ /* if (c=='i') nam = get_ptr(get_entry(string))+5;*/ /* Commande: 'H' Paramètres: hauteur Alias: Hauteur / Height Règle l'espacement vertical (hauteur supplémentaire) entre les paragraphes. */ if (c=='H') paraheight=arg1; /* Commande: 'Z' Paramètres: x0,y0,x1,y1 Alias: Zone (d'écran) / (Screen) Zone Définit la zone d'écran active. Le reste ne sera pas mis à jour à chaque changement de page. Par exemple: vous dessinez un texte au sommet de l'écran, vous changez la zone d'écran pour qu'elle ne passe pas sur ce texte, et il restera affiché jusqu'à la fin (un $lock peut-être utile dans ce cas-là, consultez la documentation). Parfois plus utile qu'une macro $; pour dessiner le texte sur chaque page. */ if (c=='Z') { //Redéfinit la zone écran #ifndef PC Ecran=(SCR_RECT){{arg1,arg2,arg3,arg4}}; #else Ecran.xy.x0=arg1, Ecran.xy.y0=arg2, Ecran.xy.x1=arg3, Ecran.xy.y1=arg4; #endif ZoneEcran=1; /* //Change également la fenêtre courante fen[num_fenster][0]=arg1; fen[num_fenster][1]=arg2; fen[num_fenster][2]=arg3; fen[num_fenster][3]=arg4;*/ arg5=num_fenster; goto fenster; } /* Commande: 'P' ou 'p' Paramètres: x,y,nom_image Alias: Picture (image en anglais) Dessine une image. Si aucune position x,y n'est spécifiée, l'image sera cadrée (P majuscule), c'est à dire que le texte ne pourra pas passer par-dessus, ou alignée (p minuscule). Si vous avez utilisé le p minuscule et que vous spécifiez des positions (ip15,10,image, ou même ip,,imagei), alors l'objet sera placé comme fond, et aucun espace ne lui sera alloué. La syntaxe étant assez souple, vous pouvez omettre la virgule entre les arguments numériques et les noms, exemples: iPimagei, iP20,15imagei et ainsi de suite... */ //Les images ne sont pas encore supportées sur PC, et les expressions ne le seront probablement jamais... #ifndef PC if (c=='P' || c=='p') { //Dessine une image et en fait éventuellement un objet if (c=='P') i=1; //Objet? else i=0; //Non! nam3 = get_ptr(get_entry(string)); //Nom du fichier? if (*(nam3+256**nam3+*(nam3+1)+1) == 0xDF) { //C'est bien une image? if (b+*(unsigned short*)(nam3+2)+espacemenh>fen[num_fenster][3] && flag!=0) { //Dépassement en bas? nam=nam2; //Restaure le pointeur sur le texte goto pgbrk; //Saut de page } if (a+*(unsigned short*)(nam3+4)+espacement>fen[num_fenster][2] && flag!=0) { //Dépassement à droite? nam=nam2; //Restaurer le pointeur, comme si on n'avait rien fait... goto brea; //Saut de ligne } if (condition) //Affichage permis? bitmap_put(arg1+(espacement>>1),arg2+(espacemenh>>1),nam3); //Dessine la bitmap if (i!=0 && num_obj<30) { //Si objet requis (i==1), le max. est 30 objets num_obj++; //Un objet de plus objet[num_obj][1]=arg1+1; //On encadre l'objet objet[num_obj][3]=arg1+espacement+*(unsigned short*)(nam3+4)-1; objet[num_obj][2]=arg2+1; objet[num_obj][4]=arg2+espacemenh+*(unsigned short*)(nam3+2)+1; } else if (flag) { //Vous avez déjà oublié à quoi sert flag (ça tombe bien moi aussi)... ça aligne le texte (mode 'p' sans spécification de position) a+=*(unsigned short*)(nam3+4)+espacement; //Le mode de base quoi, laisse l'espace requis horizontalement z=*(unsigned short*)(nam3+2)+espacemenh+1; //Et incrémente la hauteur effective de la ligne if (z>haut) haut=z; //s'il y a lieu. } } } /* Commande: 'E' ou 'e' Paramètres: x,y,expression Alias: Expression Dessine une expression en pretty print. Les mêmes règles que pour les images sont applicables. Pour les expressions, vous devez séparer le iE et l'expression d'un espace, car votre expression peut commencer par un nombre, donc être pris pour un argument numérique de repositionnement. Exemple: ie 1/(1/2+1/2)i */ if (c=='E' || c=='e') { //Dessine une expression en pretty print et en fait un objet if (c=='E') i=1; //Objet? else i=0; //Non! WinAttr(DeskTop,1); TRY errcode=0; argptr=top_estack; push_parse_text (string); Parse2DExpr (top_estack, FALSE); Parms2D(top_estack,&arg3,&arg4,&arg5); if (b+espacemenh+arg4+arg5+1>fen[num_fenster][3] && flag!=0) { nam=nam2; errcode=1; goto fn; } if (a+espacement+arg3>fen[num_fenster][2] && flag!=0 && a!=fen[num_fenster][0]) { nam=nam2; errcode=2; goto fn; } if (condition) Print2DExpr (top_estack, DeskTop, arg1+(espacement>>1)-1, arg2+arg5-1+(espacemenh>>1)); if (num_obj<30 && i) { num_obj++; objet[num_obj][1]=arg1-1; objet[num_obj][3]=arg1+espacement+arg3-1; objet[num_obj][2]=arg2-1; objet[num_obj][4]=arg2+espacemenh+arg4+arg5+1; } else if (flag) { a+=arg3+espacement; z=arg4+arg5+espacemenh+1; if (z>haut) haut=z; } fn: top_estack=argptr; ONERR ENDTRY if (errcode==1) goto pgbrk; if (errcode==2) goto brea; } #else if (c=='P' || c=='p') { //Dessine une image et en fait éventuellement un objet char *ptrslash; char tempname1[sizeof(string)+4], tempname2[sizeof(string)+4]; OBJET *tempObjet; if ((ptrslash=strstr((const char*)string,"\\"))) *ptrslash='.'; else { memmove(string+5,(const char*)string,strlen((const char*)string)); memcpy((void*)string,"main.",5); } strcpy(tempname1,(const char*)string); strcpy(tempname2,(const char*)string); strcat(tempname1,".89i"); strcat(tempname2,".bmp"); Conv89iToBmp(tempname1,tempname2); //Partie standard if (c=='P') i=1; //Objet? else i=0; //Non! _supportMasque=0; tempObjet=ChargeObjet(tempname2); _supportMasque=1; if (tempObjet) { //C'est bien une image? if (tempObjet->hauteur+espacemenh>fen[num_fenster][3] && flag!=0) { //Dépassement en bas? nam=nam2; //Restaure le pointeur sur le texte DetruitObjet(tempObjet); goto pgbrk; //Saut de page } if (a+tempObjet->largeur+espacement>fen[num_fenster][2] && flag!=0) { //Dépassement à droite? nam=nam2; //Restaurer le pointeur, comme si on n'avait rien fait... DetruitObjet(tempObjet); goto brea; //Saut de ligne } if (condition) //Affichage permis? Objet(tempObjet,arg1+(espacement>>1),arg2+(espacemenh>>1)); //Dessine la bitmap //bitmap_put(arg1+(espacement>>1),arg2+(espacemenh>>1),nam3); //Dessine la bitmap if (i!=0 && num_obj<30) { //Si objet requis (i==1), le max. est 30 objets num_obj++; //Un objet de plus objet[num_obj][1]=arg1+1; //On encadre l'objet objet[num_obj][3]=arg1+espacement+tempObjet->largeur-1; objet[num_obj][2]=arg2+1; objet[num_obj][4]=arg2+espacemenh+tempObjet->hauteur+1; } else if (flag) { //Vous avez déjà oublié à quoi sert flag (ça tombe bien moi aussi)... ça aligne le texte (mode 'p' sans spécification de position) a+=tempObjet->largeur+espacement; //Le mode de base quoi, laisse l'espace requis horizontalement z=tempObjet->hauteur+espacemenh+1; //Et incrémente la hauteur effective de la ligne if (z>haut) haut=z; //s'il y a lieu. } DetruitObjet(tempObjet); Output_Image(tempname2); } } /* Commande: 'E' ou 'e' Paramètres: x,y,expression Alias: Expression Dessine une expression en pretty print. Les mêmes règles que pour les images sont applicables. Pour les expressions, vous devez séparer le iE et l'expression d'un espace, car votre expression peut commencer par un nombre, donc être pris pour un argument numérique de repositionnement. Exemple: ie 1/(1/2+1/2)i */ if (c=='E' || c=='e') { //Dessine une expression en pretty print et en fait un objet AjWarning("Expr math: %s",string); for (i=0;i=0 &&*/ arg1<=3) { //Supprime la fenêtre arg1 fen[arg1][0]=0; //Remet les valeurs par défaut fen[arg1][1]=0; fen[arg1][2]=WIDTH; fen[arg1][3]=HEIGHT-6; if (arg1) fen[arg1][2]=0; //Si ce n'est pas la fenêtre principale, alors on la détruit en lui mettant une valeur incorrecte (sinon elle serait simplement réinitialisée) if (arg1==num_fenster) num_fenster=0; //Si on détruit la fenêtre active, alors on repasse sur la première fenêtre (principale). } /* Commande: 'O' Paramètres: x0,y0,x1,y1 Alias: Objet / Object Crée un objet imaginaire, ce qui signifie que le texte ne pourra pas passer sur la zone en question (il sera donc cadré). Quant à savoir si c'est vraiment utile... */ if (c=='O') { //Fait un objet d'une aire rectangulaire if (num_obj<30) { num_obj++; objet[num_obj][1]=arg1; objet[num_obj][2]=arg2; objet[num_obj][3]=arg3; objet[num_obj][4]=arg4; } } /* Commande: ' ' Paramètres: horizontal,vertical Alias: Espacement Modifie l'espacement alloué pour les objets (images/expressions) lors du cadrage dans le texte. */ if (c==' ') { //L'espacement espacement=arg1; espacemenh=arg2; } /* Commande: 'T' Paramètres: taille Alias: Tabulation Modifie la taille des tabulations. Lorsque vous faites un \t, il viendra aligné à la prochaine tabulation, par exemple si vous avez défini 30 comme taille de tabulation, et que le curseur se trouve (horizontalement) à 41, alors il passera à 60. */ if (c=='T') tabul=arg1; /* Commande: 'n' Paramètres: chaîne Alias: Numéro de page Change la chaîne utilisée pour l'affichage des pages. Cette chaîne aura le format printf standard, donc %i pour remplacer le numéro de page. Par défaut: inPage %02ii */ if (c=='n') { VerifPrintf((s8*)string); strcpy(chnePage,(cs8*)string); } /* Commande: 'N' Paramètres: [chaîne] Alias: Numéro de sigNet Active le mode signet (taper un numéro accède au siget désigné et non à la page correspondante) et change optionnellement la chaîne utilisée pour formater le texte "Signet %i". Si vous voulez utiliser des caractères spéciaux, pensez à mettre un espace juste après le N; exemple: iN -> %i i. */ if (c=='N') { mode_signet=1; VerifPrintf((s8*)string); if (*string) strcpy(chneSignet,(cs8*)string); } /* Commande: 'I' Paramètres: x,y Alias: Indicateur Déplace l'indicateur de page aux positions souhaitées. D'une position trop basse résultera la suppression de l'indicateur. */ if (c=='I') { OSD_x=arg1; OSD_y=arg2; } /* Commande: 'S' Paramètres: espace vertical requis Alias: Space (espace en français) Vérifie s'il reste assez d'espace sur la page courante pour placer un objet de la taille désignée et passe à la prochaine page si ce n'est pas le cas. Par exemple, si vous voulez dessiner un objet faisant exactement 36 pixels de large avec une macro, il peut être utile (si vous l'encadrez par exemple) de savoir s'il reste au moins 36 pixels de libre, car si votre objet se trouve à cheval entre deux pages, le résultat n'est parfois vraiment pas beau! */ if (c=='S') { if (b+haut-1+arg1>fen[num_fenster][3]) { nam=nam2; goto pgbrk; } } /* Commande: '-' Paramètres: 1/0 (activé/désactivé) Alias: - comme retrait (?) Active ou désactive l'indentation automatique des paragraphes. Cela revient au même que de taper manuellement un \t au début de chaque paragraphe. */ if (c=='-') indent=arg1; /* if (c=='a') { // i=mode_prelecture; if (arg1<=2) { align=arg1; mode_prelecture=arg1; // if (i!=arg1) //Etat changé... goto debu; } }*/ //Vérifications d'usage pour l'objet courant... /* if (objet[num_obj][1]<0) objet[num_obj][1]=0; if (objet[num_obj][2]<0) objet[num_obj][2]=0;*/ if (*(nam-1)==124) { //Une barre | et on interprète une seconde commande! goto special2; } goto redo; //Repart dans la boucle principale. fin: pagsaav=page; //Sauvegarde de la page courante pour y revenir avec APPS #ifdef PC free(gblConverti); #endif frii2: PortRestore(); //Restaure l'adresse de l'écran pour AMS frii: free(bloc); //Libère le "bloc" OSClearBreak(); //Evite de faire un break lorsqu'on retourne au BASIC... }