// draws a line in YZ view static void drawlineyz(HDC hdc,Tline *l,Tsector *s) { int x1=yzmap2scry(l->v1); int x2=yzmap2scry(l->v2); if ((x1<0 && x2<0) || (x1>vieww3 && x2>vieww3)) return; coord3d f1=s->getzf(verts[l->v1].x,verts[l->v1].y); coord3d f2=s->getzf(verts[l->v2].x,verts[l->v2].y); coord3d c1=s->getzc(verts[l->v1].x,verts[l->v1].y); coord3d c2=s->getzc(verts[l->v2].x,verts[l->v2].y); int z1=yzmap2scrz(f1); int z2=yzmap2scrz(f2); int zc1=yzmap2scrz(c1); int zc2=yzmap2scrz(c2); // draws the floor and ceiling MoveTo(hdc,x1,z1); LineTo(hdc,x2,z2); MoveTo(hdc,x1,zc1); LineTo(hdc,x2,zc2); Twall *w; int z3=z1,z4=z2; // draws the walls for (w=*l->walls;w;w=w->next) { if (is_hole(w)) { if (z1!=z3) { MoveTo(hdc,x1,z1); LineTo(hdc,x1,z3); } if (z2!=z4) { MoveTo(hdc,x2,z2); LineTo(hdc,x2,z4); } } z3=yzmap2scrz(w->z1c); z4=yzmap2scrz(w->z2c); MoveTo(hdc,x1,z3); LineTo(hdc,x2,z4); if (is_hole(w)) { z1=z3; z2=z4; } } if (z1!=zc1) { MoveTo(hdc,x1,z1); LineTo(hdc,x1,zc1); } if (z2!=zc2) { MoveTo(hdc,x2,z2); LineTo(hdc,x2,zc2); } }
// if the point (x,y) is near a line, divides the line with it Tvertex *insertvertex(coord3d x,coord3d y) { Tline *l; Tsector *s; if (!findline(&l,&s,x,y)) return NULL; int v=addvertex(x,y); refvertex(v); Twall *w; for (w=*l->walls;w;w=w->next) { if (is_hole(w)) { Tsector *s=((Thole *)w)->sector; Tline *l1; for (l1=s->lines;l1;l1=l1->next) if (l1->v1==l->v2 && l1->v2==l->v1) { splitline(l1,v); refvertex(v); refvertex(v); s->linesnum++; } } } splitline(l,v); s->linesnum++; return verts+v; }
void *find_neighbor_hole_of_block_from_up(void *block) { // if the next block is a hole, return its address void *neighbor = block - 4 + get_size_of_allocated_block(block); if ( is_hole( neighbor )) return neighbor; else return NULL; }
/* Requirement 6 - tests to see whether a move is valid or not */ BOOLEAN is_valid_move(struct move move, enum cell_contents board[][BOARD_WIDTH], enum move_validity *move_validity) { struct position jump_pos; /* check both positions are valid */ if (!is_valid(move.start.x, move.start.y, board)) { if (move_validity != NULL) *move_validity = INVALID_START_POSITION; return FALSE; } if (!is_valid(move.end.x, move.end.y, board)) { if (move_validity != NULL) *move_validity = INVALID_END_POSITION; return FALSE; } /* check start is peg and end is hole */ if (!is_peg(move.start.x, move.start.y, board)) { if (move_validity != NULL) *move_validity = START_NOT_PEG; return FALSE; } if (!is_hole(move.end.x, move.end.y, board)) { if (move_validity != NULL) *move_validity = END_NOT_HOLE; return FALSE; } /* check positions are on the same row/column and separated by 1 cell */ if (!is_same_row(move.start, move.end, 2) && !is_same_column(move.start, move.end, 2)) { if (move_validity != NULL) *move_validity = NOT_SAME_ROW_COLUMN; return FALSE; } /* final check: there is a peg in between the positions */ jump_pos = get_jumped_position(move.start, move.end, board); if (board[jump_pos.y][jump_pos.x] == PEG) { if (move_validity != NULL) *move_validity = VALID; return TRUE; } else { if (move_validity != NULL) *move_validity = NO_PEG_TO_JUMP; return FALSE; } }
// modifies the walls in the line if one if the heights is changed void Tline::changeheight(Tsector *s,bool wave) { #ifdef EDITOR extern int defwalltxt; // in case of linked list, a wall can be added or deleted coord3d x1=verts[v1].x; coord3d y1=verts[v1].y; coord3d x2=verts[v2].x; coord3d y2=verts[v2].y; xx=x1;yy=y1; coord3d sf1=s->getzf(x1,y1); coord3d sf2=s->getzf(x2,y2); coord3d sc1=s->getzc(x1,y1); coord3d sc2=s->getzc(x2,y2); bool fl1,fl2=false; fl1=!is_hole(*walls); Twall *w; Twall *ww[MAX_WPL]; // walls Thole *wh[MAX_WPL]; // holes int wn=0; // number of walls int hn=0; // number of holes // fills ww and wh for (w=*walls;w;w=w->next) { if (is_hole(w)) { wh[hn]=(Thole *)w; hn++; fl2=false; } else { ww[wn]=w; wn++; fl2=true; } } int hi,wi=0,i; // sorts the holes by height if (hn) { qsort(wh,hn,sizeof(wh[0]),cmpholes); coord3d z1=wh[0]->sector->getzf(x1,y1); coord3d z2=wh[0]->sector->getzf(x2,y2); // adds a new wall at the bottom if necessary if (z1>sf1 || z2>sf2) { if (!fl1) { memmove(ww+1,ww,wn*sizeof(ww[0])); ww[0]=new Twall(); ww[0]->options=waSOLID; ww[0]->texture=defwalltxt; wn++; wallsnum++; fl1=true; } } if (z1<sf1) z1=sf1; if (z2<sf2) z2=sf2; if (fl1) { ww[0]->z1c=z1; ww[0]->z2c=z2; wi++; } } // updates the heights of the walls. adds a new wall if necessary for (i=0;i<hn;i++) { Tsector *sc=wh[i]->sector; coord3d tf1=sc->getzf(x1,y1); coord3d tf2=sc->getzf(x2,y2); coord3d tc1=sc->getzc(x1,y1); coord3d tc2=sc->getzc(x2,y2); if (tf1<sf1) tf1=sf1; if (tf1>sc1) tf1=sc1; if (tf2<sf2) tf2=sf2; if (tf2>sc2) tf2=sc2; if (tc1<sf1) tc1=sf1; if (tc1>sc1) tc1=sc1; if (tc2<sf2) tc2=sf2; if (tc2>sc2) tc2=sc2; wh[i]->z1c=tc1; wh[i]->z2c=tc2; if (i>0) { if (wi>=wn) { ww[wi]=new Twall(); ww[wi]->options=waSOLID; ww[wi]->texture=defwalltxt; wallsnum++; wn++; } ww[wi]->z1c=tf1; ww[wi]->z2c=tf2; wi++; } } // updates the last wall. adds a wall at the top if necessary if (hn) { coord3d z1=wh[hn-1]->sector->getzc(x1,y1); coord3d z2=wh[hn-1]->sector->getzc(x2,y2); if (fl2 || z1<s->getzc(x1,y1) || z2<s->getzc(x2,y2)) { if (wi>=wn) { ww[wi]=new Twall(); ww[wi]->options=waSOLID; ww[wi]->texture=defwalltxt; wn++; wallsnum++; } wi++; fl2=true; } } else wi++; if (fl2) { ww[wi-1]->z1c=s->getzc(x1,y1); ww[wi-1]->z2c=s->getzc(x2,y2); } // removes the unnecessary walls for (;wn>wi;wn--) { delete ww[wn-1]; wallsnum--; } // links the walls and the holes in a list again Twall **w0=walls; wi=0; if (fl1) { *w0=ww[0]; w0=&(*w0)->next; wi++; } for (hi=0;hi<hn;hi++,wi++) { *w0=wh[hi]; w0=&(*w0)->next; if (wi<wn) { *w0=ww[wi]; w0=&(*w0)->next; } } for (;wi<wn;wi++) { *w0=ww[wi]; w0=&(*w0)->next; } *w0=NULL; #else // in case of array, just updates the heights Twall **w; int wi; coord3d x1=verts[v1].x; coord3d y1=verts[v1].y; coord3d x2=verts[v2].x; coord3d y2=verts[v2].y; coord3d sf1=s->getzf(x1,y1); coord3d sf2=s->getzf(x2,y2); coord3d sc1=s->getzc(x1,y1); coord3d sc2=s->getzc(x2,y2); int fl=0; coord3d h1[MAX_WPL+1]; coord3d h2[MAX_WPL+1]; int i=0; for (wi=0,w=walls;wi<wallsnum;wi++,NEXTWALL(w)) { if (is_hole(*w)) { Tsector *sc=((Thole *)(*w))->sector; coord3d tf1=sc->getzf(x1,y1); coord3d tf2=sc->getzf(x2,y2); coord3d tc1=sc->getzc(x1,y1); coord3d tc2=sc->getzc(x2,y2); if (tf1<sf1) tf1=sf1; if (tf1>sc1) tf1=sc1; if (tf2<sf2) tf2=sf2; if (tf2>sc2) tf2=sc2; if (tc1<sf1) tc1=sf1; if (tc1>sc1) tc1=sc1; if (tc2<sf2) tc2=sf2; if (tc2>sc2) tc2=sc2; h1[i]=tf1; h2[i]=tf2; i++; h1[i]=tc1; h2[i]=tc2; i++; } } h1[i]=sc1; h2[i]=sc2; if (i==0 || h1[i-1]<h1[i] || h2[i-1]<h2[i]) i++; for (wi=0,w=walls;wi<wallsnum;wi++,NEXTWALL(w)) { (*w)->z1c=h1[wi+fl]; (*w)->z2c=h2[wi+fl]; } #endif // calls changeheight for opposite line { int wi; Twall **w; if (wave) for (wi=0,w=walls;wi<wallsnum;wi++,NEXTWALL(w)) { if (is_hole(*w)) { Tsector *sc=((Thole *)(*w))->sector; Tline *l=sc->getline(v2,v1); if (l) l->changeheight(sc,false); } } } }