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