2 @Copyright Looking Glass Studios, Inc.
3 1996,1997,1998,1999,2000 Unpublished Work.
6 // $Header: r:/t2repos/thief2/src/editor/hilight.c,v 1.17 2000/03/24 14:33:19 adurant Exp $
7 // brush highlighting system
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
;
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
;
51 BOOL
hilightAddByObjId(int obj_id
)
54 us
=editObjGetBrushFromObj(obj_id
);
56 hilightAddByBrushId(us
->br_id
);
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
;
75 BOOL
hilightRemoveByObjid(int obj_id
)
78 us
=editObjGetBrushFromObj(obj_id
);
80 return hilightRemoveByBrushId(us
->br_id
);
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
)
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
);
113 void hilight_end(ulong flags
)
115 if (flags
& kHilightDone
)
117 hilight_active
|=hilight_cur
;
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
);
134 static BOOL
hilight_simple_run(BOOL (*br_check
)(editBrush
*br
))
141 if (!brFilter(br_check
,hilightAddByBrush
))
143 Status("No matching brushes");
149 _hilight_cur_check
=br_check
;
151 brushRunOnActive(hilight_active_check
);
152 rv
=_hilight_cur_cnt
>0;
154 hilight_end((rv
)? kHilightDone
: kHilightCancel
);
159 BOOL
highlight_check(editBrush
*br
)
161 return isActiveHighlight(br
->br_id
);
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
));
176 static BOOL
property_check_direct(editBrush
*br
)
178 if (brushGetType(br
)==brType_OBJECT
)
179 return IProperty_IsSimplyRelevant(pTestProp
,brObj_ID(br
));
183 static void hilight_obj_with_property(char *str
)
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");
197 hilight_simple_run(property_check
);
198 SafeRelease(pTestProp
);
201 static void hilight_obj_with_property_direct(char *str
)
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");
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
);
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
;
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));
246 static void hilight_nonaxial_terrain(void)
248 hilight_simple_run(nonaxial_check
);
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
;
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)
276 else if (br
->txs
[i
].tx_id
==terr_texture_target
)
278 return (use_default
&& (br
->tx_id
==terr_texture_target
));
283 static void hilight_texture_id(int texture_id
)
285 terr_texture_target
=texture_id
;
286 hilight_simple_run(terr_texture_check
);
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
;
300 tmp
=br
->pos
.el
[i
]; need_snap
|=_gedit_float_snap(&tmp
);
301 tmp
=br
->sz
.el
[i
]; need_snap
|=_gedit_float_snap(&tmp
);
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
);
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
);
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();
347 static IProperty
* pCreateProp
;
349 static BOOL
propertize(editBrush
* br
)
351 if (brushGetType(br
)==brType_OBJECT
)
353 IProperty_Create(pCreateProp
,brObj_ID(br
));
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
));
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)
395 Status("Poorly formed use bits");
398 static void hilight_clear(int which
)
403 hilightClearBits(which
);
407 static void hilight_activate(int which
)
409 hilight_active
|=which
;
413 static void hilight_deactivate(int which
)
415 hilight_active
&=~which
;
419 static void hilight_brush(int which
)
421 BOOL full_redraw
=FALSE
;
424 editBrush
*us
=vBrush_GetSel();
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
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 //////////////////////////
447 static BOOL
_list_br(editBrush
* br
)
449 mprintf("Brush %d time %d\n",br
->br_id
,br
->timestamp
);
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
);
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)
500 COMMANDS(hilight_keys
, HK_BRUSH_EDIT
);