1 /* $Id: meddraw.c,v 1.4 2004-12-24 05:17:09 btb Exp $ */
3 THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
4 SOFTWARE CORPORATION ("PARALLAX"). PARALLAX, IN DISTRIBUTING THE CODE TO
5 END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A
6 ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS
7 IN USING, DISPLAYING, AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS
8 SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE
9 FREE PURPOSES. IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE
10 CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES. THE END-USER UNDERSTANDS
11 AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE.
12 COPYRIGHT 1993-1998 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED.
17 * Med drawing functions.
22 static char rcsid[] = "$Id: meddraw.c,v 1.4 2004-12-24 05:17:09 btb Exp $";
43 #include "editor/editor.h"
64 // Colors used in editor for indicating various kinds of segments.
65 #define SELECT_COLOR BM_XRGB( 63/2 , 41/2 , 0/2)
66 #define FOUND_COLOR BM_XRGB( 0/2 , 30/2 , 45/2)
67 #define WARNING_COLOR BM_XRGB( 63/2 , 0/2 , 0/2)
68 #define AXIS_COLOR BM_XRGB( 63/2 , 0/2 , 63/2)
69 #define PLAINSEG_COLOR BM_XRGB( 45/2 , 45/2 , 45/2)
70 #define MARKEDSEG_COLOR BM_XRGB( 0/2 , 63/2 , 0/2)
71 #define MARKEDSIDE_COLOR BM_XRGB( 0/2 , 63/2 , 63/2)
72 #define CURSEG_COLOR BM_XRGB( 63/2 , 63/2 , 63/2)
73 #define CURSIDE_COLOR BM_XRGB( 63/2 , 63/2 , 0/2)
74 #define CUREDGE_COLOR BM_XRGB( 0 , 63/2 , 0 )
75 #define GROUPSEG_COLOR BM_XRGB( 0/2 , 0/2 , 63/2)
76 #define GROUPSIDE_COLOR BM_XRGB( 63/2 , 0/2 , 45/2)
77 #define GROUP_COLOR BM_XRGB( 0/2 , 45/2 , 0/2)
78 #define ROBOT_COLOR BM_XRGB( 31 , 0 , 0 )
79 #define PLAYER_COLOR BM_XRGB( 0 , 0 , 31 )
81 #define DOUBLE_BUFFER 1
83 int Search_mode=0; //if true, searching for segments at given x,y
84 int Search_x,Search_y;
85 int Automap_test=0; // Set to 1 to show wireframe in automap mode.
87 void draw_seg_objects(segment *seg)
91 for (objnum=seg->objects;objnum!=-1;objnum=Objects[objnum].next) {
92 object *obj = &Objects[objnum];
93 g3s_point sphere_point;
95 if ((obj->type==OBJ_PLAYER) && (objnum > 0 ))
96 gr_setcolor(BM_XRGB( 0, 25, 0 ));
98 gr_setcolor(obj==ConsoleObject?PLAYER_COLOR:ROBOT_COLOR);
100 g3_rotate_point(&sphere_point,&obj->pos);
102 g3_draw_sphere(&sphere_point,obj->size);
107 void draw_line(int pnum0,int pnum1)
109 g3_draw_line(&Segment_points[pnum0],&Segment_points[pnum1]);
112 // ----------------------------------------------------------------------------
113 void draw_segment(segment *seg)
119 if (seg->segnum == -1) //this segment doesn't exitst
122 med_get_vertex_list(seg,&nv,&svp); // set nv = number of vertices, svp = pointer to vertex indices
123 cc=rotate_list(nv,svp);
125 if (! cc.and) { //all off screen?
128 for (i=0;i<4;i++) draw_line(svp[i],svp[i+4]);
131 draw_line(svp[i] ,svp[i+1]);
132 draw_line(svp[i+4],svp[i+4+1]);
135 draw_line(svp[0],svp[3]);
136 draw_line(svp[0+4],svp[3+4]);
142 //for looking for segment under a mouse click
143 void check_segment(segment *seg)
149 med_get_vertex_list(seg,&nv,&svp); // set nv = number of vertices, svp = pointer to vertex indices
150 cc=rotate_list(nv,svp);
152 if (! cc.and) { //all off screen?
156 gr_pixel(Search_x,Search_y); //set our search pixel to color zero
157 gr_setcolor(1); //and render in color one
159 for (fn=0;fn<6;fn++) {
160 g3s_point *vert_list[4];
162 vert_list[0] = &Segment_points[seg->verts[Side_to_verts[fn][0]]];
163 vert_list[1] = &Segment_points[seg->verts[Side_to_verts[fn][1]]];
164 vert_list[2] = &Segment_points[seg->verts[Side_to_verts[fn][2]]];
165 g3_check_and_draw_poly(3,vert_list,NULL,NULL);
167 vert_list[1] = &Segment_points[seg->verts[Side_to_verts[fn][2]]];
168 vert_list[2] = &Segment_points[seg->verts[Side_to_verts[fn][3]]];
169 g3_check_and_draw_poly(3,vert_list,NULL,NULL);
173 if (gr_ugpixel(&grd_curcanv->cv_bitmap,Search_x,Search_y) == 1)
175 if (N_found_segs < MAX_FOUND_SEGS)
176 Found_segs[N_found_segs++] = SEG_PTR_2_NUM(seg);
178 Warning("Found too many segs! (limit=%d)",MAX_FOUND_SEGS);
183 // ----------------------------------------------------------------------------
184 void draw_seg_side(segment *seg,int side)
190 med_get_vertex_list(seg,&nv,&svp); // set nv = number of vertices, svp = pointer to vertex indices
191 cc=rotate_list(nv,svp);
193 if (! cc.and) { //all off screen?
197 draw_line(svp[Side_to_verts[side][i]],svp[Side_to_verts[side][i+1]]);
199 draw_line(svp[Side_to_verts[side][i]],svp[Side_to_verts[side][0]]);
204 void draw_side_edge(segment *seg,int side,int edge)
210 med_get_vertex_list(seg,&nv,&svp); // set nv = number of vertices, svp = pointer to vertex indices
211 cc=rotate_list(nv,svp);
213 if (! cc.and) //on screen?
214 draw_line(svp[Side_to_verts[side][edge]],svp[Side_to_verts[side][(edge+1)%4]]);
217 int Show_triangulations=0;
219 //edge types - lower number types have precedence
220 #define ET_FACING 0 //this edge on a facing face
221 #define ET_NOTFACING 1 //this edge on a non-facing face
222 #define ET_NOTUSED 2 //no face uses this edge
223 #define ET_NOTEXTANT 3 //would exist if side were triangulated
225 #define ET_EMPTY 255 //this entry in array is empty
227 //colors for those types
228 //int edge_colors[] = {BM_RGB(45/2,45/2,45/2),
229 // BM_RGB(45/3,45/3,45/3), //BM_RGB(0,0,45), //
230 // BM_RGB(45/4,45/4,45/4)}; //BM_RGB(0,45,0)}; //
232 int edge_colors[] = { 54, 59, 64 };
235 typedef struct seg_edge {
237 struct {short v0,v1;} __pack__ n;
241 ubyte face_count, backface_count;
244 #define MAX_EDGES (MAX_VERTICES*4)
246 seg_edge edge_list[MAX_EDGES];
248 short used_list[MAX_EDGES]; //which entries in edge_list have been used
251 int edge_list_size; //set each frame
253 #define HASH(a,b) ((a*5+b) % edge_list_size)
255 //define edge numberings
270 0*8+5, // right cross
272 1*8+3, // front cross
273 2*8+5, // bottom cross
277 //crosses going the other way
279 1*8+4, // other right cross
280 3*8+4, // other top cross
281 0*8+2, // other front cross
282 1*8+6, // other bottom cross
283 3*8+6, // other left cross
284 5*8+7, // other back cross
287 #define N_NORMAL_EDGES 12 //the normal edges of a box
288 #define N_EXTRA_EDGES 12 //ones created by triangulation
289 #define N_EDGES_PER_SEGMENT (N_NORMAL_EDGES+N_EXTRA_EDGES)
291 #define swap(a,b) do {int t; t=(a); (a)=(b); (b)=t;} while (0)
293 //given two vertex numbers on a segment (range 0..7), tell what edge number it is
294 int find_edge_num(int v0,int v1)
298 short *edgep = edges;
300 if (v0 > v1) swap(v0,v1);
304 // for (i=0;i<N_EDGES_PER_SEGMENT;i++)
305 // if (edges[i]==vv) return i;
307 for (i=N_EDGES_PER_SEGMENT; i; i--)
309 return (N_EDGES_PER_SEGMENT-i);
311 Error("couldn't find edge for %d,%d",v0,v1);
317 //finds edge, filling in edge_ptr. if found old edge, returns index, else return -1
318 int find_edge(int v0,int v1,seg_edge **edge_ptr)
326 oldhash = hash = HASH(v0,v1);
332 if (edge_list[hash].type == ET_EMPTY) ret=0;
333 else if (edge_list[hash].v.vv == vv) ret=1;
335 if (++hash==edge_list_size) hash=0;
336 if (hash==oldhash) Error("Edge list full!");
340 *edge_ptr = &edge_list[hash];
349 //adds an edge to the edge list
350 void add_edge(int v0,int v1,ubyte type)
356 //mprintf(0, "Verts = %2i %2i, type = %i ", v0, v1, type);
357 if (v0 > v1) swap(v0,v1);
359 found = find_edge(v0,v1,&e);
365 used_list[n_used] = e-edge_list;
366 if (type == ET_FACING)
367 edge_list[used_list[n_used]].face_count++;
368 else if (type == ET_NOTFACING)
369 edge_list[used_list[n_used]].backface_count++;
370 //mprintf(0, "Facing count = %i, Not facing count = %i\n", edge_list[used_list[n_used]].face_count, edge_list[used_list[n_used]].backface_count);
375 if (type == ET_FACING)
376 edge_list[found].face_count++;
377 else if (type == ET_NOTFACING)
378 edge_list[found].backface_count++;
379 //mprintf(0, "Facing count = %i, Not facing count = %i\n", edge_list[found].face_count, edge_list[found].backface_count);
383 //adds a segment's edges to the edge list
384 void add_edges(segment *seg)
390 med_get_vertex_list(seg,&nv,&svp); // set nv = number of vertices, svp = pointer to vertex indices
391 cc=rotate_list(nv,svp);
393 if (! cc.and) { //all off screen?
396 ubyte edge_flags[N_EDGES_PER_SEGMENT];
398 for (i=0;i<N_NORMAL_EDGES;i++) edge_flags[i]=ET_NOTUSED;
399 for (;i<N_EDGES_PER_SEGMENT;i++) edge_flags[i]=ET_NOTEXTANT;
401 for (sn=0;sn<MAX_SIDES_PER_SEGMENT;sn++) {
402 side *sidep = &seg->sides[sn];
403 int num_faces, num_vertices;
406 create_all_vertex_lists(&num_faces, vertex_list, seg-Segments, sn);
412 for (fn=0; fn<num_faces; fn++) {
416 //Note: normal check appears to be the wrong way since the normals points in, but we're looking from the outside
417 if (g3_check_normal_facing(&Vertices[seg->verts[vertex_list[fn*3]]],&sidep->normals[fn]))
422 v0 = &vertex_list[fn*3];
424 for (vn=0; vn<num_vertices-1; vn++) {
426 // en = find_edge_num(vertex_list[fn*3 + vn], vertex_list[fn*3 + (vn+1)%num_vertices]);
427 en = find_edge_num(*v0, *(v0+1));
430 if (flag < edge_flags[en]) edge_flags[en] = flag;
434 en = find_edge_num(*v0, vertex_list[fn*3]);
436 if (flag < edge_flags[en]) edge_flags[en] = flag;
440 for (i=0; i<N_EDGES_PER_SEGMENT; i++)
441 if (i<N_NORMAL_EDGES || (edge_flags[i]!=ET_NOTEXTANT && Show_triangulations))
442 add_edge(seg->verts[edges[i]/8],seg->verts[edges[i]&7],edge_flags[i]);
448 // ----------------------------------------------------------------------------
449 void draw_trigger_side(segment *seg,int side)
455 med_get_vertex_list(seg,&nv,&svp); // set nv = number of vertices, svp = pointer to vertex indices
456 cc=rotate_list(nv,svp);
458 if (! cc.and) { //all off screen?
460 draw_line(svp[Side_to_verts[side][0]],svp[Side_to_verts[side][2]]);
461 //g3_draw_line(svp[Side_to_verts[side][1]],svp[Side_to_verts[side][3]]);
465 // ----------------------------------------------------------------------------
466 void draw_wall_side(segment *seg,int side)
472 med_get_vertex_list(seg,&nv,&svp); // set nv = number of vertices, svp = pointer to vertex indices
473 cc=rotate_list(nv,svp);
475 if (! cc.and) { //all off screen?
477 draw_line(svp[Side_to_verts[side][0]],svp[Side_to_verts[side][2]]);
478 draw_line(svp[Side_to_verts[side][1]],svp[Side_to_verts[side][3]]);
483 #define WALL_BLASTABLE_COLOR BM_XRGB( 31/2 , 0/2 , 0/2) // RED
484 #define WALL_DOOR_COLOR BM_XRGB( 0/2 , 0/2 , 31/2) // DARK BLUE
485 #define WALL_DOOR_LOCKED_COLOR BM_XRGB( 0/2 , 0/2 , 63/2) // BLUE
486 #define WALL_AUTO_DOOR_COLOR BM_XRGB( 0/2 , 31/2 , 0/2) // DARK GREEN
487 #define WALL_AUTO_DOOR_LOCKED_COLOR BM_XRGB( 0/2 , 63/2 , 0/2) // GREEN
488 #define WALL_ILLUSION_COLOR BM_XRGB( 63/2 , 0/2 , 63/2) // PURPLE
490 #define TRIGGER_COLOR BM_XRGB( 63/2 , 63/2 , 0/2) // YELLOW
491 #define TRIGGER_DAMAGE_COLOR BM_XRGB( 63/2 , 63/2 , 0/2) // YELLOW
493 // ----------------------------------------------------------------------------------------------------------------
494 // Draws special walls (for now these are just removable walls.)
495 void draw_special_wall( segment *seg, int side )
497 gr_setcolor(PLAINSEG_COLOR);
499 if (Walls[seg->sides[side].wall_num].type == WALL_BLASTABLE)
500 gr_setcolor(WALL_BLASTABLE_COLOR);
501 if (Walls[seg->sides[side].wall_num].type == WALL_DOOR)
502 gr_setcolor(WALL_DOOR_COLOR);
503 if (Walls[seg->sides[side].wall_num].type == WALL_ILLUSION)
504 gr_setcolor(GROUPSIDE_COLOR);
505 if (Walls[seg->sides[side].wall_num].flags & WALL_DOOR_LOCKED)
506 gr_setcolor(WALL_DOOR_LOCKED_COLOR);
507 if (Walls[seg->sides[side].wall_num].flags & WALL_DOOR_AUTO)
508 gr_setcolor(WALL_AUTO_DOOR_COLOR);
509 if (Walls[seg->sides[side].wall_num].flags & WALL_DOOR_LOCKED)
510 if (Walls[seg->sides[side].wall_num].flags & WALL_DOOR_AUTO)
511 gr_setcolor(WALL_AUTO_DOOR_LOCKED_COLOR);
512 if (Walls[seg->sides[side].wall_num].type == WALL_OPEN)
513 gr_setcolor(PLAINSEG_COLOR);
515 draw_wall_side(seg,side);
517 if (Walls[seg->sides[side].wall_num].trigger != -1) {
520 trigger_num = Walls[seg->sides[side].wall_num].trigger;
522 gr_setcolor(TRIGGER_COLOR);
523 draw_trigger_side(seg,side);
527 gr_setcolor(PLAINSEG_COLOR);
531 // ----------------------------------------------------------------------------------------------------------------
532 // Recursively parse mine structure, drawing segments.
533 void draw_mine_sub(int segnum,int depth)
537 if (Been_visited[segnum]) return; // If segment already drawn, return.
539 Been_visited[segnum] = 1; // Say that this segment has been drawn.
541 mine_ptr = &Segments[segnum];
543 // If this segment is active, process it, else skip it.
545 if (mine_ptr->segnum != -1) {
548 if (Search_mode) check_segment(mine_ptr);
549 else add_edges(mine_ptr); //add this segments edges to list
552 for (side=0; side<MAX_SIDES_PER_SEGMENT; side++) {
553 if (IS_CHILD(mine_ptr->children[side])) {
554 if (mine_ptr->sides[side].wall_num != -1)
555 draw_special_wall(mine_ptr, side);
556 draw_mine_sub(mine_ptr->children[side],depth-1);
563 void draw_mine_edges(int automap_flag)
568 for (type=ET_NOTUSED;type>=ET_FACING;type--) {
569 gr_setcolor(edge_colors[type]);
570 for (i=0;i<n_used;i++) {
571 e = &edge_list[used_list[i]];
573 if ((!automap_flag) || (e->face_count == 1))
574 draw_line(e->v.n.v0,e->v.n.v1);
579 //draws an entire mine
580 void draw_mine(segment *mine_ptr,int depth)
584 // clear visited list
585 for (i=0; i<=Highest_segment_index; i++)
588 edge_list_size = min(Num_vertices*4,MAX_EDGES); //make maybe smaller than max
591 for (i=0; i<edge_list_size; i++) {
592 edge_list[i].type = ET_EMPTY;
593 edge_list[i].face_count = 0;
594 edge_list[i].backface_count = 0;
599 draw_mine_sub(SEG_PTR_2_NUM(mine_ptr),depth);
605 // -----------------------------------------------------------------------------
606 // Draw all segments, ignoring connectivity.
607 // A segment is drawn if its segnum != -1.
608 void draw_mine_all(segment *sp, int automap_flag)
613 // clear visited list
614 for (i=0; i<=Highest_segment_index; i++)
617 edge_list_size = min(Num_vertices*4,MAX_EDGES); //make maybe smaller than max
620 for (i=0; i<edge_list_size; i++) {
621 edge_list[i].type = ET_EMPTY;
622 edge_list[i].face_count = 0;
623 edge_list[i].backface_count = 0;
628 for (s=0; s<=Highest_segment_index; s++)
629 if (sp[s].segnum != -1) {
630 for (i=0; i<MAX_SIDES_PER_SEGMENT; i++)
631 if (sp[s].sides[i].wall_num != -1)
632 draw_special_wall(&sp[s], i);
634 check_segment(&sp[s]);
637 draw_seg_objects(&sp[s]);
641 draw_mine_edges(automap_flag);
645 void draw_selected_segments(void)
649 gr_setcolor(SELECT_COLOR);
650 for (s=0; s<N_selected_segs; s++)
651 if (Segments[Selected_segs[s]].segnum != -1)
652 draw_segment(&Segments[Selected_segs[s]]);
655 void draw_found_segments(void)
659 gr_setcolor(FOUND_COLOR);
660 for (s=0; s<N_found_segs; s++)
661 if (Segments[Found_segs[s]].segnum != -1)
662 draw_segment(&Segments[Found_segs[s]]);
665 void draw_warning_segments(void)
669 gr_setcolor(WARNING_COLOR);
670 for (s=0; s<N_warning_segs; s++)
671 if (Segments[Warning_segs[s]].segnum != -1)
672 draw_segment(&Segments[Warning_segs[s]]);
675 void draw_group_segments(void)
679 if (current_group > -1) {
680 gr_setcolor(GROUP_COLOR);
681 for (s=0; s<GroupList[current_group].num_segments; s++)
682 if (Segments[GroupList[current_group].segments[s]].segnum != -1)
683 draw_segment(&Segments[GroupList[current_group].segments[s]]);
688 void draw_special_segments(void)
693 // Highlight matcens, fuelcens, etc.
694 for (seg=0;seg<=Highest_segment_index;seg++)
695 if (Segments[seg].segnum != -1)
696 switch(Segment2s[seg].special)
698 case SEGMENT_IS_FUELCEN:
699 color = BM_XRGB( 29, 27, 13 );
701 draw_segment(&Segments[seg]);
703 case SEGMENT_IS_CONTROLCEN:
704 color = BM_XRGB( 29, 0, 0 );
706 draw_segment(&Segments[seg]);
708 case SEGMENT_IS_ROBOTMAKER:
709 color = BM_XRGB( 29, 0, 31 );
711 draw_segment(&Segments[seg]);
717 //find a free vertex. returns the vertex number
722 Assert(Num_vertices < MAX_SEGMENT_VERTICES);
724 for (vn=0; (vn < Num_vertices) && Vertex_active[vn]; vn++) ;
726 Vertex_active[vn] = 1;
734 void free_vert(int vert_num)
736 Vertex_active[vert_num] = 0;
740 // -----------------------------------------------------------------------------
741 void draw_coordinate_axes(void)
744 short Axes_verts[16];
745 vms_vector tvec,xvec,yvec,zvec;
748 Axes_verts[i] = alloc_vert();
750 create_coordinate_axes_from_segment(Cursegp,Axes_verts);
752 vm_vec_sub(&xvec,&Vertices[Axes_verts[1]],&Vertices[Axes_verts[0]]);
753 vm_vec_sub(&yvec,&Vertices[Axes_verts[2]],&Vertices[Axes_verts[0]]);
754 vm_vec_sub(&zvec,&Vertices[Axes_verts[3]],&Vertices[Axes_verts[0]]);
756 // Create the letter X
758 vm_vec_add(&Vertices[Axes_verts[4]],&Vertices[Axes_verts[1]],vm_vec_scale(&tvec,F1_0/16));
760 vm_vec_add2(&Vertices[Axes_verts[4]],vm_vec_scale(&tvec,F1_0/8));
761 vm_vec_sub(&Vertices[Axes_verts[6]],&Vertices[Axes_verts[4]],vm_vec_scale(&tvec,F2_0));
762 tvec = xvec; vm_vec_scale(&tvec,F1_0/8);
763 vm_vec_add(&Vertices[Axes_verts[7]],&Vertices[Axes_verts[4]],&tvec);
764 vm_vec_add(&Vertices[Axes_verts[5]],&Vertices[Axes_verts[6]],&tvec);
766 // Create the letter Y
768 vm_vec_add(&Vertices[Axes_verts[11]],&Vertices[Axes_verts[2]],vm_vec_scale(&tvec,F1_0/16));
769 vm_vec_add(&Vertices[Axes_verts[8]],&Vertices[Axes_verts[11]],&tvec);
770 vm_vec_add(&Vertices[Axes_verts[9]],&Vertices[Axes_verts[11]],vm_vec_scale(&tvec,F1_0*2));
771 vm_vec_add(&Vertices[Axes_verts[10]],&Vertices[Axes_verts[11]],&tvec);
772 tvec = xvec; vm_vec_scale(&tvec,F1_0/16);
773 vm_vec_sub2(&Vertices[Axes_verts[9]],&tvec);
774 vm_vec_add2(&Vertices[Axes_verts[10]],&tvec);
776 // Create the letter Z
778 vm_vec_add(&Vertices[Axes_verts[12]],&Vertices[Axes_verts[3]],vm_vec_scale(&tvec,F1_0/16));
780 vm_vec_add2(&Vertices[Axes_verts[12]],vm_vec_scale(&tvec,F1_0/8));
781 vm_vec_sub(&Vertices[Axes_verts[14]],&Vertices[Axes_verts[12]],vm_vec_scale(&tvec,F2_0));
782 tvec = zvec; vm_vec_scale(&tvec,F1_0/8);
783 vm_vec_add(&Vertices[Axes_verts[13]],&Vertices[Axes_verts[12]],&tvec);
784 vm_vec_add(&Vertices[Axes_verts[15]],&Vertices[Axes_verts[14]],&tvec);
786 rotate_list(16,Axes_verts);
788 gr_setcolor(AXIS_COLOR);
790 draw_line(Axes_verts[0],Axes_verts[1]);
791 draw_line(Axes_verts[0],Axes_verts[2]);
792 draw_line(Axes_verts[0],Axes_verts[3]);
795 draw_line(Axes_verts[4],Axes_verts[5]);
796 draw_line(Axes_verts[6],Axes_verts[7]);
799 draw_line(Axes_verts[8],Axes_verts[9]);
800 draw_line(Axes_verts[8],Axes_verts[10]);
801 draw_line(Axes_verts[8],Axes_verts[11]);
804 draw_line(Axes_verts[12],Axes_verts[13]);
805 draw_line(Axes_verts[13],Axes_verts[14]);
806 draw_line(Axes_verts[14],Axes_verts[15]);
809 free_vert(Axes_verts[i]);
812 void draw_world(grs_canvas *screen_canvas,editor_view *v,segment *mine_ptr,int depth)
814 vms_vector viewer_position;
817 grs_canvas temp_canvas;
821 // if ( screen_canvas == LargeViewBox->canvas ) {
822 // CurrentBigCanvas ^= 1;
824 // gr_set_current_canvas( BigCanvas[CurrentBigCanvas] );
827 gr_init_sub_canvas(&temp_canvas,canv_offscreen,0,0,
828 screen_canvas->cv_bitmap.bm_w,screen_canvas->cv_bitmap.bm_h);
830 gr_set_current_canvas(&temp_canvas);
833 gr_set_current_canvas(screen_canvas);
840 //g3_set_points(Segment_points,Vertices);
842 viewer_position = v->ev_matrix.fvec;
843 vm_vec_scale(&viewer_position,-v->ev_dist);
845 vm_vec_add2(&viewer_position,&Ed_view_target);
849 g3_set_view_matrix(&viewer_position,&v->ev_matrix,v->ev_zoom);
851 render_start_frame();
853 gr_setcolor(PLAINSEG_COLOR);
855 // Draw all segments or only connected segments.
856 // We might want to draw all segments if we have broken the mine into pieces.
857 if (Draw_all_segments)
858 draw_mine_all(Segments, Automap_test);
860 draw_mine(mine_ptr,depth);
862 // Draw the found segments
864 draw_warning_segments();
865 draw_group_segments();
866 draw_found_segments();
867 draw_selected_segments();
868 draw_special_segments();
870 // Highlight group segment and side.
871 if (current_group > -1)
872 if (Groupsegp[current_group]) {
873 gr_setcolor(GROUPSEG_COLOR);
874 draw_segment(Groupsegp[current_group]);
876 gr_setcolor(GROUPSIDE_COLOR);
877 draw_seg_side(Groupsegp[current_group],Groupside[current_group]);
880 // Highlight marked segment and side.
882 gr_setcolor(MARKEDSEG_COLOR);
883 draw_segment(Markedsegp);
885 gr_setcolor(MARKEDSIDE_COLOR);
886 draw_seg_side(Markedsegp,Markedside);
889 // Highlight current segment and current side.
890 gr_setcolor(CURSEG_COLOR);
891 draw_segment(Cursegp);
893 gr_setcolor(CURSIDE_COLOR);
894 draw_seg_side(Cursegp,Curside);
896 gr_setcolor(CUREDGE_COLOR);
897 draw_side_edge(Cursegp,Curside,Curedge);
899 // Draw coordinate axes if we are rendering the large view.
901 if (screen_canvas == LargeViewBox->canvas)
902 draw_coordinate_axes();
905 gr_set_fontcolor((v==current_view)?CRED:CWHITE, -1 );
906 if ( screen_canvas == LargeViewBox->canvas ) {
907 gr_ustring( 5, 5, "USER VIEW" );
908 switch (Large_view_index) {
909 case 0: gr_ustring( 85, 5, "-- TOP"); break;
910 case 1: gr_ustring( 85, 5, "-- FRONT"); break;
911 case 2: gr_ustring( 85, 5, "-- RIGHT"); break;
915 else if ( screen_canvas == TopViewBox->canvas )
916 gr_ustring( 5, 5, "TOP" );
917 else if ( screen_canvas == FrontViewBox->canvas )
918 gr_ustring( 5, 5, "FRONT" );
919 else if ( screen_canvas == RightViewBox->canvas )
920 gr_ustring( 5, 5, "RIGHT" );
922 Error("Ortho views have been removed, what gives?\n");
930 // if ( screen_canvas == LargeViewBox->canvas ) {
931 // if (BigCanvasFirstTime) {
932 // BigCanvasFirstTime = 0;
933 // gr_set_current_canvas( screen_canvas );
934 // gr_ubitmap( 0, 0, &BigCanvas[CurrentBigCanvas]->cv_bitmap );
936 // gr_vesa_update( &BigCanvas[CurrentBigCanvas]->cv_bitmap, &screen_canvas->cv_bitmap, &BigCanvas[CurrentBigCanvas ^ 1]->cv_bitmap );
939 gr_set_current_canvas( screen_canvas );
940 gr_ubitmap( 0, 0, &temp_canvas.cv_bitmap );
949 //find the segments that render at a given screen x,y
950 //parms other than x,y are like draw_world
951 //fills in globals N_found_segs & Found_segs
952 void find_segments(short x,short y,grs_canvas *screen_canvas,editor_view *v,segment *mine_ptr,int depth)
954 vms_vector viewer_position;
957 grs_canvas temp_canvas;
959 gr_init_sub_canvas(&temp_canvas,canv_offscreen,0,0,
960 screen_canvas->cv_bitmap.bm_w,screen_canvas->cv_bitmap.bm_h);
962 gr_set_current_canvas(&temp_canvas);
964 gr_set_current_canvas(screen_canvas);
969 //g3_set_points(Segment_points,Vertices);
971 viewer_position = v->ev_matrix.fvec;
972 vm_vec_scale(&viewer_position,-v->ev_dist);
974 vm_vec_add(&viewer_position,&viewer_position,&Ed_view_target);
977 g3_set_view_matrix(&viewer_position,&v->ev_matrix,v->ev_zoom);
979 render_start_frame();
987 Search_x = x; Search_y = y;
989 if (Draw_all_segments)
990 draw_mine_all(Segments, 0);
992 draw_mine(mine_ptr,depth);
1000 void meddraw_init_views( grs_canvas * canvas)
1002 Views[0]->ev_canv = canvas;
1004 Views[1]->ev_canv = TopViewBox->canvas;
1005 Views[2]->ev_canv = FrontViewBox->canvas;
1006 Views[3]->ev_canv = RightViewBox->canvas;