1 //gnauralscape.c, main file of project vulcan by Bret Logan
2 //2010 (c) Bret Byron Logan
3 //NOTE:
4 //define "GS_STANDALONE" to run this standalone.
5 #define GS_STANDALONE
6 
7 #include <stdlib.h>
8 #include <math.h>
9 #include "MakeLand.h"
10 #include "LandCaster.h"
11 
12 #include <gtk/gtk.h>
13 
14 #define VULCAN_FPS 25   //this is the animation speed
15 #define VULCAN_TARGETS 20
16 
17 //Game messages/data:
18 #define VULCAN_HIT 1
19 #define VULCAN_GROUND 2
20 #define VULCAN_FIRE 4
21 #define VULCAN_WIN 8
22 #define VULCAN_NEWGAME 16
23 #define VULCAN_MAXSPEED 10
24 #define VULCAN_MISSILE_LIFE 80
25 #define VULCAN_FORWARD 0
26 #define VULCAN_BEHIND 1
27 #define VULCAN_RIGHT 2
28 #define VULCAN_LEFT 3
29 #define VULCAN_NORMAL 0
30 #define VULCAN_FOLLOW 1
31 #define VULCAN_CIRCLE 2
32 #define VULCAN_CHASE 3
33 #define VULCAN_BLIND 4
34 #define VC_SPEED 14
35 
36 //globals:
37 //////////////////////////////////
38 typedef struct
39 {
40  GtkWidget *drawing_area;
41  int *BmpDest;                  //GTK+ prefers rgb char triplets buffers, but LandCaster was set up for int-sized rgbp data
42  int width;
43  int height;
44  int size;
45  gint rowstride;                //drawing_area need this; it is 3*width for an RGB bitmap, 4*width for an int-sized RGBP
46  double FPS;                    //frames-per-second animation speed);
47  guint GUIUpdateHandle;         //to keep track of it's own timer
48  int Turn;
49  int Lift;
50  int GameObjects;
51  double GameTime;               // holds duration from whenever main_Stopwatch() was last called
52  int FireCount;
53  int pixelfly;                  //if non-0, renders in flat mode
54 } vulcan_Data;
55 
56 vulcan_Data *main_VD = NULL;
57 
58 gchar main_msgstring[1024];     //use this for any string stuff
59 void main_GameCallback (int message);
60 void main_NewGame (vulcan_Data * vd);
61 void main_Cleanup ();           //assumes global main_VD
62 
63 //////////////////////////////////
64 // standard handlers
main_delete_event(GtkWidget * widget,GdkEvent event,gpointer data)65 gint main_delete_event (GtkWidget * widget, GdkEvent event, gpointer data)
66 {
67  printf ("main_delete_event\n");
68  //kill GUI updating if here:
69  if (NULL != main_VD && 0 != main_VD->GUIUpdateHandle)
70  {
71   g_source_remove (main_VD->GUIUpdateHandle);
72   main_VD->GUIUpdateHandle = 0;
73  }
74 
75  return FALSE;
76 }
77 
78 /////////////////////////////
main_end_program(GtkWidget * widget,gpointer data)79 void main_end_program (GtkWidget * widget, gpointer data)
80 {
81  printf ("main_end_program\n");
82  main_Cleanup ();
83 #ifdef GS_STANDALONE
84  gtk_main_quit ();
85 #endif
86 }
87 
88 /*
89    //////////////////////////////
90    //this is an example only to demonstrate how to fill the buffer
91    void main_Fill (vulcan_Data * vd)
92    {
93    // Set up the RGB buffer:
94    guchar r,
95    g,
96    b;
97 
98    static unsigned int color1 = 0;
99 
100    color1 = 1 + color1 * 1.1;
101 
102    r = (guchar) ((color1 >> 0) & 0xff);
103    g = (guchar) ((color1 >> 8) & 0xff);
104    b = (guchar) ((color1 >> 16) & 0xff);
105 
106    guchar *pos = vd->rgbbuf;
107    int i = vd->size;
108    while (i > 1)
109    {
110    *pos++ = r;
111    *pos++ = g;
112    *pos++ = b;
113    i -= 3;
114    }
115    }
116  */
117 
118 //////////////////////////////
119 //this is a timer; set vd->running to FALSE to exit
main_Render(gpointer data)120 gboolean main_Render (gpointer data)
121 {
122 #define DUR 300
123  static int toggle = 0;
124  if (NULL == data)
125   return TRUE;
126 
127  vulcan_Data *vd = (vulcan_Data *) data;
128  if (vd->size <= 0)
129  {
130   return TRUE;
131  }
132 
133  if (NULL != vd->BmpDest)
134  {
135   if (++toggle > DUR)
136   {
137    toggle = 0;
138   }
139 
140   vd->pixelfly = 0;
141   if (0 == vd->pixelfly)
142   {
143    if (!(7 & toggle))   //to just do followtheleader occasionally
144    {
145     //printf ("Toggles %d, %x\n", toggle, toggle);
146     LC_TargetFollowTheLeader ();
147    }
148    LC_LandscapeRollSkyFlyingObjects ();
149    if (0 != LC_AP.running)
150    {
151     LC_AutoPilot ((toggle > (DUR >> 1)) ? -1 : 1, 30);
152     vd->Turn = LC_AP.Turn;
153     vd->Lift = LC_AP.Lift;
154     //printf ("LC_Lift: %d, LC_Turn: %d\n", LC_Lift, LC_Turn);
155    }
156   }
157   else
158   {
159    //LC_ShowColorsBitmap ();
160    LC_PixelFly ();
161    if (10 > LC_Altitude)
162     LC_Altitude = 10;
163   }
164 
165   LC_Turn = vd->Turn >> 2;
166   LC_Tilt = (vd->height >> 1) + vd->Lift;
167   LC_Lift = (vd->Lift >> 4);
168 
169   if (0 != vd->pixelfly)
170   {
171    LC_Turn = -LC_Turn;
172   }
173 
174   LC_SetRoll ((LC_CircleRez >> 1) + (LC_Turn << 2));
175   LC_DoMovement ((0 == vd->pixelfly) ? 1 : 0);
176   gdk_window_invalidate_rect (vd->drawing_area->window, NULL, FALSE);
177  }
178 
179  return TRUE;
180 }
181 
182 //////////////////////////////
main_CleanupArrays(vulcan_Data * vd)183 void main_CleanupArrays (vulcan_Data * vd)
184 {
185  if (NULL == vd)
186   return;
187 
188  //Free background if we created it
189  if (NULL != vd->BmpDest)
190  {
191   //fprintf (stderr, "deleting old rgbbuf\n");
192   free (vd->BmpDest);
193   vd->BmpDest = NULL;
194  }
195 }
196 
197 //////////////////////////////
198 //this cleans up global main_VD and MakeLand and LandCaster resources
main_Cleanup()199 void main_Cleanup ()
200 {
201  LC_LandCaster_Cleanup ();
202  MakeLand_Cleanup ();
203  if (NULL != main_VD)
204  {
205   main_CleanupArrays (main_VD);
206   free (main_VD);
207   main_VD = NULL;       // have to set the real one
208  }
209 }
210 
211 //////////////////////////////
212 //called only from configure_event:
main_InitRenderer(vulcan_Data * vd)213 void main_InitRenderer (vulcan_Data * vd)
214 {
215  //init MakeLand:
216  /////////////////////////////
217  //creates the color and heights bitmap:
218  MakeLand_SeedRand (time (NULL), 0);
219  MakeLand_Init_InternalBitmaps (8);     //size is given as power of 2, since bitmap must be
220  MakeLand_Clear (MakeLand_bmpHeights, 0);
221  MakeLand_HeightsCreate ();
222  //MakeLand_TerrainCraters (8, MakeLand_Height>>5, 1, 0, 0, 0, 0, 0, 0, 7, -1);    //lava
223  //MakeLand_TerrainCraters (8, 512, 1, 8, 4, .08, 20, .3, 0, 10, -1);  //craters
224  MakeLand_TranslateHeightsToColors (256);
225  //MakeLand_ErosionFine (-400, -10, 4, 4, 3);
226  MakeLand_HeightsSmooth (2, 1);
227  MakeLand_HeightsBottomReference (0);
228  MakeLand_HeightsScaleMax (256 + 64);
229  MakeLand_HeightsSmooth (1, 1);
230  MakeLand_HeightsBottomReference (0);
231  MakeLand_ColorsBlur (3, 1, 1);
232  MakeLand_ColorsShade (20, 'u', 5, 3, 62);
233  MakeLand_Level (64);
234  //MakeLand_TerrainCraters (512, MakeLand_Height, 1, 0, 0, 0, 0, 0, 0, 7, -1);    //lava
235  //MakeLand_TerrainCraters (4096, 512, 1, 8, 4, .08, 20, .3, 0, 10, -1);  //craters
236  MakeLand_HeightsBottomReference (0);
237  //MakeLand_HeightsScaleMax (1);
238  MakeLand_ColorsRGBtoBGR ();
239 
240  //init LandCaster:
241 
242  LC_LandCaster_Initialize (vd->BmpDest,
243                            vd->width,
244                            vd->height,
245                            MakeLand_bmpHeights,
246                            MakeLand_Width,
247                            MakeLand_Height,
248                            MakeLand_bmpColors,
249                            MakeLand_Width, MakeLand_Height, 5, 8, 12);
250  // ColorsShade(pColors, pHeights, width, height, 10, 10, 1, 64, -32);
251  // ColorsShadow(pColors, pHeights, width, height,(M_PI*1)/4,10,-64,2);
252  //PrepareLC_BmpHeights(0xFF); // not necessary to call, just convenient
253  LC_SetCallbackFast (main_GameCallback);
254  LC_SetRoll (LC_CircleRez >> 1);
255  LC_Lift = -1;
256  LC_Altitude = 5;
257  LC_Tilt = vd->height >> 1;
258  //LC_SetNumberOfFlyingObjects (12);
259  //LC_SetLC_Raylength(2000);
260  LC_Turn = 0;
261  LC_Speed = 10;
262  main_NewGame (vd);
263 }
264 
265 //////////////////////////////////////////////////////////////////////
266 
267 ////////////////////////////////////
268 //quick way to put up a message:
main_messagebox(gchar * message)269 void main_messagebox (gchar * message)
270 {
271  GtkWidget *dialog;
272  dialog = gtk_message_dialog_new (NULL,
273                                   GTK_DIALOG_DESTROY_WITH_PARENT,
274                                   GTK_MESSAGE_INFO,
275                                   GTK_BUTTONS_CLOSE, "%s", message);
276  gtk_dialog_run (GTK_DIALOG (dialog));
277  gtk_widget_destroy (dialog);
278 }
279 
280 /////////////////////////////////////////////////////////////////////
main_HideFlyingObject(int id)281 void main_HideFlyingObject (int id)
282 {       //needed to make this because erasing Object is hard outside of this class
283  LC_FlyingObject[id].Visible = 0;
284  int pos = LC_FlyingObject[id].SizeY;
285  if (pos > 0)
286  {
287   do
288    LC_BmpFlyingObjects[LC_FlyingObject[id].pErase[--pos]] = 0;  //erase old positions
289   while (pos);
290  }
291  return;
292 }
293 
294 /////////////////////////////////////////////////////////////////////
295 //only counts visible targets
main_GetLiveTargetCount()296 int main_GetLiveTargetCount ()
297 {
298  int i,
299   j = 0;
300  for (i = LC_FlyingObjectCount - 1; i > 0; i--)
301  {
302   if (LC_FlyingObject[i].Type == LC_TARGET && LC_FlyingObject[i].Visible)
303    ++j;
304  }
305  // printf ("Flying Target Objects: %d\n", j);
306  return j;
307 }
308 
309 /*
310    //////////////////////////////////////////////
311    //THIS IS THE BEST ONE, but clock_gettime can't run on Windows
312    //20101109: Returns elapsed time since previous call. First call it
313    //returns 0.
314    //NOTE: used to use gettimeofday (&newtime, NULL), but this is better.
315    double main_Stopwatch_hirez ()
316    {
317    #define BILLION 1000000000L;
318    struct timespec newtime;
319    static struct timespec oldtime;
320    double result;
321 
322    if (clock_gettime (CLOCK_REALTIME, &newtime) == -1)
323    {
324    return 0;
325    }
326 
327    result = (newtime.tv_sec - oldtime.tv_sec)
328    + (double) (newtime.tv_nsec - oldtime.tv_nsec) / (double) BILLION;
329 
330    //deal with first-time call
331    if (0 == oldtime.tv_nsec && 0 == oldtime.tv_sec)
332    {
333    result = 0;
334    }
335 
336    oldtime.tv_sec = newtime.tv_sec;
337    oldtime.tv_nsec = newtime.tv_nsec;
338 
339    return result;
340    }
341  */
342 
343 //////////////////////////////////////////////
344 //20101129: Returns elapsed time since previous call. First call it
345 //returns 0.
346 //This version uses crappy time () so it will run on windows (and clock () is WAY too broken)
main_Stopwatch()347 double main_Stopwatch ()
348 {
349  static clock_t oldtime = 0;
350  clock_t newtime;
351  double result;
352  newtime = time (&newtime);
353 
354  result = (double) (newtime - oldtime);
355  //result = difftime(newtime, oldtime)/CLOCKS_PER_SEC;
356 
357  //deal with first-time call
358  if (0 == oldtime)
359  {
360   result = 0;
361  }
362 
363  oldtime = newtime;
364  return result;
365 }
366 
367 /////////////////////////
main_NewGame(vulcan_Data * vd)368 void main_NewGame (vulcan_Data * vd)
369 {
370  main_HideFlyingObject (0);
371  LC_SetNumberOfFlyingObjects (vd->GameObjects);
372  vd->GameTime = main_Stopwatch ();
373  vd->FireCount = 0;
374  LC_PositionX = LC_FlyingObject[1].PosX =
375   MakeLand_Rand () % (LC_BmpColors.w << 10);
376  LC_PositionY = LC_FlyingObject[1].PosY =
377   MakeLand_Rand () % (LC_BmpColors.h << 10);
378 }
379 
380 /////////////////////////////////////////////////////////////////////
main_GameCallback(int message)381 void main_GameCallback (int message)
382 {
383  /////////////////////////////////////////////////////////////////////
384  // GameMessages - LANDSCAPE'S way of sending fast messages
385  // from within game or rendering loops
386  /////////////////////////////////////////////////////////////////////
387  switch (message)
388  {
389  case LC_OBJECTHIT:
390   if (LC_FlyingObject[LC_UserData1].Type == LC_TARGET)  //was a target
391   {
392    main_HideFlyingObject (LC_UserData1);
393    LC_FlyingObject[LC_UserData1].Speed = 0;     //freeze the target
394    // UserCallback(VULCAN_HIT);
395 
396    //see if user won:
397    if (!main_GetLiveTargetCount ())
398    {
399     sprintf (main_msgstring,
400              "You destroyed %d targets with %d shots in %g seconds",
401              main_VD->GameObjects - 1, main_VD->FireCount, main_Stopwatch ());
402     main_messagebox (main_msgstring);
403     main_NewGame (main_VD);
404    }
405    return;
406   }
407 
408  case LC_GROUND:
409   // UserCallback(VULCAN_GROUND);
410   return;
411 
412  default:
413   return;
414  }
415 }
416 
417 //////////////////////////////
main_drawing_area_expose_event(GtkWidget * widget,GdkEventExpose * event,vulcan_Data * vd)418 gint main_drawing_area_expose_event (GtkWidget * widget,
419                                      GdkEventExpose * event, vulcan_Data * vd)
420 {
421  gdk_draw_rgb_32_image (widget->window,
422                         widget->style->fg_gc[GTK_STATE_NORMAL],
423                         0, 0, vd->width, vd->height,
424                         // GDK_RGB_DITHER_MAX,
425                         GDK_RGB_DITHER_NONE,
426                         (guchar *) (vd->BmpDest), vd->width << 2);
427 
428  /*
429     //20101202: disabled rgbbuf because changing LandCaster and MakeLand
430     //from ints proved nightmarish. Kept this as an example of how to do it:
431     //translate vd->BmpDest to vd->rgbbuf:
432     int x;
433     int y;
434     int y_index = 0;
435     int indexrgb = 0;              //(vd->rowstride)
436     int color;
437 
438     y = vd->width * vd->height;
439     for (x = 0; x < y; x++)
440     {
441     color = vd->BmpDest[x];
442     vd->rgbbuf[indexrgb++] = ((color >> 16) & 0xff);
443     vd->rgbbuf[indexrgb++] = ((color >> 8) & 0xff);
444     vd->rgbbuf[indexrgb++] = ((color >> 0) & 0xff);
445     }
446     gdk_draw_rgb_image (widget->window,
447     widget->style->fg_gc[GTK_STATE_NORMAL],
448     0,
449     0,
450     vd->width,
451     vd->height,
452     GDK_RGB_DITHER_NONE, vd->rgbbuf, vd->rowstride);
453   */
454  return FALSE;
455 }
456 
457 //////////////////////////////
main_drawing_area_button_press_event(GtkWidget * widget,GdkEventButton * event,vulcan_Data * vd)458 gint main_drawing_area_button_press_event (GtkWidget * widget,
459                                            GdkEventButton * event,
460                                            vulcan_Data * vd)
461 {
462  //Fire missile:
463  vd->FireCount++;
464  LC_FlyingObject[0].Visible = VULCAN_MISSILE_LIFE;      //gets it outta sight
465  LC_FlyingObject[0].PosX = LC_PositionX;        //position == mine
466  LC_FlyingObject[0].PosY = LC_PositionY;
467  LC_FlyingObject[0].Direction = LC_Direction;   //direction==mine
468  LC_FlyingObject[0].Alt = LC_Altitude;
469  LC_FlyingObject[0].Lift = LC_Lift << 1;        //takes my sink or rise once
470  return TRUE;
471 }
472 
473 //////////////////////////////
main_drawing_area_button_release_event(GtkWidget * widget,GdkEventButton * event,vulcan_Data * vd)474 gint main_drawing_area_button_release_event (GtkWidget * widget,
475                                              GdkEventButton * event,
476                                              vulcan_Data * vd)
477 {
478  //printf ("clock(): %d time: %g\n", (int) clock (), main_Stopwatch ());
479  return TRUE;
480 }
481 
482 //////////////////////////////
main_drawing_area_key_press_event(GtkWidget * widget,GdkEventKey * event,vulcan_Data * vd)483 gint main_drawing_area_key_press_event (GtkWidget * widget,
484                                         GdkEventKey * event, vulcan_Data * vd)
485 {
486  return TRUE;
487 }
488 
489 //////////////////////////////
main_drawing_area_key_release_event(GtkWidget * widget,GdkEventKey * event,vulcan_Data * vd)490 gint main_drawing_area_key_release_event (GtkWidget * widget,
491                                           GdkEventKey * event,
492                                           vulcan_Data * vd)
493 {
494  return TRUE;
495 }
496 
497 //////////////////////////////
main_drawing_area_motion_notify_event(GtkWidget * widget,GdkEventMotion * event,vulcan_Data * vd)498 gint main_drawing_area_motion_notify_event (GtkWidget * widget,
499                                             GdkEventMotion * event,
500                                             vulcan_Data * vd)
501 {
502  //get the coords of the mouse:
503  int x;
504  int y;
505  GdkModifierType state;
506 
507  if (event->is_hint)
508   gdk_window_get_pointer (event->window, &x, &y, &state);
509  else
510  {
511   x = (int) (event->x + .5);
512   y = (int) (event->y + .5);
513   state = (GdkModifierType) event->state;
514  }
515 
516  vd->Turn = (((vd->width) >> 1) - x);
517  vd->Lift = (((vd->height) >> 1) - y);
518 
519  return TRUE;
520 }
521 
522 //////////////////////////////
main_drawing_area_enter_notify_event(GtkWidget * widget,GdkEventCrossing * event,vulcan_Data * vd)523 gint main_drawing_area_enter_notify_event (GtkWidget * widget,
524                                            GdkEventCrossing * event,
525                                            vulcan_Data * vd)
526 {
527  LC_AP.running = 0;
528  return TRUE;
529 }
530 
531 //////////////////////////////
main_drawing_area_leave_notify_event(GtkWidget * widget,GdkEventCrossing * event,vulcan_Data * vd)532 gint main_drawing_area_leave_notify_event (GtkWidget * widget,
533                                            GdkEventCrossing * event,
534                                            vulcan_Data * vd)
535 {
536  LC_AP.running = 1;
537  return TRUE;
538 }
539 
540 //////////////////////////////
541 //THIS is where MakeLand and LandCaster get setup (cleaned if already existant)
main_drawing_area_configure_event(GtkWidget * widget,GdkEventConfigure * event,vulcan_Data * vd)542 gint main_drawing_area_configure_event (GtkWidget * widget,
543                                         GdkEventConfigure * event,
544                                         vulcan_Data * vd)
545 {
546  //kill GUI updating if here:
547  if (0 != vd->GUIUpdateHandle)
548  {
549   g_source_remove (vd->GUIUpdateHandle);
550   vd->GUIUpdateHandle = 0;
551  }
552 
553  //fprintf (stderr, "Got here %d\n", __LINE__);
554 
555  //make sure timer isn't doing anything illegal:
556  //erase any old rgb array:
557  main_CleanupArrays (vd);
558 
559  vd->width = widget->allocation.width;
560  vd->height = widget->allocation.height;
561  //fprintf (stderr, "Line %d: %d %d\n", __LINE__, vd->width, vd->height);
562 
563  vd->rowstride = 3 * vd->width;
564  vd->size = vd->rowstride * vd->height;
565  // vd->rgbbuf = (guchar *) malloc (vd->size * sizeof (guchar));
566  vd->BmpDest = (int *) malloc (vd->width * vd->height * sizeof (int));  //the main drawing surface
567 
568  //Setup Lanscape and Makeland:
569  main_InitRenderer (vd);
570  //setup the main GUI timer:
571  vd->GUIUpdateHandle =
572   g_timeout_add (1000 / VULCAN_FPS, main_Render, (gpointer) main_VD);
573 
574  return TRUE;
575 }
576 
577 //////////////////////////////
578 //this should ONLY be called with already cleaned vulcan_Data
main_Init(int WIDTH,int HEIGHT,int FPS)579 vulcan_Data *main_Init (int WIDTH, int HEIGHT, int FPS)
580 {
581  vulcan_Data *vd = (vulcan_Data *) malloc (sizeof (vulcan_Data));
582 
583  vd->GameObjects = VULCAN_TARGETS + 1;  //remember, object[0] is the missile
584  vd->GameTime = 0;
585  vd->FireCount = 0;
586  vd->pixelfly = 0;
587  vd->GUIUpdateHandle = 0;       //handle to the timer that updates the GUI
588  vd->width = WIDTH;
589  vd->height = HEIGHT;
590  vd->FPS = FPS;
591  vd->size = 0;  //gets set in configure_event
592  vd->rowstride = 0;     //gets set in configure_event
593  vd->BmpDest = NULL;    //gets set in configure_event
594  vd->drawing_area = gtk_drawing_area_new ();
595  gtk_widget_set_size_request (vd->drawing_area, WIDTH, HEIGHT);
596 
597  gtk_widget_add_events (GTK_WIDGET (vd->drawing_area),
598                         GDK_EXPOSURE_MASK | GDK_POINTER_MOTION_MASK |
599                         GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK |
600                         GDK_BUTTON_RELEASE_MASK | GDK_KEY_PRESS_MASK |
601                         GDK_KEY_RELEASE_MASK | GDK_ENTER_NOTIFY_MASK |
602                         GDK_LEAVE_NOTIFY_MASK);
603 
604  //now setup all the signals:
605  gtk_signal_connect (GTK_OBJECT (vd->drawing_area), "expose_event",
606                      (GtkSignalFunc) main_drawing_area_expose_event, vd);
607 
608  gtk_signal_connect (GTK_OBJECT (vd->drawing_area), "configure_event",
609                      (GtkSignalFunc) main_drawing_area_configure_event, vd);
610 
611  g_signal_connect (vd->drawing_area, "button_press_event",
612                    G_CALLBACK (main_drawing_area_button_press_event), vd);
613 
614  g_signal_connect (vd->drawing_area, "button_release_event",
615                    G_CALLBACK (main_drawing_area_button_release_event), vd);
616 
617  g_signal_connect (vd->drawing_area, "key_press_event",
618                    G_CALLBACK (main_drawing_area_key_press_event), vd);
619 
620  g_signal_connect (vd->drawing_area, "key_release_event",
621                    G_CALLBACK (main_drawing_area_key_release_event), vd);
622 
623  g_signal_connect (vd->drawing_area, "motion_notify_event",
624                    G_CALLBACK (main_drawing_area_motion_notify_event), vd);
625 
626  g_signal_connect (vd->drawing_area, "enter_notify_event",
627                    G_CALLBACK (main_drawing_area_enter_notify_event), vd);
628 
629  g_signal_connect (vd->drawing_area, "leave_notify_event",
630                    G_CALLBACK (main_drawing_area_leave_notify_event), vd);
631 
632  return vd;
633 }
634 
635 //////////////////////////////////
636 #ifdef GS_STANDALONE
main(int argc,char ** argv)637 int main (int argc, char **argv)
638 #else
639 int gnauralscape_main ()
640 #endif
641 {
642  GtkWidget *window;
643  GtkHBox *hbox;
644 
645  // initialize GTK+, create a window, attach handlers
646 #ifdef GS_STANDALONE
647  gtk_init (&argc, &argv);
648 #endif
649 
650  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
651  //gtk_window_fullscreen (GTK_WINDOW(window));
652 
653  // create a new HBox, pack the image and vboxes above
654  hbox = g_object_new (GTK_TYPE_HBOX, NULL);
655  // pack everything into the window, show everything, start GTK+ main loop
656  gtk_container_add (GTK_CONTAINER (window), GTK_WIDGET (hbox));
657 
658  // attach standard event handlers
659  g_signal_connect (window, "delete_event", G_CALLBACK (main_delete_event),
660                    NULL);
661  g_signal_connect (window, "destroy", G_CALLBACK (main_end_program), NULL);
662  gint w = 1,
663   h = 1;
664  gtk_window_resize (GTK_WINDOW (window), 512, 512);
665  gtk_window_get_size (GTK_WINDOW (window), &w, &h);
666  gtk_window_set_policy (GTK_WINDOW (window), TRUE, FALSE, FALSE);
667  main_VD = main_Init (w, h, VULCAN_FPS);
668 
669  //INIT MAKELAND AND LANSCAPE HERE:
670 
671  gtk_box_pack_start (GTK_BOX (hbox), GTK_WIDGET (main_VD->drawing_area), TRUE,
672                      TRUE, 0);
673  gtk_widget_show_all (GTK_WIDGET (window));
674 
675 #ifdef GS_STANDALONE
676  gtk_main ();
677 #endif
678  return 0;
679 }
680