#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "lzw.h" #include "mgifeobj.h" #include "mgifedit.h" #include "mgifeact.h" #include "mgifebld.h" #define PRJ ".PRJ" FRAME_DEFS_T *mgf_frames=NULL; MGIF_HEADER_T mgf_header; char *mgif_filename; word preview_frame[320*180+3]; word check1; word work_frame[320*180]; word check2; word frame_shift; TRACK_INFO_T *smp_prg=NULL; int samples_total=0; int last_unchanged_frame=0; long total_frames=0; void set_mgif(char *filename) { mgif_filename=NewArr(char,strlen(filename)+1); strcpy(mgif_filename,filename); } #define error_exit(f,n) {fclose(f);return (n);} int examine_mgif_file(char (*progress)(int perc)) { FILE *f; MGIF_HEADER_T head; int r; int frame_size=0; char chunks; int chunk_size=0; char chunk_type; int frame,chunk; int track_size=-1; FRAME_DEFS_T *fd; FRAME_DEFS_T *fg; char fgp=0; frame_shift=0; f=fopen(mgif_filename,"rb"); if (f==NULL) return EX_NOT_FOUND; r=fread(&head,1,sizeof(head),f); if (r!=sizeof(head)) error_exit(f,EX_READ_ERROR); memcpy(&mgf_header,&head,sizeof(head)); total_frames=head.frames; mgf_frames=NewArr(FRAME_DEFS_T,total_frames); memset(mgf_frames,0,sizeof(FRAME_DEFS_T)*total_frames); fg=fd=mgf_frames; for(frame=0;frameframe_start=ftell(f); if (fread(&chunks,1,1,f)!=1) error_exit(f,EX_READ_ERROR); if (fread(&frame_size,1,3,f)!=3) error_exit(f,EX_READ_ERROR); for(chunk=0;chunkdisplay_start=ftell(f); fg->displ_type=chunk_type; fg->display_size=chunk_size; fgp=1; break; case MGIF_SOUND:fd->sound_start=ftell(f); track_size=chunk_size; sound=1; fd->track_size=track_size; break; case MGIF_PAL: fg->pal_start=ftell(f); break; } fseek(f,chunk_size,SEEK_CUR); } fd->changed=1;fd->vol_save=0; if (!sound) error_exit(f,EX_NO_SOUND); if (progress(frame*100/total_frames)) break; } fclose(f); return EX_NO_ERROR; } int add_sample(char *sample) { char *d; d=NewArr(char,strlen(sample)+1); strcpy(d,sample); samples_total++; smp_prg=grealloc(smp_prg,samples_total*sizeof(TRACK_INFO_T)); smp_prg[samples_total-1].sample_name=d; smp_prg[samples_total-1].loop_start=-1; smp_prg[samples_total-1].loop_end=-1; smp_prg[samples_total-1].user_name=NULL; smp_prg[samples_total-1].levy=NULL; smp_prg[samples_total-1].pravy=NULL; smp_prg[samples_total-1].starts=NULL; smp_prg[samples_total-1].starts_count=0; return samples_total-1; } void remove_sample(int id) { TRACK_DATA_T *p,*q; if (id>=samples_total) return; p=smp_prg[id].levy; while(p!=NULL) { q=p->next;free(p);p=q; } p=smp_prg[id].pravy; while(p!=NULL) { q=p->next;free(p);p=q; } free(smp_prg[id].starts); free(smp_prg[id].sample_name); free(smp_prg[id].user_name); samples_total--; if (id!=samples_total)memcpy(smp_prg+id,smp_prg+id+1,(samples_total-id)*sizeof(TRACK_INFO_T)); smp_prg=grealloc(smp_prg,samples_total*sizeof(TRACK_INFO_T)); } void build_sample_list(void *list) { TSTR_LIST ls; int id; memcpy(&ls,list,sizeof(void **)); if (ls!=NULL) release_list(ls); ls=create_list(samples_total+1); for(id=0;id"); memcpy(list,&ls,sizeof(void **)); } char get_vpoint(TRACK_DATA_T *track,int frame,TRACK_DATA_T *vp) { int fr; TRACK_DATA_T *p,*q; if (track==NULL) { vp->vpoint1=0; vp->vpoint2=0; vp->time=total_frames-frame; vp->next=NULL; return 1; } fr=0; q=p=track; while (p!=NULL && p->time+fr<=frame) { fr+=p->time; q=p; p=p->next; } if (p!=NULL) if (fr==frame) { memcpy(vp,p,sizeof(*vp)); return 0; } else { int dif; int half; fr=frame-fr; half=p->time/2; dif=(p->vpoint2-p->vpoint1); vp->vpoint1=p->vpoint1+(dif*fr+half)/p->time; vp->vpoint2=p->vpoint2; vp->time=p->time-fr; vp->next=p->next; } else { vp->vpoint1=vp->vpoint2=q->vpoint2; vp->time=total_frames-frame; vp->next=NULL; } return 1; } void add_vpoint(TRACK_DATA_T **track,int frame) { TRACK_DATA_T *p,*z; int fr,alltime; p=*track; if (p==NULL) { z=New(TRACK_DATA_T); get_vpoint(p,0,z); *track=z; z->next=NULL; add_vpoint(track,frame); return; } fr=0; while (p!=NULL && fr+p->time<=frame) { fr+=p->time; p=p->next; } if (p==NULL) crash("Frame out of range!"); if (fr==frame) return; alltime=p->time; p->time=frame-fr; z=New(TRACK_DATA_T); z->vpoint1=p->vpoint1+((p->vpoint2-p->vpoint1)*p->time+alltime/2)/alltime; z->vpoint2=p->vpoint2; z->changed=1;p->changed=1; p->vpoint2=z->vpoint1; z->next=p->next; p->next=z; z->time=alltime-p->time; } void change_vpoint_spacing(TRACK_DATA_T *track,int frame,int value) { TRACK_DATA_T *p,*q; int fr; p=track; if (track==NULL) return; while (p->next!=NULL) p=p->next; if (p->time<=value) value=p->time-1; if (!value) return; q=track;fr=0; while (q!=NULL && q->time+fr<=frame) { fr+=q->time; q=q->next; } if (q==NULL) return; if (fr+q->time+value<=frame) return; if (q->time+value<1) return; if (frtime+=value; p->time-=value; } void set_vpoint(TRACK_DATA_T **track,int frame,int vp1,int vp2) { int fr=0; TRACK_DATA_T *p,*q; add_vpoint(track,frame); p=*track;q=NULL; while (p!=NULL && fr!=frame) { fr+=p->time; q=p; p=p->next; } p->changed=1; p->vpoint1=vp2; if (q!=NULL) { q->vpoint2=vp1; q->changed=1; } } void add_restart(TRACK_INFO_T *ti,int frame) { int *p=ti->starts; int sc=ti->starts_count; int i; for(i=0;iframe) break; p=grealloc(p,sizeof(int)*(sc+1)); p[sc]=frame; for(i=sc-1;i>=0;i--) { if (p[i]>p[i+1]) { p[i]^=p[i+1]; p[i+1]^=p[i]; p[i]^=p[i+1]; } } ti->starts=p; ti->starts_count++; } void delete_restart(TRACK_INFO_T *ti,int frame) { int i; int *p=ti->starts; int sc=ti->starts_count; for(i=0;iframe) return;else if (p[i]==frame) break; if (i==sc) return; memcpy(p+i,p+i+1,sizeof(int)*(sc-i-1)); p=grealloc(p,sizeof(int)*(sc-1)); ti->starts=p; ti->starts_count--; } void delete_vpoint(TRACK_DATA_T **track,int frame) { int fr; TRACK_DATA_T *p,*q; fr=0; p=*track; if (p==NULL) return; q=NULL; while (p!=NULL && fr!=frame) { fr+=p->time; q=p;p=p->next; } if (p==NULL) return; if (q==NULL) { if (p->next!=NULL) { *track=p->next; p->next->vpoint1=p->vpoint1; p->next->time+=p->time; } else { *track=NULL; } free(p); } else { q->next=p->next; q->vpoint2=p->vpoint2; q->time+=p->time; free(p); } return; } char join_two_frames(void *source,void *target); #pragma aux join_two_frames parm[esi][edi]=\ "mov ecx,57600"\ "xor bl,bl"\ "lp1: lodsw"\ " test [edi],0x8000"\ " jz sk1"\ " mov [edi],ax"\ " or bl,ah"\ "sk1: add edi,2"\ " dec ecx"\ " jnz lp1"\ modify[ecx eax] value[bl]; void build_frame(int frame_num,int *exit) { void *data_buff; void *delta_buff; void *p; word palette[256]; FILE *f; FRAME_DEFS_T *fd=mgf_frames+frame_num; char full=0; int counter=0; static last_frame=-1; char fast,flash; static zavora=0; if (last_frame==frame_num) { *exit=0; return; } if (frame_num>=total_frames) crash("frame_num>=total_frames"); if (frame_num-last_frame!=1) { memset(preview_frame,0x80,sizeof(preview_frame)); memset(work_frame,0x80,sizeof(work_frame)); p=work_frame;fast=0; } else { p=preview_frame+3; last_frame=frame_num; fast=1; } preview_frame[0]=320; preview_frame[1]=180; preview_frame[2]=15; while (zavora==1) task_sleep(NULL); zavora=1; f=fopen(mgif_filename,"rb"); data_buff=getmem(100000); delta_buff=getmem(100000); init_lzw_compressor(8); do { reinit_lzw(); if (fd->pal_start) { fseek(f,fd->pal_start,SEEK_SET); fread(palette,1,sizeof(palette),f); } if (fd->display_start) { fseek(f,fd->display_start,SEEK_SET); fread(data_buff,1,fd->display_size,f); switch (fd->displ_type) { case MGIF_LZW:lzw_decode(data_buff,delta_buff); show_full_lfb12e(delta_buff,p,palette); break; case MGIF_DELTA:lzw_decode(data_buff,delta_buff); show_delta_lfb12e(delta_buff,p,palette); break; case MGIF_COPY:show_full_lfb12e(data_buff,p,palette); break; } if (!fast) full=!(join_two_frames(work_frame,preview_frame+3) & 0x80); if (!((counter++) & 0xf) || full) { c_set_value(win_preview,10,0); c_set_value(win_preview,10,(int)&preview_frame); c_set_value(win_preview,5,(full||fast)?LABELCOLOR:(flash?0x7c00:0x3e0)); flash=!flash; if (waktual->id!=win_preview)redraw_desktop(); } if (!fast) task_sleep(NULL); if (task_info[curtask]) break; } fd--; } while (fd>=mgf_frames && !full && !fast); done_lzw_compressor(); free(data_buff); free(delta_buff); fclose(f); if (full) last_frame=frame_num; zavora=0; *exit=0; } extern char backsndbuff[BACK_BUFF_SIZE]; extern volatile long backsnd; extern volatile long backstep; extern volatile int backfine; extern long vals_save; static stop_preview_flag=0; static void *bufpos; void preview_block(int start_frame,int x, int y) { word *scr; void *data_buff; char *dt; void *delta_buff; word *palette; FILE *f; FRAME_DEFS_T *fd=mgf_frames+start_frame; int i; char chunks; int fsize,shift; char chunk_type; int chunk_size; schovej_mysku(); zobraz_mysku(); stop_preview_flag=0; if (banking)scr=screen+640*y+x;else scr=(word *)lbuffer+640*y+x; memset(backsndbuff,0,sizeof(backsndbuff)); i=total_frames-start_frame; bufpos=NULL; if (!i) return; start_mixing(); f=fopen(mgif_filename,"rb"); data_buff=getmem(100000); delta_buff=getmem(100000); shift=frame_shift; fseek(f,fd->frame_start,SEEK_SET); init_lzw_compressor(8); backsnd=0;backstep=0x10000;vals_save=fd->vol_save; do { char *gr,*s;char grtype; long ssize; fread(&fsize,1,4,f);chunks=fsize & 0xff;fsize>>=8; fread(data_buff,1,fsize,f); dt=data_buff; grtype=0xff; while (chunks--) { chunk_size=*(int *)dt;dt+=4; chunk_type=chunk_size&0xff;chunk_size>>=8; switch(chunk_type) { case MGIF_PAL:palette=(word *)dt;break; case MGIF_LZW: case MGIF_DELTA:reinit_lzw();lzw_decode(dt,delta_buff);grtype=chunk_type;break; case MGIF_COPY:gr=dt;grtype=chunk_type;break; case MGIF_SOUND:s=dt;ssize=chunk_size;break; } dt+=chunk_size; } do_events(); while (test_next_frame(bufpos,ssize)) do_events(); bufpos=sound_decompress(s,bufpos,ssize,&mgf_header.ampl_table); if (!shift) { switch(grtype) { case MGIF_LZW: show_full_interl_lfb130(delta_buff,scr,palette);break; case MGIF_DELTA:show_delta_interl_lfb130(delta_buff,scr,palette);break; case MGIF_COPY:show_full_interl_lfb130(gr,scr,palette);break; } if (banking) showview(x,y,320,180); } else shift--; fd++; } while (--i && !stop_preview_flag && !exit_wait); done_lzw_compressor(); free(data_buff); free(delta_buff); fclose(f); stop_mixing(); exit_wait=0; } void stop_preview() { stop_preview_flag=1; } void save_track(FILE *f,TRACK_DATA_T *t,char *id) { fprintf(f,"%s ",id); while (t!=NULL) { fprintf(f,"%d %d %d ",t->vpoint1,t->vpoint2,t->time); t=t->next; } fprintf(f,"\n"); } void save_starts(FILE *f,int *p,int pocet) { int i; fprintf(f,"%s %d ","START",pocet); for(i=0;isample_name,ti->user_name==NULL?"":ti->user_name, ti->loop_start,ti->loop_end,ti->starts_count); save_track(f,smp_prg[i].levy,"LEFT"); save_track(f,smp_prg[i].pravy,"RIGHT"); save_starts(f,smp_prg[i].starts,smp_prg[i].starts_count); if (smp_prg[i].muted) fputs("MUTED\n",f); } fclose(f); } void *get_project_name(char *name) { char *c,*d; c=NewArr(char,strlen(name)+7); strcpy(c,name); d=strrchr(c,'\\');if (d==NULL) d=c; d=strchr(d,'.');if (d!=NULL) *d=0; strcat(c,PRJ); return c; } static void skip_space(FILE *f) { int c; while ((c=getc(f))==32); ungetc(c,f); } static void skip_nline(FILE *f) { int c; while ((c=getc(f))!='\n' && c!=EOF); } static void *load_track(FILE *f) { TRACK_DATA_T *p,*st; int vp1,vp2,tim,i; st=NULL; i=fscanf(f,"%d %d %d",&vp1,&vp2,&tim); while (i==3) { if (st==NULL) p=st=New(TRACK_DATA_T); else p=(p->next=New(TRACK_DATA_T)); p->next=NULL; p->vpoint1=vp1; p->vpoint2=vp2; p->time=tim; p->changed=0; i=fscanf(f,"%d %d %d",&vp1,&vp2,&tim); } return st; } static void load_starts(FILE *f,int **pole,int *pocet) { int i; fscanf(f,"%d",pocet); *pole=NewArr(int,*pocet); for(i=0;i<*pocet;i++) fscanf(f,"%d",*pole+i); } int load_project(char *prj_name) { FILE *f; int p,i,j; TRACK_INFO_T *ti; f=fopen(prj_name,"r"); if (f==NULL) return 0; fscanf(f,"%d %d",&p,&lifikace);skip_nline(f); smp_prg=NewArr(TRACK_INFO_T,p); for(i=0;ilevy=NULL;ti->pravy=NULL;ti->starts=NULL; do { skip_space(f); j=getc(f);ungetc(j,f); if (j=='#') break; if (j=='\n') { skip_nline(f); continue; } if (j==EOF) break; fscanf(f,"%s",s);skip_space(f); if (!strcmp(s,"TRACK")) { char s[256]; ti->muted=0; fscanf(f,"%[^]",s); ti->sample_name=NewArr(char,strlen(s)+1);strcpy(ti->sample_name,s); getc(f);s[0]=0; fscanf(f,"%[^]",s); if (s[0]) { ti->user_name=NewArr(char,strlen(s)+1);strcpy(ti->user_name,s); } else ti->user_name=NULL; getc(f); fscanf(f,"%d %d %d",&ti->loop_start,&ti->loop_end,&ti->starts_count); } else if (!strcmp(s,"LEFT")) ti->levy=load_track(f); else if (!strcmp(s,"RIGHT")) ti->pravy=load_track(f); else if (!strcmp(s,"START")) load_starts(f,&ti->starts,&ti->starts_count); else if (!strcmp(s,"MUTED")) ti->muted=1; else {fclose(f);return -1;} if (feof(f)) { fclose(f);return -2; } skip_nline(f); } while (1); } samples_total=p; return 0; } void set_changed_full_track(TRACK_INFO_T *tr) { set_changed_range(last_unchanged_frame,total_frames-1); set_changed_track(tr->levy); set_changed_track(tr->pravy); last_unchanged_frame=total_frames; } static void do_vol_table_track(TRACK_DATA_T *tr,int indx,char action) { int i; int fr; int p; TRACK_DATA_T v; FRAME_DEFS_T *d; for(i=0,fr=0,d=mgf_frames;ichanged|=(d->last_vol[indx]!=p); d->last_vol[indx]=p; if (v.time==1) { fr+=tr->time; tr=tr->next; } } } void read_vol_table(TRACK_INFO_T *tr) { do_vol_table_track(tr->levy,0,0); do_vol_table_track(tr->pravy,1,0); } void compare_vol_table(TRACK_INFO_T *tr) { do_vol_table_track(tr->levy,0,1); do_vol_table_track(tr->pravy,1,1); } void set_vol_table_nul(void) { int i; FRAME_DEFS_T *d; for(i=0,d=mgf_frames;ilast_vol[0]=0; d->last_vol[1]=0; } } static long get_track_size(TRACK_INFO_T *tr) { long size1=0,size2=0; TRACK_DATA_T *l,*r; l=tr->levy; r=tr->pravy; while (l!=NULL) size1+=l->time,l=l->next; while (r!=NULL) size2+=r->time,r=r->next; if (size2>size1) return size2;else return size1; } static void track_dopln_na_konci(TRACK_INFO_T *tr) { long size1=0,size2=0; TRACK_DATA_T *l,*r; l=tr->levy; r=tr->pravy; while (l->next!=NULL) size1+=l->time,l=l->next; while (r->next!=NULL) size2+=r->time,r=r->next; l->time=total_frames-size1; r->time=total_frames-size2; } void warn_size_mistmach(void) { int size=total_frames; int sizeh=size; int i; for(i=0;isizeh) sizeh=s; } if (sizetotal_frames) { msg_box(PRG_HEADER,'\x1',"MGIFEDIT zjistil,‘e film je krat¨¡, ne‘ stopy " "ulo‘en‚ v souboru PRJ. Ke spr vn‚mu um¡stˆn¡ pou‘ij funkci GDelete","Ok",NULL); } } int get_inserted_frames(int frame) { int s; frame+=1; s=1; while (framesizeh) sizeh=s; } return sizeh-total_frames; } void insert_global(int frame,int count) { int i; for(i=0;i0) { delete_vpoint(&smp_prg[i].levy,frame+j); delete_vpoint(&smp_prg[i].pravy,frame+j); } change_vpoint_spacing(smp_prg[i].levy,frame,-count); change_vpoint_spacing(smp_prg[i].pravy,frame,-count); track_dopln_na_konci(smp_prg+i); set_vpoint(&smp_prg[i].levy,frame,vl.vpoint1,vl.vpoint1); set_vpoint(&smp_prg[i].pravy,frame,vp.vpoint1,vp.vpoint1); } }