]> icculus.org git repositories - taylor/freespace2.git/blob - src/nebedit/nebedit.cpp
The Great Newline Fix
[taylor/freespace2.git] / src / nebedit / nebedit.cpp
1 /*
2  * $Logfile: /Freespace2/code/nebedit/NebEdit.cpp $
3  * $Revision$
4  * $Date$
5  * $Author$
6  *
7  * Program to edit nebulas in 2d
8  *
9  * $Log$
10  * Revision 1.2  2002/05/07 03:16:47  theoddone33
11  * The Great Newline Fix
12  *
13  * Revision 1.1.1.1  2002/05/03 03:28:10  root
14  * Initial import.
15  *
16  * 
17  * 7     7/15/99 3:07p Dave
18  * 32 bit detection support. Mouse coord commandline.
19  * 
20  * 6     5/19/99 4:07p Dave
21  * Moved versioning code into a nice isolated common place. Fixed up
22  * updating code on the pxo screen. Fixed several stub problems.
23  * 
24  * 5     1/08/99 2:06p Dave
25  * Fixed pfoview for software mode.
26  * 
27  * 4     12/18/98 1:14a Dave
28  * Rough 1024x768 support for Direct3D. Proper detection and usage through
29  * the launcher.
30  * 
31  * 3     11/13/98 2:32p Dave
32  * Improved commandline parsing for exe pathname.
33  * 
34  * 2     10/24/98 9:51p Dave
35  * 
36  * 1     10/24/98 9:39p Dave
37  * 
38  * 13    4/13/98 10:11a John
39  * Made timer functions thread safe.  Made timer_init be called in all
40  * projects.
41  * 
42  * 12    3/23/98 1:35p Sandeep
43  * 
44  * 11    3/05/98 11:15p Hoffoss
45  * Changed non-game key checking to use game_check_key() instead of
46  * game_poll().
47  * 
48  * 10    12/29/97 5:10p Allender
49  * fixed problems with speed not being reported properly in multiplayer
50  * games.  Made read_flying_controls take frametime as a parameter.  More
51  * ship/weapon select stuff
52  * 
53  * 9     12/04/97 3:47p John
54  * Made joystick move mouse cursor
55  * 
56  * 8     11/21/97 11:32a John
57  * Added nebulas.   Fixed some warpout bugs.
58  * 
59  * 7     11/19/97 10:15p Adam
60  * upped maxtris to 200
61  * 
62  * 6     11/19/97 4:28p Sandeep
63  * added poly/vert counter
64  * 
65  * 5     11/19/97 1:59p Sandeep
66  * Added multiple vertex editing mode
67  * 
68  * 4     11/16/97 2:29p John
69  * added versioning to nebulas; put nebula code into freespace.
70  * 
71  * 3     11/13/97 12:04p Sandeep
72  * Added face editing support, deletion support, and a saving and loading
73  * stuff.
74  * 
75  * 2     11/10/97 9:59p John
76  * some tweaking
77  * 
78  * 1     11/10/97 9:42p John
79  *
80  * $NoKeywords: $
81  */
82
83
84 #include <windows.h>
85 #include <stdio.h>
86 #include <stdlib.h>
87 #include <string.h>
88 #include <ctype.h>
89 #include <dos.h>
90
91 #include "pstypes.h"
92 #include "2d.h"
93 #include "3d.h"
94 #include "key.h"
95 #include "palman.h"
96 #include "bmpman.h"
97 #include "timer.h"
98 #include "floating.h"
99 #include "osapi.h"
100 #include "cfile.h"
101 #include "linklist.h"
102 #include "lighting.h"
103 #include "mouse.h"
104 #include "vecmat.h"
105 #include "physics.h"
106 #include "model.h"
107 #include "font.h"
108
109
110 #define SCREEN_W        640     
111 #define SCREEN_H        480
112
113 vector ViewerPos;
114 matrix ViewerOrient;
115 matrix ModelOrient;
116 vector ModelPos;
117 physics_info ViewerPhysics;
118 float ViewerZoom = 1.0f;
119
120 int test_model = -1;
121 int Fred_running = 0;
122 int Pofview_running = 0;
123 float flFrametime = 0.0f;
124
125 int Font1 = -1;
126
127 color color_green;
128
129 vector Global_light_world = { 0.208758f, -0.688253f, -0.694782f };
130
131 // nebula stuff
132
133 #define NEB_W 6
134 #define NEB_H 6
135 #define MAX_TRIS 200
136 #define MAX_POINTS 300
137
138 int neb_w = 0, neb_h = 0;
139
140 int nebula_inited = 0;
141 int num_pts = 0;
142
143 int x[MAX_POINTS], y[MAX_POINTS], l[MAX_POINTS];
144 float scale_factor = 1.0f;
145
146 int num_tris = 0;
147 int tri[MAX_TRIS][3];
148
149 color nebula_color;
150
151 int Mouse_x, Mouse_y;
152 int Current_point;
153 BOOL Selected[MAX_POINTS];
154 BOOL Sel_mode = 0;   // 0 = 1 point at a time, 1 = select multiple points
155 int Current_face;
156
157 int View_mode = 0;      // 0 = 2d editor, 1 = 3d viewer
158
159 int Vert_mode = 0;   // 0 = Move vertices/Add vertices, 2 = Move face/Add face
160
161 int Which_vert = 0;  // Current vertex of the faceadd
162
163 int Orig_pos_x;
164 int Orig_pos_y;
165 int End_pos_x;
166 int End_pos_y;
167 BOOL Draw_sel_box = FALSE;
168
169 int Neb_created = 0;
170
171 int Nebedit_running = 1;
172
173 extern int load_nebula_sub(char*);
174 extern void project_2d_onto_sphere(vector *, float, float);
175
176 void create_default_neb()
177 {
178         int i,j;
179         neb_w = NEB_W;
180         neb_h = NEB_H;
181         num_pts = neb_w*neb_h;
182
183         for (j=0; j<neb_h; j++ )        {
184                 for (i=0; i<neb_w; i++ )        {
185                         x[i+j*neb_w] = ((i+1)*SCREEN_W)/(neb_w+2);
186                         y[i+j*neb_w] = ((j+3)*SCREEN_H)/(neb_h+6);
187                         if ( (j==0) || (j==neb_h-1))    {
188                                 l[i+j*neb_w] = 0;
189                         } else {
190                                 l[i+j*neb_w] = 31;
191                         }
192                 }
193         }
194
195         num_tris = 0;
196
197         for (j=0; j<neb_h-1; j++ )      {
198                 for (i=0; i<neb_w-1; i++ )      {
199                         tri[num_tris][0] = i+neb_w*j;
200                         tri[num_tris][1] = i+neb_w*j+1;
201                         tri[num_tris][2] = i+neb_w*(j+1)+1;
202                         num_tris++;
203
204                         tri[num_tris][0] = i+neb_w*j;
205                         tri[num_tris][1] = i+neb_w*(j+1)+1;
206                         tri[num_tris][2] = i+neb_w*(j+1);
207                         num_tris++;
208                 }
209         }
210
211         Neb_created = 1;
212 }
213
214 #define NEBULA_FILE_ID "NEBU"                   
215 #define NEBULA_MAJOR_VERSION 1          // Can be 1-?
216 #define NEBULA_MINOR_VERSION 0          // Can be 0-99
217
218 void save_nebula_sub(char *filename)
219 {
220         FILE *fp;
221         float xf, yf;
222         int version;
223
224         fp = fopen(filename, "wb");
225
226         // ID of NEBU
227         fwrite( "NEBU", 4, 1, fp );     
228         version = NEBULA_MAJOR_VERSION*100+NEBULA_MINOR_VERSION;
229         fwrite( &version, sizeof(int), 1, fp );
230         fwrite( &num_pts, sizeof(int), 1, fp );
231         fwrite( &num_tris, sizeof(int), 1, fp );
232
233         for (int i=0; i<num_pts; i++ )  {
234                 xf = float(x[i])/640.0f;
235                 yf = float(y[i])/480.0f;
236                 fwrite( &xf, sizeof(float), 1, fp );
237                 fwrite( &yf, sizeof(float), 1, fp );
238                 fwrite( &l[i], sizeof(int), 1, fp );
239         }
240
241         for (i=0; i<num_tris; i++ )     {
242                 fwrite( &tri[i][0], sizeof(int), 1, fp );
243                 fwrite( &tri[i][1], sizeof(int), 1, fp );
244                 fwrite( &tri[i][2], sizeof(int), 1, fp );
245         }
246
247         fclose(fp);
248 }
249
250 void nebedit_close()
251 {
252         save_nebula_sub( "autosaved.neb" );
253 }
254
255 void save_nebula()
256 {
257         char filename[255] = "\0";
258         //char filter[255] = "Nebula Files\0
259         OPENFILENAME o;
260         memset(&o,0,sizeof(o));
261         o.lStructSize = sizeof(o);
262         //o.hwndOwner = GetActiveWindow();
263         o.lpstrFilter = "Nebula Files\0*.NEB\0\0";
264         o.lpstrFile = filename;
265         o.nMaxFile = 256;
266         o.Flags = OFN_OVERWRITEPROMPT | OFN_PATHMUSTEXIST;
267         o.lpstrDefExt = "*.NEB";
268         if (!GetSaveFileName(&o)) return;
269
270         save_nebula_sub(filename);
271 }
272
273 void load_nebula()
274 {
275         char filename[255] = "\0";
276         OPENFILENAME o;
277         memset(&o,0,sizeof(o));
278         o.lStructSize = sizeof(OPENFILENAME);
279         //o.hwndOwner = GetActiveWindow();
280         o.lpstrFilter = "Nebula Files\0*.NEB\0\0";
281         o.lpstrFile = filename;
282         o.nMaxFile = 256;
283         o.Flags = OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST;
284         o.lpstrDefExt = "*.NEB";
285
286         int create_default = 0;
287         if (!GetOpenFileName(&o)) {
288                 create_default = 1;
289         } else {
290                 if ( !load_nebula_sub(filename))        {
291                         create_default = 1;
292                 }
293         }
294
295         if ( create_default )   {       
296                 create_default_neb();   
297         }
298
299         Neb_created = 1;
300 }
301
302 void nebula_init()
303 {
304         if ( nebula_inited ) return;
305         memset(Selected, 0, sizeof(BOOL)*MAX_POINTS);
306         nebula_inited++;
307
308         create_default_neb();   
309         gr_init_alphacolor( &nebula_color, 0, 255, 0, 255 );
310
311         return;
312 }
313
314 void draw_tri_2d( int i, int j, int k )
315 {
316         int index[3];
317
318         index[0] = i;
319         index[1] = j;
320         index[2] = k;
321
322         vertex va, vb, vc;
323         vertex * verts[3] = { &va, &vb, &vc };
324 //      gr_zbuffering = 0;
325         for (int v=0; v<3; v++ )        {
326                 verts[v]->sx = i2fl(x[index[v]]);   
327                 verts[v]->sy = i2fl(y[index[v]]);
328                 verts[v]->u = 0.0f;
329                 verts[v]->v = 0.0f;
330                 verts[v]->sw = 1.0f; 
331                 verts[v]->r = verts[v]->g = verts[v]->b = (ubyte)(i2fl(l[index[v]])/31.0f);
332
333         }
334
335 //      gr_set_color( 0, 0, 0 );
336         gr_tmapper(3, verts, TMAP_FLAG_RAMP | TMAP_FLAG_GOURAUD | TMAP_FLAG_NEBULA );
337
338         if ( !keyd_pressed[KEY_LSHIFT] )        {
339                 gr_set_color(100,100,100);
340                 gr_line( x[i], y[i], x[j], y[j] );
341                 gr_line( x[j], y[j], x[k], y[k] );
342                 gr_line( x[k], y[k], x[i], y[i] );
343         }
344 }
345
346 void nebula_draw_2d()
347 {
348         int i;
349         
350         for (i=0; i<num_tris; i++ )     {
351                 draw_tri_2d( tri[i][0], tri[i][1], tri[i][2] );
352         }               
353
354                 gr_set_color(100,0,0);
355                 for (i=0; i<num_pts; i++ )      {
356                         gr_circle( x[i], y[i], 4 );
357                 }
358                 if ((Sel_mode==1)) { // multiple selection
359                         if (Draw_sel_box) {
360                                 gr_set_color(200,0,200);
361                                 gr_line(Orig_pos_x, Orig_pos_y, Orig_pos_x, End_pos_y);
362                                 gr_line(Orig_pos_x, End_pos_y, End_pos_x, End_pos_y);
363                                 gr_line(End_pos_x, Orig_pos_y, End_pos_x, End_pos_y);
364                                 gr_line(End_pos_x, Orig_pos_y, Orig_pos_x, Orig_pos_y);
365                         } else {
366                                 gr_set_color(0,100,0);
367                                 for (int i=0;i<num_pts;i++)
368                                         if (Selected[i]) gr_circle( x[i], y[i], 5);
369                         }
370                 } else if ((Vert_mode==0)&&(Current_point>-1)) {
371                         gr_set_color(0,100,0);
372                         gr_circle( x[Current_point], y[Current_point], 5);
373                 } else if (Vert_mode == 1) {
374                         for (i=0;i<Which_vert;i++) {
375                                 gr_set_color(0,0,100);
376                                 gr_circle( x[tri[num_tris][i]], y[tri[num_tris][i]], 6);
377                         }
378                         gr_set_color(200,200,0);
379                         if (Current_face>-1) {
380                                 gr_line(x[tri[Current_face][0]], y[tri[Current_face][0]], 
381                                                 x[tri[Current_face][1]], y[tri[Current_face][1]]);
382                                 gr_line(x[tri[Current_face][1]], y[tri[Current_face][1]], 
383                                                 x[tri[Current_face][2]], y[tri[Current_face][2]]);
384                                 gr_line(x[tri[Current_face][2]], y[tri[Current_face][2]], 
385                                                 x[tri[Current_face][0]], y[tri[Current_face][0]]);
386                         }
387                 }
388 }
389
390
391 void draw_tri_3d( int i, int j, int k )
392 {
393         int index[3];
394
395         index[2] = k;
396         index[1] = j;
397         index[0] = i;
398
399         vertex va, vb, vc;
400         vertex * verts[3] = { &va, &vb, &vc };
401         //gr_zbuffering = 0;
402         for (int v=0; v<3; v++ )        {
403                 vector tmp;
404                 
405                 project_2d_onto_sphere( &tmp, 1.0f - i2fl(x[index[v]])/640.0f, i2fl(y[index[v]])/480.0f );
406         
407                 vm_vec_scale( &tmp, 10.0f );
408
409                 g3_rotate_faraway_vertex( verts[v], &tmp );
410                 //g3_rotate_vertex( verts[v], &tmp );
411                 g3_project_vertex( verts[v] );
412
413                 verts[v]->r = verts[v]->g = verts[v]->b = (ubyte)(i2fl(l[index[v]])/31.0f);
414         }
415
416         //gr_zbuffering = 0;
417         //gr_set_color_fast( &nebula_color );
418         //gr_set_color( 0, 0, 0 );
419         g3_draw_poly(3, verts, TMAP_FLAG_RAMP | TMAP_FLAG_GOURAUD | TMAP_FLAG_NEBULA );
420 }
421
422 void nebula_draw_3d()
423 {
424         int i;
425         for (i=0; i<num_tris; i++ )     {
426                 draw_tri_3d( tri[i][0], tri[i][1], tri[i][2] );
427         }               
428 }
429
430 void render_frame()
431 {
432         gr_reset_clip();
433
434         gr_set_color(0,0,0);            // set color to black
435         gr_rect(0,0,SCREEN_W,SCREEN_H); // clear screen
436
437         light_reset();
438         light_add_directional( &Global_light_world, 0.1f, 1.0f, 1.0f, 1.0f );
439
440         g3_start_frame(1);
441
442         g3_set_view_matrix(&ViewerPos, &ViewerOrient,ViewerZoom);
443
444         if ( View_mode == 0 )   {
445                 nebula_draw_2d();
446
447                 gr_set_font(Font1);
448                 gr_set_color_fast( &color_green );
449                 gr_printf(10,10,"Nebula Editor. Mode :");
450                 if (Sel_mode ==1) {
451                                 gr_printf(180, 10, "Multiple Vertex Selection Editing");
452                 } else if (Vert_mode ==0 ) {
453                         gr_printf(180,10,"Vertex Editing");
454                         if(Current_point >= 0){
455                                 gr_printf(180, 20, "Current vertex intensity : %d\n", l[Current_point]);
456                         }
457                 } else if (Vert_mode ==1) {
458                         gr_printf(180,10,"Face Editing");
459                 }
460                 char blah[255];
461                 gr_printf(20,30,"# Points:");
462                 gr_printf(100,30, itoa(num_pts, blah, 10));
463                 gr_printf(220,30,"# Polys:");
464                 gr_printf(300,30, itoa(num_tris, blah, 10));            
465         } else {
466                 nebula_draw_3d();
467                 model_render( test_model, &ModelOrient, &ModelPos );
468         }
469
470         g3_end_frame();
471
472         gr_flip();
473 }
474
475 int get_closest(int mx, int my)
476 {
477         int i, closest = -1, cval = 100000;
478
479         for (i=0; i<num_pts; i++ )      {
480                 int dist;
481                 int dx, dy;
482                 
483                 dx = x[i] - mx;
484                 dy = y[i] - my;
485                 
486                 dist = fl2i(fl_sqrt( i2fl((dx*dx)+(dy*dy)) ));
487
488                 if ( dist < cval )      {
489                         cval = dist;
490                         closest = i;
491                 }
492         }
493
494         return closest;
495 }
496
497 int get_closest_face(int mx, int my)
498 {
499         int i, closest = -1, cval = 100000;
500
501         for (i=0; i<num_tris; i++ )     {
502                 int dist;
503                 int dx, dy;
504                 
505                 dx = x[tri[i][0]] - mx;
506                 dy = y[tri[i][0]] - my;
507
508                 dx += x[tri[i][1]] - mx;
509                 dy += y[tri[i][1]] - my;
510                 
511                 dx += x[tri[i][2]] - mx;
512                 dy += y[tri[i][2]] - my;
513
514                 dist = fl2i(fl_sqrt( i2fl((dx*dx)+(dy*dy)) ));
515 /*
516                 dist += fl2i(fl_sqrt( i2fl((dx*dx)+(dy*dy)) ));
517
518                 dx = x[tri[i][2]] - mx;
519                 dy = y[tri[i][2]] - my;
520                 dist += fl2i(fl_sqrt( i2fl((dx*dx)+(dy*dy)) ));
521 */
522
523                 if ( dist < cval )      {
524                         cval = dist;
525                         closest = i;
526                 }
527         }
528
529         return closest;
530 }
531
532 void delete_face(int i)
533 {
534         for (int j=i;j<num_tris;j++) {
535                 memcpy(tri[j], tri[j+1], sizeof(int)*3);
536         }
537         num_tris--;
538 }
539
540 void delete_vert(int i)
541 {
542         for (int j=0;j<num_tris;j++) {
543                 if ((tri[j][0]==i)||(tri[j][1]==i)||(tri[j][2]==i)) {
544                         delete_face(j);
545                         j=0;
546                 }
547         }
548         for (j=0;j<num_tris;j++) {
549                 if (tri[j][0]>i) tri[j][0]--;
550                 if (tri[j][1]>i) tri[j][1]--;
551                 if (tri[j][2]>i) tri[j][2]--;
552         }
553         for (j=i;j<num_pts;j++) {
554                 x[j] = x[j+1];
555                 y[j] = y[j+1];
556                 l[j] = l[j+1];
557         }
558         num_pts--;
559 }
560
561 int add_vert(int mx, int my)
562 {
563         Assert(num_pts<300);
564         x[num_pts] = mx;
565         y[num_pts] = my;
566         l[num_pts] = 0;
567         num_pts++;
568         return num_pts-1;
569 }
570
571 void select_by_box(int x1, int y1, int x2, int y2)
572 {
573         if (x1>x2) {
574                 int temp = x1;
575                 x1 = x2;
576                 x2 = temp;
577         }
578         if (y1>y2) {
579                 int temp = y1;
580                 y1 = y2;
581                 y2 = temp;
582         }
583         for (int i=0;i<num_pts;i++) {
584                 if ((x[i]<=x2) && (x[i]>=x1) &&
585                          (y[i]<=y2) && (y[i]>=y1)) {
586                         Selected[i] = TRUE;
587                 }
588         }
589 }
590
591 void sphericalize_nebula()
592 {
593         int idx1, idx2;
594         int px = SCREEN_W / (neb_w - 1);
595         int py = SCREEN_H / (neb_h - 1);
596
597         // flatten out the nebula so that it covers the entire sphere evenly
598         for(idx1=0; idx1<neb_w; idx1++){
599                 for(idx2=0; idx2<neb_h; idx2++){
600                         x[idx1+idx2*neb_w] = px * idx1;
601                         y[idx1+idx2*neb_w] = py * idx2;
602                 }
603         }
604 }
605
606 void controls_read_all(control_info * ci, float sim_time )
607 {
608         float kh;
609
610         {
611                 float temp = ci->heading;
612                 float temp1 = ci->pitch;
613                 memset( ci, 0, sizeof(control_info) );
614                 ci->heading = temp;
615                 ci->pitch = temp1;
616         }
617
618         // From keyboard...
619         kh = (key_down_timef(KEY_PAD6) - key_down_timef(KEY_PAD4))/8.0f;
620         if (kh == 0.0f)
621                 ci->heading = 0.0f;
622         else if (kh > 0.0f) {
623                 if (ci->heading < 0.0f)
624                         ci->heading = 0.0f;
625         } else // kh < 0
626                 if (ci->heading > 0.0f)
627                         ci->heading = 0.0f;
628         ci->heading += kh;
629
630         kh = (key_down_timef(KEY_PAD8) - key_down_timef(KEY_PAD2))/8.0f;
631         if (kh == 0.0f)
632                 ci->pitch = 0.0f;
633         else if (kh > 0.0f) {
634                 if (ci->pitch < 0.0f)
635                         ci->pitch = 0.0f;
636         } else // kh < 0
637                 if (ci->pitch > 0.0f)
638                         ci->pitch = 0.0f;
639         ci->pitch += kh;
640
641         ci->bank = (key_down_timef(KEY_PAD7) - key_down_timef(KEY_PAD9))*.75f;
642         ci->forward = key_down_timef(KEY_A) - key_down_timef(KEY_Z);
643         ci->sideways = key_down_timef(KEY_PAD3) - key_down_timef(KEY_PAD1);
644         ci->vertical = key_down_timef(KEY_PADPLUS) - key_down_timef(KEY_PADENTER);
645 }
646
647 int check_keys()
648 {
649         int k;
650
651         while( (k = key_inkey()) != 0 ) {
652 //mprintf(( "Key = %x\n", k ));
653                 if ( k == KEY_ESC ) {
654                         return 1;
655                 }
656
657                 switch( k )     {
658                 case KEY_ENTER:
659                         Sel_mode = FALSE;
660                         Vert_mode = !Vert_mode;
661                         Which_vert = 0;
662                         break;
663
664                 case KEY_DELETE:
665                         if (Sel_mode) break;
666                         if (Vert_mode==1) delete_face(Current_face);
667                         else if (Vert_mode==0) {
668                                 delete_vert(Current_point);
669                         }
670                         break;
671
672                 case KEY_MINUS:
673                         scale_factor -= 0.05f;
674                         mprintf(( "Scale = %.1f\n", scale_factor ));
675                         break;
676
677
678                 case KEY_EQUAL:
679                         scale_factor += 0.05f;
680                         mprintf(( "Scale = %.1f\n", scale_factor ));
681                         break;
682
683                 case KEY_INSERT:
684                         Sel_mode = !Sel_mode;
685                         break;
686
687                 case KEY_SPACEBAR:
688                         View_mode = !View_mode;
689                         break;
690
691                 case KEY_COMMA:
692                         if (Sel_mode) {
693                                 int i;
694                                 for (i=0;i<num_pts;i++) if (Selected[i]) {
695                                         if ( l[i] > 0 ) {
696                                                 l[i]--;
697                                         }
698                                 }
699                         } else if (Vert_mode==0) {
700                                 if ( Current_point > -1 )       {
701                                         if ( l[Current_point] > 0 )     {
702                                                 l[Current_point]--;
703                                         }
704                                 }
705                         } else if (Vert_mode ==1) {
706                                 if ( l[tri[Current_face][0]] > 0 )      {
707                                                 l[tri[Current_face][0]]--;
708                                         }
709                                 if ( l[tri[Current_face][1]] > 0 )      {
710                                                 l[tri[Current_face][1]]--;
711                                         }
712                                 if ( l[tri[Current_face][2]] > 0 )      {
713                                                 l[tri[Current_face][2]]--;
714                                         }
715                         }
716                         break;
717
718                 case KEY_PERIOD:        
719                         if (Sel_mode) {
720                                 int i;
721                                 for (i=0;i<num_pts;i++) if (Selected[i]) {
722                                         if ( l[i] < 31 )        {
723                                                 l[i]++;
724                                         }
725                                 }
726                         } else if (Vert_mode==0) {
727                                 if ( Current_point > -1 )       {
728                                         if ( l[Current_point] < 31 )    {
729                                                 l[Current_point]++;
730                                         }
731                                 }
732                         } else if (Vert_mode ==1) {
733                                 if ( l[tri[Current_face][0]] <31 )      {
734                                                 l[tri[Current_face][0]]++;
735                                         }
736                                 if ( l[tri[Current_face][1]] <31)       {
737                                                 l[tri[Current_face][1]]++;
738                                         }
739                                 if ( l[tri[Current_face][2]] <31 )      {
740                                                 l[tri[Current_face][2]]++;
741                                         }
742                         }
743                         
744                         break;          
745
746                 case KEY_F5:
747                         save_nebula();
748                         break;
749                 case KEY_F7:
750                         load_nebula();
751                         break;
752
753                 case KEY_BACKSP:
754                         sphericalize_nebula();
755                         break;
756                 }
757         }
758         return 0;
759 }
760
761 void os_close()
762 {
763         exit(1);
764 }
765
766 int newtri[3];
767
768 int mdflag = 0;
769
770 int PASCAL WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR szCmdLine, int nCmdShow)
771 {
772         int i;
773         fix t1, t2;
774         control_info ci;
775         float speed = 20.0f;            // how fast viewer moves        
776
777         // setup the fred exe directory so CFILE can init properly
778         /*
779         char *c = GetCommandLine();
780         Assert(c != NULL);
781         char *tok = strtok(c, " ");
782         Assert(tok != NULL);    
783         */
784
785         timer_init();
786         // cfile_init(tok);
787         cfile_init(__argv[0]);
788         os_init( "NebEdit", "NebEdit" );        //SCREEN_W, SCREEN_H );
789         palette_load_table( "gamepalette1-01.pcx" );    
790         gr_init(GR_640, GR_SOFTWARE, 8);
791         key_init();
792         mouse_init();
793         Font1 = gr_init_font( "font01.vf" );
794         gr_init_alphacolor( &color_green, 0,255,0,255 );
795
796         test_model = model_load( "fighter01.pof", 0, NULL );
797
798         physics_init( &ViewerPhysics );
799         ViewerPhysics.flags |= PF_ACCELERATES | PF_SLIDE_ENABLED;
800         
801         ViewerPhysics.max_vel.x = 2.0f*speed;           //sideways
802         ViewerPhysics.max_vel.y = 2.0f*speed;           //up/down
803         ViewerPhysics.max_vel.z = 2.0f*speed;           //forward
804         ViewerPhysics.max_rear_vel = 2.0f*speed;        //backward -- controlled seperately
805         
806         memset( &ci, 0, sizeof(control_info) );
807
808         ModelOrient = vmd_identity_matrix;
809         ModelPos.x=0.0f; ModelPos.y = 0.0f; ModelPos.z = 0.0f;
810
811         ViewerOrient = vmd_identity_matrix;
812         ViewerPos.x=0.0f; ViewerPos.y = 0.0f; ViewerPos.z = -50.0f;
813
814         flFrametime = 0.033f;
815
816         t1 = timer_get_fixed_seconds();
817
818         nebula_init();
819
820         int some_selected = 0;
821
822         while(1)        {
823                 some_selected = FALSE;
824                 if (Sel_mode==1) {
825                         for (i=0;i<num_pts;i++) {
826                                 if (Selected[i]) {
827                                         some_selected = TRUE;
828                                         break;
829                                 }
830                         }
831                 }
832
833                 mouse_get_pos( &Mouse_x, &Mouse_y );
834
835                 if (Current_face==-1) {
836                         Current_face = get_closest_face(Mouse_x, Mouse_y);
837                 }
838                 
839                 if ( check_keys() ){
840                         break;
841                 }
842
843                 if ( Sel_mode==1 ) {
844                         // Special mouse handlers for multiple selmode
845                         if (mouse_down_count(LOWEST_MOUSE_BUTTON)) {
846                                 Orig_pos_x = Mouse_x;
847                                 Orig_pos_y = Mouse_y;
848                         }
849                         if (mouse_down(LOWEST_MOUSE_BUTTON)) {
850                                 for (i=0;i<num_pts;i++) {
851                                         if (Selected[i]) {
852                                                 x[i]+=Mouse_x - Orig_pos_x;
853                                                 y[i]+=Mouse_y - Orig_pos_y;
854                                         }
855                                 }
856                                 Orig_pos_x = Mouse_x;
857                                 Orig_pos_y = Mouse_y;
858                         }
859                         if (mouse_down_count(MOUSE_RIGHT_BUTTON)) {
860                                 Orig_pos_x = Mouse_x;
861                                 Orig_pos_y = Mouse_y;
862                                 for (i=0;i<num_pts;i++) {
863                                         Selected[i] = FALSE;
864                                 }
865                         }
866                         if (mouse_down(MOUSE_RIGHT_BUTTON)) {
867                                 Draw_sel_box = TRUE;
868                                 End_pos_x = Mouse_x;
869                                 End_pos_y = Mouse_y;
870                         }
871                         if (mouse_up_count(MOUSE_RIGHT_BUTTON)) {
872                                 Draw_sel_box = FALSE;
873                                 End_pos_x = Mouse_x;
874                                 End_pos_y = Mouse_y;
875                                 select_by_box(Orig_pos_x, Orig_pos_y, End_pos_x, End_pos_y);
876                         }
877
878                 } else {
879
880                 if ( mouse_down(LOWEST_MOUSE_BUTTON) )  {
881                         if ( mdflag )   {
882                                 if (Vert_mode==0) {
883                                         x[Current_point] = Mouse_x;
884                                         y[Current_point] = Mouse_y;
885                                 } else if (Vert_mode==1) {
886                                         x[tri[Current_face][0]] += Mouse_x - Orig_pos_x;
887                                         y[tri[Current_face][0]] += Mouse_y - Orig_pos_y;
888                                         x[tri[Current_face][1]] += Mouse_x - Orig_pos_x;
889                                         y[tri[Current_face][1]] += Mouse_y - Orig_pos_y;
890                                         x[tri[Current_face][2]] += Mouse_x - Orig_pos_x;
891                                         y[tri[Current_face][2]] += Mouse_y - Orig_pos_y;
892                                         Orig_pos_x = Mouse_x;
893                                         Orig_pos_y = Mouse_y;
894                                 }
895                         } else {
896                                 if (Vert_mode == 1) {
897                                         Current_face = get_closest_face(Mouse_x, Mouse_y);
898                                         Orig_pos_x = Mouse_x;
899                                         Orig_pos_y = Mouse_y;
900                                 }
901                                 if (Vert_mode==0) {
902                                         Current_point = get_closest(Mouse_x, Mouse_y);
903                                         mouse_set_pos(x[Current_point], y[Current_point]);
904                                 }
905                                 mdflag = TRUE;
906                         }
907                 }
908                 if ( mouse_up_count(LOWEST_MOUSE_BUTTON)) {
909                         //Current_point = -1;
910                         //Current_face = -1;
911                         mdflag = FALSE;
912                 }
913
914                 if ( mouse_up_count(MOUSE_RIGHT_BUTTON) ) {
915                         if (Vert_mode==0) {
916                                 Current_point = add_vert(Mouse_x, Mouse_y);
917                         } else if (Vert_mode==1) {
918                                 if ((num_tris<MAX_TRIS-1)) { 
919                                         tri[num_tris][Which_vert] = get_closest(Mouse_x, Mouse_y);
920                                         Which_vert++;
921                                         if (Which_vert>2) {
922                                                 Which_vert = 0;
923                                                 num_tris++;
924                                         }
925                                 }
926                         }
927                 }
928                 }
929                 controls_read_all(&ci, flFrametime );
930                 physics_read_flying_controls( &ViewerOrient, &ViewerPhysics, &ci, flFrametime );
931                 physics_sim(&ViewerPos, &ViewerOrient, &ViewerPhysics, flFrametime );           
932
933                 render_frame();
934
935                 t2 = timer_get_fixed_seconds();
936                 if ( t2 > t1 )  {
937                         flFrametime = f2fl(t2 - t1);
938                 }
939
940                 t1 = t2;
941         }
942
943         nebedit_close();
944
945         return 0;
946 }
947
948 // Stub functions and variables.
949 // These do nothing but are needed to prevent link errors.
950 void demo_set_playback_filter() {}
951
952 void freespace_menu_background()
953 {
954         gr_reset_clip();
955         gr_clear();
956 }
957
958 int game_check_key()
959 {
960         return key_inkey();
961 }
962
963 int game_poll()
964 {
965         return key_inkey();
966 }
967
968 vector Camera_pos;
969 vector Dead_player_last_vel;
970 // end stubs
971