9 // We use seconds for measuring time, meters for measuring distance
19 }TKeyBinding
;//TODO: s/int/real data type for a key
22 Vect Pos
; //where he is
23 Vect Move
; //how he want to move
24 Vect BSize
; //Size of bounding rect
25 Area
*Shape
; //how fat he is
26 //Area *TrShape; //translated Shape -- don't optimize yet
27 int Frags
; //no comment
29 double Speed
; //meters per second
30 int Orientation
; //1-up 2-left 3-down 4-right 0-down
31 int WannaShoot
; //1-want 0-don't want
32 double ReloadTime
; //time from last shot
33 int WannaDie
; //1-want suicide 2-died and still holding suicide 0-don't want
34 double AnimationTime
; //in seconds
46 int Exists
; // 0- doesn't exist 1-exists
56 Vect Vel
; //velocity i m/s
57 double Speed
; //for Templates
59 int lid
; //who shoot this bullet?
60 int Exists
; // 0- doesn't exist 1-exists
61 double SFuzzy
; // Fuzzy factor for spawning 0-1 :)
62 double VFuzzy
; // Fuzzy factor for traveling 0-1 :)
66 Area
**FArea
; //forbidden Area
67 int noFArea
; //no used FArea
73 Area
*BoundingArea
; // ALL OBJECTS MUST BE IN THIS POLY
74 double XX
,YY
; //margins for random placement
75 double X
,Y
; //left top corner MUST be != [0,0]
79 TMap
*Map
; //where we are playing
80 TLilanek
*Lilanek
; //our heroes-ehm bad guys
83 TWeapon
*Weapon
; //Weapons lying on floor
85 TWeapon
*WeaponTemplate
;
86 TBullet
*BulletTemplate
;
87 int noWID
; //biggest WID, also number of WeaponTemplates
90 double PWeapondrop
; // Probability of weapon drop per second
100 Orientations
[2].x
=-1;
111 int AreaInMap(TMap
*m
, Area
*p
){ //returns 0 if p collides with something in m otherwise 1
113 if(!AreaInAreaComp(m
->BoundingArea
, p
)){
116 for(i
=0; i
< m
->noLayer
; i
++){
117 for(j
=0; j
< m
->Layer
[i
]->noFArea
; j
++)
118 if(AreaInArea(p
, m
->Layer
[i
]->FArea
[j
]))
123 void SpawnLilanek(Game
*g
, int lid
){
132 for(tries
=0; tries
<1000; tries
++){ //TODO: remove exact number
133 Pos
.x
= RandD(0,g
->Map
->XX
);
134 Pos
.y
= RandD(0,g
->Map
->YY
);
136 tp
= TranslateArea(g
->Lilanek
[lid
].Shape
, &Pos
);
137 printf("%s\n", Area2String(tp
));
138 if(!AreaInMap(g
->Map
, tp
)){
142 for(olid
=0; olid
< g
->noLilaneks
; olid
++){
145 if(!g
->Lilanek
[olid
].Alive
){
148 oltp
= TranslateArea(g
->Lilanek
[olid
].Shape
, &g
->Lilanek
[olid
].Pos
);
149 if(AreaInArea(tp
, oltp
)){
159 g
->Lilanek
[lid
].Pos
.x
= Pos
.x
;
160 g
->Lilanek
[lid
].Pos
.y
= Pos
.y
;
161 g
->Lilanek
[lid
].Alive
= 1;
169 void DropWeapon(Game
*g
, int weapon
){
175 for(tries
=0; tries
<100; tries
++){ //TODO: remove exact number
176 Pos
.x
= RandD(0,g
->Map
->XX
);
177 Pos
.y
= RandD(0,g
->Map
->YY
);
178 WID
= RandI(0, g
->noWID
);
179 tp
= TranslateArea(g
->WeaponTemplate
[WID
].Shape
, &Pos
);
180 if(AreaInMap(g
->Map
, tp
)){
183 memcpy(&g
->Weapon
[weapon
], &g
->WeaponTemplate
[WID
], sizeof(TWeapon
));
184 g
->Weapon
[weapon
].Shape
= g
->WeaponTemplate
[WID
].Shape
;
185 g
->Weapon
[weapon
].Pos
.x
= Pos
.x
;
186 g
->Weapon
[weapon
].Pos
.y
= Pos
.y
;
187 g
->Weapon
[weapon
].WID
= WID
;
188 g
->Weapon
[weapon
].Exists
= 1;
196 void DropWeapons(Game
*g
, double dtime
){
200 if( RandD(0.0, 1.0) >= (g
->PWeapondrop
*dtime
))
202 for(i
=0; i
< g
->noWeapons
; i
++){
203 if(g
->Weapon
[i
].Exists
)continue; //we don't like teleporting weapons :)
205 printf("A Weapon drop!\n");
207 break; //spawn max one weapon per update
211 void WeaponPickedUp(Game
*g
, double dtime
, int lid
, int wid
){
215 l
= &g
->Lilanek
[lid
];
218 l
->Ammo
[w
->WID
] += w
->Ammo
;
219 if(l
->Ammo
[w
->WID
] > w
->MaxAmmo
)
220 l
->Ammo
[w
->WID
] = w
->MaxAmmo
;
221 printf("%d\n",l
->Ammo
[w
->WID
]);
222 l
->ActiveWeapon
= w
->WID
;
223 printf("%d\n",l
->ActiveWeapon
);
229 void PickUpWeapons(Game
*g
, double dtime
){
233 for(lid
=0; lid
<g
->noLilaneks
; lid
++){
234 LArea
= TranslateArea(g
->Lilanek
[lid
].Shape
, &g
->Lilanek
[lid
].Pos
);
235 for(wid
=0; wid
< g
->noWeapons
; wid
++){
236 if(!g
->Weapon
[wid
].Exists
)
238 WArea
= TranslateArea(g
->Weapon
[wid
].Shape
, &g
->Weapon
[wid
].Pos
);
239 if(!AreaInArea( WArea
, LArea
)){
243 WeaponPickedUp(g
, dtime
, lid
, wid
);
250 void BulletExplodes(Game
*g
, int i
){
251 g
->Bullet
[i
].Exists
=0;
255 void MoveBullet(Game
*g
, double dtime
, int i
){
257 ff
= g
->Bullet
[i
].Speed
*g
->Bullet
[i
].VFuzzy
;
258 g
->Bullet
[i
].Pos
.x
+= (g
->Bullet
[i
].Vel
.x
+= RandD(-ff
,ff
))* dtime
;
259 g
->Bullet
[i
].Pos
.y
+= (g
->Bullet
[i
].Vel
.y
+= RandD(-ff
,ff
))* dtime
;
262 void CollideBulletMap(Game
*g
, double dtime
, int i
){
265 p
=TranslateArea(g
->Bullet
[i
].Shape
, &g
->Bullet
[i
].Pos
);
266 if(AreaInMap(g
->Map
, p
)==0)
267 BulletExplodes(g
, i
);
270 void LilanekKilled(Game
*g
, double dtime
, int BulletID
, int LilanekID
){
271 g
->Bullet
[BulletID
].Exists
= 0;
272 g
->Lilanek
[LilanekID
].Deaths
++;
273 g
->Lilanek
[g
->Bullet
[BulletID
].lid
].Frags
++;
274 SpawnLilanek(g
, LilanekID
);
277 void CollideBulletLilanek(Game
*g
, double dtime
, int BulletID
){
281 BArea
=TranslateArea(g
->Bullet
[BulletID
].Shape
, &g
->Bullet
[BulletID
].Pos
);
282 for(LilanekID
=0; LilanekID
<g
->noLilaneks
; LilanekID
++){
283 LArea
=TranslateArea(g
->Lilanek
[LilanekID
].Shape
, &g
->Lilanek
[LilanekID
].Pos
);
284 if(AreaInArea(LArea
,BArea
))
285 LilanekKilled(g
, dtime
, BulletID
, LilanekID
);
293 void UpdateBullets(Game
*g
, double dtime
){
295 for(BulletID
=0; BulletID
<g
->noBullets
; BulletID
++){
296 if(g
->Bullet
[BulletID
].Exists
==0)
297 continue; //We won't update non-existending bullets
298 MoveBullet(g
, dtime
, BulletID
);
299 CollideBulletMap(g
, dtime
, BulletID
);
300 CollideBulletLilanek(g
, dtime
, BulletID
);
304 int CheckLilanekvsLilaneks(Game
*g
, Area
*a
, int LilanekID
){ //returns 0 if he collides with others, 1 if it's OK to move there
310 for(i
=0; i
<g
->noLilaneks
&& rval
==1; i
++){
313 nb
= TranslateArea(g
->Lilanek
[i
].Shape
, &g
->Lilanek
[i
].Pos
);
314 if(AreaInArea(nb
, a
))
322 void MoveLilaneks(Game
*g
, double dtime
){
329 for(i
=0; i
<g
->noLilaneks
; i
++){
330 //skip this Lilanek if he doesn't wanna move
331 if(g
->Lilanek
[i
].Move
.x
== 0.0 && g
->Lilanek
[i
].Move
.y
== 0.0)
333 for(dt
=dtime
, steps
=0; steps
<4; dt
/=2.0, steps
++){ //TODO: get rid of exact number
335 va
.x
= g
->Lilanek
[i
].Pos
.x
+ dt
*g
->Lilanek
[i
].Move
.x
;
336 va
.y
= g
->Lilanek
[i
].Pos
.y
+ dt
*g
->Lilanek
[i
].Move
.y
;
337 FreeArea(pa
); //we don't want memory leaks
338 pa
= TranslateArea(g
->Lilanek
[i
].Shape
, &va
);
339 //check for collision with map
340 if(AreaInMap(g
->Map
, pa
)==0)
341 continue; //try smaller dt if he collided with map
342 //check for collision with other Lilaneks
343 if(CheckLilanekvsLilaneks(g
, pa
, i
)==0)
345 //move him if we got here
346 g
->Lilanek
[i
].Pos
.x
+= dt
*g
->Lilanek
[i
].Move
.x
;
347 g
->Lilanek
[i
].Pos
.y
+= dt
*g
->Lilanek
[i
].Move
.y
;
351 FreeArea(pa
); //For sure
356 void ParseInput(Game
*g
, double dtime
){
362 keystate
= SDL_GetKeyState(NULL
);
364 for(i
=0; i
< g
->noLilaneks
; i
++){
365 curlil
= &g
->Lilanek
[i
];
368 if(keystate
[curlil
->Keys
.Up
]){
369 curlil
->Orientation
= 1;
370 curlil
->Move
.x
= curlil
->Speed
* Orientations
[1].x
;
371 curlil
->Move
.y
= curlil
->Speed
* Orientations
[1].y
;
375 if(keystate
[curlil
->Keys
.Down
]){
376 curlil
->Orientation
= 3;
377 curlil
->Move
.x
= curlil
->Speed
* Orientations
[3].x
;
378 curlil
->Move
.y
= curlil
->Speed
* Orientations
[3].y
;
382 if(keystate
[curlil
->Keys
.Left
]){
383 curlil
->Orientation
= 2;
384 curlil
->Move
.x
= curlil
->Speed
* Orientations
[2].x
;
385 curlil
->Move
.y
= curlil
->Speed
* Orientations
[2].y
;
389 if(keystate
[curlil
->Keys
.Right
]){
390 curlil
->Orientation
= 4;
391 curlil
->Move
.x
= curlil
->Speed
* Orientations
[4].x
;
392 curlil
->Move
.y
= curlil
->Speed
* Orientations
[4].y
;
401 if(keystate
[curlil
->Keys
.Shoot
]){
402 curlil
->WannaShoot
= 1;
404 curlil
->WannaShoot
= 0;
407 if(keystate
[curlil
->Keys
.Suicide
]){
408 if(curlil
->WannaDie
!= 2){
409 curlil
->WannaDie
= 1;
412 curlil
->WannaDie
= 0;
416 void SpawnBullet(Game
*g
, double dtime
, int lid
, int bid
){
421 LArea
= TranslateArea(g
->Lilanek
[lid
].Shape
, &g
->Lilanek
[lid
]. Pos
);
423 bt
= &g
->BulletTemplate
[g
->Lilanek
[lid
].ActiveWeapon
];
424 memcpy (b
, bt
, sizeof(TBullet
));
426 b
->Pos
.x
= g
->Lilanek
[lid
].Pos
.x
+g
->Lilanek
[lid
].BSize
.x
*0.5; //TODO: remove these magic constants
427 b
->Pos
.y
= g
->Lilanek
[lid
].Pos
.y
+g
->Lilanek
[lid
].BSize
.y
*0.5;
428 b
->Vel
.x
= Orientations
[g
->Lilanek
[lid
].Orientation
].x
* b
->Speed
+RandD(-b
->Speed
*b
->SFuzzy
, b
->Speed
*b
->SFuzzy
);
429 b
->Vel
.y
= Orientations
[g
->Lilanek
[lid
].Orientation
].y
* b
->Speed
+RandD(-b
->Speed
*b
->SFuzzy
, b
->Speed
*b
->SFuzzy
);
432 BArea
= TranslateArea(b
->Shape
, &b
->Pos
);
433 if(!AreaInArea(BArea
, LArea
))
435 b
->Pos
.x
+= b
->Vel
.x
* dtime
*0.5;
436 b
->Pos
.y
+= b
->Vel
.y
* dtime
*0.5;
441 void Shoot(Game
*g
, double dtime
, int lid
){
445 for(i
=0; i
<g
->WeaponTemplate
[g
->Lilanek
[lid
].ActiveWeapon
].Burst
; i
++){
446 if(g
->Lilanek
[lid
].Ammo
[g
->Lilanek
[lid
].ActiveWeapon
] == 0)
448 for(bid
=0; bid
<g
->noBullets
; bid
++){
449 if(g
->Bullet
[bid
].Exists
)
451 SpawnBullet(g
, dtime
, lid
, bid
);
452 g
->Lilanek
[lid
].Ammo
[g
->Lilanek
[lid
].ActiveWeapon
]--;
453 g
->Lilanek
[lid
].ReloadTime
= 0;
459 void SwitchNextWeapon(Game
*g
, int lid
){
463 void ShootIfTheyWantTo(Game
*g
, double dtime
){
466 for(lid
=0; lid
<g
->noLilaneks
; lid
++){
467 //if(!g->Lilanek[lid].Exists)
469 if(g
->Lilanek
[lid
].Ammo
[g
->Lilanek
[lid
].ActiveWeapon
] == 0)
470 SwitchNextWeapon(g
,lid
);
472 if(g
->Lilanek
[lid
].ReloadTime
< g
->WeaponTemplate
[g
->Lilanek
[lid
].ActiveWeapon
].ReloadTime
){
473 g
->Lilanek
[lid
].ReloadTime
+= dtime
;
475 if(!g
->Lilanek
[lid
].WannaShoot
)
477 Shoot(g
, dtime
, lid
);
482 int UpdateLogic(Game
*g
,double dtime
){
483 DropWeapons(g
, dtime
);
484 UpdateBullets(g
, dtime
);
485 ParseInput(g
, dtime
);
486 MoveLilaneks(g
, dtime
);
487 PickUpWeapons(g
, dtime
);
488 ShootIfTheyWantTo(g
, dtime
);
489 return 0; //TODO: return something useful
492 Game
*testgame(){ //return testing game, function for use before we have some menu/loading mechanism
496 double sq2
= 1/sqrt(2.0);
498 Config conf
= GetConfig();
500 g
= malloc(sizeof(Game
));
501 g
->Map
= malloc(sizeof(TMap
));
503 g
->Map
->Layer
= malloc(sizeof(TMapLayer
*)*g
->Map
->noLayer
);
504 g
->Map
->Layer
[0] = malloc(sizeof(TMapLayer
));
505 g
->Map
->Layer
[0]->noFArea
= 2;
506 g
->Map
->Layer
[0]->FArea
= malloc(sizeof(Area
*) * g
->Map
->Layer
[0]->noFArea
);
507 p
= NewRect(4,2,3,3);
511 g
->Map
->Layer
[0]->FArea
[0] = a
;
514 AddToPolyXY(p
, 11,9);
515 AddToPolyXY(p
, 9,11);
520 g
->Map
->Layer
[0]->FArea
[1] = a
;
521 p
= NewRect(1,1,20,15);
525 g
->Map
->BoundingArea
= a
;
532 g
->Weapon
= malloc(sizeof(TWeapon
) * g
->noWeapons
);
534 fprintf(stderr
, "Cannot allocate memory for Weapons\n");
536 for(i
=0; i
<g
->noWeapons
; i
++){
537 g
->Weapon
[i
].Exists
= 0;
538 g
->Weapon
[i
].Shape
= 0;
542 g
->WeaponTemplate
= malloc(sizeof(TWeapon
)*g
->noWID
);
543 p
= NewRect(0,0,0.5,0.5);
547 g
->WeaponTemplate
[0].Shape
= a
;
548 g
->WeaponTemplate
[0].WID
= 0;
549 g
->WeaponTemplate
[0].Exists
= 1;
550 g
->WeaponTemplate
[0].Ammo
= 50;
551 g
->WeaponTemplate
[0].MaxAmmo
= 150;
552 g
->WeaponTemplate
[0].ReloadTime
= 0.2;
553 g
->WeaponTemplate
[0].Burst
= 24;
556 g
->Lilanek
= malloc(sizeof(TLilanek
) * g
->noLilaneks
);
557 g
->Lilanek
[1].Alive
= 0;
558 g
->Lilanek
[0].BSize
.x
= 1;
559 g
->Lilanek
[0].BSize
.y
= 1;
560 //g->Lilanek[0].Shape = NewRect(0.6,0.2,0.8,1.6);
562 AddToPolyXY(p
, 1, 0);
563 AddToPolyXY(p
, 1.4, 0.2);
564 AddToPolyXY(p
, 1.66, 1.38);
565 AddToPolyXY(p
, 1.42, 2);
566 AddToPolyXY(p
, 0.6, 2);
567 AddToPolyXY(p
, 0.4, 1.46);
568 AddToPolyXY(p
, 0.66, 0.2);
569 MultiplyPoly(p
, 0.5*g
->Lilanek
[0].BSize
.x
, 0.5*g
->Lilanek
[0].BSize
.y
);
573 g
->Lilanek
[0].Shape
= a
;
574 g
->Lilanek
[0].Pos
.x
= 12;
575 g
->Lilanek
[0].Pos
.y
= 4;
576 g
->Lilanek
[0].Speed
= 4;
577 g
->Lilanek
[0].Alive
= 0;
578 g
->Lilanek
[0].Keys
.Up
= conf
.pl1_key_up
;
579 g
->Lilanek
[0].Keys
.Down
= conf
.pl1_key_down
;
580 g
->Lilanek
[0].Keys
.Left
= conf
.pl1_key_left
;
581 g
->Lilanek
[0].Keys
.Right
= conf
.pl1_key_right
;
582 g
->Lilanek
[0].Keys
.Shoot
= conf
.pl1_key_fire
;
583 g
->Lilanek
[0].Keys
.Suicide
= conf
.pl1_key_suicide
;
584 g
->Lilanek
[0].Ammo
= malloc(sizeof(int)*g
->noWID
);
585 for(i
=0; i
<g
->noWID
; i
++){
586 g
->Lilanek
[0].Ammo
[i
] = 0;
588 g
->Lilanek
[0].ActiveWeapon
= 0;
593 p
= g
->Lilanek
[0].Shape
->p
[0];
596 g
->Lilanek
[1].Shape
= a
;
597 g
->Lilanek
[1].BSize
.x
= g
->Lilanek
[0].BSize
.x
;
598 g
->Lilanek
[1].BSize
.y
= g
->Lilanek
[0].BSize
.y
;
599 g
->Lilanek
[1].Pos
.x
= 14;
600 g
->Lilanek
[1].Pos
.y
= 4;
601 g
->Lilanek
[1].Speed
= 4;
602 g
->Lilanek
[1].Alive
= 0;
603 g
->Lilanek
[1].Keys
.Up
= conf
.pl2_key_up
;
604 g
->Lilanek
[1].Keys
.Down
= conf
.pl2_key_down
;
605 g
->Lilanek
[1].Keys
.Left
= conf
.pl2_key_left
;
606 g
->Lilanek
[1].Keys
.Right
= conf
.pl2_key_right
;
607 g
->Lilanek
[1].Keys
.Shoot
= conf
.pl2_key_fire
;
608 g
->Lilanek
[1].Keys
.Suicide
= conf
.pl2_key_suicide
;
609 g
->Lilanek
[1].Ammo
= malloc(sizeof(int)*g
->noWID
);
610 for(i
=0; i
<g
->noWID
; i
++){
611 g
->Lilanek
[1].Ammo
[i
] = 0;
613 g
->Lilanek
[1].ActiveWeapon
= 0;
616 g
->BulletTemplate
= malloc(sizeof(TBullet
) * g
->noWID
);
617 p
= NewRect(0,0,0.1,0.1);
621 g
->BulletTemplate
[0].Shape
= a
;
622 g
->BulletTemplate
[0].WID
= 0;
623 g
->BulletTemplate
[0].Speed
= 20;
624 g
->BulletTemplate
[0].SFuzzy
= 0.20;
625 g
->BulletTemplate
[0].VFuzzy
= 0.15;
628 g
->Bullet
= malloc(sizeof(TBullet
) * g
->noBullets
);
629 for(i
=0; i
<g
->noBullets
; i
++){
630 g
->Bullet
[i
].Exists
= 0;
631 g
->Bullet
[i
].Shape
= 0;
634 g
->PWeapondrop
= 0.4;
653 Uint32
callback_fps(Uint32 interval
, void *param
)
656 event
.type
= SDL_USEREVENT
;
657 SDL_PushEvent(&event
);
665 QueueDrawSprite(bg
, 0.0, 0.0,0.0);
666 QueueDrawSprite(prek1
, 3.0, 1.0,0.0);
667 QueueDrawSprite(prek2
, 6.0, 6.0,0.0);
669 QueueDrawSprite(lil
[g
->Lilanek
[0].Orientation
], g
->Lilanek
[0].Pos
.x
-1.0, g
->Lilanek
[0].Pos
.y
-1.0, 1);
670 QueueDrawSprite(lil
[g
->Lilanek
[1].Orientation
], g
->Lilanek
[1].Pos
.x
-1.0, g
->Lilanek
[1].Pos
.y
-1.0, 1);
672 for(i
=0; i
< g
->noWeapons
; i
++)
673 if(g
->Weapon
[i
].Exists
)
674 QueueDrawSprite(kul
, g
->Weapon
[i
].Pos
.x
- 1.0, g
->Weapon
[i
].Pos
.y
- 1.0,0.0);
676 for(i
=0; i
< g
->noBullets
; i
++)
677 if(g
->Bullet
[i
].Exists
)
678 QueueDrawSprite(kulka
, g
->Bullet
[i
].Pos
.x
- 1.0, g
->Bullet
[i
].Pos
.y
- 1.0,0.0);
682 int InitAll(Game
**g
){
686 //TODO: odstranit SaveConfig... je to tu jenom kvuli debugovani
689 if (SDL_Init(SDL_INIT_VIDEO
| SDL_INIT_TIMER
) < 0) {
690 fprintf(stderr
, "Unable to init SDL: %s\n", SDL_GetError());
698 prek1
= LoadSpriteSVG("graphics/prek1.svg", 3.0, 3.0);
699 prek2
= LoadSpriteSVG("graphics/prek2.svg", 4.0, 4.0);
700 lil
[0] = LoadSpriteSVG("graphics/lil.svg", 1.0, 1.0);
701 lil
[1] = LoadSpriteSVG("graphics/lilb.svg", 1.0, 1.0);
702 lil
[2] = LoadSpriteSVG("graphics/lill.svg", 1.0, 1.0);
703 lil
[3] = LoadSpriteSVG("graphics/lil.svg", 1.0, 1.0);
704 lil
[4] = LoadSpriteSVG("graphics/lilr.svg", 1.0, 1.0);
706 bg
= LoadSpriteSVG("graphics/bg.svg", 20.0, 15.0);
707 kul
= LoadSpriteSVG("graphics/kul.svg", 0.5, 0.5);
708 kulka
= LoadSpriteSVG("graphics/kulka.svg", 0.1, 0.1);
710 SDL_AddTimer(1000, callback_fps
, NULL
);
715 int GameLoop(Game
*g
){
718 double lasttime
, dtime
;
720 lasttime
= SDL_GetTicks()*0.001;
722 while (SDL_PollEvent(&event
)) {
723 switch (event
.type
) {
725 if (event
.key
.keysym
.sym
== SDLK_q
) {
734 case SDL_VIDEORESIZE
:
735 /* Resize the screen and redraw */
737 conf
.screen_width
=event
.resize
.w
;
738 conf
.screen_height
=event
.resize
.h
;
745 printf("%d frames\n",frames
);
753 dtime
= SDL_GetTicks()*0.001-lasttime
;
759 UpdateLogic(g
, dtime
*0.5);
760 UpdateLogic(g
, dtime
*0.5);
765 //we don't want to waste cpu...
773 int main(int argc
, char **argv
){