#include #include #include #include #include #include #include #include int ap_id,av_id=-1; int av_state; #include "cltr.h" #include "coltris.rsh" #define min(a,b) (a)<(b)?(a):(b) #define max(a,b) (a)>(b)?(a):(b) OBJECT *menue,*options,*info,*user_keys; OBJECT *score,*stat; OBJECT *hi_name,*hiscore; POSITION *pos; int handle; typedef struct { int entry; int key; int state; } KEY_COMMAND; KEY_COMMAND commands[]={ M_START ,0x13, K_CTRL, /* r */ M_START ,0x13, 0, /* r */ M_START ,0x1c, 0, /* return */ M_START ,0x72, 0, /* enter */ M_HISCORE ,0x23, K_CTRL, /* h */ M_HISCORE ,0x23, 0, /* h */ M_SAVE ,0x1f, K_CTRL, /* s */ M_QUIT ,0x10, K_CTRL, /* q */ M_TETRIS ,0x14, K_CTRL, /* t */ M_TETRIS ,0x14, 0, /* t */ M_COLUMNS ,0x2e, K_CTRL, /* c */ M_COLUMNS ,0x2e, 0, /* c */ M_SCORE ,0x17, K_CTRL, /* i */ M_SCORE ,0x17, 0, /* i */ M_PREVIEW ,0x31, K_CTRL, /* n */ M_PREVIEW ,0x31, 0, /* n */ M_STATISTIC ,0x30, K_CTRL, /* b */ M_STATISTIC ,0x30, 0, /* b */ M_OPTS ,0x18, K_CTRL, /* o */ M_OPTS ,0x18, 0, /* o */ }; char set_file[128]="COLTRIS.SET"; OPTS opts={ PM_TETRIS,{0},1,0,0,1,0,0,0,0, {"---",0,0,"---",0,0,"---",0,0,"---",0,0,"---",0,0,"---",0,0,"---",0,0,"---",0,0,"---",0,0,"---",0,0}, {"---",0,0,"---",0,0,"---",0,0,"---",0,0,"---",0,0,"---",0,0,"---",0,0,"---",0,0,"---",0,0,"---",0,0}, {7,0,1,0,0},{7,0,1,0,0}, }; POSITION *pos; static uint last_score; int columns_vdi,tetris_vdi; /* -1 -> disabled */ /* 0 -> qcopy m”glich */ /* 1 -> vdi only */ int score_flag,preview_flag,stat_flag; int end_flag=0; long screen_addr; long buffer_addr; long buffer_size; int buffer_width,buffer_height; /* width in byte */ int screen_width; /* in byte */ int screen_w,screen_h,planes; int quick_flag; /* copy in screen mit ass-routine erlaubt */ static int x_off,y_off,width; MFDB screen,buffer; void redraw_play(int *message); void close_window(void); void set_score(void); void redraw_score(int *message); void set_preview(void); void redraw_preview(int *message); void set_statistic(void); void redraw_statistic(int *message); #define WIND_ANZ 4 typedef enum { W_PLAY, W_SCORE, W_PREVIEW, W_STATISTIC, } WINDOWS; typedef struct { int handle; void (*redraw)(int *message); void (*close)(void); } WINDOW; WINDOW wind[WIND_ANZ]={-1,redraw_play,close_window, -1,redraw_score,set_score, -1,redraw_preview,set_preview, -1,redraw_statistic,set_statistic}; /* zufallsgenerator nach knuth */ #define MBIG 1000000000l #define MSEED 161803398l #define FAC 1e-9 long xrandom(void) { /* return Random();*/ static int first=0; static long ma[55],inext,inextp; long mj,mk; int i,ii,k; if ( !first ) { first=1; mj=MSEED-Random(); /* -> bios zufallszahl fr init */ mj=labs(mj%MBIG); ma[54]=mj; mk=1; for ( i=0; i<54; i++ ) { ii=(21*i+21)%55-1; ma[ii]=mk; mk=mj-mk; if ( mk<0 ) mk+=MBIG; mj=ma[ii]; } for ( k=0; k<4; k++ ) { for ( i=0; i<55; i++ ) { ma[i]=ma[i]-ma[(i+31)%55]; if ( ma[i]<0 ) ma[i]+=MBIG; } } inext=-1; inextp=30; } inext++; if ( inext==55 ) inext=0; inextp++; if ( inextp==55 ) inextp=0; mj=ma[inext]-ma[inextp]; if ( mj<0 ) mj+=MBIG; ma[inext]=mj; return mj; } long gettime() { long stack; long time; stack=Super(0L); time=*(long*)0x4BA; Super((void*)stack); return(time); } static long time; void init_wait(void) { time=gettime(); } void do_wait(int ms) { while ( gettime()v_lin_wr; } static void init_copy_out(void) { if ( !opts.graph && !((opts.play_mode==PM_TETRIS && tetris_vdi) || (opts.play_mode==PM_COLUMNS && columns_vdi)) ) { quick_flag=1; if ( !screen_addr ) init_quickcopy(); if ( opts.play_mode==PM_TETRIS ) qcopy=copy_tet; else qcopy=copy_col; } else { quick_flag=0; } if ( opts.multi ) copy_out=mcopy_out; else if ( quick_flag ) copy_out=qcopy_out; else copy_out=vcopy_out; copy_min=buffer_height; copy_max=0; } /*------------------------------------------------------------------------------ hiscore ------------------------------------------------------------------------------*/ void do_score(uint score,HI_SCORE *hi) { int i,j; int x,y,w,h; last_score=score; for ( i=0; i<10; i++ ) { if ( score>hi[i].score ) { wind_update(BEG_UPDATE); form_center(hi_name,&x,&y,&w,&h); form_dial(FMD_START,x,y,w,h,x,y,w,h); objc_draw(hi_name,0,10,x,y,w,h); form_do(hi_name,HI_NAME); form_dial(FMD_FINISH,x,y,w,h,x,y,w,h); wind_update(END_UPDATE); objc_unselect(hi_name,HI_NAME); for ( j=9; j>i; j-- ) hi[j]=hi[j-1]; strcpy(hi[i].name,objc_tedstr(hi_name,HI_NAME)); hi[i].score=score; hi[i].date=Tgetdate(); return; } } } void show_hiscore(void) { HI_SCORE *hi; int i,ret,x,y,w,h; uint date; if ( opts.play_mode==PM_TETRIS ) { hi=opts.tet_hi; objc_spec(hiscore,HI_TITEL)="Tetris Hiscore"; } else { hi=opts.col_hi; objc_spec(hiscore,HI_TITEL)="Columns Hiscore"; } objc_hide(hiscore,HI_MARKE); for ( i=0; i<10; i++ ) { if ( hi[i].score!=0 ) { strcpy(objc_spec(hiscore,HISCORE1+i+i+i),hi[i].name); date=hi[i].date; sprintf(objc_spec(hiscore,HISCORE1+1+i+i+i),"%2d.%2d.%4d",date&31,(date>>5)&15,(date>>9)+1980); sprintf(objc_spec(hiscore,HISCORE1+2+i+i+i),"%5d",hi[i].score); if ( hi[i].score==last_score ) { objc_unhide(hiscore,HI_MARKE); hiscore[HI_MARKE].ob_y=hiscore[HISCORE1+i+i+i].ob_y; } } else { *objc_spec(hiscore,HISCORE1+i+i+i)=0; *objc_spec(hiscore,HISCORE1+1+i+i+i)=0; *objc_spec(hiscore,HISCORE1+2+i+i+i)=0; } } form_center(hiscore,&x,&y,&w,&h); wind_update(BEG_UPDATE); form_dial(FMD_START,x,y,w,h,x,y,w,h); objc_draw(hiscore,0,10,x,y,w,h); ret=form_do(hiscore,0)&0x7FFF; objc_unselect(hiscore,ret); form_dial(FMD_FINISH,x,y,w,h,x,y,w,h); wind_update(END_UPDATE); if ( ret==CLR_HI ) { for ( i=0; i<10; i++ ) { strcpy(hi[i].name,""); hi[i].score=0; hi[i].date=0; } } } /*------------------------------------------------------------------------------ schreibe optionen in / lese optionen aus dialogbox ------------------------------------------------------------------------------*/ void set_opts(void) { GAME_OPTS *go; int i; if ( opts.play_mode==PM_COLUMNS ) { objc_select(options,O_COLUMNS); objc_unselect(options,O_TETRIS); go=&opts.columns; } else { objc_select(options,O_TETRIS); objc_unselect(options,O_COLUMNS); go=&opts.tetris; } for ( i=LEVEL0; i<=LEVEL9; i++ ) { objc_unselect(options,i); } if ( go->start_level<9 ) objc_select(options,LEVEL0+go->start_level); for ( i=RANDOM0; i<=RANDOM14; i++ ) { objc_unselect(options,i); } if ( go->random<14 ) objc_select(options,RANDOM0+go->random); objc_unselect(options,GRAPH_ST); objc_unselect(options,GRAPH_VDI); if ( opts.graph ) objc_select(options,GRAPH_VDI); else objc_select(options,GRAPH_ST); objc_unselect(options,SINGLE); objc_unselect(options,MULTI); if ( opts.multi ) objc_select(options,MULTI); else objc_select(options,SINGLE); objc_unselect(options,CYCLENONE); objc_unselect(options,CYCLEPLAY); objc_unselect(options,CYCLEALL); if ( opts.cycle==0 ) objc_select(options,CYCLENONE); else if ( opts.cycle==1 ) objc_select(options,CYCLEPLAY); else objc_select(options,CYCLEALL); if ( opts.top ) objc_select(options,TOP_ALL); else objc_unselect(options,TOP_ALL); } void get_opts(void) { GAME_OPTS *go; int i; if ( opts.play_mode==PM_COLUMNS ) go=&opts.columns; else go=&opts.tetris; for ( i=LEVEL0; i<=LEVEL9; i++ ) { if ( objc_selected(options,i) ) { go->start_level=i-LEVEL0; break; } } for ( i=RANDOM0; i<=RANDOM14; i++ ) { if ( objc_selected(options,i) ) { go->random=i-RANDOM0; break; } } if ( objc_selected(options,GRAPH_VDI) ) opts.graph=1; else opts.graph=0; if ( objc_selected(options,MULTI) ) opts.multi=1; else opts.multi=0; if ( objc_selected(options,CYCLENONE) ) opts.cycle=0; else if ( objc_selected(options,CYCLEPLAY) ) opts.cycle=1; else opts.cycle=2; if ( objc_selected(options,TOP_ALL) ) opts.top=1; else opts.top=0; } void get_user_keys(void) { int x,y,w,h; wind_update(BEG_MCTRL); wind_update(BEG_UPDATE); strcpy(objc_spec(user_keys,KEYS_TXT),"Left"); form_center(user_keys,&x,&y,&w,&h); objc_draw(user_keys,0,10,x,y,w,h); opts.left=xget_key(); strcpy(objc_spec(user_keys,KEYS_TXT),"Right"); form_center(user_keys,&x,&y,&w,&h); objc_draw(user_keys,0,10,x,y,w,h); opts.right=xget_key(); strcpy(objc_spec(user_keys,KEYS_TXT),"Rotate"); form_center(user_keys,&x,&y,&w,&h); objc_draw(user_keys,0,10,x,y,w,h); opts.rotate=xget_key(); strcpy(objc_spec(user_keys,KEYS_TXT),"Drop"); form_center(user_keys,&x,&y,&w,&h); objc_draw(user_keys,0,10,x,y,w,h); opts.drop=xget_key(); wind_update(END_MCTRL); wind_update(END_UPDATE); } void do_options(void) { int x,y,w,h,r; wind_update(BEG_UPDATE); form_center(options,&x,&y,&w,&h); form_dial(FMD_START,x,y,w,h,x,y,w,h); set_opts(); do { objc_draw(options,0,10,x,y,w,h); r=form_do(options,0)&0x7FFF; objc_unselect(options,r); if ( r==USER_KEY ) { get_user_keys(); } } while ( r!=OK && r!=ABBR ); if ( r==OK ) { get_opts(); init_copy_out(); } form_dial(FMD_FINISH,x,y,w,h,x,y,w,h); wind_update(END_UPDATE); } void save_options(void) { int f_id; f_id=Fcreate(set_file,0); if ( f_id>0 ) { Fwrite(f_id,sizeof(opts),&opts); Fclose(f_id); } } /*------------------------------------------------------------------------------ sende fr av_protokol ------------------------------------------------------------------------------*/ char *get_send_puffer(void) { static char *send_puffer=0l; if ( !send_puffer ) { send_puffer=Mxalloc(128,0x0022); if ( send_puffer==(char*)-32 ) send_puffer=Malloc(128); } return send_puffer; } void av_send(int msg_typ,int d1,int d2,char *str) { int msg[8]; char *puf; if ( av_id<0 || (msg_typ==AV_SENDKEY && !(av_state&1)) || (msg_typ==AV_OPENWIND && !(av_state&16)) || ((msg_typ==AV_ACCWINDOPEN || msg_typ==AV_ACCWINDCLOSED) && !(av_state&64)) || ((msg_typ==AV_PATH_UPDATE|| msg_typ==AV_WHAT_IZIT) && !(av_state&16)) || (msg_typ==AV_EXIT && !(av_state&1024)) ) return; if ( str ) { puf=get_send_puffer(); if ( !puf ) return; strcpy(puf,str); } msg[0]=msg_typ; msg[1]=ap_id; msg[2]=0; if ( str ) { *(char**)&msg[3]=puf; } else { msg[3]=d1; msg[4]=d2; } msg[5]=msg[6]=msg[7]=0; if ( msg_typ==AV_PROTOKOLL ) *(char**)&msg[6]="COLTRIS "; appl_write(av_id,16,msg); } void av_init(void) { char *av,_av[32]; /* av/va kommunikationspartner einstellen */ av=getenv("AVSERVER"); if ( av!=0l ) { strncpy(_av,av,16); _av[16]=0; strcat(_av," "); _av[8]=0; av_id=appl_find(_av); } if ( av_id<0 ) { av_id=appl_find("GEMINI "); if ( av_id<0 ) { av_id=appl_find("EASE "); if ( av_id<0 ) { av_id=appl_find("AVSERVER"); } } } av_send(AV_PROTOKOLL,2,0,0l); } void av_getproto(void) { int evnt; EVENT event; do { memset(&event,0,sizeof(event)); event.ev_mflags=MU_MESAG|MU_TIMER; event.ev_mtlocount=10; /*event.ev_mthicount=0;*/ evnt=EvntMulti(&event); if ( evnt&MU_MESAG && event.ev_mmgpbuf[0]==VA_PROTOSTATUS ) av_state=event.ev_mmgpbuf[3]; } while ( evnt&MU_MESAG ); } /*------------------------------------------------------------------------------ init/exit, main ------------------------------------------------------------------------------*/ void get_tetris_size(int *w,int *h); void get_columns_size(int *w,int *h); void init_buffer(int width,int height) { int xwidth; if ( buffer_addr ) free((void*)buffer_addr); xwidth=(width+15)&~15; buffer_size=(long)xwidth*(long)height*(long)planes/8l; buffer_addr=(long)malloc(buffer_size); if ( !buffer_addr ) exit(1); memset((void*)buffer_addr,0,buffer_size); buffer.fd_addr=(void*)buffer_addr; buffer.fd_w=xwidth; buffer.fd_h=height; buffer.fd_wdwidth=xwidth/16; buffer.fd_nplanes=planes; buffer.fd_stand=0; buffer.fd_r1=buffer.fd_r2=buffer.fd_r3=0; buffer_width=xwidth/8; buffer_height=height; } void check_windpos(int *x,int *y) { if ( *xdesk_x ) *x=pos->desk_x; else if ( *x>pos->desk_x+pos->desk_w-32 ) *x=pos->desk_x+pos->desk_w-32; if ( *ydesk_y ) *y=pos->desk_y; else if ( *y>pos->desk_y+pos->desk_h-32 ) *y=pos->desk_y+pos->desk_h-32; } void init_window(int *x_x,int *y_y,int *w_w,int *h_h) { int x,y,w,h,xx,yy,ww,hh; int height; if ( objc_state(menue,M_TETRIS)&CHECKED ) get_tetris_size(&width,&height); else get_columns_size(&width,&height); wind_calc(WC_BORDER,NAME|MOVER|CLOSER,pos->wind_pos[W_PLAY].x,pos->wind_pos[W_PLAY].y,width,height,&x,&y,&w,&h); check_windpos(&x,&y); wind_calc(WC_WORK,NAME|MOVER|CLOSER,x,y,w,h,&xx,&yy,&ww,&hh); xx&=~15; wind_calc(WC_BORDER,NAME|MOVER|CLOSER,xx,yy,ww,hh,&x,&y,&w,&h); *x_x=x; *y_y=y; *w_w=w; *h_h=h; init_buffer(width,height); init_copy_out(); } void open_window(void) { int x,y,w,h,dummy; wind[W_PLAY].handle=wind_create(NAME|MOVER|CLOSER,0,0,screen_w,screen_h); init_window(&x,&y,&w,&h); if ( opts.play_mode==PM_COLUMNS ) wind_set(wind[W_PLAY].handle,WF_NAME," Columns "); else wind_set(wind[W_PLAY].handle,WF_NAME," Tetris "); wind_open(wind[W_PLAY].handle,x,y,w,h); if ( opts.cycle ) av_send(AV_ACCWINDOPEN,wind[W_PLAY].handle,0,0l); wind_get(wind[W_PLAY].handle,WF_WORKXYWH,&pos->wind_pos[W_PLAY].x,&pos->wind_pos[W_PLAY].y,&dummy,&dummy); } void close_window(void) { wind_close(wind[W_PLAY].handle); wind_delete(wind[W_PLAY].handle); av_send(AV_ACCWINDCLOSED,wind[W_PLAY].handle,0,0l); } #define ABSTAND 24 void xhide(int *hide,int x,int y,int w,int h) { int mx,my,dummy; if ( *hide ) return; /* maus ist hidden */ graf_mkstate(&mx,&my,&dummy,&dummy); if ( mx>x-ABSTAND && mx<=x+w+ABSTAND && my>y-ABSTAND && my<=y+h+ABSTAND ) { *hide=1; v_hide_c(handle); } } int check_recs(int x,int y,int w,int h,int *x1,int *y1,int *w1,int *h1) { int hx1,hy1,hx2,hy2; hx2=min(x+w,*x1+*w1); hy2=min(y+h,*y1+*h1); hx1=max(x,*x1); hy1=max(y,*y1); *x1=hx1; *y1=hy1; *w1=hx2-hx1; *h1=hy2-hy1; return( (hx2>hx1)&&(hy2>hy1) ); } void redraw_play(int *message) { int m[8]; int xy[8]; int x,y,w,h,_w; int xo,yo,ww,hh; int hide=0; if ( !message ) { m[3]=wind[W_PLAY].handle; m[4]=m[5]=0; m[6]=screen_w; m[7]=screen_h; message=m; } wind_update(BEG_UPDATE); wind_get(message[3],WF_WORKXYWH,&xo,&yo,&ww,&hh); wind_get(message[3],WF_FIRSTXYWH,&x,&y,&w,&h); while ( w!=0 ) { _w=w; if ( check_recs(message[4],message[5],message[6],message[7],&x,&y,&w,&h) ) { if ( _w==ww && quick_flag ) { char *source,*dest; xhide(&hide,xo,y,_w,h); source=(char*)buffer_addr+(long)(y-yo)*buffer_width; dest=(char*)screen_addr+(long)y*screen_width+xo/8; qcopy(dest,source,h-1); } else { xhide(&hide,x,y,w,h); xy[0]=x-xo; xy[1]=y-yo; xy[2]=x-xo+w-1; xy[3]=y-yo+h-1; xy[4]=x; xy[5]=y; xy[6]=x+w-1; xy[7]=y+h-1; vro_cpyfm(handle,S_ONLY,xy,&buffer,&screen); } } wind_get(message[3],WF_NEXTXYWH,&x,&y,&w,&h); } if ( hide ) v_show_c(handle,1); wind_update(END_UPDATE); } #define OFFSET 11 void do_endgame(void) { /************ int i,j; char *source,*dest; end_flag=1; dest=(char*)buffer_addr+buffer_size/2-sizeof(tet_ende); if ( opts.play_mode==PM_TETRIS ) source=(char*)tet_ende; else source=(char*)col_ende; init_wait(); for ( i=0,j=0; j<(int)sizeof(tet_ende); i+=OFFSET,j++ ) { if ( i>=(int)sizeof(tet_ende) ) { i-=(int)sizeof(tet_ende); redraw_play(0l); do_wait(2); init_wait(); } dest[i]=source[i]; } /******** init_wait(); for ( i=0; i<7; i++ ) { if ( i&1 ) { for ( j=0; j<(int)sizeof(tet_ende); j++ ) dest[j]=~source[j]; } else { for ( j=0; j<(int)sizeof(tet_ende); j++ ) dest[j]=source[j]; } redraw_play(0l); do_wait(125); init_wait(); } ********/ redraw_play(0l); ********/ } void set_tetris(void) { int x,y,w,h; if ( opts.play_mode==PM_TETRIS ) return; opts.play_mode=PM_TETRIS; menu_icheck(menue,M_TETRIS,1); menu_icheck(menue,M_COLUMNS,0); init_window(&x,&y,&w,&h); wind_set(wind[W_PLAY].handle,WF_CURRXYWH,x,y,w,h); wind_set(wind[W_PLAY].handle,WF_NAME," Tetris "); clr_feld(); objc_hide(stat,C_STAT); objc_unhide(stat,TSTAT); if ( opts.tetris.score!=score_flag ) set_score(); if ( opts.tetris.preview!=preview_flag ) set_preview(); if ( opts.tetris.statistic!=stat_flag ) set_statistic(); else if ( stat_flag ) redraw_statistic(0l); } void set_columns(void) { int x,y,w,h; if ( opts.play_mode==PM_COLUMNS ) return; opts.play_mode=PM_COLUMNS; menu_icheck(menue,M_COLUMNS,1); menu_icheck(menue,M_TETRIS,0); init_window(&x,&y,&w,&h); wind_set(wind[W_PLAY].handle,WF_CURRXYWH,x,y,w,h); wind_set(wind[W_PLAY].handle,WF_NAME," Columns "); clr_feld(); objc_unhide(stat,C_STAT); objc_hide(stat,TSTAT); if ( opts.columns.score!=score_flag ) set_score(); if ( opts.columns.preview!=preview_flag ) set_preview(); if ( opts.columns.statistic!=stat_flag ) set_statistic(); else if ( stat_flag ) redraw_statistic(0l); } static uint xlevel,xlines,xstones,xscore; void dr_score(uint level,uint lines,uint stones,uint sc) { static int _level=-1,_lines=-1; int le,li; int x,y,w,h; int hide=0; xlevel=level; xlines=lines; xstones=stones; xscore=sc; if ( !score_flag ) return; le=li=0; if ( _level!=level ) { _level=level; sprintf(objc_tedstr(score,LEVEL),"%d",level); le=1; } if ( _lines!=lines ) { _lines=lines; sprintf(objc_tedstr(score,LINES),"%5d",lines); li=1; } sprintf(objc_tedstr(score,STONES),"%5d",stones); sprintf(objc_tedstr(score,SCORE),"%5d",sc); wind_get(wind[W_SCORE].handle,WF_WORKXYWH,&x,&y,&w,&h); score->ob_x=x; score->ob_y=y; wind_update(BEG_UPDATE); wind_get(wind[W_SCORE].handle,WF_FIRSTXYWH,&x,&y,&w,&h); while ( w ) { xhide(&hide,x,y,w,h); if ( le ) objc_draw(score,LEVEL,0,x,y,w,h); if ( li ) objc_draw(score,LINES,0,x,y,w,h); objc_draw(score,STONES,0,x,y,w,h); objc_draw(score,SCORE,0,x,y,w,h); wind_get(wind[W_SCORE].handle,WF_NEXTXYWH,&x,&y,&w,&h); } if ( hide ) v_show_c(handle,1); wind_update(END_UPDATE); } void redraw_score(int *message) { int m[8]; int dummy; int x,y,w,h; int hide=0; if ( !message ) { m[3]=wind[W_SCORE].handle; m[4]=m[5]=0; m[6]=screen_w; m[7]=screen_h; message=m; } wind_get(wind[W_SCORE].handle,WF_WORKXYWH,&x,&y,&dummy,&dummy); score->ob_x=x; score->ob_y=y; wind_update(BEG_UPDATE); wind_get(message[3],WF_FIRSTXYWH,&x,&y,&w,&h); while ( w!=0 ) { if ( check_recs(message[4],message[5],message[6],message[7],&x,&y,&w,&h) ) { xhide(&hide,x,y,w,h); objc_draw(score,0,MAX_DEPTH,x,y,w,h); } wind_get(message[3],WF_NEXTXYWH,&x,&y,&w,&h); } if ( hide ) v_show_c(handle,1); wind_update(END_UPDATE); } void open_score(void) { int x,y,w,h,dummy; wind[W_SCORE].handle=wind_create(NAME|MOVER|CLOSER,0,0,screen_w,screen_h); wind_calc(WC_BORDER,NAME|MOVER|CLOSER,pos->wind_pos[W_SCORE].x,pos->wind_pos[W_SCORE].y,score->ob_width,score->ob_height,&x,&y,&w,&h); check_windpos(&x,&y); wind_set(wind[W_SCORE].handle,WF_NAME," Score "); dr_score(xlevel,xlines,xstones,xscore); wind_open(wind[W_SCORE].handle,x,y,w,h); if ( opts.cycle==2 ) av_send(AV_ACCWINDOPEN,wind[W_SCORE].handle,0,0l); wind_get(wind[W_SCORE].handle,WF_WORKXYWH,&pos->wind_pos[W_SCORE].x,&pos->wind_pos[W_SCORE].y,&dummy,&dummy); redraw_score(0l); if ( wind[W_PLAY].handle ) { wind_set(wind[W_PLAY].handle,WF_TOP); redraw_play(0l); } } void set_score(void) { score_flag=1-score_flag; if ( opts.play_mode==PM_TETRIS ) opts.tetris.score=score_flag; else opts.columns.score=score_flag; menu_icheck(menue,M_SCORE,score_flag); if ( !score_flag ) { wind_close(wind[W_SCORE].handle); wind_delete(wind[W_SCORE].handle); av_send(AV_ACCWINDCLOSED,wind[W_SCORE].handle,0,0l); wind[W_SCORE].handle=-1; } else { open_score(); } } int prev_x,prev_y,prev_w,prev_h; void redraw_preview(int *message) { int xy[4]; int m[8]; int x,y,w,h; int hide=0; if ( !message ) { m[3]=wind[W_PREVIEW].handle; m[4]=m[5]=0; m[6]=screen_w; m[7]=screen_h; message=m; } vsf_style(handle,8); vsf_color(handle,0); wind_update(BEG_UPDATE); wind_get(message[3],WF_FIRSTXYWH,&x,&y,&w,&h); while ( w!=0 ) { if ( check_recs(message[4],message[5],message[6],message[7],&x,&y,&w,&h) ) { xhide(&hide,x,y,w,h); xy[0]=x; xy[1]=y; xy[2]=x+w-1; xy[3]=y+h-1; v_bar(handle,xy); } wind_get(message[3],WF_NEXTXYWH,&x,&y,&w,&h); } if ( hide ) v_show_c(handle,1); wind_update(END_UPDATE); } void draw_preview(Draw_Funct draw,void *data) { int xy[4]; int x,y,w,h; int hide=0; wind_update(BEG_UPDATE); wind_get(wind[W_PREVIEW].handle,WF_FIRSTXYWH,&x,&y,&w,&h); while ( w!=0 ) { xhide(&hide,x,y,w,h); xy[0]=x; xy[1]=y; xy[2]=x+w-1; xy[3]=y+h-1; vs_clip(handle,1,xy); draw(data,x,y,w,h); wind_get(wind[W_PREVIEW].handle,WF_NEXTXYWH,&x,&y,&w,&h); } vs_clip(handle,0,xy); if ( hide ) v_show_c(handle,1); wind_update(END_UPDATE); } void open_preview(void) { int x,y,w,h; int cw,ch,tw,th,width,height; void get_columns_prev(int *w,int *h); void get_tetris_prev(int *w,int *h); get_columns_prev(&cw,&ch); get_tetris_prev(&tw,&th); width=max(cw,tw); height=max(ch,th); wind[W_PREVIEW].handle=wind_create(NAME|MOVER|CLOSER,0,0,screen_w,screen_h); wind_calc(WC_BORDER,NAME|MOVER|CLOSER,pos->wind_pos[W_PREVIEW].x,pos->wind_pos[W_PREVIEW].y,width,height,&x,&y,&w,&h); check_windpos(&x,&y); wind_set(wind[W_PREVIEW].handle,WF_NAME," Next "); wind_open(wind[W_PREVIEW].handle,x,y,w,h); if ( opts.cycle==2 ) av_send(AV_ACCWINDOPEN,wind[W_PREVIEW].handle,0,0l); wind_get(wind[W_PREVIEW].handle,WF_WORKXYWH,&prev_x,&prev_y,&prev_w,&prev_h); pos->wind_pos[W_PREVIEW].x=prev_x; pos->wind_pos[W_PREVIEW].y=prev_y; redraw_preview(0l); if ( wind[W_PLAY].handle ) { wind_set(wind[W_PLAY].handle,WF_TOP); redraw_play(0l); } } void set_preview(void) { preview_flag=1-preview_flag; if ( opts.play_mode==PM_TETRIS ) opts.tetris.preview=preview_flag; else opts.columns.preview=preview_flag; menu_icheck(menue,M_PREVIEW,preview_flag); if ( !preview_flag ) { wind_close(wind[W_PREVIEW].handle); wind_delete(wind[W_PREVIEW].handle); av_send(AV_ACCWINDCLOSED,wind[W_PREVIEW].handle,0,0l); wind[W_PREVIEW].handle=-1; } else { open_preview(); } } void redraw_statistic(int *message) { int m[8]; int dummy; int x,y,w,h,xy[4]; int st_x,st_y,st_dy; int hide=0; void dr_tstat(int x,int y,int dy); void dr_cstat(int x,int y,int dy); if ( !message ) { m[3]=wind[W_STATISTIC].handle; m[4]=m[5]=0; m[6]=screen_w; m[7]=screen_h; message=m; } wind_get(wind[W_STATISTIC].handle,WF_WORKXYWH,&x,&y,&dummy,&dummy); stat->ob_x=x; stat->ob_y=y; st_x=x; if ( opts.play_mode==PM_TETRIS ) { objc_offset(stat,TSTAT0,&h,&st_y); y=st_y+stat[TSTAT0].ob_height/2; objc_offset(stat,TSTAT0+1,&w,&h); h+=stat[TSTAT0+1].ob_height/2; } else { objc_offset(stat,CSTAT0,&h,&st_y); y=st_y+stat[CSTAT0].ob_height/2; objc_offset(stat,CSTAT0+1,&w,&h); h+=stat[CSTAT0+1].ob_height/2; } st_dy=h-y; wind_update(BEG_UPDATE); wind_get(message[3],WF_FIRSTXYWH,&x,&y,&w,&h); while ( w!=0 ) { if ( check_recs(message[4],message[5],message[6],message[7],&x,&y,&w,&h) ) { xhide(&hide,x,y,w,h); objc_draw(stat,0,MAX_DEPTH,x,y,w,h); xy[0]=x; xy[1]=y; xy[2]=x+w-1; xy[3]=y+h-1; vs_clip(handle,1,xy); if ( opts.play_mode==PM_TETRIS ) dr_tstat(st_x,st_y,st_dy); else dr_cstat(st_x,st_y,st_dy); vs_clip(handle,0,xy); } wind_get(message[3],WF_NEXTXYWH,&x,&y,&w,&h); } if ( hide ) v_show_c(handle,1); wind_update(END_UPDATE); } int _stat[10]; void dr_stat(uint *nstat) { int x,y,w,h; int i,ii,o; if ( opts.play_mode==PM_TETRIS ) { ii=7; o=TSTAT0; } else { ii=6; o=CSTAT0; } for ( i=0; iob_x=x; stat->ob_y=y; wind_update(BEG_UPDATE); wind_get(wind[W_STATISTIC].handle,WF_FIRSTXYWH,&x,&y,&w,&h); while ( w ) { xhide(&hide,x,y,w,h); objc_draw(stat,o,0,x,y,w,h); wind_get(wind[W_STATISTIC].handle,WF_NEXTXYWH,&x,&y,&w,&h); } if ( hide ) v_show_c(handle,1); wind_update(END_UPDATE); } } } void open_stat(void) { int x,y,w,h,dummy; wind[W_STATISTIC].handle=wind_create(NAME|MOVER|CLOSER,0,0,screen_w,screen_h); wind_calc(WC_BORDER,NAME|MOVER|CLOSER,pos->wind_pos[W_STATISTIC].x,pos->wind_pos[W_STATISTIC].y,stat->ob_width,stat->ob_height,&x,&y,&w,&h); check_windpos(&x,&y); wind_set(wind[W_STATISTIC].handle,WF_NAME," Statistic "); wind_open(wind[W_STATISTIC].handle,x,y,w,h); if ( opts.cycle==2 ) av_send(AV_ACCWINDOPEN,wind[W_STATISTIC].handle,0,0l); wind_get(wind[W_STATISTIC].handle,WF_WORKXYWH,&pos->wind_pos[W_STATISTIC].x,&pos->wind_pos[W_STATISTIC].y,&dummy,&dummy); redraw_statistic(0l); if ( wind[W_PLAY].handle ) { wind_set(wind[W_PLAY].handle,WF_TOP); redraw_play(0l); } } void set_statistic(void) { stat_flag=1-stat_flag; if ( opts.play_mode==PM_TETRIS ) opts.tetris.statistic=stat_flag; else opts.columns.statistic=stat_flag; menu_icheck(menue,M_STATISTIC,stat_flag); if ( !stat_flag ) { wind_close(wind[W_STATISTIC].handle); wind_delete(wind[W_STATISTIC].handle); av_send(AV_ACCWINDCLOSED,wind[W_STATISTIC].handle,0,0l); wind[W_STATISTIC].handle=-1; } else { open_stat(); } } void do_play(void) { int dummy,gret; int preview,score,statistic; int message[8]; WINDOWS w; int columns(void); int tetris(void); if ( opts.multi ) { menu_tnormal(menue,MT_FILE,1); menu_ienable(menue,M_QUIT,0); menu_ienable(menue,M_START,0); menu_ienable(menue,M_TETRIS,0); menu_ienable(menue,M_COLUMNS,0); menu_ienable(menue,M_OPTS,0); } else { v_hide_c(handle); wind_update(BEG_MCTRL); wind_update(BEG_UPDATE); } if ( opts.top ) { for ( w=WIND_ANZ-1; w>=0; w-- ) { wind_set(wind[w].handle,WF_TOP); wind[w].redraw(0l); } } else { wind_set(wind[W_PLAY].handle,WF_TOP); } preview=preview_flag; score=score_flag; statistic=stat_flag; end_flag=0; clr_feld(); if ( preview_flag ) wind_get(wind[W_PREVIEW].handle,WF_WORKXYWH,&prev_x,&prev_y,&prev_w,&prev_h); wind_get(wind[W_PLAY].handle,WF_WORKXYWH,&x_off,&y_off,&dummy,&dummy); init_copy_out(); if ( opts.play_mode==PM_COLUMNS ) gret=columns(); else gret=tetris(); if ( !gret ) /* spielabbruch -> loesche spielfeld */ clr_feld(); else { do_endgame(); } if ( preview!=preview_flag ) set_preview(); else if ( preview_flag ) { message[3]=wind[W_PREVIEW].handle; message[4]=0; message[5]=0; message[6]=screen_w; message[7]=screen_h; redraw_preview(message); } if ( score!=score_flag ) set_score(); if ( statistic!=stat_flag ) set_statistic(); if ( opts.multi ) { menu_ienable(menue,M_QUIT,1); menu_ienable(menue,M_START,1); if ( tetris_vdi!=-1 ) menu_ienable(menue,M_TETRIS,1); if ( columns_vdi!=-1 ) menu_ienable(menue,M_COLUMNS,1); menu_ienable(menue,M_OPTS,1); } else { wind_update(END_MCTRL); wind_update(END_UPDATE); v_show_c(handle,1); } } void prog_info(void) { int x,y,w,h,r; form_center(info,&x,&y,&w,&h); wind_update(BEG_UPDATE); form_dial(FMD_START,x,y,w,h,x,y,w,h); objc_draw(info,0,10,x,y,w,h); r=form_do(info,0)&0x7FFF; form_dial(FMD_FINISH,x,y,w,h,x,y,w,h); wind_update(END_UPDATE); objc_unselect(info,r); } int do_menue(int titel,int entry) { if ( objc_state(menue,entry)&DISABLED ) return 0; switch ( entry ) { case M_INFO: prog_info(); break; case M_START: do_play(); break; case M_HISCORE: show_hiscore(); break; case M_QUIT: return 1; case M_TETRIS: set_tetris(); break; case M_COLUMNS: set_columns(); break; case M_SCORE: set_score(); break; case M_PREVIEW: set_preview(); break; case M_STATISTIC: set_statistic(); break; case M_OPTS: do_options(); break; case M_SAVE: save_options(); break; } if ( titel ) menu_tnormal(menue,titel,1); return 0; } void do_ctrl(int flag) { int dummy; WINDOWS w; EVENT event; int evnt,i; int key; if ( !flag ) { event.ev_mflags=MU_MESAG|MU_KEYBD; } else { event.ev_mflags=MU_MESAG|MU_TIMER; event.ev_mtlocount=1; event.ev_mthicount=0; } while ( 1 ) { evnt=EvntMulti(&event); if ( evnt==MU_TIMER ) return; if ( evnt&MU_KEYBD ) { key=*(char*)&event.ev_mkreturn; event.ev_mmokstate&=~(K_LSHIFT|K_RSHIFT); for ( i=0; i<(int)(sizeof(commands)/sizeof(commands[0])); i++ ) { if ( key==commands[i].key && event.ev_mmokstate==commands[i].state ) { if ( do_menue(0,commands[i].entry) ) return; break; } } if ( i==(int)(sizeof(commands)/sizeof(commands[0])) ) av_send(AV_SENDKEY,event.ev_mmokstate,event.ev_mkreturn,0l); } else if ( evnt&MU_MESAG ) { switch ( event.ev_mmgpbuf[0] ) { case MN_SELECTED: if( do_menue(event.ev_mmgpbuf[3],event.ev_mmgpbuf[4]) ) return; break; case WM_REDRAW: for ( w=0; wwind_pos[w].x,&pos->wind_pos[w].y,&dummy,&dummy); break; } } break; case WM_CLOSED: for ( w=0; w0 ) { Fread(f_id,sizeof(opts),&opts); Fclose(f_id); } wind_get(0,WF_WORKXYWH,&desk_x,&desk_y,&desk_w,&desk_h); for ( i=0; i<8; i++ ) { pos=&opts.pos[i]; if ( pos->desk_x==desk_x && pos->desk_y==desk_y && pos->desk_w==desk_w && pos->desk_h==desk_h ) break; } if ( i==8 ) { for ( i=7; i>0; i-- ) opts.pos[i]=opts.pos[i-1]; pos=&opts.pos[0]; for ( w=0; wwind_pos[w].x-pos->desk_x)*desk_w; pos->wind_pos[w].x=(int)(h/pos->desk_w)+desk_x; h=(long)(pos->wind_pos[w].y-pos->desk_y)*desk_h; pos->wind_pos[w].y=(int)(h/pos->desk_h)+desk_y; } pos->desk_x=desk_x; pos->desk_y=desk_y; pos->desk_w=desk_w; pos->desk_h=desk_h; } /* init vdi */ handle=graf_handle(&dummy,&dummy,&dummy,&dummy); for ( i=0; i<10; i++ ) work_in[i]=1; work_in[10]=2; v_opnvwk(work_in,&handle,work_out); graf_mouse(0,0); screen_w=work_out[0]+1; screen_h=work_out[1]+1; vq_extnd(handle,1,work_out); planes=work_out[4]; vswr_mode(handle,MD_REPLACE); vsf_interior(handle,FIS_PATTERN); vsf_perimeter(handle,0); vst_color(handle,0); vst_height(handle,20,&dummy,&dummy,&dummy,&dummy); /*vst_effects(handle,16);*/ vst_alignment(handle,1,1,&dummy,&dummy); av_getproto(); } void do_exit(int ret) { WINDOWS w; if ( ret==1 ) { form_error(8); } else if ( ret==2 ) { form_alert(1,"[1][ | Missing or incorrect | | Image-Files! | ][ Exit ]"); } else if ( ret!=0 ) { form_alert(1,"[1][ | Something went wrong! | ][ Exit ]"); } for ( w=0; w