/**************************************************************************** ----------------- V I E W 8 0 ----------------- v1.1 by Federico Giannici Lettore ultraveloce di file ASCII ad 80 colonne con scroll-bar. Da linkare con: BLink FROM CBack.o+tinymain.o+view.o+fasttext.o+FileFinder.o TO View80 LIB LIB:lc.lib+LIB:amiga.lib NODEBUG BATCH VERBOSE STORIA: 10/08/89 v0.1 Inizio 14/08/89 v0.2 Font proprio 16/08/89 v0.3 Routine fasttext Gestione tastiera 17/08/89 v0.4 Numero di linea Gestione tastiera velocizzata Aggiunta nuove voci al menu Allocazione dinamica di ffdata (-4.3K) 23/08/89 v0.5 Inizio preparazione Requester Gadget OK e CANCEL Eliminato bug in findlines Miglioramento ed eliminazione bug gestione tastiera ALT up e down Inizio routine search() Modifica dimensioni AutoRequest Elimina CARRIAGE RETURN 27/08/89 v0.6 Routine print() Aggiunta menu My Colors Modifica routine print() My Colors 29/08/89 v0.7 Utilizzo del Blitter (WHOW!!!) Modifica gestione tastiera Tasto AutoScroll Modifica gestione tastiera 01/09/89 v0.8 Modifica menu Print di una linea Help dei tasti Implementazione TAB Eliminazione bug in reformat Modifica priorita` Esperimenti scrollup() CheckMark proprio 11/09/89 v0.9 Apparizione fine della linea in !fastscroll Movimento con il mouse Adattamento PAL - NTSC Caricamento da WB Files da WB Aggiunta del Logo e by 21/09/89 v0.A Toglie mouse mentre si usa la tastiera Ottimizzazione GetMsg() Settaggio margini in stampa Compilato con Lattice C V5.02 05/10/89 v0.B Eliminazione bug nella gestione repeat tasti Modifiche al menu Opzione WordWrap Eliminati Dead-Lock con MENUVERIFY (solo con nopointer) Eliminati bug in newfile() 11/10/89 v0.C Piccoli ritocchi generali Uso di CBack.o 18/10/89 v0.D Eliminazione menu durante uso tastiera 20/10/89 v1.0 Eliminazione piccolo bug nella title-bar PRIMA RELEASE UFFICIALE 25/10/89 v1.01 Risolto BUG in doppio uso del requester 02/11/89 v1.02 FastText in assembler Velocizzazione scrittura 08/11/89 v1.03 Piccolo bug in newfile() 11/11/89 v1.04 Uso tasti funzione Funzione scrolloutframe() Terza velocita`: TURBO scroll 13/11/89 v1.05 Stampa redirezionabile 18/11/89 v1.06 MultiFile Modifiche al menu` Clear file Free Memory Jump to 25/11/89 v1.07 flashpos() 01/12/89 v1.1 SECONDA RELEASE UFFICIALE 01/12/89 Adesso ****************************************************************************/ /* #include "exec/types.h" */ /* #include "intuition/intuition.h" */ /* #include "libraries/dos.h" */ /* #include "string.h" */ /* #include "clib/macros.h" */ /* #include "proto/exec.h" */ /* #include "proto/dos.h" */ /* #include "proto/graphics.h" */ /* #include "proto/intuition.h" */ #include "General.h" /* sostituisce gli include precedenti */ #include "workbench/startup.h" #include "MyRoutines/FileFinder.h" #include "hardware/custom.h" #include "hardware/blit.h" /* #define PROVANTSC */ #define VERSIONE "1.1 " /* Deve essere 4 caratteri */ #define LIBVER 33 #define MAXFN 3 #define FRAMELAST (framenum-1) #define SEARCHLEN (30+1) /* Lunghezza search string */ #define LINELEN (7+1) /* Lunghezza gadgets numero di linea */ #define SENDTOLEN (40+1) #define DELTAFRAME (framenum*3) /* numero massimo di linee oltre cui fare outframe() */ #define SDELTAFRAME (framenum+framenum/2) #define DOUBLECLICK 400000 /* DoubleClick in 0.4 secondi */ #define REPDELAY 15 /* Ritardo repeat dei tasti */ #define IDCMPFLAGS (GADGETDOWN | GADGETUP | MENUPICK | RAWKEY | MOUSEBUTTONS | MOUSEMOVE) #define WINDOWW 640 #define MEDSCREEN (framenum<<2) #define MESSW 290 #define MESSH 75 #define GADGETH 11 #define MENUCAR 40 #define MENUW (MENUCAR*8) /* Largezza del menu */ #define MENUH (116+14*4+2+11+2) #define MENUL (56+8) #define ITEMB 5 /* Distanza degli item dal bordo */ #define ITEMB2 4 /* Distanza delle scritte dal item box */ #define ITEMW (MENUW-ITEMB*2) /* Largezza degli item */ #define SITEMW (ITEMW/2-1-8) /* Larghezza item piccoli */ #define SITEMT 111 /* Inizio piccoli item */ #define SITEMD 12 /* Distanza piccoli item */ #define ITEMGAP 3 /* Distanza piccoli item e check item */ #define ITEMGAP2 2 #define INFOT 0 #define REQW 300 #define REQH 90 #define HREQW 500 /* Requester Help */ #define HREQH 184 #define OKGW 29 #define CANCELGW 76 #define REQGW (90) #define REQGH (11+2) #define REQGL (6+12) #define REQGB (-3-REQGH-4) #define PRINTGL 30 #define HELPL ((HREQW-54*8)/2) #define HELPTT 23 #define HELPTD 8 /* distanza elementi help */ #define HELPG 1 #define FREEMLEN 13 #define FREEMT (HREQH-8-8) #define UPID 1 /* ID dei Gadgets */ #define DOWNID 2 #define PROPID 3 #define SEARCHID 10 #define PRINTID 20 #define FROMID 21 #define TOID 22 #define JUMPTOID 30 #define CANCELID 100 #define OKID 101 /* ridefinito ogni volta */ #define MINX 0 /* limiti area testo */ #define MINY 1 #define MAXX (MINX+WINDOWW-1) #define MAXY (MINY+framenum*8-1) #define FLASHDELAY 3 /* Usati da flashpos() */ #define FLASHREPEAT 2 #define RAWUP 0x4c /* RAWKEY codes */ #define RAWDOWN 0x4d #define RAWRIGHT 0x4e #define RAWLEFT 0x4f #define RAWSPACE 0x40 #define RAWHELP 0x5F #define RAWF1 0x50 #define RAWF3 0x52 #define RAWF4 0x53 #define RAWF5 0x54 #define RAWF6 0x55 #define RAWF7 0x56 #define RAWF8 0x57 #define RAWF9 0x58 #define RAWF0 0x59 #define ALTMASK (IEQUALIFIER_LALT | IEQUALIFIER_RALT) #define SHIFTMASK (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT) #define MOVEASC 0 /* bltmove ascendente */ #define MOVEDISC BC1F_DESC /* bltmove discendente */ #define BITMAPADD(l) (bitmapstart+(l)*80*8) /* indirizzo linea l (da 0) */ #define TOLOW(c) (((c)>='A' && (c)<='Z')?((c)+('a'-'A')):(c)) #define ISSPACE(c) ((c)==' ' || (c)==9) #include "viewdata.c" /***** Le mie Proto *****/ void newfile( BOOL formatonly ); void findlines( struct linee *linee); void numcpy( UBYTE *to, LONG numero ); void makebartext( void ); void changefn( UWORD newfn ); void bltclear( UBYTE *add, UWORD lines ); void bltmove( UBYTE *from, UBYTE *to, UWORD lines, UWORD dir ); extern void __asm fasttext( register __a0 struct line *line, register __a1 UBYTE *tostart ); void outframe( LONG newpos ); void scrolloutframe( LONG newpos ); void scrollup( void ); void scrolldown( void ); void up( void ); void down( void ); void setprop( void ); void showreverse( LONG line ); void flashpos( void ); void search( void ); void print( LONG from, LONG to ); void helpkeys( void ); void openall( void ); LONG mygetmsg( void ); LONG messaggio2( UBYTE *testo, UBYTE *positivo, UBYTE*negativo ); void messaggio( UBYTE *testo ); void outs( UBYTE *text ); void fine( UBYTE *text ); extern struct Custom __far custom; extern struct WBStartup *WBenchMsg; UWORD framenum=29; /* numero di linee in un frame */ struct Window *window=NULL; struct RastPort *rp, *barrp; struct ViewPort *vp; struct Screen *screen=NULL; struct IntuitionBase *IntuitionBase=NULL; struct GfxBase *GfxBase=NULL; struct Process *process=NULL; /* per i messaggi ADOS */ APTR adoswin; BOOL autoload=FALSE; BPTR lock=NULL; BPTR file=NULL; struct FileInfoBlock *fib=NULL; UWORD fn=0; /* File Number attuale (0-2) */ UBYTE filenamefn[MAXFN][ 30+1 ]; /* nome del file in memoria */ UBYTE *bufferfn[MAXFN]={NULL, NULL, NULL}; LONG blenfn[MAXFN]; struct line *linepfn[MAXFN]={NULL, NULL, NULL}; LONG linenumfn[MAXFN]; /* Numero di linee (vedi linenum) */ LONG posfn[MAXFN]; /* Linea corrente (vedi pos) */ LONG markfn[MAXFN][ 2 ]; /* Mark F4-F5 */ LONG printposfn[MAXFN][ 2 ]; /* Prima e ultima linea di stampa F6-F7 */ BOOL wordwrapfn[MAXFN]={FALSE, FALSE, FALSE}; UBYTE tabfn[MAXFN]={0, 0, 0}; /* Tab==none */ LONG pos; /* Per ridurre e velocizzare il codice */ LONG linenum; struct line *linep=NULL; BOOL wordwrap=FALSE; UBYTE tab=0; LONG newpos, oldpos; UBYTE printername[]="prt:"; UWORD propbody; BOOL fastscroll; BOOL turboscroll; UBYTE *tempbitmap=NULL; /* Buffer per la scrittura della linea */ BOOL nopointer=FALSE; BOOL clearmsg=FALSE; WORD olddheight; UBYTE *bitmapstart; UBYTE *bma1, *bma2, *bma3, *bma4, *bma5, *bma6, *bma7; UWORD cos1, cos2; struct IntuiMessage *msg; ULONG class; UWORD code; UWORD qualifier; ULONG seconds, micros; struct Gadget *gadget; struct ffdata data; /***** Questi sono necessari per CBack.o *****/ long _stack = 4000; /* a reasonable amount of stack space */ char *_procname = "View80"; long _priority = 0; /* run at standard priority */ long _BackGroundIO = 1; /* perform background I/O */ extern BPTR _Backstdout; /* file handle we will write to with */ /************** MAIN **************/ main( LONG argc, UBYTE **argv) { LONG oldseconds=0, oldmicros=0; WORD y; /* usato in MOUSEBUTTONS */ BYTE ritardo; COUNT i; BOOL dosetprop; /* usato dal TURBO scroll */ SetTaskPri( FindTask(NULL), 1 ); if( (fib=AllocMem( sizeof(struct FileInfoBlock), MEMF_PUBLIC ))==NULL ) fine( "No memory for FIB" ); if( (tempbitmap=AllocMem( 80*8, MEMF_CHIP | MEMF_PUBLIC ))==NULL ) fine( "No memory for TempBitMap" ); openall(); if( argc>MAXFN+1 || (argc==0 && WBenchMsg->sm_NumArgs>MAXFN+1) ) messaggio( "I cannot load more than 3 files" ); if( argc==1 || (argc==0 && WBenchMsg->sm_NumArgs==1) ) /* niente argomenti */ newfile( FALSE ); /* autoload=FALSE */ else if( argc>1 ) { for( i=0; i=sizeof(data.complete) ) messaggio( "Argument too long" ); else { changefn( i ); strcpy( data.complete, argv[i+1] ); autoload=TRUE; newfile( FALSE ); } } changefn( 0 ); } else { for( i=0; ism_NumArgs-1 && ism_ArgList+i+1)->wa_Lock ); strcpy( data.complete, (WBenchMsg->sm_ArgList+i+1)->wa_Name ); autoload=TRUE; newfile( FALSE ); } changefn( 0 ); } FOREVER /* Main Loop */ { if( pos!=oldpos && linenum ) /* aggiorna la title bar */ { strncpy( &bartext[ BTLINE ], " ", BTLINELEN ); numcpy( &bartext[ BTLINE ], pos+1 ); SetAPen( barrp, 3 ); Move( barrp, (BTLINE)*8+5, 6+1 ); Text( barrp, &bartext[ BTLINE ], BTLINELEN ); oldpos=pos; } if( clearmsg ) { while( mygetmsg () ) ; clearmsg=FALSE; } window->Flags &= ((ULONG)-1)^RMBTRAP; /* Ripristina menu */ WaitPort( window->UserPort ); mygetmsg(); window->Flags |= RMBTRAP; /* Elimina menu */ turboscroll=FALSE; switch( class ) { case MENUPICK: while( code!=MENUNULL ) { switch( ITEMNUM( code ) ) { case 2: /* newfile */ newfile( FALSE ); break; case 3: /* quit */ if( messaggio2( quitstr, " Yes ", " No " )==TRUE ) fine( NULL ); break; case 4: /* Search */ requester.ReqGadget=&searchgadg; requester.ReqText=&searchtext; okGadg.GadgetID=SEARCHID; if( Request( &requester, window )==TRUE ) { Delay( 6 ); ActivateGadget( &searchgadg, window, &requester ); clearmsg=TRUE; } else messaggio( noreqstr ); break; case 5: /* Search Next */ search(); break; case 6: /* Print */ if( linenum==0 ) { messaggio( nofilestr ); break; } fromgstrinfo.LongInt=printposfn[fn][0]; stci_d( frombuff, printposfn[fn][0] ); togstrinfo.LongInt=printposfn[fn][1]; stci_d( tobuff, printposfn[fn][1] ); fromgstrinfo.DispPos=0; togstrinfo.DispPos=0; requester.ReqGadget=&fromgadg; requester.ReqText=&printtext; okGadg.GadgetID=PRINTID; if( Request( &requester, window )==TRUE ) { Delay( 6 ); ActivateGadget( &fromgadg, window, &requester ); clearmsg=TRUE; } else messaggio( noreqstr ); break; case 7: /* Print line */ if( linenum==0 ) { messaggio( nofilestr ); break; } print( pos, pos ); fastscroll=TRUE; down(); break; case 8: /* Jump to */ jumptogstrinfo.LongInt=0; jumptobuff[0]='\0'; requester.ReqGadget=&jumptogadg; requester.ReqText=&jumptotext; okGadg.GadgetID=JUMPTOID; if( Request( &requester, window )==TRUE ) { Delay( 6 ); ActivateGadget( &jumptogadg, window, &requester ); clearmsg=TRUE; } else messaggio( noreqstr ); break; case 9: /* Clear file */ if( linenum ) { FreeMem( linep, sizeof(struct line)*linenum ); FreeMem( bufferfn[fn], blenfn[fn] ); pos=posfn[fn]=0; linenum=linenumfn[fn]=0; linep=linepfn[fn]=0; outframe( 0 ); makebartext(); propbody=0xFFFF; setprop(); markfn[fn][0]=markfn[fn][1]=0; } break; case 10: /* My colors */ LoadRGB4( vp, colormap, 4 ); break; case 11: /* Help keys */ helpkeys(); break; case 12: case 13: case 14: changefn( (UWORD)(ITEMNUM( code )-12) ); break; case 15: /* WordWrap */ case 16: wordwrap=ITEMNUM( code )==15 ? FALSE : TRUE; newfile( TRUE ); break; case 17: /* Tabs */ case 18: case 19: case 20: case 21: tab=ITEMNUM( code )-17; if( tab ) tab=(1<<(tab-1)); newfile( TRUE ); break; default: fine( "INTERNAL ERROR #3" ); } code=ItemAddress( &menu, code )->NextSelect; } break; case GADGETDOWN: switch( code ) { case UPID: /* up */ case DOWNID: /* down */ fastscroll=(((seconds-oldseconds)<=1) && ((seconds-oldseconds)*1000000+(micros-oldmicros)Flags & SELECTED ); break; case PROPID: /* scroll bar */ fastscroll=TRUE; turboscroll=TRUE; do { newpos=linenum>framenum ? ((ULONG)(linenum-framenum)*propinfo.HorizPot+(1<<15))>>16 : 0; if( newpos!=pos ) { if( ABS(newpos-pos)>=DELTAFRAME ) outframe( newpos ); else if( newpos>pos ) scrolldown(); else scrollup(); } }while( propgadg.Flags & SELECTED ); scrolloutframe( linenum>framenum ? ((ULONG)(linenum-framenum)*propinfo.HorizPot+(1<<15))>>16 : 0 ); break; default: fine( "INTERNAL ERROR #4" ); } break; case GADGETUP: switch( code) { case SEARCHID: search(); break; case PRINTID: { LONG from, to; from=fromgstrinfo.LongInt-1; to=togstrinfo.LongInt-1; if( from>to || from<0 || to>=linenum ) messaggio( "Invalid range of lines" ); else print( from, to); } break; case FROMID: ActivateGadget( &togadg, window, &requester ); break; case TOID: ActivateGadget( &sendtogadg, window, &requester ); break; case JUMPTOID: { LONG line=jumptogstrinfo.LongInt-1; if( line!=-1 ) if( line<0 || line>=linenum ) messaggio( "Line number out of range" ); else if( line>linenum-framenum ) showreverse( line ); else scrolloutframe( line ); } break; case CANCELID: case UPID: case DOWNID: break; /* Ignorali */ default: fine( "INTERNAL ERROR #5" ); } break; case RAWKEY: if( helprequester.Flags & REQACTIVE ) { if( code<128 ) EndRequest( &helprequester, window ); break; } if( code==RAWHELP ) helpkeys(); if( code>=RAWF1 && code<=RAWF3 ) changefn( (UWORD)(code-RAWF1) ); if( code==RAWF4 || code==RAWF5 ) { UBYTE i=code-RAWF4; if( qualifier & SHIFTMASK ) { markfn[fn][i]=pos; flashpos(); } else scrolloutframe( markfn[fn][i] ); } if( code==RAWF6 || code==RAWF7 ) { printposfn[fn][ code-RAWF6 ]=pos+1; flashpos(); } if( code==RAWF8 ) search(); if( code==RAWF9 ) newfile( FALSE ); if( code==RAWF0 ) if( messaggio2( quitstr, " Yes ", " No " )==TRUE ) fine( NULL ); if( code!=RAWSPACE && (codeRAWLEFT) ) break; if( nopointer==FALSE ) /* Elimina il pointer */ { SetPointer( window, pointerdata, 0, 0, 0, 0 ); ReportMouse( window, TRUE ); ModifyIDCMP( window, IDCMPFLAGS | MENUVERIFY ); nopointer=TRUE; } if( qualifier & ALTMASK ) turboscroll=TRUE; fastscroll=(qualifier & SHIFTMASK) || turboscroll ? TRUE : FALSE; if( code==RAWSPACE ) { if( pos+framenum=linenum ) break; } else { outframe( MIN( pos+(framenum-1), linenum-framenum ) ); setprop(); } } else DisplayBeep( screen ); break; } if( !ritardo ) for( ; ritardoMouseY)/8; fastscroll= (y<=1 || y>=framenum-2) ? TRUE : FALSE; if( y<(framenum/2)-1 ) up(); if( y>(framenum/2)+1 ) down(); while( mygetmsg() && class!=MOUSEBUTTONS && code!=SELECTUP ) ; }while( !msg || class!=MOUSEBUTTONS || code!=SELECTUP); break; case MOUSEMOVE: /* Servono solo per ripristinare il pointer */ case MENUVERIFY: break; default: fine( "INTERNAL ERROR #2" ); break; } } } /***** Carica un nuovo file *****/ void newfile( BOOL formatonly ) { LONG errore; OffGadget( &Imml1Gadg, window, NULL ); OffGadget( &Immr1Gadg, window, NULL ); OffGadget( &propgadg, window, NULL ); for(;;) { if( formatonly ) { goto format; } if( lock ) /* in caso di errore */ { UnLock( lock ); lock=NULL; } if( file ) { Close( file ); file=NULL; } if( autoload==FALSE ) { errore=filefinder( &data ); if( errore==FFERROR ) { messaggio( "FileFinder error!" ); goto newfileend; } if( errore==FFCANCEL ) goto newfileend; } else autoload=FALSE; if( (lock=Lock( data.complete, ACCESS_READ ))==NULL ) { if( IoErr()==ERROR_OBJECT_NOT_FOUND ) messaggio( "File not found" ); else messaggio( "Cannot make lock" ); continue; } if( Examine( lock, fib )==NULL ) { messaggio( "Cannot Examine" ); continue; } if( fib->fib_DirEntryType>0 ) { messaggio( "It's a directory!" ); continue; } UnLock( lock ); lock=NULL; if( fib->fib_Size==0 ) { messaggio( "That file is empty!" ); continue; } if( (file=Open( data.complete, MODE_OLDFILE ))==NULL ) { messaggio( "Cannot Open file" ); continue; } RectFill( rp, MINX, MINY, MAXX, MAXY ); PrintIText( rp, &waittext, 0, MEDSCREEN ); /* cancella vecchio buffer */ if( linenum ) { FreeMem( linep, sizeof(struct line)*linenum ); FreeMem( bufferfn[fn], blenfn[fn] ); linenum=0; } /* leggi quello nuovo */ blenfn[fn]=fib->fib_Size; if( (bufferfn[fn]=AllocMem( blenfn[fn], NULL ))==NULL ) { messaggio( "No memory for buffer" ); continue; } if( Read( file, bufferfn[fn], blenfn[fn] )!=blenfn[fn] ) { messaggio( "Cannot Read file" ); FreeMem( bufferfn[fn], blenfn[fn] ); continue; } Close( file ); file=NULL; strcpy( filenamefn[fn], fib->fib_FileName ); format: RectFill( rp, MINX, MINY, MAXX, MAXY ); PrintIText( rp, &formattext, 0, MEDSCREEN ); if( formatonly && linenum ) { FreeMem( linep, sizeof(struct line)*linenum ); linenum=0; } formatonly=FALSE; findlines( NULL ); /* linenum e` 0 */ if( linenum ) { if( (linep=AllocMem( sizeof(struct line)*linenum, 0 ))==NULL ) { messaggio( "No memory for index" ); FreeMem( bufferfn[fn], blenfn[fn] ); linenum=0; continue; } findlines( linep ); } break; /* esce dal ciclo di richiesta file \/ */ } markfn[fn][0]=0; /* Top of file */ markfn[fn][1]= linenum-framenum>0 ? linenum-framenum : 0; /* End of file */ printposfn[fn][0]=1; printposfn[fn][1]=linenum; newfileend: /* routine di uscita */ makebartext(); outframe( 0 ); propbody=linenum>framenum ? (ULONG)(framenum*0xFFFF)/linenum : 0xFFFF; setprop(); posfn[fn]=pos; linenumfn[fn]=linenum; linepfn[fn]=linep; OnGadget( &Imml1Gadg, window, NULL ); OnGadget( &Immr1Gadg, window, NULL ); OnGadget( &propgadg, window, NULL ); } /***** Trova gli inizi e le lunghezze delle linee *****/ /***** se linep!=NULL memorizza i dati *****/ void findlines( struct line *linep) { UBYTE *p, *add, *lastspace=NULL; UBYTE c; UBYTE llen=0, plen=0; ULONG oldlinenum; UBYTE *plim=bufferfn[fn]+blenfn[fn]; struct line *linepact=linep; oldlinenum=linenum; linenum=0; for( p=add=bufferfn[fn]; p=80 && c!='\n' && !(c==0x0D && p+1add ) { if( !ISSPACE(c) ) { p=lastspace; llen=p-add; } while( ISSPACE(*p) ) p++; p--; c='\n'; } } /* prossimo test soddisfatto (plen>=80) */ if( c=='\n' || plen>=80 || (c==0x0D && p+1add=add; linepact->len=llen; linepact++; } if( c==0x0D ) c=*(++p); if( c=='\n' ) { add=p+1; llen=plen=0; } else { add=p; llen=plen=1; } linenum++; } else if( c==9 && tab ) { plen+=(tab-(plen%tab)); llen++; } else { llen++; plen++; } if( wordwrap && ISSPACE(c) ) lastspace=p; } if( llen ) /* ultima linea non termina con \n */ { if( linep ) { linepact->add=add; linepact->len=llen; } linenum++; } if( oldlinenum && oldlinenum!=linenum ) fine( "INTERNAL ERROR #1" ); } /***** Scrive un numero all'indirizzo to, niente NULL alla fine *****/ void numcpy( UBYTE *to, LONG numero ) { UBYTE buff[ 12 ]; stci_d( buff, numero ); strncpy( to, buff, strlen(buff) ); } /***** Costruisce e visualizza la nuova BarText *****/ void makebartext( void ) { strcpy( bartext, defbartext ); if( linenum ) { strncpy( &bartext[ BTFILE ], filenamefn[fn], MIN( strlen(filenamefn[fn]), BTFILELEN ) ); numcpy( &bartext[ BTSIZE ], blenfn[fn] ); numcpy( &bartext[ BTLINES ], linenum ); oldpos=-1; /* Mostra il numero di linea */ } else { strcpy( &bartext[ BTFILE+11 ], "--== No File Loaded ==--" ); } bartext[ BTFN ]='1'+fn; ShowTitle( screen, TRUE ); } /***** Cambia FileNumber *****/ void changefn( UWORD newfn ) { COUNT i; struct MenuItem *item; if( newfn!=fn ) { posfn[fn]=pos; /* linenumfn e linepfn sono modificati */ tabfn[fn]=tab; /* e aggiornati solo da newfile() */ wordwrapfn[fn]=wordwrap; fn=newfn; pos=posfn[fn]; linenum=linenumfn[fn]; linep=linepfn[fn]; tab=tabfn[fn]; wordwrap=wordwrapfn[fn]; outframe( pos ); makebartext(); oldpos=-1; propbody=linenum>framenum ? (ULONG)(framenum*0xFFFF)/linenum : 0xFFFF; setprop(); /* Aggiorna il menu` */ ClearMenuStrip( window ); for( i=0, item=&item12; iNextItem ) if( i==fn ) item->Flags|=CHECKED; else item->Flags&=((USHORT)-1)^CHECKED; if( wordwrap ) { item15.Flags&=((USHORT)-1)^CHECKED; item16.Flags|=CHECKED; } else { item15.Flags|=CHECKED; item16.Flags&=((USHORT)-1)^CHECKED; } if( !tab ) item17.Flags|=CHECKED; else item17.Flags&=((USHORT)-1)^CHECKED; for( i=1, item=&item18; i<=8; i*=2, item=item->NextItem ) if( i==tab ) item->Flags|=CHECKED; else item->Flags&=((USHORT)-1)^CHECKED; SetMenuStrip( window, &menu ); } } /***** Azzeramento di memoria con Blitter *****/ /***** ipotizza possesso del blitter e WaitBlit() *****/ void bltclear( UBYTE *add, UWORD lines ) { custom.bltdpt=(APTR)add; custom.bltdmod=0; custom.bltcon0=BC0F_DEST; custom.bltcon1=0; custom.bltafwm=0xFFFF; custom.bltalwm=0xFFFF; custom.bltsize=(80/2) | (lines<<6); } /***** Spostamento di memoria con Blitter *****/ /***** ipotizza possesso del blitter e WaitBlit() *****/ void bltmove( UBYTE *from, UBYTE *to, UWORD lines, UWORD dir ) { custom.bltapt=(APTR)from; custom.bltdpt=(APTR)to; custom.bltamod=0; custom.bltdmod=0; custom.bltcon0=A_TO_D | BC0F_DEST | BC0F_SRCA; custom.bltcon1=dir; custom.bltafwm=0xFFFF; custom.bltalwm=0xFFFF; custom.bltsize=(80/2) | (lines<<6); } /***** La prossima routine e` stata sostituita in assembler dalla v1.1 *****/ /***** Rotine di scrittura veloce *****/ /* void fasttext( struct line *li, UBYTE *tostart ) { register UBYTE *to; register UBYTE *from; UBYTE *p=li->add; UBYTE *plim=p+li->len; UBYTE i; UBYTE *tostart2=tostart; for( ; pSDELTAFRAME ) outframe( newpos ); else { fastscroll=TRUE; while( i-- ) { if( newpos>pos ) down(); else up(); } } setprop(); } /***** Sale di una linea lo schermo *****/ void scrollup( void ) { --pos; OwnBlitter(); WaitBlit(); bltclear( tempbitmap, 8 ); if( fastscroll ) { WaitBlit(); bltmove( bma1, bma2, cos1, MOVEDISC ); fasttext( linep+pos, tempbitmap ); WaitBlit(); bltmove( tempbitmap, BITMAPADD(0), 8, MOVEASC ); } else { UBYTE i; for( i=0; i<4; i++) { WaitBlit(); vp->DHeight=olddheight-70; WaitBOVP( vp ); vp->DHeight=olddheight; bltmove( bma3, bma2, cos2, MOVEDISC ); if( i==0 ) fasttext( linep+pos, tempbitmap ); WaitBlit(); bltmove( bma4-i*2*80, BITMAPADD(0), 2, MOVEASC ); } } DisownBlitter(); } /***** Scende di una linea lo schermo *****/ void scrolldown( void ) { ++pos; OwnBlitter(); WaitBlit(); bltclear( tempbitmap, 8 ); if( fastscroll ) { WaitBlit(); bltmove( bma5, BITMAPADD(0), cos1, MOVEASC ); fasttext( linep+(pos+FRAMELAST), tempbitmap ); WaitBlit(); bltmove( tempbitmap, bma6, 8, MOVEASC ); } else { UBYTE i; UBYTE *tbm; for( i=0, tbm=tempbitmap; i<4; i++, tbm+=2*80) { WaitBlit(); WaitBOVP( vp ); bltmove( BITMAPADD(0)+80*2, BITMAPADD(0), cos2, MOVEASC ); if( i==0 ) fasttext( linep+(pos+FRAMELAST), tempbitmap ); WaitBlit(); bltmove( tbm, bma7, 2, MOVEASC ); } } DisownBlitter(); } /***** Muovi in alto, se puoi ed aggiorna scrollbar *****/ void up( void ) { if( linenum) if( pos ) { scrollup(); if( !turboscroll) setprop(); } else DisplayBeep( screen ); } /***** Muovi in basso, se puoi ed aggiorna scrollbar *****/ void down( void ) { if( linenum ) if( pos+framenumframenum ? MIN( 0xFFFF, ((pos<<16))/(linenum-framenum)) : 0; NewModifyProp( &propgadg, window, NULL, propinfo.Flags, pot, 0, propbody, 0, 1 ); } /***** Fa scrolloutframe() ed il reverse di una linea *****/ void showreverse( LONG line ) { UBYTE *screenadd; ULONG *l; scrolloutframe( MIN( line, linenum-framenum ) ); screenadd=BITMAPADD(line-pos); for( l=(ULONG *)screenadd; l<(ULONG *)(screenadd+80*8); l++ ) *l=0; fasttext( linep+line, screenadd ); for( l=(ULONG *)screenadd; l<(ULONG *)(screenadd+80*8); l++ ) *l^=0xFFFFFFFF; } /***** Lampeggia alla posizione attuale *****/ void flashpos( void ) { COUNT i; ULONG *l; for( i=0; iadd ; padd>p ) break; newpos--; showreverse( newpos ); return; } } messaggio( "Nothing found, from here" ); } /***** Routine di print *****/ void print( LONG from, LONG to ) { BPTR file; LONG linea; struct line *lineact; UBYTE c, *p, *plim; UBYTE rep, i; UBYTE plen; BOOL printer; BPTR lock; LONG mode=MODE_NEWFILE; for( i=0; i<4; i++ ) if( printername[i]!=TOLOW(sendtobuff[i]) ) break; printer= (i==4 ? TRUE : FALSE); if( !printer ) if( (lock=Lock( sendtobuff, SHARED_LOCK ))!=NULL ) { UnLock( lock ); mode=MODE_OLDFILE; } if( (file=Open( sendtobuff, mode ))==NULL ) { messaggio( "Cannot open the printer or file" ); return; } if( !printer ) if( Seek( file, 0, OFFSET_END )==-1 ) { messaggio( "Problem with the print file" ); goto fineprint; } if( from!=to ) { requester.ReqGadget=&cancelGadg; requester.ReqText=&waitprinttext; if( Request( &requester, window )==FALSE ) { messaggio( noreqstr ); goto fineprint; } } if( printer ) if( Write( file, "\x1B[1;80s", 7 )!=7 ) /* Setta i margini */ { messaggio( priprostr ); goto fineprint; } for( linea=from, lineact=linep+from; linea<=to; linea++, lineact++ ) { if( from!=to && mygetmsg() && class==GADGETUP ) goto fineprint; plen=0; for( p=lineact->add, plim=lineact->add+lineact->len; p<=plim; p++ ) { rep=1; if( (c=*p)<32 ) if( c==9 && tab ) { c=' '; rep=tab-plen%tab; } else c='X'; if( p==plim ) c='\n'; for( i=0; iDisplayFlags & NTSC ) #endif { framenum=22; screendata.Height=200; windowdata.Height=200-11; requester.TopEdge=((200-11)-REQH)/2; helprequester.TopEdge=((200-11)-HREQH)/2; } if( (screen=(struct Screen *)OpenScreen( &screendata ))==NULL ) fine( "Cannot open screen" ); vp=&(screen->ViewPort); olddheight=vp->DHeight; barrp=screen->BarLayer->rp; SetBPen( barrp, 2 ); data.screen=screen; data.title="File to load..."; windowdata.Screen=screen; if( (window=(struct Window *)OpenWindow( &windowdata ))==NULL ) fine( "Cannot open window" ); rp=window->RPort; bitmapstart=rp->BitMap->Planes[0]+12*80; SetAPen( rp, 0 ); SetMenuStrip( window, &menu ); /* Messaggi AmigaDOS nella mia finestra */ process=(struct Process *)FindTask( NULL ); adoswin=process->pr_WindowPtr; process->pr_WindowPtr=(APTR)window; /* definisce un po` di valori per velocizzare lo scroll */ bma1=BITMAPADD(framenum-1)-1; bma2=BITMAPADD(framenum)-1; bma3=bma2-80*2; bma4=tempbitmap+80*6; bma5=BITMAPADD(1); bma6=BITMAPADD(FRAMELAST); bma7=BITMAPADD(framenum)-80*2; cos1=(UWORD)((framenum-1)*8); cos2=(UWORD)(framenum*8-2); } /***** Prende un messaggio, se esiste *****/ LONG mygetmsg( void ) { if( msg=(struct IntuiMessage *)GetMsg( window->UserPort ) ) { class=msg->Class; code=msg->Code; qualifier=msg->Qualifier; seconds=msg->Seconds; micros=msg->Micros; if( class==GADGETDOWN || class==GADGETUP ) { gadget=(struct Gadget *)msg->IAddress; code=gadget->GadgetID; } ReplyMsg( (struct Message *)msg ); if( nopointer==TRUE && class!=RAWKEY ) /* ripristina pointer */ { ClearPointer( window ); ReportMouse( window, FALSE ); ModifyIDCMP( window, IDCMPFLAGS ); nopointer=FALSE; } } return( (LONG)msg ); } /***** Mostra un messaggio con AutoRequest, con 2 risposte definibili *****/ LONG messaggio2( UBYTE *testo, UBYTE *positivo, UBYTE*negativo ) { messtesto.IText=testo; messtesto.LeftEdge=(MESSW-25-strlen(testo)*8)/2; messpositivo.IText=positivo; messnegativo.IText=negativo; return( AutoRequest( window, &messtesto, positivo ? &messpositivo : NULL, &messnegativo, positivo?VANILLAKEY:NULL, positivo?NULL:VANILLAKEY, MESSW, MESSH ) ); } /***** Mostra un messaggio con AutoRequest *****/ void messaggio( UBYTE *testo ) { messaggio2( testo, NULL, "Continue" ); } /***** Scrivi text in Output() *****/ void outs( UBYTE *text ) { Write( _Backstdout, text, strlen(text) ); } /***** Chiudi tutto e muori *****/ void fine( UBYTE *text ) { linenumfn[fn]=linenum; /* per sicurezza */ linepfn[fn]=linep; for( fn=0; fnpr_WindowPtr=adoswin; if( window ) { ClearMenuStrip( window ); CloseWindow( window ); } if( screen ) CloseScreen( screen ); if( GfxBase ) CloseLibrary( (struct Library *)GfxBase ); if( IntuitionBase ) CloseLibrary( (struct Library *)IntuitionBase ); if( text && _Backstdout ) { outs( "\nView80 Error: " ); outs( text ); outs( "!\n\n" ); } if( _Backstdout ) Close( _Backstdout ); #ifndef DEBUG _exit( NULL ); #else exit( NULL ); #endif }