convert line ends
[canaan.git] / prj / cam / src / editor / editgeom.c
blob4108bea1948c73d9d9b42a82f54aff2679b70da7
1 /*
2 @Copyright Looking Glass Studios, Inc.
3 1996,1997,1998,1999,2000 Unpublished Work.
4 */
6 // $Header: r:/t2repos/thief2/src/editor/editgeom.c,v 1.130 2000/02/19 13:10:33 toml Exp $
8 // test code for geometry editor
9 // parses camera control keys, calls outer 3d stuff
10 // calls to gedit for most real stuff, i think
12 #include <stdlib.h>
13 #include <string.h>
14 #include <math.h>
16 #include <lg.h>
17 #include <mprintf.h>
18 #include <res.h>
19 #include <2dres.h>
20 #include <r3d.h>
21 #include <event.h>
22 #include <kb.h>
23 #include <kbcook.h>
24 #include <config.h>
25 #include <g2pt.h>
27 #include <portal.h>
28 #include <pt.h>
30 #include <command.h>
31 #include <status.h>
33 #include <editbr.h>
34 #include <brlist.h>
35 #include <gedit.h>
36 #include <media.h>
38 #include <viewmgr.h>
40 #include <loopapi.h>
41 #include <dispatch.h>
42 #include <dispbase.h>
43 #include <dbasemsg.h>
44 #include <vismsg.h>
45 #include <loopmsg.h>
47 #include <scrnman.h>
48 #include <scrnloop.h>
49 #include <editgeom.h>
50 #include <gamecam.h>
51 #include <palette.h>
52 #include <brloop.h>
53 #include <undoredo.h>
55 #include <editgeo_.h>
56 #include <uiapp.h>
57 #include <objloop.h>
58 #include <mipmap.h>
59 #include <family.h>
60 #include <appsfx.h>
61 #include <plyrloop.h>
62 #include <prof.h>
63 #include <editbr_.h> // for creating initial level
64 #include <ged_room.h>
66 #include <lresname.h>
67 #include <texmem.h>
69 #include <wrloop.h>
71 #include <dbfile.h>
72 #include <dbasemsg.h>
73 #include <render.h>
75 // hacked data file
76 #include <texture.h>
78 extern BOOL g_null_raster;
80 mxs_vector player_pos;
81 static mxs_angvec player_ang;
83 int scale_factor=4;
85 bool single_step=TRUE;
87 bool scene_setup(void)
89 editBrush* tmp;
91 player_pos.el[0]=0; player_pos.el[1]=0; player_pos.el[2]=0;
92 player_ang.tx=player_ang.ty=player_ang.tz=0;
94 tmp=brushInstantiate(DEF_PRIMAL);
95 tmp->sz.el[0]*=4;
96 tmp->sz.el[1]*=4;
97 tmp->sz.el[2]*=4;
98 tmp->tx_id=0;
99 blistInsert(tmp);
100 return TRUE;
103 mxs_vector last_left, last_up, last_forward;
105 void print_info(int vol)
107 char *p;
108 while ((p = portal_scene_info(vol)) != 0)
109 mprintf("%s\n", p);
112 bool spotlight=FALSE;
114 #define SF (scale_factor * 0.125)
116 static float editor_3d_speed_fac = 1.0;
118 void slew(int x)
120 mxs_vector temp;
122 temp.x = 0;
123 temp.y = 0;
124 temp.z = 0;
126 ((mxs_real *) &temp) [ x % 3 ] = 3.0 * 0.0625 * editor_3d_speed_fac * scale_factor * (x >= 3 ? -1 : 1);
127 vm_cur_slew(&temp);
130 void rot(int x)
132 mxs_angvec temp;
134 temp.tx = 0;
135 temp.ty = 0;
136 temp.tz = 0;
138 ((mxs_ang *) &temp) [ x % 3 ] = 3.0 * 0x0100 * editor_3d_speed_fac * scale_factor * (x >= 3 ? -1 : 1);
139 vm_cur_rotate(&temp);
142 void level_cam(void)
144 vm_cur_level (1);
147 void unroll_cam(void)
149 vm_cur_level (0);
152 void rescale(bool up)
154 if (up) {
155 if (scale_factor<1024) { scale_factor*=2; vm_scale_all(2.0); }
156 } else {
157 if (scale_factor>1) { scale_factor/=2; vm_scale_all(0.5); }
162 void decode_scroll(int x)
164 switch(x) {
165 case 7: vm_cur_scroll(-SF, -SF); break;
166 case 8: vm_cur_scroll( 0, -SF); break;
167 case 9: vm_cur_scroll( SF, -SF); break;
168 case 4: vm_cur_scroll(-SF, 0); break;
169 case 5: vm_cur_scroll( 0, 0); break;
170 case 6: vm_cur_scroll( SF, 0); break;
171 case 1: vm_cur_scroll(-SF, SF); break;
172 case 2: vm_cur_scroll( 0, SF); break;
173 case 3: vm_cur_scroll( SF, SF); break;
179 #define MAX_FAILURES 8192
180 Location raycast_dest[MAX_FAILURES], raycast_hit[MAX_FAILURES];
181 Location fail_source;
182 int failure_count, min_show = 0, max_show = MAX_FAILURES;
183 extern bool show_raycasts, show_lightmap, record_movement;
185 void save_failures(Location *hit, Location *dest)
187 if (failure_count < MAX_FAILURES) {
188 raycast_dest[failure_count] = *dest;
189 raycast_hit[failure_count++] = *hit;
193 void render_failures(void)
195 int i;
196 r3s_point source, dest, hit;
198 r3_transform_point(&source, &fail_source.vec);
200 for (i=0; i < failure_count; ++i) {
201 if (i >= min_show && i <= max_show) {
202 r3_transform_point(&hit, &raycast_hit[i].vec);
203 r3_transform_point(&dest, &raycast_dest[i].vec);
204 r3_set_color(1);
205 if (!record_movement) {
206 r3_draw_line(&source, &hit);
207 r3_set_color(4);
209 r3_draw_line(&hit, &dest);
215 #if 0
216 extern void (*failed_light_callback)(Location *hit, Location *dest);
218 extern void portal_add_omni_light_perfect(float x, float y, float z, float br, LightPermanence dynamic);
220 void raycast_light(void)
222 mxs_vector *loc;
223 mxs_angvec *ang;
225 failed_light_callback = save_failures;
226 failure_count = 0;
228 if (vm_spotlight_loc(&loc, &ang)) {
229 MakeLocationFromVector(&fail_source, loc);
230 portal_add_omni_light_perfect(loc->x, loc->y, loc->z, 64, LIGHT_DYNAMIC);
233 failed_light_callback = 0;
235 #endif
237 // stolen from Jaemz
238 void RenDebugShadTab(uchar *shadtab,int numentries)
240 int i;
241 int col,row;
242 int x,y;
243 uchar *tab;
244 int rowsize;
245 int w,h;
247 w=grd_canvas->bm.w/64;
248 h=grd_canvas->bm.h/(4*numentries);
250 rowsize=numentries;
251 tab=shadtab;
253 for (i=0;i<256*rowsize;++i) {
254 col = i%256;
255 row = i/256;
257 x = (col%64)*w;
258 y = (col/64)*(h*rowsize+2) + row*h;
260 if (tab) {
261 gr_set_fcolor(tab[i]);
262 } else {
263 gr_set_fcolor(i);
265 gr_rect(x,y,x+w-1,y+h-1);
269 extern void gedit_busywait(BOOL clear);
270 static void show_shad_tab(void)
272 gr_clear(0);
273 RenDebugShadTab(gr_get_light_tab(),16);
274 gedit_busywait(TRUE);
277 extern float portal_detail_level;
278 extern int max_draw_polys;
280 void PickDistanceFunction(int which); // Declared right below
282 static Command parse_keys[]=
284 // local commands
285 { "cam_rotate", FUNC_INT, rot, "rotate current camera" },
286 { "cam_slew", FUNC_INT, slew, "slew current camera" },
287 { "speed_fac", VAR_FLOAT, &editor_3d_speed_fac, "set speed factor of 3d move in editor" },
288 { "cam_level", FUNC_VOID, level_cam, "level current camera" },
289 { "cam_unroll", FUNC_VOID, unroll_cam, "unroll current camera" },
290 { "num_scroll", FUNC_INT, decode_scroll, "scroll via numeric keypad" },
291 { "global_scale", FUNC_BOOL, rescale, "zoom in/out & rescale" },
293 { "show_raycasts", TOGGLE_BOOL, &show_raycasts, "display light raycasts" },
294 { "min_show", VAR_INT, &min_show, "min id# raycast to show" },
295 { "max_show", VAR_INT, &max_show, "max id# raycast to show" },
296 { "record_movement", TOGGLE_BOOL, &record_movement, "show rays of samples moving" },
298 // imported commands
299 // The following commands should all be registered
300 // by the systems that provide them, not here, but
301 // for now we'll just get it working...
303 { "cam_spotlight", TOGGLE_BOOL, &spotlight, "mounted spotlight toggle" },
306 // more imported commands that should be in both editor
307 // and game mode. obviously this belongs elsewhere.
309 extern bool surface_cache, skip_clip;
310 extern bool surf_256; // false all surfaces to row == 256
311 extern bool show_span_lengths, show_render_times;
312 extern bool portal_clip_poly, portal_clip_fast, poly_clip_fast;
313 extern palette_light, project_space, cache_feedback;
314 extern float light_scale;
315 extern float dynamic_light_min;
316 extern int player_light;
317 extern int portal_info_volume;
318 extern bool keep_all_lit;
319 extern float max_dist_2;
320 extern float dot_clamp;
321 extern bool show_cells;
322 extern bool linear_map;
323 extern bool portal_model;
324 extern bool portal_object_complete_test;
325 extern bool portal_write_traversal;
326 extern bool show_split;
327 extern BOOL show_bbox, show_bbox_2d;
328 extern bool disable_topsort;
330 #ifndef SHIP
331 extern BOOL always_slow_split;
332 #endif
334 #ifdef LOUD_D3D
335 #define d3d_talk(x) mprintf x
336 #else
337 #define d3d_talk(x)
338 #endif
340 #include <lgd3d.h>
341 #include <memall.h>
342 #include <dbmem.h> // must be last header!
344 static double z_far = 200.0;
345 static double z_near = 1.0;
347 extern void SetZNearFar(double zn, double zf);
349 extern BOOL g_null_raster;
350 extern BOOL lgd3d_z_normal;
351 extern BOOL g_lgd3d;
352 extern BOOL g_zbuffer;
354 static void toggle_null_raster(void)
356 g_null_raster = !g_null_raster;
357 if (g_null_raster)
358 r3_use_null();
359 else
360 if (g_lgd3d)
361 r3_use_lgd3d();
362 else
363 r3_use_g2();
366 extern BOOL pt_aggregate_lightmaps;
368 static BOOL linear=FALSE;
369 extern void lgd3d_set_zlinear(BOOL lin);
370 static void toggle_linear(void)
372 linear=!linear;
373 lgd3d_set_zlinear(linear);
376 static void znup(void)
378 z_near *= 2.0;
379 SetZNearFar(z_near, z_far);
380 d3d_talk(("z_near: %g\n", z_near));
383 static void zndown(void)
385 z_near *= 0.5;
386 SetZNearFar(z_near, z_far);
387 d3d_talk(("z_near: %g\n", z_near));
390 static void zfup(void)
392 z_far *= 2.0;
393 SetZNearFar(z_near, z_far);
394 d3d_talk(("z_far: %g\n", z_far));
397 static void zfdown(void)
399 z_far *= 0.5;
400 SetZNearFar(z_near, z_far);
401 d3d_talk(("z_far: %g\n", z_far));
404 extern BOOL lgd3d_punt_d3d;
405 extern BOOL rendloop_clear;
406 extern int portal_hack_blend;
407 extern BOOL portal_test_blend;
409 #ifndef SHIP
410 EXTERN void ParticleGroupCountSim(void);
411 extern int show_particle_counts;
412 #endif
414 static Command all_keys[]=
416 { "blend", VAR_INT, &portal_hack_blend },
417 { "test_blend", TOGGLE_BOOL, &portal_test_blend },
418 { "traverse_log", TOGGLE_BOOL, &portal_write_traversal,
419 "log cell traversal to traverse.log\n" },
420 { "clear", TOGGLE_BOOL, &rendloop_clear, "clear framebuffer to pink" },
421 { "max_polys", VAR_INT, &max_draw_polys, "maximum polygons to draw" },
422 { "show_lightmap", TOGGLE_BOOL, &show_lightmap, "display light sampling" },
423 { "render_info", FUNC_INT, print_info, "rendering stats at some volume" },
424 { "detail_level", VAR_FLOAT, &portal_detail_level,
425 "mipmap detail level (0-1)" },
426 { "dot_clamp", VAR_FLOAT, &dot_clamp, "mipmap orientation limit" },
427 { "surf_256", TOGGLE_BOOL, &surf_256, "surfaces are all row==256" },
428 { "show_span_lengths", TOGGLE_BOOL, &show_span_lengths, 0 },
429 { "show_render_times", TOGGLE_BOOL, &show_render_times, "detailed rendering timing info" },
430 { "info_volume", VAR_INT, &portal_info_volume, "determine amount of rendering information" },
432 // @TODO: optimize
433 // when we have shippable levels, test which combination of these three
434 // flags is fastest
435 { "portal_clip_poly", TOGGLE_BOOL, &portal_clip_poly, 0 },
436 { "portal_clip_fast", TOGGLE_BOOL, &portal_clip_fast, 0 },
437 { "poly_clip_fast", TOGGLE_BOOL, &poly_clip_fast, 0 },
439 #ifndef SHIP
440 { "always_slow_split", TOGGLE_BOOL, &always_slow_split, "force split objects to do things the hard way" },
441 { "show_particle_counts", TOGGLE_INT, &show_particle_counts, "show count of particle sim/render" },
442 { "show_particle_sim", FUNC_VOID, ParticleGroupCountSim, "list particle objects set to always_simulate" },
443 #endif
445 { "cache_feedback", TOGGLE_BOOL, &cache_feedback, "get extra surface cache info" },
446 { "light_scale", VAR_FLOAT, &light_scale, 0 },
447 { "player_light", VAR_INT, &player_light, "attach a light to the player" },
448 { "min_light", VAR_FLOAT, &dynamic_light_min, "minimum dynamic light on a surface allowed visible" },
449 { "max_dist_2", VAR_FLOAT, &max_dist_2, "maximum distance dynamic light can reach" },
451 { "keep_all_lit", TOGGLE_BOOL, &keep_all_lit, 0 },
453 { "show_cells", TOGGLE_BOOL, &show_cells, "Display cells containing refs" },
454 { "span_clip", TOGGLE_BOOL, &g2pt_span_clip, "enable span clipping in the renderer" },
455 { "portal_model", TOGGLE_BOOL, &portal_model, "render models through portal tmappers" },
456 { "full_obj_test", TOGGLE_BOOL, &portal_object_complete_test, "choose all/incomplete cell lists for object sort testing" },
458 { "show_split", TOGGLE_BOOL, &show_split, "outline objects being split" },
459 { "show_bbox", TOGGLE_BOOL, &show_bbox, "show bounding boxes around objects" },
460 { "show_bbox_2d", TOGGLE_BOOL, &show_bbox_2d, "outline objects" },
461 { "disable_topsort", TOGGLE_BOOL, &disable_topsort, "disable good objsort" },
463 // Shading Table Fun
464 { "show_shadtab", FUNC_VOID, show_shad_tab, "draw shading table" },
465 { "pick_shade_dist", FUNC_INT, PickDistanceFunction, "pick which rule for distance" },
467 // lgd3d hacks
468 { "puntd3d", TOGGLE_BOOL, &lgd3d_punt_d3d, 0},
469 { "zbuffer", TOGGLE_BOOL, &g_zbuffer, 0 },
470 { "znup", FUNC_VOID, znup, 0 },
471 { "zndown", FUNC_VOID, zndown, 0 },
472 { "zfup", FUNC_VOID, zfup, 0 },
473 { "zfdown", FUNC_VOID, zfdown, 0 },
474 { "zlinear", FUNC_VOID, toggle_linear, 0 },
475 { "agglight", TOGGLE_BOOL, &pt_aggregate_lightmaps, 0 },
476 { "nullrast", FUNC_VOID, toggle_null_raster, 0},
478 // the following flags should be desupported
479 // { "asm_outer", TOGGLE_BOOL, &asm_outer, 0 },
480 { "palette_light", TOGGLE_BOOL, &palette_light, 0 },
481 { "skip_clip", TOGGLE_BOOL, &skip_clip, 0 },
482 { "project_space", TOGGLE_BOOL, &project_space, 0 },
483 { "linear_map", TOGGLE_BOOL, &linear_map, "affine mapper for terrain" },
484 { "surface_cache", TOGGLE_BOOL, &surface_cache, "cache lit surfaces" },
488 //////////////////////////////////////////////////
491 extern void brushPickColors(void);
493 ////////////////////////////////////////////////////////////
494 // DATABASE EVENT HANDLERS
499 void editgeom_reset_database(void)
507 void editgeom_pal_change(void)
509 brushPickColors();
510 vm_pick_colors();
513 void editgeom_visual_message(DispatchData* msg)
515 switch(msg->subtype)
517 case kPaletteChange:
518 editgeom_pal_change();
519 break;
523 void editgeom_db_message(DispatchData* msg)
525 /// msgDatabaseData* data = (msgDatabaseData*)msg->data;
526 switch(DB_MSG(msg->subtype))
528 case kDatabaseReset:
529 editgeom_reset_database();
530 break;
531 case kDatabaseLoad:
532 //gedit_update();
533 break;
535 case kDatabasePostLoad:
536 if (msg->subtype & kDBMap)
538 if (blistCount() == 0)
539 scene_setup();
540 undoClearUndoStack();
543 if (msg->subtype & kObjPartConcrete)
544 ged_room_postload();
545 break;
546 case kDatabaseDefault:
547 scene_setup();
548 undoClearUndoStack();
549 ged_room_postload();
550 break;
554 ////////////////////////////////////////////////////////////
555 // STARTUP/SHUTDOWN
558 static int texturefilenum;
560 void editgeom_init(void)
562 texturefilenum = ResOpenFile("texture.res");
563 gedit_init();
564 COMMANDS(parse_keys, HK_EDITOR);
565 COMMANDS(all_keys, HK_ALL);
568 void editgeom_term(void)
570 ResCloseFile(texturefilenum);
571 gedit_term();
574 ////////////////////////////////////////////////////////////
575 // LOOPMODE HANDLERS
578 void testgeom_startup(void)
580 gedit_full_redraw();
583 void testgeom_shutdown(void)
587 bool testgeom_inner(void)
588 { PROF
589 mxs_vector *loc;
590 mxs_angvec *ang;
591 bool have_spot;
593 have_spot=vm_spotlight_loc(&loc, &ang);
595 reset_dynamic_lights();
596 if (spotlight&&have_spot)
598 Position pos;
599 MakePositionFromVectors(&pos, loc, ang);
600 gr_push_canvas(grd_canvas);
601 portal_add_spotlight(100.0, &pos, 1.0, LIGHT_DYNAMIC);
602 gr_pop_canvas();
605 if (!have_spot)
606 { loc=NULL; ang=NULL; }
607 SFX_Frame(loc,ang); // remove me too, please
609 vm_render_cameras();
610 END_PROF;
611 return TRUE;
615 ////////////////////////////////////////////////////////////
616 // LOOP CLIENT
619 typedef void Context;
621 typedef struct _StateRecord
623 Context* context;
624 } StateRecord;
628 ////////////////////////////////////////
630 // LOOP/DISPATCH callback
633 static eLoopMessageResult LGAPI _LoopFunc(void* data, eLoopMessage msg, tLoopMessageData hdata)
635 eLoopMessageResult result = kLoopDispatchContinue;
636 StateRecord* state = (StateRecord*)data;
637 LoopMsg info;
639 info.raw = hdata;
641 switch(msg)
643 case kMsgEnterMode:
644 case kMsgResumeMode:
645 testgeom_startup();
646 editgeom_pal_change();
647 break;
649 case kMsgExitMode:
650 case kMsgSuspendMode:
651 testgeom_shutdown();
652 break;
654 case kMsgNormalFrame:
655 case kMsgPauseFrame:
656 testgeom_inner();
657 break;
659 case kMsgDatabase:
660 editgeom_db_message(info.dispatch);
661 break;
663 case kMsgVisual:
664 editgeom_visual_message(info.dispatch);
665 break;
667 case kMsgAppInit:
668 editgeom_init();
669 break;
671 case kMsgAppTerm:
672 editgeom_term();
673 break;
675 case kMsgEnd:
676 Free(state);
677 break;
679 return result;
682 extern sLoopClientDesc EditGeomBaseClientDesc;
684 #pragma off(unreferenced)
685 static ILoopClient* LGAPI _CreateClient(sLoopClientDesc * pDesc, tLoopClientData data)
687 StateRecord* state;
688 sLoopClientDesc* desc = (data) ? &EditGeomClientDesc : &EditGeomBaseClientDesc;
689 // Assrt((void*)data != NULL);
690 state = (StateRecord*) Malloc(sizeof(StateRecord));
691 state->context = (Context*)data;
693 return CreateSimpleLoopClient(_LoopFunc,state,desc);
695 #pragma on(unreferenced)
697 #define BASE_MSGS (kMsgDatabase|kMsgVisual|kMsgEnd|kMsgAppInit|kMsgAppTerm)
699 sLoopClientDesc EditGeomClientDesc =
701 &LOOPID_EditGeom,
702 "EditGeom Client",
703 kPriorityNormal,
704 kMsgsMode|kMsgsFrame|BASE_MSGS,
706 kLCF_Callback,
707 _CreateClient,
709 NO_LC_DATA,
712 { kConstrainAfter, &LOOPID_ScrnMan, kMsgsMode},
713 { kConstrainAfter, &LOOPID_ObjSys, (ulong)kMsgsAll},
714 { kConstrainAfter, &LOOPID_BrushList, kMsgDatabase },
715 { kConstrainAfter, &LOOPID_Wr, kMsgDatabase},
717 {kNullConstraint}
721 sLoopClientDesc EditGeomBaseClientDesc =
723 &LOOPID_EditGeom,
724 "EditGeom Client",
725 kPriorityNormal,
726 BASE_MSGS,
727 kLCF_Callback,
729 _CreateClient,
731 NO_LC_DATA,
734 { kConstrainAfter, &LOOPID_ScrnMan, kMsgsMode},
735 { kConstrainAfter, &LOOPID_ObjSys, (ulong)kMsgsAll},
736 { kConstrainAfter, &LOOPID_BrushList, (ulong)kMsgsAll},
737 { kConstrainAfter, &LOOPID_Wr, kMsgDatabase},
739 {kNullConstraint}