convert line ends
[canaan.git] / prj / cam / src / editor / hilight.c
bloba9d4a9154266fd6ebe7c4bd3f4001ac2842da673
1 /*
2 @Copyright Looking Glass Studios, Inc.
3 1996,1997,1998,1999,2000 Unpublished Work.
4 */
6 // $Header: r:/t2repos/thief2/src/editor/hilight.c,v 1.17 2000/03/24 14:33:19 adurant Exp $
7 // brush highlighting system
9 #include <string.h>
11 #include <command.h>
12 #include <status.h>
14 #include <property.h>
16 #include <csgbrush.h>
17 #include <hilight.h>
18 #include <editbr_.h>
19 #include <brinfo.h>
20 #include <brquery.h>
21 #include <brrend.h>
22 #include <gedit.h>
23 #include <vbrush.h>
24 #include <objpos.h>
25 #include <editobj.h>
27 #include <mprintf.h>
28 #include <memall.h>
29 #include <dbmem.h> // must be last header!
31 #define HILIGHT_NUM_BITS 8
33 // global highlight controls
34 uchar hilight_array[MAX_CSG_BRUSHES];
35 uchar hilight_active=0; // which hilights im actually showing
37 // are we hilighting everything, or just rendered brushes
38 static BOOL hilight_global=TRUE;
40 //////////////////
41 // common core add/remove of various types
42 static uchar hilight_cur=1; // what hilight im currently adding
43 static bool hilight_autoclear=TRUE; // do i reclear every time i add
45 BOOL hilightAddByBrushId(int brush_id)
47 hilight_array[brush_id]|=hilight_cur;
48 return TRUE;
51 BOOL hilightAddByObjId(int obj_id)
53 editBrush *us;
54 us=editObjGetBrushFromObj(obj_id);
55 if (us)
56 hilightAddByBrushId(us->br_id);
57 return TRUE;
60 BOOL hilightAddByBrush(editBrush *br)
62 return hilightAddByBrushId(br->br_id);
65 BOOL hilightRemoveByBrushId(int brush_id)
67 if (hilight_array[brush_id]&hilight_cur)
69 hilight_array[brush_id]&=~hilight_cur;
70 return TRUE;
72 return FALSE;
75 BOOL hilightRemoveByObjid(int obj_id)
77 editBrush *us;
78 us=editObjGetBrushFromObj(obj_id);
79 if (us)
80 return hilightRemoveByBrushId(us->br_id);
81 return FALSE;
84 BOOL hilightRemoveByBrush(editBrush *br)
86 return hilightRemoveByBrushId(br->br_id);
89 static void hilight_clear_all(void)
91 memset(hilight_array,0,MAX_CSG_BRUSHES);
94 void hilightClearBits(int bitmask)
96 int i;
97 for (i=0; i<MAX_CSG_BRUSHES; i++)
98 hilight_array[i]&=~bitmask;
101 //////////////////////////
102 // common setup/operation code for highlights
104 void hilight_begin(void)
106 if ((hilight_cur&hilight_active)&&(hilight_autoclear))
108 hilightClearBits(hilight_cur);
109 hilight_active=0;
113 void hilight_end(ulong flags)
115 if (flags & kHilightDone)
117 hilight_active|=hilight_cur;
118 gedit_full_redraw();
122 static BOOL (*_hilight_cur_check)(editBrush *br)=NULL;
123 static int _hilight_cur_cnt=0;
124 void hilight_active_check(editBrush *br)
126 if (_hilight_cur_check)
127 if ((*_hilight_cur_check)(br))
129 hilightAddByBrush(br);
130 _hilight_cur_cnt++;
134 static BOOL hilight_simple_run(BOOL (*br_check)(editBrush *br))
136 BOOL rv=TRUE;
138 hilight_begin();
139 if (hilight_global)
141 if (!brFilter(br_check,hilightAddByBrush))
143 Status("No matching brushes");
144 rv=FALSE;
147 else
149 _hilight_cur_check=br_check;
150 _hilight_cur_cnt=0;
151 brushRunOnActive(hilight_active_check);
152 rv=_hilight_cur_cnt>0;
154 hilight_end((rv)? kHilightDone : kHilightCancel);
156 return rv;
159 BOOL highlight_check(editBrush *br)
161 return isActiveHighlight(br->br_id);
164 ////////////////
165 // obj highlighting - wants to scan through all objects, checking for this property
167 static IProperty *pTestProp;
169 static BOOL property_check(editBrush *br)
171 if (brushGetType(br)==brType_OBJECT)
172 return IProperty_IsRelevant(pTestProp,brObj_ID(br));
173 return FALSE;
176 static BOOL property_check_direct(editBrush *br)
178 if (brushGetType(br)==brType_OBJECT)
179 return IProperty_IsSimplyRelevant(pTestProp,brObj_ID(br));
180 return FALSE;
183 static void hilight_obj_with_property(char *str)
185 BOOL haveProp;
186 if ((str==NULL)||(str[0]=='\0'))
188 Status("Prop menu not yet supported here");
189 return; // want to bring up dialog with which to choose a property
191 haveProp = GetPropertyInterfaceNamed(str,IProperty,&pTestProp);
192 if (!haveProp||(pTestProp==NULL))
194 Status("Dont know about that property");
195 return;
197 hilight_simple_run(property_check);
198 SafeRelease(pTestProp);
201 static void hilight_obj_with_property_direct(char *str)
203 BOOL haveProp;
204 if ((str==NULL)||(str[0]=='\0'))
206 Status("Prop menu not yet supported here");
207 return; // want to bring up dialog with which to choose a property
209 haveProp = GetPropertyInterfaceNamed(str,IProperty,&pTestProp);
210 if (!haveProp||(pTestProp==NULL))
212 Status("Dont know about that property");
213 return;
215 hilight_simple_run(property_check_direct);
216 SafeRelease(pTestProp);
219 // needs to do wacky stuff, basically
220 static void hilight_split_obj(void)
222 extern BOOL hilight_split_objs; // in eosapp, really
223 if ((hilight_cur&hilight_active)&&(hilight_autoclear))
225 hilightClearBits(hilight_cur);
226 hilight_active=0;
228 hilight_split_objs=TRUE;
229 ObjDeleteAllRefs(); // this will cause it to call out
230 ObjBuildAllRefs(); // since split_objs is true..
231 hilight_split_objs=FALSE;
232 hilight_active|=hilight_cur;
233 gedit_full_redraw();
236 ////////////////
237 // terrain highlighting
238 // find nonaxial stuff
239 static BOOL nonaxial_check(editBrush *br)
241 if (brushGetType(br)==brType_TERRAIN)
242 return ((br->ang.el[0]&0x3fff)||(br->ang.el[1]&0x3fff)||(br->ang.el[2]&0x3fff));
243 return FALSE;
246 static void hilight_nonaxial_terrain(void)
248 hilight_simple_run(nonaxial_check);
251 // find given media
252 static int terr_media_target=0;
253 static BOOL terr_media_check(editBrush *br)
255 if (brushGetType(br)==brType_TERRAIN)
256 return br->media==terr_media_target;
257 return FALSE;
260 static void hilight_media_type(int media_id)
262 terr_media_target=media_id;
263 hilight_simple_run(terr_media_check);
266 // check for terrain texture id
267 static int terr_texture_target=0;
268 static BOOL terr_texture_check(editBrush *br)
270 if (brushGetType(br)==brType_TERRAIN)
272 int i, use_default=0;
273 for (i=0; i<br->num_faces; i++)
274 if (br->txs[i].tx_id==-1)
275 use_default++;
276 else if (br->txs[i].tx_id==terr_texture_target)
277 return TRUE;
278 return (use_default && (br->tx_id==terr_texture_target));
280 return FALSE;
283 static void hilight_texture_id(int texture_id)
285 terr_texture_target=texture_id;
286 hilight_simple_run(terr_texture_check);
289 // for snap checking
290 static BOOL any_snap_check(editBrush *br)
292 if (brushGetType(br)==brType_TERRAIN)
293 if (!br->grid.grid_enabled)
295 BOOL need_snap=FALSE;
296 float tmp;
297 int i;
298 for (i=0; i<3; i++)
300 tmp=br->pos.el[i]; need_snap|=_gedit_float_snap(&tmp);
301 tmp=br->sz.el[i]; need_snap|=_gedit_float_snap(&tmp);
303 return need_snap;
305 return FALSE;
308 static BOOL ortho_snap_check(editBrush *br)
310 if (brushGetType(br)==brType_TERRAIN)
311 if (!nonaxial_check(br))
312 return any_snap_check(br);
313 return FALSE;
316 static void hilight_check_snap(int cntrl)
318 hilight_simple_run(cntrl?any_snap_check:ortho_snap_check);
321 static BOOL do_snap_op(editBrush *us)
323 return gedit_snap_brush(us);
326 static void hilight_do_snap(void)
328 brFilter(highlight_check,do_snap_op);
329 gedit_full_redraw();
332 ////////////////
333 // multibrush interface
335 static BOOL add_to_mbrush(editBrush *br)
337 return vBrush_editBrush_Op(br,vBrush_OP_ADD);
340 static void multibrush_the_highlight(void)
342 brFilter(highlight_check,add_to_mbrush);
343 vBrush_getToCurGroup();
344 gedit_full_redraw();
347 static IProperty* pCreateProp;
349 static BOOL propertize(editBrush* br)
351 if (brushGetType(br)==brType_OBJECT)
353 IProperty_Create(pCreateProp,brObj_ID(br));
354 return TRUE;
356 return FALSE;
359 static void propertize_the_highlight(char* propname)
361 pCreateProp = GetPropertyNamed(propname);
362 brFilter(highlight_check,propertize);
363 SafeRelease(pCreateProp);
366 static BOOL unpropertize(editBrush* br)
368 if (brushGetType(br)==brType_OBJECT)
370 IProperty_Delete(pCreateProp,brObj_ID(br));
371 return TRUE;
373 return FALSE;
376 static void unpropertize_the_highlight(char* propname)
378 pCreateProp = GetPropertyNamed(propname);
379 brFilter(highlight_check,unpropertize);
380 SafeRelease(pCreateProp);
383 //////////////////////////
384 // dumb really basic UI
385 static void hilight_use(int use)
387 int i, bitval, hits=0;
389 for (i=0, bitval=1; i<HILIGHT_NUM_BITS; i++, bitval<<=1)
390 if (bitval&use)
391 hits++;
392 if (hits==1)
393 hilight_cur=use;
394 else
395 Status("Poorly formed use bits");
398 static void hilight_clear(int which)
400 if (which==0)
401 hilight_clear_all();
402 else
403 hilightClearBits(which);
404 gedit_full_redraw();
407 static void hilight_activate(int which)
409 hilight_active|=which;
410 gedit_full_redraw();
413 static void hilight_deactivate(int which)
415 hilight_active&=~which;
416 gedit_full_redraw();
419 static void hilight_brush(int which)
421 BOOL full_redraw=FALSE;
422 if (which==0)
424 editBrush *us=vBrush_GetSel();
425 which=us->br_id;
426 // perhaps should check if vbrush
427 // if so, do fancy stuff (tm)
428 full_redraw=TRUE; // for now, since hilight doesnt seem to work right with incremental update
430 else
431 full_redraw=TRUE;
432 hilightAddByBrushId(which);
433 hilight_active|=hilight_cur;
434 if (full_redraw) gedit_full_redraw();
437 static void reinstantiate_and_highlight(char *str)
439 hilight_obj_with_property(str);
440 unpropertize_the_highlight(str);
441 propertize_the_highlight(str);
444 //////////////////////////
445 // misc ui stuff
447 static BOOL _list_br(editBrush* br)
449 mprintf("Brush %d time %d\n",br->br_id,br->timestamp);
450 return TRUE;
453 static BOOL _list_obj(editBrush* br)
455 if (brushGetType(br)==brType_OBJECT)
457 mprintf("Obj %d brush %d\n",brObj_ID(br),br->br_id);
458 return TRUE;
460 return FALSE;
463 static void hilight_list(BOOL all_br)
465 brFilter(highlight_check,all_br?_list_br:_list_obj);
468 //////////////////////////
469 // actual key commands for highlight system
470 Command hilight_keys[] =
472 { "hilight_by_prop", FUNC_STRING, hilight_obj_with_property, "give property name, highlights obj's with it" },
473 { "hilight_by_prop_direct", FUNC_STRING, hilight_obj_with_property_direct, "give property name, highlights obj's with it specifically on them (not inherited)" },
474 { "hilight_nonaxial", FUNC_VOID, hilight_nonaxial_terrain, "highlights any terrain with non-90 angles" },
475 { "hilight_media", FUNC_INT, hilight_media_type, "highlight terrain w/media_op of type <arg>" },
476 { "hilight_texture", FUNC_INT, hilight_texture_id, "highlight terrain w/texture id <arg>" },
477 { "hilight_split_obj", FUNC_VOID, hilight_split_obj, "highlight objects crossing a portal" },
478 { "multibrush_the_highlight", FUNC_VOID, multibrush_the_highlight, "make hilight objs the multibrush" },
479 { "hilight_brush", FUNC_INT, hilight_brush, "hilight current (0) or brush_id" },
480 { "hilight_check_snap", FUNC_INT, hilight_check_snap, "hilight unangled unsnapped brushes, or if (1) all unsnapped brushes" },
481 { "hilight_do_snap", FUNC_INT, hilight_do_snap, "grid snap all hilight brushes..." },
482 { "hilight_list", FUNC_BOOL, hilight_list, "list objs, or, if arg 1, all brush ids" },
483 { "hilight_global", TOGGLE_BOOL, &hilight_global, "if true, we will hilight everything, else just active" },
485 { "hilight_autoclear", TOGGLE_BOOL, &hilight_autoclear, "do we autoclear old hilight and make it only active" },
486 { "hilight_use", FUNC_INT, hilight_use, "set which hilight bit to use (bitfield, must be just 1)" },
487 { "hilight_clear", FUNC_INT, hilight_clear, "clear current highlights (all if 0, else bitfields)" },
488 { "hilight_activate", FUNC_INT, hilight_activate, "turn on hilight bits" },
489 { "hilight_deactivate", FUNC_INT, hilight_deactivate, "turn off hilight bits" },
490 { "hilight_add_prop", FUNC_STRING, propertize_the_highlight, "Add a named property to all hilit objects"},
491 { "hilight_rem_prop", FUNC_STRING, unpropertize_the_highlight, "Add a named property to all hilit objects"},
493 { "hilight_render", TOGGLE_BOOL, &renderHilightOnly },
494 { "hilight_reinstantiate", FUNC_STRING, reinstantiate_and_highlight, "Hilight all objects with property, then remove and readd property"},
495 }; // all take bitfields since while ugly it is consistent
497 void hilightCommandRegister(void)
499 hilight_clear_all();
500 COMMANDS(hilight_keys, HK_BRUSH_EDIT);