17 /* For loading lines from ASCII files */
19 /* Used in conjunction with "line" variable */
20 unsigned char *pos
=DUMMY
;
21 /* Pointer to a cube of chars containing all the positions of the avi animation
22 * The char and attributre are in a consecutive pair, first comes char, then
25 /* Number of valid positions in the animation */
26 int left
=0,right
=0,top
=0,bottom
=0;
27 /* left: x coord of the leftmost char
28 * right: x coord of the rightmost char +1
29 * top: y coord of the topmost char
30 * bottom: y coord of the bottommost char +1
33 /* For testing purpose only */
35 /* Pointer where the sequence of which positions are played after which is
38 /* Number of pos entries in the sequence. If the positions should be played
39 * 1,2,3,4,5,5,5,5,4,4,3,3,2,2,1,1, then sequence contains these numbers and
40 * sequence_size is 16. */
42 /* File from which the avi is loaded and into which it is written */
43 int cursor_x
, cursor_y
, cursor_pos
;
44 int window_size_x
, window_size_y
;
45 volatile int resize_needed_flag
;
46 unsigned char char_block
[]=" `~1!2@3#4$5%6^7&8*9(0)-_=+\\|qQwWeErRtTyYuUiIoOpP[{]}aAsSdDfFgGhHjJkKlL"
47 ";:'\"zZxXcCvVbBnNmM,<.>/?";
49 int mode
=0; /* 0: command mode, 1: drawing mode */
52 int last_color
, last_char
;
54 #define MY_ERROR {ERROR("Syntax error of input file\n");EXIT(-1);}
60 if (!(fgets(line
,sizeof(line
),f
))){
64 } while (*lptr
!= '#');
70 retval
=strtol(lptr
,(char **)&lptr
,0);
74 void add_pos(int how_much
)
77 pos
=mem_realloc(pos
,(right
-left
)*(bottom
-top
)*2*n_pos
);
78 memset(pos
+(right
-left
)*(bottom
-top
)*2*(n_pos
-how_much
),0,2*(right
-left
)*(bottom
-top
)*how_much
);
81 void resize(int new_left
, int new_right
, int new_top
, int new_bottom
);
83 /* If do_resize is 1, then out-of-range is solved as a resize. If do_resize is a
84 * zero, then a NULL value is returned. */
85 unsigned char *get_pointer(int x
, int y
, int p
, int do_resize
)
89 int new_left
=left
,new_right
=right
,new_top
=top
,new_bottom
=bottom
;
112 resize(new_left
,new_right
,new_top
,new_bottom
);
117 offset
*=(bottom
-top
);
119 offset
*=(right
-left
);
124 void resize(int new_left
, int new_right
, int new_top
, int new_bottom
)
126 unsigned char *new_pointer
;
127 int new_length
=(new_right
-new_left
)*2*(new_bottom
-new_top
)*n_pos
;
132 new_pointer
=mem_alloc(new_length
);
133 memset(new_pointer
,0,new_length
);
134 for (p
=0;p
<n_pos
;p
++){
135 for (y
=top
;y
<bottom
;y
++){
136 lp
=get_pointer(left
,y
,p
,1);
138 offset
*=(new_bottom
-new_top
);
140 offset
*=(new_right
-new_left
);
141 offset
+=left
-new_left
;
143 memcpy(new_pointer
+offset
,lp
, 2*(right
-left
));
154 void put_element(int x
,int y
,int pos
, int chr
)
158 ptr
=get_pointer(x
,y
,pos
,1);
162 void put_attribute(int x
,int y
,int pos
, int chr
)
166 ptr
=get_pointer(x
,y
,pos
,1);
167 if ((chr
<'0'||chr
>'9')&&(chr
<'a'||chr
>'z')&&(chr
<'A'||chr
>'Z'))chr
=0;
169 if (chr
>='0'&&chr
<='9'){
171 }else if (chr
>='a'&&chr
<='z'){
173 }else if (chr
>='A'&&chr
<='Z'){
180 void load_avi(char *filename
)
182 int xoffset
=0, yoffset
=-1,pos
=-1,x
;
184 f
=fopen(filename
,"r");
186 sequence
=mem_realloc(sequence
,sizeof(*sequence
));
196 xoffset
=read_number();
197 if ((*lptr
++)!=',') MY_ERROR
;
198 yoffset
=read_number();
207 while((*lptr
)&&(*lptr
!='\n')){
208 put_element(x
,yoffset
,pos
,*lptr
);
216 while(*lptr
&&*lptr
!='\n'){
217 put_attribute(x
,yoffset
,pos
,*lptr
);
226 sequence
=mem_realloc(sequence
,sequence_size
*sizeof(*sequence
));
227 sequence
[sequence_size
-1]=read_number();
228 if ((*lptr
++)==',') goto new_number
;
239 void normalize_transparency(void)
241 int length
=(right
-left
)*(bottom
-top
)*n_pos
;
242 unsigned char *ptr
=pos
;
243 for (;length
;length
--,ptr
+=2){
245 if ((!ptr
[1])||(!(*ptr
)))*ptr
=32;
251 void save_avi(char *filename
)
254 unsigned char *char_pointer
,*attr_pointer
;
259 normalize_transparency();
260 f
=fopen(filename
,"w");
263 for (pos
=0;pos
<n_pos
;pos
++){
267 /* skip heading empty lines */
268 for (y
=top
;y
<bottom
;y
++){
269 char_pointer
=get_pointer(left
,y
,pos
,0);
271 while((nonempty
>0)&&(!char_pointer
[2*nonempty
-1]))
277 for (;state
;state
--)t
++;
288 for (y
=t
;y
<bottom
;y
++)
290 c
=get_pointer(left
,y
,pos
,0);
292 for (a
=0;a
<right
-left
;a
++)
294 if (a
+left
<l
)l
=a
+left
;
298 fprintf(f
,"#%d\np%d,%d\n",pos
,l
,t
);
300 for (y
=t
;y
<bottom
;y
++){
301 char_pointer
=get_pointer(l
,y
,pos
,0);
302 attr_pointer
=char_pointer
+1;
304 while((nonempty
>0)&&(!char_pointer
[2*nonempty
-1]))
315 for (x
=nonempty
;x
;x
--){
316 unsigned char c
=*char_pointer
;
326 for (x
=nonempty
;x
;x
--){
327 unsigned char c
=*attr_pointer
;
329 if (c
<10)c
+='0';else c
=c
-10+'a';
331 fputc(c
=='0'?' ':c
,f
);
345 for (pos
=0;pos
<sequence_size
;pos
++){
347 fprintf(f
,"%d%s",sequence
[pos
],pos
==sequence_size
-1?"":",");
357 void filter_background(void)
359 int l
=SCREEN_X
*SCREEN_Y
;
360 unsigned char *ptr
=screen
;
361 unsigned char *ptr1
=screen_a
;
362 for (;l
;l
--,ptr
++,ptr1
++){
370 int get_colour(void){
373 ptr
=get_pointer(cursor_x
,cursor_y
,cursor_pos
,1);
377 void print_bottom_line(void)
379 int offs
=SCREEN_X
*(SCREEN_Y
-2);
383 memset(screen_a
+offs
,7,SCREEN_X
);
384 memset(screen
+offs
,' ',SCREEN_X
);
385 memset(screen
+offs
+SCREEN_X
,' ',SCREEN_X
);
386 memset(screen_a
+offs
+SCREEN_X
,0,SCREEN_X
);
388 print2screen(x
,SCREEN_Y
-2,11,mode
?"DRAW":"COMMAND");x
+=9;
389 print2screen(x
,SCREEN_Y
-2,11,anim
?"ANIM":"");x
+=6;
390 print2screen(x
,SCREEN_Y
-2,11,hold_mode
?"HOLD":"");x
+=6;
391 print2screen(x
,SCREEN_Y
-2,get_colour(),"COLOR");x
+=7;
392 print2screen(x
,SCREEN_Y
-2,7,"POS=");x
+=4;
393 snprintf(txt
,32,"%d",cursor_pos
);
394 print2screen(x
,SCREEN_Y
-2,11,txt
);x
+=strlen(txt
)+2;
395 print2screen(x
,SCREEN_Y
-2,7,"[");x
+=1;
396 snprintf(txt
,32,"% 5d",cursor_x
);
397 print2screen(x
,SCREEN_Y
-2,11,txt
);x
+=5;
398 print2screen(x
,SCREEN_Y
-2,7,",");x
+=1;
399 snprintf(txt
,32,"% 5d",cursor_y
);
400 print2screen(x
,SCREEN_Y
-2,11,txt
);x
+=5;
401 print2screen(x
,SCREEN_Y
-2,7,"]");x
+=3;
404 screen_a
[offs
+SCREEN_X
-16+x
]=x
;
405 screen
[offs
+SCREEN_X
-16+x
]=x
<10?'0'+x
:'A'+x
-10;
409 print2screen(x
,SCREEN_Y
-1,9,"F1,O");x
+=4;
410 print2screen(x
,SCREEN_Y
-1,7,"-help");x
+=6;
411 print2screen(x
,SCREEN_Y
-1,9,"ENTER");x
+=5;
412 print2screen(x
,SCREEN_Y
-1,7,"-mode");x
+=6;
413 print2screen(x
,SCREEN_Y
-1,9,"TAB");x
+=3;
414 print2screen(x
,SCREEN_Y
-1,7,"-hold");x
+=6;
415 print2screen(x
,SCREEN_Y
-1,9,"Q");x
+=1;
416 print2screen(x
,SCREEN_Y
-1,7,"-save&end");x
+=10;
417 print2screen(x
,SCREEN_Y
-1,9,"<,>");x
+=3;
418 print2screen(x
,SCREEN_Y
-1,7,"-shift");x
+=7;
419 print2screen(x
,SCREEN_Y
-1,9,"[,]");x
+=3;
420 print2screen(x
,SCREEN_Y
-1,7,"-copy pos");x
+=10;
421 print2screen(x
,SCREEN_Y
-1,9,"-,+");x
+=3;
422 print2screen(x
,SCREEN_Y
-1,7,"-prev/next");x
+=11;
426 void print_view(void)
429 int left
,right
,top
,bottom
;
430 unsigned char dummy
[2]={32,0};
431 unsigned char *pointer
;
433 left
=cursor_x
-(window_size_x
>>1);
434 top
=cursor_y
-(window_size_y
>>1);
435 right
=left
+window_size_x
;
436 bottom
=top
+window_size_y
;
439 for (y
=top
;y
<bottom
;y
++){
440 for (x
=left
;x
<right
;x
++){
441 pointer
=get_pointer(x
,y
,cursor_pos
,0);
442 if (!pointer
) pointer
=dummy
;
443 screen_a
[(x
-left
)+SCREEN_X
*(y
-top
)]=pointer
[1];
444 screen
[(x
-left
)+SCREEN_X
*(y
-top
)]=*pointer
;
448 /*screen[(cursor_x-left)+SCREEN_X*(cursor_y-top)]='+';
449 screen_a[(cursor_x-left)+SCREEN_X*(cursor_y-top)]=15;*/
452 if (help
)print_help_window();
457 c_goto((cursor_x
-left
),(cursor_y
-top
));
465 unsigned long_long animate_speed
=1000000/36;
469 for (s
=0;s
<sequence_size
;s
++){
475 cursor_pos
=sequence
[s
];
477 sleep_until(get_time()+animate_speed
);
483 void draw_colour(int colour
){
486 ptr
=get_pointer(cursor_x
,cursor_y
,cursor_pos
,1);
491 void draw_char(int character
){
494 ptr
=get_pointer(cursor_x
,cursor_y
,cursor_pos
,1);
496 if (!ptr
[1]) ptr
[1]=7;
500 void copy_pos(int dest
, int src
)
502 if (max(dest
,src
)>=n_pos
)
503 add_pos(max(dest
,src
)+1-n_pos
);
504 memcpy(pos
+(right
-left
)*(bottom
-top
)*2*dest
,pos
+(right
-left
)*(bottom
-top
)*2*src
,(right
-left
)*(bottom
-top
)*2);
507 void shift_right(int p
)
511 unsigned char *ptr
=pos
+(right
-left
)*(bottom
-top
)*2*p
;
513 if (right
==left
) return;
514 for (y
=bottom
-top
;y
;y
--){
515 a1
=ptr
[(right
-left
)*2-1];
516 a2
=ptr
[(right
-left
)*2-2];
517 memmove(ptr
+2,ptr
,(right
-left
-1)*2);
524 void shift_left(int p
)
527 unsigned char *ptr
=pos
+(right
-left
)*(bottom
-top
)*2*p
,a1
,a2
;
529 if (right
==left
) return;
530 for (y
=bottom
-top
;y
;y
--){
533 memmove(ptr
,ptr
+2,(right
-left
-1)*2);
534 ptr
[(right
-left
)*2-1]=a1
;
535 ptr
[(right
-left
)*2-2]=a2
;
542 typedef unsigned long_long ttp
;
545 ttp last_left
=0, last_right
=0, last_up
=0, last_down
=0, repeat
,
547 ttp last_plus
=0, last_minus
=0;
555 repeat
=get_time()-repeat_time
;
557 xdelta
=ydelta
=posdelta
=0;
558 l
=!!c_pressed(K_LEFT
);
559 r
=!!c_pressed(K_RIGHT
);
561 d
=!!c_pressed(K_DOWN
);
563 if (l
&&last_left
<repeat
){
565 last_left
=get_time();
567 if (r
&&last_right
<repeat
){
569 last_right
=get_time();
573 if (u
&&last_up
<repeat
){
577 if (d
&&last_down
<repeat
){
579 last_down
=get_time();
582 if (c_pressed('=')&&last_plus
<repeat
){
584 last_plus
=get_time();
586 if (c_pressed('-')&&last_minus
<repeat
){
588 last_minus
=get_time();
590 if (c_was_pressed(K_TAB
)){
594 if (c_was_pressed(K_ENTER
)){
599 if (c_was_pressed(K_F1
))
601 if (mode
){ /* draw */
604 for (a
=0;a
<((signed)sizeof(char_block
))-1;a
+=2){
605 if (c_pressed(char_block
[a
])){
607 (c_pressed(K_LEFT_SHIFT
)||c_pressed(K_RIGHT_SHIFT
))
608 draw_char(char_block
[a
+1]);
610 draw_char(char_block
[a
]);
617 if (c_was_pressed('o'))
619 if (c_was_pressed('q')) return;
620 if (c_was_pressed('g')){animate();goto redraw
;}
624 if (c_pressed('0'+a
)){
633 if (c_pressed('a'+a
)){
639 if (c_was_pressed('[')){
640 copy_pos(cursor_pos
,(cursor_pos
+n_pos
-1)%n_pos
);
643 if (c_was_pressed(']')){
644 copy_pos(cursor_pos
,(cursor_pos
+1)%n_pos
);
647 if (c_was_pressed(',')){
648 shift_left(cursor_pos
);
651 if (c_was_pressed('.')){
652 shift_right(cursor_pos
);
657 if (!cursor_pos
&&posdelta
<0) posdelta
=0;
660 cursor_pos
+=posdelta
;
664 draw_char(last_char
);
666 draw_colour(last_color
);
669 if (oldhelp
^help
)goto redraw
;
670 if (xdelta
||ydelta
||posdelta
) goto redraw
;
675 void signal_handler(int signum
)
681 psignal(signum
,"Exiting on signal");
683 fprintf(stderr
, "Exiting on signal: %d\n", signum
);
685 check_memory_leaks();
691 int main(int argc
, char **argv
)
694 fprintf(stderr
,"usage: %s foo.avi\n",argv
[0]);
698 signal(SIGINT
,signal_handler
);
699 signal(SIGTERM
,signal_handler
);
700 signal(SIGILL
,signal_handler
);
701 signal(SIGABRT
,signal_handler
);
702 signal(SIGFPE
,signal_handler
);
703 signal(SIGSEGV
,signal_handler
);
704 signal(SIGQUIT
,signal_handler
);
705 signal(SIGBUS
,signal_handler
);
707 c_get_size(&SCREEN_X
,&SCREEN_Y
);
709 c_init(SCREEN_X
,SCREEN_Y
);
710 c_get_size(&window_size_x
,&window_size_y
);
718 check_memory_leaks();