/* ------------------------------------------------------------------- */ /* GeMiniTel - ‚mulateur vid‚o DRCS "temps r‚‚l" pour ATARI ST */ /* */ /* SystŠme de transfert graphique DRCS / animation */ /* */ /* Algo/programme (c)1995 ROCHE Xavier - ATARI - PureC */ /* */ /* Attention! Ce source ne doit pas ˆtre utilis‚ … des fins */ /* commerciales */ /* Toute exploitation de ce source, … des fins quelconques, est */ /* interdite sans l'autorisation de l'auteur */ /* */ /* ------------------------------------------------------------------- */ #include #include #include #include #include #include "gr.h" #include "arrstr.h" #include "tos.h" #include "gu_type.h" #include "gmt.h" #define VERSION "0.2" /* l'adresse bitmap de gmt c'est notre adr_old */ #define gmt_bit_adr adr_old /* l'adresse bitmap de comparaison de gmt c'est notre adr_col */ #define gmt_bit_cmp adr_col /* longueur d'une ligne de gmt_bit_adr et gmt_bit_cmp en octets */ #define gmt_line_len lindest /* Position de d‚part gmtel xy (0..39 et 1..24) et dimensions de la fenˆtre */ #define gmt_startmx startmx #define gmt_startmy startmy #define gmt_sizemw sizemw #define gmt_sizemh sizemh /* couleur texte et fond (0..7) */ #define gmt_colt colt #define gmt_colf colf /* option de chargement de fonte (voir … I_optcode) */ #define gmt_opt I_optcode /* mode animation ON (<> mode de simple digitalisation) */ #define gmt_anim 1 #define gmt_opt2 0 #define gmt_optcom 1 #define gmt_opt3 1 #define gmt_opt4 0 /* --------------------------------------------------------------------- */ /* vars globales */ char activ=-1; char speed=2; /* 9600 */ char buffer[4096]; ARRSTR vpage; extern int _app; int gl_wchar, gl_hchar, gl_wbox, gl_hbox; int phys_handle, handle; int max_x, max_y; int appl_id, menu_id; int work_in[11]; int work_out[57]; int aux; /* fopen aux */ int aux_flag; /* redir vers fichier */ /* quitter appli */ int quit=0; /* heure: */ time_t Tim; /* --------------------------------------------------------------------- */ /* Variables GMT_GRAPH */ int plan; MFDB mf1,mf2,mf3; long screen=0L; int xy[8]; /* Position sur l'‚cran du cadre (cadre 0, haut … gauche) */ int xscr=0,yscr=0; int sizemw=20; int sizemh=15; #define max_gmx (max_x/8) #define max_gmy (max_y/10) /* adr_old=‚cran mono pr‚c‚dent */ long adr_old; /* adr_tempo=tempo - adr_col=‚cran couleur puis s‚par‚ selon plans */ long adr_tempo,adr_col; /* taille ligne couleur et mono en octets */ int linsrc,lindest; int lindest; /* Position et taille de la fenˆtre minitel */ int startmx=2; int startmy=1; int colf=1,colt=6; /* Option de codage de la fonte: 0 = Fonte avant (le texte) 1 = Fonte aprŠs 2 = Fonte avant chaque ligne (entrelac‚) 3 = Fonte aprŠs chaque ligne */ char I_optcode=2; /* librairie gmtel! */ #include "gmtlib.c" /* --------------------------------------------------------------------- */ /* Les routines GMT_GRAPH */ void get_plans(void); int gmt_init(void); void gmt_cl2(void); void gmt_close(void); void gmt_setwind(int x0,int y0,int w0,int h0); void gmt_setpos(int x,int y); int gmt_get(void); void main(void); void dograph(int x,int y,int w,int h); int gmt_cls(ARRSTR *blk); void Csendmntl(const char *s); void sendmntl(ARRSTR *blk); int inftime(ARRSTR *blk); void config(int opc); void mouse_on( void ); void mouse_off( void ); int handle_message( int pipe[8] ); void event_loop( void ); #define PRO2 "\x1B:" #define V1200 PRO2"\x6B""d" #define V4800 PRO2"\x6B""v" #define V9600 PRO2"\x6B""\x7F" const char _vit[3][5] = {"1200\x0","4800\x0","9600\x0"}; const char _col[8][8] = {"Noir\x0","Bleu\x0","Rouge\x0","Magenta\x0","Vert\x0","Cyan\x0","Jaune\x0","Blanc\x0"}; OBJECT *FORM1; int FX,FY,FW,FH; /* --------------------------------------------------------------------- */ /* routines */ void main( void ) { int i; vpage.maxlen=4096; vpage.len=0; vpage.str=(char*) &buffer; /* RSconf (init) */ xbios(15,7,0,174,-1,-1,-1); aux=(int) Fopen("AUX:",2); aux_flag=0; /* ouvrire e/s sur aux: */ appl_id = appl_init( ); if ( appl_id != -1 ) { for ( i = 0; i < 10; i++ ) work_in[i] = 1; work_in[10] = 2; phys_handle = graf_handle( &gl_wchar, &gl_hchar, &gl_wbox, &gl_hbox ); handle = phys_handle; v_opnvwk( work_in, &handle, work_out ); if ( handle != 0 ) { max_x = work_out[0]; max_y = work_out[1]; if ( rsrc_load( "GMT.RSC" ) <= 0 ) { form_alert(1,"[3][Fichier RSC introuvable][Annuler]"); exit(1); } rsrc_gaddr( 0, 0, &FORM1 ); form_center( FORM1, &FX , &FY , &FW , &FH ); get_plans(); gmt_init(); if ( !_app ) { menu_id = menu_register( appl_id, " GeMiniTel " ); } else { defmouse(0); /*form_alert(1,"[3][|GeMiniTel ne fonctionne |qu'en accessoire!|][ Annuler ]");*/ } defmouse(2); xbios(15,7,0,174,-1,-1,-1); evnt_timer(50,0); Csendmntl( V4800 ); evnt_timer(250,0); xbios(15,2,0,174,-1,-1,-1); defmouse(0); gmt_setpos(16,16); gmt_setwind(1,1,20,12); config(1); event_loop( ); v_clsvwk( handle ); Fclose(aux); /* fermer fichier aux */ } appl_exit( ); } exit( 0 ); } void mouse_on( void ) { graf_mouse( M_ON, (void *)0 ); } void mouse_off( void ) { graf_mouse( M_OFF, (void *)0 ); } long objc_adr(int o) { long adr=0; rsrc_gaddr(1,o,&adr); return adr; } long str_adr(int o) { OBJECT *obj; obj = (OBJECT*) objc_adr(o); return obj->ob_spec.index; } void str_put(int o,const char *str) { char *a; a = (char*) str_adr(o); while ( (*(a++) = *(str++)) != 0); } void setspeed( void ) { switch ( speed ) { case 0: { Csendmntl( V1200 ); evnt_timer(250,0); xbios(15,7,0,174,-1,-1,-1); break; } case 1: { Csendmntl( V4800 ); evnt_timer(250,0); xbios(15,2,0,174,-1,-1,-1); break; } case 2: { Csendmntl( V9600 ); evnt_timer(250,0); xbios(15,1,0,174,-1,-1,-1); break; } } } int handle_message( int pipe[8] ) { switch ( pipe[0] ) { case AC_OPEN: if ( pipe[4] == menu_id ) { config(0); break; } case AC_CLOSE: /* if ( pipe[3] == menu_id ); */ break; } return ( 0 ); } void config( int opc ) { wind_update(1); wind_update(3); str_put(TITRE,"GeMiniTel V"VERSION); graf_growbox(max_x/2,max_y/2,8,8,FX,FY,FW,FH); objc_draw(FORM1 , 0 , 7 , FX , FY , FW , FH ); { int cont=TRUE; char i_activ=activ; char i_speed=speed; int i_sizemw=sizemw,i_sizemh=sizemh; int i_startmx=startmx,i_startmy=startmy; int i_colt=colt,i_colf=colf; int form_rep; OBJECT *A; if ( opc ) { activ=0; } do { { char buff[8]; sprintf(buff,"%d",i_sizemw); str_put(LARGEUR,buff); objc_draw(FORM1 , LARGEUR , 7 , FX , FY , FW , FH ); sprintf(buff,"%d",i_sizemh); str_put(HAUTEUR,buff); objc_draw(FORM1 , HAUTEUR , 7 , FX , FY , FW , FH ); sprintf(buff,"%d",i_startmx + 1 ); str_put(X_POS,buff); objc_draw(FORM1 , X_POS , 7 , FX , FY , FW , FH ); sprintf(buff,"%d",i_startmy); str_put(Y_POS,buff); objc_draw(FORM1 , Y_POS , 7 , FX , FY , FW , FH ); str_put(BPS,_vit[i_speed]); objc_draw(FORM1 , BPS , 7 , FX , FY , FW , FH ); str_put(TEXTE,_col[i_colt]); objc_draw(FORM1 , TEXTE , 7 , FX , FY , FW , FH ); str_put(FOND,_col[i_colf]); objc_draw(FORM1 , FOND , 7 , FX , FY , FW , FH ); if ( i_activ ) { str_put(ACTIVER,"Activ‚"); } else { str_put(ACTIVER,"D‚sactiv‚"); } /* if i_activ */ objc_draw(FORM1 , ACTIVER , 7 , FX , FY , FW , FH ); } form_rep = (int) (char) form_do(FORM1 , 0); A = (OBJECT*) objc_adr(form_rep); objc_change(FORM1 , form_rep , 0 , FX , FY , FW , FH , (A->ob_state) & (~1) , 1 ); switch ( form_rep ) { case W_M: { i_sizemw--; i_sizemw=max(i_sizemw,2); break; } case W_P: { i_sizemw++; i_sizemw=min(i_sizemw,vmax_x-i_startmx); break; } case H_M: { i_sizemh--; i_sizemh=max(i_sizemh,2); break; } case H_P: { i_sizemh++; i_sizemh=min(i_sizemh,vmax_y-i_startmy); break; } case X_M: { i_startmx--; i_startmx=max(i_startmx,1); /* = 2Š col */ break; } case X_P: { i_startmx++; i_startmx=min(i_startmx,vmax_x-i_sizemw); break; } case Y_M: { i_startmy--; i_startmy=max(i_startmy,1); /* 1Š ligne */ break; } case Y_P: { i_startmy++; i_startmy=min(i_startmy,vmax_y-i_sizemh); break; } case B_M: { i_speed--; i_speed=max(i_speed,0); break; } case B_P: { i_speed++; i_speed=min(i_speed,2); break; } case T_M: { i_colt--; i_colt=max(i_colt,0); break; } case T_P: { i_colt++; i_colt=min(i_colt,7); break; } case F_M: { i_colf--; i_colf=max(i_colf,0); break; } case F_P: { i_colf++; i_colf=min(i_colf,7); break; } case ACTIVER: { i_activ = (i_activ == 0); break; } /* case */ case OK: { /* redirection vers fichier */ if ( ( bios(11,-1) & 15 ) == 14 ) { if ( form_alert(1,"[3][Redirection vers fichier?|GMT_LOG.VDT][Confirmer| Annuler ]") == 1 ) { defmouse(2); Fclose(aux); aux=(int) Fcreate("GMT_LOG.VDT",0); aux_flag=1; /* ouvrire e/s sur fichier */ defmouse(0); } } else if ( aux_flag ) { defmouse(2); Fclose(aux); aux=(int) Fopen("AUX:",2); aux_flag=0; /* ouvrire e/s sur aux: */ defmouse(0); } activ=i_activ; if ( (i_sizemw != sizemw) || (i_sizemh != sizemh) || (i_startmx != startmx) || (i_startmy != startmy) ) { colf=i_colf; colt=i_colt; sizemw=i_sizemw; sizemh=i_sizemh; startmx=i_startmx; startmy=i_startmy; graf_mouse(2,0); gmt_cl2(); mem_clr(vpage); gmt_cls(&vpage); sendmntl(&vpage); mem_clr(vpage); graf_mouse(0,0); } else if ( (i_colt != colt) || (i_colf != colf) ) { colt=i_colt; colf=i_colf; } if (i_speed != speed) { speed=i_speed; setspeed(); } cont=0; break; } case ANNULER: { cont=0; break; } case INIT: { graf_mouse(2,0); gmt_cl2(); mem_clr(vpage); gmt_cls(&vpage); sendmntl(&vpage); mem_clr(vpage); graf_mouse(0,0); break; } } /* switch */ } while ( cont ) ; } /* block */ wind_update(0); wind_update(2); form_dial(3,0,0,0,0,FX,FY,FW,FH); graf_shrinkbox(max_x/2,max_y/2,8,8,FX,FY,FW,FH); } void event_loop( void ) { int x, y, kstate, key, clicks, event, state; int pipe[8]; if ( _app ) { printf("GeMiniTel"VERSION"\n^A to STOP\n"); } #if AFFDEB if ( _app ) { hidem; deffillcol(3); pbox(0,0,max_x,max_y); color(2); box(10,10,200,150); } #endif #if DEBUG printf("\x1bHMem=%d",(double) (long) malloc(-1)); #endif #if AFFDEB deffillcol(0); color(1); boundary(1); pbox(400,yscr,sizemw*8+400,sizemh*10+yscr); deffillcol(1); #endif showm; mem_clr(vpage); gmt_cls(&vpage); sendmntl(&vpage); mem_clr(vpage); do /* boucle principale */ { if ( !_app ) { event = evnt_multi( MU_MESAG | MU_TIMER, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, pipe, 250, 0, &x, &y, &state, &kstate, &key, &clicks ); } else { event = evnt_multi( MU_MESAG | MU_TIMER | MU_KEYBD | MU_BUTTON, 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, pipe, 100, 0, &x, &y, &state, &kstate, &key, &clicks ); } /* wind_update( BEG_UPDATE ); */ #if AFFDEB if ( event & MU_BUTTON ) { if (t) { boundary(0); deffillcol(0); t=0; } else { boundary(1); deffillcol(2); t=1; } do{ mouse(&x,&y,&clicks); hidem; pcircle(x,y,7-t*4); showm; } while(clicks); } #endif if ( event & MU_MESAG ) quit = handle_message( pipe ); if ( (event & MU_TIMER) AND (activ) ) { printf("\x1bH*"); if ( ( x >= (xscr + sizemw*8) ) OR ( x < xscr ) OR ( y >= (yscr + sizemh*10) ) OR ( y < yscr ) ) { int xpos,ypos; xpos = ( (x-sizemw*4) /8 ) * 8; ypos = ( (y-sizemh*5) /10 ) * 10; xpos=max(0,xpos); ypos=max(0,ypos); gmt_setpos(xpos,ypos); } if (gmt_get()==0) { /* transfert */ int px,py; px=(x-xscr)/8; py=(y-yscr)/10; if ( px>=0 ) if ( py>=0 ) if ( px <= sizemw-3 ) if ( py <= sizemh-3 ) { /* dograph(px,py,3,3); */ } dograph(0,0,sizemw,sizemh); /* d‚coupage */ /* horloge */ mem_clr(vpage); if ( inftime(&vpage) == 0 ) { sendmntl(&vpage); mem_clr(vpage); } } printf("\x1bH "); } if ( event & MU_KEYBD ) { /* D‚coder touche sur 2 octets -> 1 seul octet */ if (((char) key)==0) { key>>=8; key+=0x80; } else key=((int) (char) key); switch(key) { case 1: { if (_app) quit=1; break; } case 13: { deffillcol(0); hidem; pbox(xscr,yscr,xscr+(sizemw MUL8)-1,yscr+sizemh*10-1); showm; break; } case 32: { /*showm;*/ break; } } /* switch key */ } /* if evnt_timer */ /* wind_update( END_UPDATE ); */ } while ( !quit ); gmt_close(); } void dograph(int x,int y,int w,int h) { if (gmt_cut(x,y,w,h)==0) { /* d‚coupage */ mem_clr(vpage); if (gmt_code( &vpage,3,x,y,w,h ) == 0 ) { sendmntl(&vpage); } } } void Csendmntl(const char *s) { int i=0; while ( s[i++] ); if ( --i ) { Fwrite(aux,i,s); if (bios(8,1)==0) { for(i=0 ; (i<10000) AND (bios(8,1)==0) ; i++); if (bios(8,1)==0) printf("XMit error, timeout"); } } } void sendmntl(ARRSTR *blk) { int i=0; if ( blk->len > 0) { Fwrite(aux,blk->len,blk->str); if (bios(8,1)==0) { for(i=0 ; (i<10000) AND (bios(8,1)==0) ; i++); if (bios(8,1)==0) printf("XMit error, timeout"); } } } /* --------------------------------------------------------------------- */ /* Nombre de plans? */ void get_plans(void) { /* Combien de plans? */ vq_extnd(handle, 1, work_out); switch(work_out[5]) { case 0: { /*plans=2^work_out[4];*/ plan=work_out[4]; break; } default: { plan=work_out[4]; break; } } } int gmt_init(void) { gmt_cl2(); return 0; } void gmt_setwind(int x0,int y0,int w0,int h0) { /* V‚rifier intervalles de valeurs! */ x0=min(vmax_x,max(1,x0)); /* commencer en col1 */ y0=min(vmax_y,max(1,y0)); /* pas de ligne 0 */ w0=min(vmax_x-x0+1,max(0,w0)); h0=min(vmax_y-y0+1,max(0,h0)); w0=min(w0,max_gmx-x0+1); h0=min(h0,max_gmy-y0+1); /* Divisibles par 2! (2*8=16!) - (inutile pour y) */ if (w0%2) w0=((w0 DIV2 ) MUL2); /* Noter coordonn‚es et tailles! */ startmx=x0; startmy=y0; sizemw=w0; sizemh=h0; /* Recalculer variables, allouer blocs */ gmt_cl2(); } /* Position … l'‚cran du cadre */ void gmt_setpos(int x,int y) { xscr=max(0,min(x,max_x-sizemw*8+1)); yscr=max(0,min(y,max_y-sizemh*10+1)); } void gmt_cl2(void) { /* effacer tout */ gmt_clear(); /* effacer variables de gmt */ { long size; if (adr_old) { free((void*) adr_old); adr_old=0; } if (adr_col) { /* d‚sallouer 2 blocs image (couleur/mono) */ free((void*) adr_col); adr_col=0; } if (adr_tempo) { free((void*) adr_tempo); adr_tempo=0; } linsrc=(sizemw*plan); /* Taille ligne couleur */ lindest=sizemw; /* Taille ligne mono */ size=linsrc*sizemh*10; if ( ((long) malloc(-1)) > ((long) (size*3)) ) { long a; adr_tempo = (long) malloc(size); adr_col = (long) malloc(size); adr_old = (long) malloc(size); if ( (adr_col<=0) OR (adr_old<=0) OR (adr_tempo<=0) ) { printf("\nErreur, malloc(x) insuffisant!\n"); getchar(); gmt_close(); quit=TRUE; exit(1); } else { /* initialiser adr_old */ for( a=0 ; a=1) { switch(plan) { case 2: { /* Transfert en 4 couleurs */ mf3.fd_addr=(void*) (adr_col+lindest*sizemh*10); mf3.fd_w=(sizemw MUL8); mf3.fd_h=sizemh*10; mf3.fd_wdwidth=sizemw DIV2; /* largeur /16 */ mf3.fd_stand=0; mf3.fd_nplanes=1; mf3.fd_r1=mf3.fd_r2=mf3.fd_r3=0; /* Ajouter 1 plan */ vro_cpyfm(handle,7,xy,&mf3,&mf2); break; } case 4: { /* Transfert en 16 couleurs */ mf3.fd_addr=(void*) (adr_col+lindest*sizemh*10); mf3.fd_w=(sizemw MUL8); mf3.fd_h=sizemh*10; mf3.fd_wdwidth=sizemw DIV2; /* largeur /16 */ mf3.fd_stand=0; mf3.fd_nplanes=1; mf3.fd_r1=mf3.fd_r2=mf3.fd_r3=0; /* Ajouter 3 plans */ vro_cpyfm(handle,7,xy,&mf3,&mf2); mf3.fd_addr=(void*) (adr_col+lindest*sizemh*10*2); vro_cpyfm(handle,7,xy,&mf3,&mf2); mf3.fd_addr=(void*) (adr_col+lindest*sizemh*10*3); vro_cpyfm(handle,7,xy,&mf3,&mf2); break; } case 8: case 16: case 24: { /* Transfert en 256 couleurs et TC */ mf3.fd_addr=(void*) (adr_col+lindest*sizemh*10); mf3.fd_w=(sizemw MUL8); mf3.fd_h=sizemh*10; mf3.fd_wdwidth=sizemw DIV2; /* largeur /16 */ mf3.fd_stand=0; mf3.fd_nplanes=1; mf3.fd_r1=mf3.fd_r2=mf3.fd_r3=0; /* Ajouter 3 plans SEULEMENT!! */ vro_cpyfm(handle,7,xy,&mf3,&mf2); mf3.fd_addr=(void*) (adr_col+lindest*sizemh*10*2); vro_cpyfm(handle,7,xy,&mf3,&mf2); mf3.fd_addr=(void*) (adr_col+lindest*sizemh*10*3); vro_cpyfm(handle,7,xy,&mf3,&mf2); break; } } /* switch plan */ } /* if plan>1 */ #if 0 /* on Xor l'ancienne image pour y d‚tecter des diff‚rences ainsi l'algo utilis‚ est … mˆme de g‚rer de animations rapides, par exemple lors du d‚placement de la souris */ mf3.fd_addr=(void*) (adr_old); mf3.fd_w=(sizemw MUL8); mf3.fd_h=sizemh*10; mf3.fd_wdwidth=sizemw DIV2; /* largeur /16 */ mf3.fd_stand=0; mf3.fd_nplanes=1; mf3.fd_r1=mf3.fd_r2=mf3.fd_r3=0; vro_cpyfm(handle,6,xy,&mf2,&mf3); /* copie Xor */ #endif #if 0 deffillcol(0); pbox(0,0,sizemw-1,sizemh-1); color(1); boundary(1); deffillcol(1); #endif /* Inits */ { int a,b; for( a=0 ; a<94*2 ; a++ ) { switch( keep[a] ) { case -1: { keep[a]=1; /* old val */ break; } case 1:{ keep[a]=0; /* annul‚ */ break; } } newload[a]=FALSE; } newfull=0; I_nchar=0; for(a=0 ; a<25 ; a++) { for(b=0 ; b<40 ; b++) { change[a][b]=-1; /* tout est cens‚ avoir chang‚ */ treated[a][b]=FALSE; } /* next b */ } /* next a */ } /* ‚change adr_col/adr_old */ { long swap; swap=adr_col; adr_col=adr_old; adr_old=swap; } return 0; } /* gmt_get */ int inftime(ARRSTR *blk) { char s[80]; const char Time_pattern[40] = " %H:%M:%S - %a %d.%b %Y"; time_t tim; /* Wieder eine Minute vergangen? */ if ( ( ( tim = time( &tim ) / 5 ) > Tim ) ) { Tim = tim; /* Ja, dann Minuten merken. */ tim*=5; strftime( s, 80, Time_pattern, localtime( &tim )); } else { return 2; } if ( pos(blk,1,24) ) return 1; if ( mem_write(blk,DRCST_OFF) ) return 1; if ( mem_write(blk,s) ) return 1; return 0; } /* vecteur GeMiniTel */ long cdecl gmt_vecteur(int fonct,int param[]) { switch( fonct ) { case 0: /* infos version */ return (long) 0x0001; case 1: return param[1]; default: { return (long) 0; } } } /* ------------------------------------------------------------------- */ /* Fin du source - (c) 1995 Xavier ROCHE - C - ATARI */