2 THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
3 SOFTWARE CORPORATION ("PARALLAX"). PARALLAX, IN DISTRIBUTING THE CODE TO
4 END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A
5 ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS
6 IN USING, DISPLAYING, AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS
7 SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE
8 FREE PURPOSES. IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE
9 CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES. THE END-USER UNDERSTANDS
10 AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE.
11 COPYRIGHT 1993-1998 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED.
14 * $Source: /cvs/cvsroot/d2x/main/editor/meddraw.c,v $
17 * $Date: 2004-12-19 13:54:27 $
19 * Med drawing functions.
21 * $Log: not supported by cvs2svn $
22 * Revision 1.1.1.1 1999/06/14 22:03:50 donut
23 * Import of d1x 1.37 source.
25 * Revision 2.0 1995/02/27 11:34:42 john
26 * Version 2.0! No anonymous unions, Watcom 10.0, with no need
29 * Revision 1.34 1994/11/09 11:46:30 matt
30 * Don't draw non-existant special segments
32 * Revision 1.33 1994/10/27 10:06:38 mike
33 * adapt to no inverse table.
35 * Revision 1.32 1994/10/17 18:06:23 john
36 * Made net player objects draw in dark green.
38 * Revision 1.31 1994/09/26 16:44:33 yuan
39 * Colored special segments.
41 * Revision 1.30 1994/09/01 17:02:41 matt
42 * Redraw pointer after world draw
44 * Revision 1.29 1994/08/25 21:56:21 mike
47 * Revision 1.28 1994/08/11 18:59:46 mike
48 * Adapt to new int (vs short) version of gameseg functions.
50 * Revision 1.27 1994/08/09 16:06:03 john
51 * Added the ability to place players. Made old
52 * Player variable be ConsoleObject.
54 * Revision 1.26 1994/07/25 00:03:05 matt
55 * Various changes to accomodate new 3d, which no longer takes point numbers
56 * as parms, and now only takes pointers to points.
58 * Revision 1.25 1994/07/09 17:38:13 mike
59 * comment out mprintf(0, "\n");
61 * Revision 1.24 1994/07/07 19:34:47 matt
62 * These changes are mostly Mike's, but I fixed a little bug that caused
63 * some edges to think they were never used.
65 * Revision 1.23 1994/07/06 16:36:18 mike
66 * Optionally only draw segment lines which are in only one segment.
68 * Revision 1.22 1994/05/27 10:34:28 yuan
69 * Added new Dialog boxes for Walls and Triggers.
71 * Revision 1.21 1994/05/14 18:00:56 matt
72 * Got rid of externs in source (non-header) files
74 * Revision 1.20 1994/05/09 23:35:21 mike
75 * Change order of drawing found and selected segments.
77 * Revision 1.19 1994/05/05 12:55:38 yuan
78 * Fixed a bunch of group bugs.
80 * Revision 1.18 1994/05/04 13:07:52 matt
81 * Made current edge draw in green in wire-frame window
82 * Also, moved a bunch of color constants here from editor.h
88 static char rcsid[] = "$Id: meddraw.c,v 1.1 2004-12-19 13:54:27 btb Exp $";
101 #include "segpoint.h"
105 #include "editor/editor.h"
120 #include "textures.h"
126 // Colors used in editor for indicating various kinds of segments.
127 #define SELECT_COLOR BM_XRGB( 63/2 , 41/2 , 0/2)
128 #define FOUND_COLOR BM_XRGB( 0/2 , 30/2 , 45/2)
129 #define WARNING_COLOR BM_XRGB( 63/2 , 0/2 , 0/2)
130 #define AXIS_COLOR BM_XRGB( 63/2 , 0/2 , 63/2)
131 #define PLAINSEG_COLOR BM_XRGB( 45/2 , 45/2 , 45/2)
132 #define MARKEDSEG_COLOR BM_XRGB( 0/2 , 63/2 , 0/2)
133 #define MARKEDSIDE_COLOR BM_XRGB( 0/2 , 63/2 , 63/2)
134 #define CURSEG_COLOR BM_XRGB( 63/2 , 63/2 , 63/2)
135 #define CURSIDE_COLOR BM_XRGB( 63/2 , 63/2 , 0/2)
136 #define CUREDGE_COLOR BM_XRGB( 0 , 63/2 , 0 )
137 #define GROUPSEG_COLOR BM_XRGB( 0/2 , 0/2 , 63/2)
138 #define GROUPSIDE_COLOR BM_XRGB( 63/2 , 0/2 , 45/2)
139 #define GROUP_COLOR BM_XRGB( 0/2 , 45/2 , 0/2)
140 #define ROBOT_COLOR BM_XRGB( 31 , 0 , 0 )
141 #define PLAYER_COLOR BM_XRGB( 0 , 0 , 31 )
143 #define DOUBLE_BUFFER 1
145 int Search_mode=0; //if true, searching for segments at given x,y
146 int Search_x,Search_y;
147 int Automap_test=0; // Set to 1 to show wireframe in automap mode.
149 void draw_seg_objects(segment *seg)
153 for (objnum=seg->objects;objnum!=-1;objnum=Objects[objnum].next) {
154 object *obj = &Objects[objnum];
155 g3s_point sphere_point;
157 if ((obj->type==OBJ_PLAYER) && (objnum > 0 ))
158 gr_setcolor(BM_XRGB( 0, 25, 0 ));
160 gr_setcolor(obj==ConsoleObject?PLAYER_COLOR:ROBOT_COLOR);
162 g3_rotate_point(&sphere_point,&obj->pos);
164 g3_draw_sphere(&sphere_point,obj->size);
169 void draw_line(int pnum0,int pnum1)
171 g3_draw_line(&Segment_points[pnum0],&Segment_points[pnum1]);
174 // ----------------------------------------------------------------------------
175 void draw_segment(segment *seg)
181 if (seg->segnum == -1) //this segment doesn't exitst
184 med_get_vertex_list(seg,&nv,&svp); // set nv = number of vertices, svp = pointer to vertex indices
185 cc=rotate_list(nv,svp);
187 if (! cc.and) { //all off screen?
190 for (i=0;i<4;i++) draw_line(svp[i],svp[i+4]);
193 draw_line(svp[i] ,svp[i+1]);
194 draw_line(svp[i+4],svp[i+4+1]);
197 draw_line(svp[0],svp[3]);
198 draw_line(svp[0+4],svp[3+4]);
204 //for looking for segment under a mouse click
205 void check_segment(segment *seg)
211 med_get_vertex_list(seg,&nv,&svp); // set nv = number of vertices, svp = pointer to vertex indices
212 cc=rotate_list(nv,svp);
214 if (! cc.and) { //all off screen?
218 gr_pixel(Search_x,Search_y); //set our search pixel to color zero
219 gr_setcolor(1); //and render in color one
221 for (fn=0;fn<6;fn++) {
222 g3s_point *vert_list[4];
224 vert_list[0] = &Segment_points[seg->verts[Side_to_verts[fn][0]]];
225 vert_list[1] = &Segment_points[seg->verts[Side_to_verts[fn][1]]];
226 vert_list[2] = &Segment_points[seg->verts[Side_to_verts[fn][2]]];
227 g3_check_and_draw_poly(3,vert_list,NULL,NULL);
229 vert_list[1] = &Segment_points[seg->verts[Side_to_verts[fn][2]]];
230 vert_list[2] = &Segment_points[seg->verts[Side_to_verts[fn][3]]];
231 g3_check_and_draw_poly(3,vert_list,NULL,NULL);
235 if (gr_ugpixel(&grd_curcanv->cv_bitmap,Search_x,Search_y) == 1)
237 if (N_found_segs < MAX_FOUND_SEGS)
238 Found_segs[N_found_segs++] = SEG_PTR_2_NUM(seg);
240 Warning("Found too many segs! (limit=%d)",MAX_FOUND_SEGS);
245 // ----------------------------------------------------------------------------
246 void draw_seg_side(segment *seg,int side)
252 med_get_vertex_list(seg,&nv,&svp); // set nv = number of vertices, svp = pointer to vertex indices
253 cc=rotate_list(nv,svp);
255 if (! cc.and) { //all off screen?
259 draw_line(svp[Side_to_verts[side][i]],svp[Side_to_verts[side][i+1]]);
261 draw_line(svp[Side_to_verts[side][i]],svp[Side_to_verts[side][0]]);
266 void draw_side_edge(segment *seg,int side,int edge)
272 med_get_vertex_list(seg,&nv,&svp); // set nv = number of vertices, svp = pointer to vertex indices
273 cc=rotate_list(nv,svp);
275 if (! cc.and) //on screen?
276 draw_line(svp[Side_to_verts[side][edge]],svp[Side_to_verts[side][(edge+1)%4]]);
279 int Show_triangulations=0;
281 //edge types - lower number types have precedence
282 #define ET_FACING 0 //this edge on a facing face
283 #define ET_NOTFACING 1 //this edge on a non-facing face
284 #define ET_NOTUSED 2 //no face uses this edge
285 #define ET_NOTEXTANT 3 //would exist if side were triangulated
287 #define ET_EMPTY 255 //this entry in array is empty
289 //colors for those types
290 //int edge_colors[] = {BM_RGB(45/2,45/2,45/2),
291 // BM_RGB(45/3,45/3,45/3), //BM_RGB(0,0,45), //
292 // BM_RGB(45/4,45/4,45/4)}; //BM_RGB(0,45,0)}; //
294 int edge_colors[] = { 54, 59, 64 };
297 typedef struct seg_edge {
299 struct {short v0,v1;} __pack__ n;
303 ubyte face_count, backface_count;
306 #define MAX_EDGES (MAX_VERTICES*4)
308 seg_edge edge_list[MAX_EDGES];
310 short used_list[MAX_EDGES]; //which entries in edge_list have been used
313 int edge_list_size; //set each frame
315 #define HASH(a,b) ((a*5+b) % edge_list_size)
317 //define edge numberings
332 0*8+5, // right cross
334 1*8+3, // front cross
335 2*8+5, // bottom cross
339 //crosses going the other way
341 1*8+4, // other right cross
342 3*8+4, // other top cross
343 0*8+2, // other front cross
344 1*8+6, // other bottom cross
345 3*8+6, // other left cross
346 5*8+7, // other back cross
349 #define N_NORMAL_EDGES 12 //the normal edges of a box
350 #define N_EXTRA_EDGES 12 //ones created by triangulation
351 #define N_EDGES_PER_SEGMENT (N_NORMAL_EDGES+N_EXTRA_EDGES)
353 #define swap(a,b) do {int t; t=(a); (a)=(b); (b)=t;} while (0)
355 //given two vertex numbers on a segment (range 0..7), tell what edge number it is
356 int find_edge_num(int v0,int v1)
360 short *edgep = edges;
362 if (v0 > v1) swap(v0,v1);
366 // for (i=0;i<N_EDGES_PER_SEGMENT;i++)
367 // if (edges[i]==vv) return i;
369 for (i=N_EDGES_PER_SEGMENT; i; i--)
371 return (N_EDGES_PER_SEGMENT-i);
373 Error("couldn't find edge for %d,%d",v0,v1);
379 //finds edge, filling in edge_ptr. if found old edge, returns index, else return -1
380 int find_edge(int v0,int v1,seg_edge **edge_ptr)
388 oldhash = hash = HASH(v0,v1);
394 if (edge_list[hash].type == ET_EMPTY) ret=0;
395 else if (edge_list[hash].v.vv == vv) ret=1;
397 if (++hash==edge_list_size) hash=0;
398 if (hash==oldhash) Error("Edge list full!");
402 *edge_ptr = &edge_list[hash];
411 //adds an edge to the edge list
412 void add_edge(int v0,int v1,ubyte type)
418 //mprintf(0, "Verts = %2i %2i, type = %i ", v0, v1, type);
419 if (v0 > v1) swap(v0,v1);
421 found = find_edge(v0,v1,&e);
427 used_list[n_used] = e-edge_list;
428 if (type == ET_FACING)
429 edge_list[used_list[n_used]].face_count++;
430 else if (type == ET_NOTFACING)
431 edge_list[used_list[n_used]].backface_count++;
432 //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);
437 if (type == ET_FACING)
438 edge_list[found].face_count++;
439 else if (type == ET_NOTFACING)
440 edge_list[found].backface_count++;
441 //mprintf(0, "Facing count = %i, Not facing count = %i\n", edge_list[found].face_count, edge_list[found].backface_count);
445 //adds a segment's edges to the edge list
446 void add_edges(segment *seg)
452 med_get_vertex_list(seg,&nv,&svp); // set nv = number of vertices, svp = pointer to vertex indices
453 cc=rotate_list(nv,svp);
455 if (! cc.and) { //all off screen?
458 ubyte edge_flags[N_EDGES_PER_SEGMENT];
460 for (i=0;i<N_NORMAL_EDGES;i++) edge_flags[i]=ET_NOTUSED;
461 for (;i<N_EDGES_PER_SEGMENT;i++) edge_flags[i]=ET_NOTEXTANT;
463 for (sn=0;sn<MAX_SIDES_PER_SEGMENT;sn++) {
464 side *sidep = &seg->sides[sn];
465 int num_faces, num_vertices;
468 create_all_vertex_lists(&num_faces, vertex_list, seg-Segments, sn);
474 for (fn=0; fn<num_faces; fn++) {
478 //Note: normal check appears to be the wrong way since the normals points in, but we're looking from the outside
479 if (g3_check_normal_facing(&Vertices[seg->verts[vertex_list[fn*3]]],&sidep->normals[fn]))
484 v0 = &vertex_list[fn*3];
486 for (vn=0; vn<num_vertices-1; vn++) {
488 // en = find_edge_num(vertex_list[fn*3 + vn], vertex_list[fn*3 + (vn+1)%num_vertices]);
489 en = find_edge_num(*v0, *(v0+1));
492 if (flag < edge_flags[en]) edge_flags[en] = flag;
496 en = find_edge_num(*v0, vertex_list[fn*3]);
498 if (flag < edge_flags[en]) edge_flags[en] = flag;
502 for (i=0; i<N_EDGES_PER_SEGMENT; i++)
503 if (i<N_NORMAL_EDGES || (edge_flags[i]!=ET_NOTEXTANT && Show_triangulations))
504 add_edge(seg->verts[edges[i]/8],seg->verts[edges[i]&7],edge_flags[i]);
510 // ----------------------------------------------------------------------------
511 void draw_trigger_side(segment *seg,int side)
517 med_get_vertex_list(seg,&nv,&svp); // set nv = number of vertices, svp = pointer to vertex indices
518 cc=rotate_list(nv,svp);
520 if (! cc.and) { //all off screen?
522 draw_line(svp[Side_to_verts[side][0]],svp[Side_to_verts[side][2]]);
523 //g3_draw_line(svp[Side_to_verts[side][1]],svp[Side_to_verts[side][3]]);
527 // ----------------------------------------------------------------------------
528 void draw_wall_side(segment *seg,int side)
534 med_get_vertex_list(seg,&nv,&svp); // set nv = number of vertices, svp = pointer to vertex indices
535 cc=rotate_list(nv,svp);
537 if (! cc.and) { //all off screen?
539 draw_line(svp[Side_to_verts[side][0]],svp[Side_to_verts[side][2]]);
540 draw_line(svp[Side_to_verts[side][1]],svp[Side_to_verts[side][3]]);
545 #define WALL_BLASTABLE_COLOR BM_XRGB( 31/2 , 0/2 , 0/2) // RED
546 #define WALL_DOOR_COLOR BM_XRGB( 0/2 , 0/2 , 31/2) // DARK BLUE
547 #define WALL_DOOR_LOCKED_COLOR BM_XRGB( 0/2 , 0/2 , 63/2) // BLUE
548 #define WALL_AUTO_DOOR_COLOR BM_XRGB( 0/2 , 31/2 , 0/2) // DARK GREEN
549 #define WALL_AUTO_DOOR_LOCKED_COLOR BM_XRGB( 0/2 , 63/2 , 0/2) // GREEN
550 #define WALL_ILLUSION_COLOR BM_XRGB( 63/2 , 0/2 , 63/2) // PURPLE
552 #define TRIGGER_COLOR BM_XRGB( 63/2 , 63/2 , 0/2) // YELLOW
553 #define TRIGGER_DAMAGE_COLOR BM_XRGB( 63/2 , 63/2 , 0/2) // YELLOW
555 // ----------------------------------------------------------------------------------------------------------------
556 // Draws special walls (for now these are just removable walls.)
557 void draw_special_wall( segment *seg, int side )
559 gr_setcolor(PLAINSEG_COLOR);
561 if (Walls[seg->sides[side].wall_num].type == WALL_BLASTABLE)
562 gr_setcolor(WALL_BLASTABLE_COLOR);
563 if (Walls[seg->sides[side].wall_num].type == WALL_DOOR)
564 gr_setcolor(WALL_DOOR_COLOR);
565 if (Walls[seg->sides[side].wall_num].type == WALL_ILLUSION)
566 gr_setcolor(GROUPSIDE_COLOR);
567 if (Walls[seg->sides[side].wall_num].flags & WALL_DOOR_LOCKED)
568 gr_setcolor(WALL_DOOR_LOCKED_COLOR);
569 if (Walls[seg->sides[side].wall_num].flags & WALL_DOOR_AUTO)
570 gr_setcolor(WALL_AUTO_DOOR_COLOR);
571 if (Walls[seg->sides[side].wall_num].flags & WALL_DOOR_LOCKED)
572 if (Walls[seg->sides[side].wall_num].flags & WALL_DOOR_AUTO)
573 gr_setcolor(WALL_AUTO_DOOR_LOCKED_COLOR);
574 if (Walls[seg->sides[side].wall_num].type == WALL_OPEN)
575 gr_setcolor(PLAINSEG_COLOR);
577 draw_wall_side(seg,side);
579 if (Walls[seg->sides[side].wall_num].trigger != -1) {
582 trigger_num = Walls[seg->sides[side].wall_num].trigger;
584 gr_setcolor(TRIGGER_COLOR);
585 draw_trigger_side(seg,side);
589 gr_setcolor(PLAINSEG_COLOR);
593 // ----------------------------------------------------------------------------------------------------------------
594 // Recursively parse mine structure, drawing segments.
595 void draw_mine_sub(int segnum,int depth)
599 if (Been_visited[segnum]) return; // If segment already drawn, return.
601 Been_visited[segnum] = 1; // Say that this segment has been drawn.
603 mine_ptr = &Segments[segnum];
605 // If this segment is active, process it, else skip it.
607 if (mine_ptr->segnum != -1) {
610 if (Search_mode) check_segment(mine_ptr);
611 else add_edges(mine_ptr); //add this segments edges to list
614 for (side=0; side<MAX_SIDES_PER_SEGMENT; side++) {
615 if (IS_CHILD(mine_ptr->children[side])) {
616 if (mine_ptr->sides[side].wall_num != -1)
617 draw_special_wall(mine_ptr, side);
618 draw_mine_sub(mine_ptr->children[side],depth-1);
625 void draw_mine_edges(int automap_flag)
630 for (type=ET_NOTUSED;type>=ET_FACING;type--) {
631 gr_setcolor(edge_colors[type]);
632 for (i=0;i<n_used;i++) {
633 e = &edge_list[used_list[i]];
635 if ((!automap_flag) || (e->face_count == 1))
636 draw_line(e->v.n.v0,e->v.n.v1);
641 //draws an entire mine
642 void draw_mine(segment *mine_ptr,int depth)
646 // clear visited list
647 for (i=0; i<=Highest_segment_index; i++)
650 edge_list_size = min(Num_vertices*4,MAX_EDGES); //make maybe smaller than max
653 for (i=0; i<edge_list_size; i++) {
654 edge_list[i].type = ET_EMPTY;
655 edge_list[i].face_count = 0;
656 edge_list[i].backface_count = 0;
661 draw_mine_sub(SEG_PTR_2_NUM(mine_ptr),depth);
667 // -----------------------------------------------------------------------------
668 // Draw all segments, ignoring connectivity.
669 // A segment is drawn if its segnum != -1.
670 void draw_mine_all(segment *sp, int automap_flag)
675 // clear visited list
676 for (i=0; i<=Highest_segment_index; i++)
679 edge_list_size = min(Num_vertices*4,MAX_EDGES); //make maybe smaller than max
682 for (i=0; i<edge_list_size; i++) {
683 edge_list[i].type = ET_EMPTY;
684 edge_list[i].face_count = 0;
685 edge_list[i].backface_count = 0;
690 for (s=0; s<=Highest_segment_index; s++)
691 if (sp[s].segnum != -1) {
692 for (i=0; i<MAX_SIDES_PER_SEGMENT; i++)
693 if (sp[s].sides[i].wall_num != -1)
694 draw_special_wall(&sp[s], i);
696 check_segment(&sp[s]);
699 draw_seg_objects(&sp[s]);
703 draw_mine_edges(automap_flag);
707 void draw_selected_segments(void)
711 gr_setcolor(SELECT_COLOR);
712 for (s=0; s<N_selected_segs; s++)
713 if (Segments[Selected_segs[s]].segnum != -1)
714 draw_segment(&Segments[Selected_segs[s]]);
717 void draw_found_segments(void)
721 gr_setcolor(FOUND_COLOR);
722 for (s=0; s<N_found_segs; s++)
723 if (Segments[Found_segs[s]].segnum != -1)
724 draw_segment(&Segments[Found_segs[s]]);
727 void draw_warning_segments(void)
731 gr_setcolor(WARNING_COLOR);
732 for (s=0; s<N_warning_segs; s++)
733 if (Segments[Warning_segs[s]].segnum != -1)
734 draw_segment(&Segments[Warning_segs[s]]);
737 void draw_group_segments(void)
741 if (current_group > -1) {
742 gr_setcolor(GROUP_COLOR);
743 for (s=0; s<GroupList[current_group].num_segments; s++)
744 if (Segments[GroupList[current_group].segments[s]].segnum != -1)
745 draw_segment(&Segments[GroupList[current_group].segments[s]]);
750 void draw_special_segments(void)
755 // Highlight matcens, fuelcens, etc.
756 for (seg=0;seg<=Highest_segment_index;seg++)
757 if (Segments[seg].segnum != -1)
758 switch( Segments[seg].special ) {
759 case SEGMENT_IS_FUELCEN:
760 color = BM_XRGB( 29, 27, 13 );
762 draw_segment(&Segments[seg]);
764 case SEGMENT_IS_CONTROLCEN:
765 color = BM_XRGB( 29, 0, 0 );
767 draw_segment(&Segments[seg]);
769 case SEGMENT_IS_ROBOTMAKER:
770 color = BM_XRGB( 29, 0, 31 );
772 draw_segment(&Segments[seg]);
778 //find a free vertex. returns the vertex number
783 Assert(Num_vertices < MAX_SEGMENT_VERTICES);
785 for (vn=0; (vn < Num_vertices) && Vertex_active[vn]; vn++) ;
787 Vertex_active[vn] = 1;
795 void free_vert(int vert_num)
797 Vertex_active[vert_num] = 0;
801 // -----------------------------------------------------------------------------
802 void draw_coordinate_axes(void)
805 short Axes_verts[16];
806 vms_vector tvec,xvec,yvec,zvec;
809 Axes_verts[i] = alloc_vert();
811 create_coordinate_axes_from_segment(Cursegp,Axes_verts);
813 vm_vec_sub(&xvec,&Vertices[Axes_verts[1]],&Vertices[Axes_verts[0]]);
814 vm_vec_sub(&yvec,&Vertices[Axes_verts[2]],&Vertices[Axes_verts[0]]);
815 vm_vec_sub(&zvec,&Vertices[Axes_verts[3]],&Vertices[Axes_verts[0]]);
817 // Create the letter X
819 vm_vec_add(&Vertices[Axes_verts[4]],&Vertices[Axes_verts[1]],vm_vec_scale(&tvec,F1_0/16));
821 vm_vec_add2(&Vertices[Axes_verts[4]],vm_vec_scale(&tvec,F1_0/8));
822 vm_vec_sub(&Vertices[Axes_verts[6]],&Vertices[Axes_verts[4]],vm_vec_scale(&tvec,F2_0));
823 tvec = xvec; vm_vec_scale(&tvec,F1_0/8);
824 vm_vec_add(&Vertices[Axes_verts[7]],&Vertices[Axes_verts[4]],&tvec);
825 vm_vec_add(&Vertices[Axes_verts[5]],&Vertices[Axes_verts[6]],&tvec);
827 // Create the letter Y
829 vm_vec_add(&Vertices[Axes_verts[11]],&Vertices[Axes_verts[2]],vm_vec_scale(&tvec,F1_0/16));
830 vm_vec_add(&Vertices[Axes_verts[8]],&Vertices[Axes_verts[11]],&tvec);
831 vm_vec_add(&Vertices[Axes_verts[9]],&Vertices[Axes_verts[11]],vm_vec_scale(&tvec,F1_0*2));
832 vm_vec_add(&Vertices[Axes_verts[10]],&Vertices[Axes_verts[11]],&tvec);
833 tvec = xvec; vm_vec_scale(&tvec,F1_0/16);
834 vm_vec_sub2(&Vertices[Axes_verts[9]],&tvec);
835 vm_vec_add2(&Vertices[Axes_verts[10]],&tvec);
837 // Create the letter Z
839 vm_vec_add(&Vertices[Axes_verts[12]],&Vertices[Axes_verts[3]],vm_vec_scale(&tvec,F1_0/16));
841 vm_vec_add2(&Vertices[Axes_verts[12]],vm_vec_scale(&tvec,F1_0/8));
842 vm_vec_sub(&Vertices[Axes_verts[14]],&Vertices[Axes_verts[12]],vm_vec_scale(&tvec,F2_0));
843 tvec = zvec; vm_vec_scale(&tvec,F1_0/8);
844 vm_vec_add(&Vertices[Axes_verts[13]],&Vertices[Axes_verts[12]],&tvec);
845 vm_vec_add(&Vertices[Axes_verts[15]],&Vertices[Axes_verts[14]],&tvec);
847 rotate_list(16,Axes_verts);
849 gr_setcolor(AXIS_COLOR);
851 draw_line(Axes_verts[0],Axes_verts[1]);
852 draw_line(Axes_verts[0],Axes_verts[2]);
853 draw_line(Axes_verts[0],Axes_verts[3]);
856 draw_line(Axes_verts[4],Axes_verts[5]);
857 draw_line(Axes_verts[6],Axes_verts[7]);
860 draw_line(Axes_verts[8],Axes_verts[9]);
861 draw_line(Axes_verts[8],Axes_verts[10]);
862 draw_line(Axes_verts[8],Axes_verts[11]);
865 draw_line(Axes_verts[12],Axes_verts[13]);
866 draw_line(Axes_verts[13],Axes_verts[14]);
867 draw_line(Axes_verts[14],Axes_verts[15]);
870 free_vert(Axes_verts[i]);
873 void draw_world(grs_canvas *screen_canvas,editor_view *v,segment *mine_ptr,int depth)
875 vms_vector viewer_position;
878 grs_canvas temp_canvas;
882 // if ( screen_canvas == LargeViewBox->canvas ) {
883 // CurrentBigCanvas ^= 1;
885 // gr_set_current_canvas( BigCanvas[CurrentBigCanvas] );
888 gr_init_sub_canvas(&temp_canvas,canv_offscreen,0,0,
889 screen_canvas->cv_bitmap.bm_w,screen_canvas->cv_bitmap.bm_h);
891 gr_set_current_canvas(&temp_canvas);
894 gr_set_current_canvas(screen_canvas);
901 //g3_set_points(Segment_points,Vertices);
903 viewer_position = v->ev_matrix.fvec;
904 vm_vec_scale(&viewer_position,-v->ev_dist);
906 vm_vec_add2(&viewer_position,&Ed_view_target);
910 g3_set_view_matrix(&viewer_position,&v->ev_matrix,v->ev_zoom);
912 render_start_frame();
914 gr_setcolor(PLAINSEG_COLOR);
916 // Draw all segments or only connected segments.
917 // We might want to draw all segments if we have broken the mine into pieces.
918 if (Draw_all_segments)
919 draw_mine_all(Segments, Automap_test);
921 draw_mine(mine_ptr,depth);
923 // Draw the found segments
925 draw_warning_segments();
926 draw_group_segments();
927 draw_found_segments();
928 draw_selected_segments();
929 draw_special_segments();
931 // Highlight group segment and side.
932 if (current_group > -1)
933 if (Groupsegp[current_group]) {
934 gr_setcolor(GROUPSEG_COLOR);
935 draw_segment(Groupsegp[current_group]);
937 gr_setcolor(GROUPSIDE_COLOR);
938 draw_seg_side(Groupsegp[current_group],Groupside[current_group]);
941 // Highlight marked segment and side.
943 gr_setcolor(MARKEDSEG_COLOR);
944 draw_segment(Markedsegp);
946 gr_setcolor(MARKEDSIDE_COLOR);
947 draw_seg_side(Markedsegp,Markedside);
950 // Highlight current segment and current side.
951 gr_setcolor(CURSEG_COLOR);
952 draw_segment(Cursegp);
954 gr_setcolor(CURSIDE_COLOR);
955 draw_seg_side(Cursegp,Curside);
957 gr_setcolor(CUREDGE_COLOR);
958 draw_side_edge(Cursegp,Curside,Curedge);
960 // Draw coordinate axes if we are rendering the large view.
962 if (screen_canvas == LargeViewBox->canvas)
963 draw_coordinate_axes();
966 gr_set_fontcolor((v==current_view)?CRED:CWHITE, -1 );
967 if ( screen_canvas == LargeViewBox->canvas ) {
968 gr_ustring( 5, 5, "USER VIEW" );
969 switch (Large_view_index) {
970 case 0: gr_ustring( 85, 5, "-- TOP"); break;
971 case 1: gr_ustring( 85, 5, "-- FRONT"); break;
972 case 2: gr_ustring( 85, 5, "-- RIGHT"); break;
976 else if ( screen_canvas == TopViewBox->canvas )
977 gr_ustring( 5, 5, "TOP" );
978 else if ( screen_canvas == FrontViewBox->canvas )
979 gr_ustring( 5, 5, "FRONT" );
980 else if ( screen_canvas == RightViewBox->canvas )
981 gr_ustring( 5, 5, "RIGHT" );
983 Error("Ortho views have been removed, what gives?\n");
991 // if ( screen_canvas == LargeViewBox->canvas ) {
992 // if (BigCanvasFirstTime) {
993 // BigCanvasFirstTime = 0;
994 // gr_set_current_canvas( screen_canvas );
995 // gr_ubitmap( 0, 0, &BigCanvas[CurrentBigCanvas]->cv_bitmap );
997 // gr_vesa_update( &BigCanvas[CurrentBigCanvas]->cv_bitmap, &screen_canvas->cv_bitmap, &BigCanvas[CurrentBigCanvas ^ 1]->cv_bitmap );
1000 gr_set_current_canvas( screen_canvas );
1001 gr_ubitmap( 0, 0, &temp_canvas.cv_bitmap );
1010 //find the segments that render at a given screen x,y
1011 //parms other than x,y are like draw_world
1012 //fills in globals N_found_segs & Found_segs
1013 void find_segments(short x,short y,grs_canvas *screen_canvas,editor_view *v,segment *mine_ptr,int depth)
1015 vms_vector viewer_position;
1018 grs_canvas temp_canvas;
1020 gr_init_sub_canvas(&temp_canvas,canv_offscreen,0,0,
1021 screen_canvas->cv_bitmap.bm_w,screen_canvas->cv_bitmap.bm_h);
1023 gr_set_current_canvas(&temp_canvas);
1025 gr_set_current_canvas(screen_canvas);
1030 //g3_set_points(Segment_points,Vertices);
1032 viewer_position = v->ev_matrix.fvec;
1033 vm_vec_scale(&viewer_position,-v->ev_dist);
1035 vm_vec_add(&viewer_position,&viewer_position,&Ed_view_target);
1038 g3_set_view_matrix(&viewer_position,&v->ev_matrix,v->ev_zoom);
1040 render_start_frame();
1048 Search_x = x; Search_y = y;
1050 if (Draw_all_segments)
1051 draw_mine_all(Segments, 0);
1053 draw_mine(mine_ptr,depth);
1061 void meddraw_init_views( grs_canvas * canvas)
1063 Views[0]->ev_canv = canvas;
1065 Views[1]->ev_canv = TopViewBox->canvas;
1066 Views[2]->ev_canv = FrontViewBox->canvas;
1067 Views[3]->ev_canv = RightViewBox->canvas;