Refactoring
[Lilanci.git] / ebulanci.c
blobc6fc70e27b2459768d89ddc95128084e9fa4f5d0
1 #include <math.h>
2 #include <time.h>
3 #include "geometry.h"
4 #include "util.h"
5 #include "config.h"
6 #include "gr.h"
7 #include "map.h"
9 //typedef int Uint8;
10 // We use seconds for measuring time, meters for measuring distance
13 typedef struct{
14 int Up;
15 int Down;
16 int Left;
17 int Right;
18 int Shoot;
19 int Suicide;
20 int Switch;
21 }TKeyBinding;//TODO: s/int/real data type for a key
23 typedef struct{
24 Vect Pos; //where he is
25 Vect Move; //how he want to move
26 Vect BSize; //Size of bounding rect
27 Area *Shape; //how fat he is
28 //Area *TrShape; //translated Shape -- don't optimize yet
29 int Frags; //no comment
30 int Deaths; //R.I.P.
31 double Speed; //meters per second
32 int Orientation; //1-up 2-left 3-down 4-right 0-down
33 int WannaShoot; //1-want 0-don't want
34 double ReloadTime; //time from last shot
35 int WannaDie; //1-want suicide 2-died and still holding suicide 0-don't want
36 double AnimationTime; //in seconds
37 TKeyBinding Keys;
38 int *Ammo;
39 int ActiveWeapon;
40 int SwitchLock;
41 int Alive;
42 }TLilanek;
45 typedef struct{
46 Vect Pos;
47 Area *Shape;
48 int WID; //Weapon ID
49 int Exists; // 0- doesn't exist 1-exists
50 int Ammo;
51 int MaxAmmo;
52 int Burst;
53 double ReloadTime;
54 }TWeapon;
56 typedef struct{
57 Vect Pos;
58 Area *Shape;
59 Vect Vel; //velocity i m/s
60 double Speed; //for Templates
61 int WID; //Weapon ID
62 int lid; //who shoot this bullet?
63 int Exists; // 0- doesn't exist 1-exists
64 double SFuzzy; // Fuzzy factor for spawning 0-1 :)
65 double VFuzzy; // Fuzzy factor for traveling 0-1 :)
66 }TBullet;
69 typedef struct{
70 TMap *Map; //where we are playing
71 TLilanek *Lilanek; //our heroes-ehm bad guys
72 int noLilaneks;
74 TWeapon *Weapon; //Weapons lying on floor
75 int noWeapons;
76 TWeapon *WeaponTemplate;
77 TBullet *BulletTemplate;
78 int noWID; //biggest WID, also number of WeaponTemplates
79 TBullet *Bullet;
80 int noBullets;
81 double PWeapondrop; // Probability of weapon drop per second
82 }Game;
84 Vect Orientations[5];
86 void SwitchNextWeapon(Game *g, int lid);
88 int InitBase(){
89 Orientations[0].x=0;
90 Orientations[0].y=0;
91 Orientations[1].x=0;
92 Orientations[1].y=-1;
93 Orientations[2].x=-1;
94 Orientations[2].y=0;
95 Orientations[3].x=0;
96 Orientations[3].y=1;
97 Orientations[4].x=1;
98 Orientations[4].y=0;
99 //TODO: write code
101 return 0;
104 void SpawnLilanek(Game *g, int lid){
105 Vect Pos;
106 int tries;
107 Area *tp, *oltp;
108 int good;
109 int olid;
111 oltp = 0;
112 tp = 0;
113 for(tries=0; tries <1000; tries++){ //TODO: remove exact number
114 Pos.x = RandD(0,g->Map->XX);
115 Pos.y = RandD(0,g->Map->YY);
116 good=1;
117 tp = TranslateArea(g->Lilanek[lid].Shape, &Pos);
118 printf("%s\n", Area2String(tp));
119 if(!AreaInMap(g->Map, tp,0,1)){
120 good=0;
123 for(olid=0; olid < g->noLilaneks; olid++){
124 if(olid == lid)
125 continue;
126 if(!g->Lilanek[olid].Alive){
127 continue;
129 oltp = TranslateArea(g->Lilanek[olid].Shape, &g->Lilanek[olid].Pos);
130 if(AreaInArea(tp, oltp)){
131 good=0;
133 FreeArea(oltp);
134 oltp = 0;
137 if(good){
138 FreeArea(tp);
139 tp=0;
140 g->Lilanek[lid].Pos.x = Pos.x;
141 g->Lilanek[lid].Pos.y = Pos.y;
142 g->Lilanek[lid].Alive = 1;
143 break;
145 FreeArea(tp);
146 tp=0;
150 void DropWeapon(Game *g, int weapon){
151 Vect Pos;
152 int tries;
153 int WID;
154 Area *tp;
156 for(tries=0; tries <100; tries++){ //TODO: remove exact number
157 Pos.x = RandD(0,g->Map->XX);
158 Pos.y = RandD(0,g->Map->YY);
159 WID = RandI(0, g->noWID);
160 tp = TranslateArea(g->WeaponTemplate[WID].Shape, &Pos);
161 if(AreaInMap(g->Map, tp, 0, g->Map->noLayer)){
162 FreeArea(tp);
163 tp=0;
164 memcpy(&g->Weapon[weapon], &g->WeaponTemplate[WID], sizeof(TWeapon));
165 g->Weapon[weapon].Shape = g->WeaponTemplate[WID].Shape;
166 g->Weapon[weapon].Pos.x = Pos.x;
167 g->Weapon[weapon].Pos.y = Pos.y;
168 g->Weapon[weapon].WID = WID;
169 g->Weapon[weapon].Exists = 1;
170 break;
172 FreeArea(tp);
173 tp=0;
177 void DropWeapons(Game *g, double dtime){
178 int i;
179 double r;
181 if( RandD(0.0, 1.0) >= (g->PWeapondrop*dtime))
182 return;
183 for(i=0; i < g->noWeapons; i++){
184 if(g->Weapon[i].Exists)continue; //we don't like teleporting weapons :)
186 printf("A Weapon drop!\n");
187 DropWeapon(g, i);
188 break; //spawn max one weapon per update
192 void WeaponPickedUp(Game *g, double dtime, int lid, int wid){
193 TLilanek *l;
194 TWeapon *w;
196 l = &g->Lilanek[lid];
197 w = &g->Weapon[wid];
199 l->Ammo[w->WID] += w->Ammo;
200 if(l->Ammo[w->WID] > w->MaxAmmo)
201 l->Ammo[w->WID] = w->MaxAmmo;
202 printf("Ammo: %d\n",l->Ammo[w->WID]);
203 l->ActiveWeapon = w->WID;
204 printf("AW: %d\n",l->ActiveWeapon);
206 w->Exists = 0;
207 //TODO: sound effect
210 void PickUpWeapons(Game *g, double dtime){
211 int lid,wid;
212 Area *WArea, *LArea;
214 for(lid=0; lid<g->noLilaneks; lid++){
215 LArea = TranslateArea(g->Lilanek[lid].Shape, &g->Lilanek[lid].Pos);
216 for(wid=0; wid < g->noWeapons; wid++){
217 if(!g->Weapon[wid].Exists)
218 continue;
219 WArea = TranslateArea(g->Weapon[wid].Shape, &g->Weapon[wid].Pos);
220 if(!AreaInArea( WArea, LArea)){
221 FreeArea(WArea);
222 continue;
224 WeaponPickedUp(g, dtime, lid, wid);
225 FreeArea(WArea);
227 FreeArea(LArea);
231 void BulletExplodes(Game *g, int i){
232 g->Bullet[i].Exists=0;
233 //TODO: some effects
236 void MoveBullet(Game *g, double dtime, int i){
237 double ff;
238 ff= g->Bullet[i].Speed*g->Bullet[i].VFuzzy;
239 g->Bullet[i].Pos.x += (g->Bullet[i].Vel.x += RandD(-ff,ff))* dtime;
240 g->Bullet[i].Pos.y += (g->Bullet[i].Vel.y += RandD(-ff,ff))* dtime;
243 void CollideBulletMap(Game *g, double dtime, int i){
244 Area *p;
246 p=TranslateArea(g->Bullet[i].Shape, &g->Bullet[i].Pos);
247 if(AreaInMap(g->Map, p, 1,1)==0)
248 BulletExplodes(g, i);
249 FreeArea(p);
251 void LilanekKilled(Game *g, double dtime, int BulletID, int LilanekID){
252 g->Bullet[BulletID].Exists = 0;
253 g->Lilanek[LilanekID].Deaths ++;
254 g->Lilanek[g->Bullet[BulletID].lid].Frags ++;
255 SpawnLilanek(g, LilanekID);
258 void CollideBulletLilanek(Game *g, double dtime, int BulletID){
259 Area *BArea, *LArea;
260 int LilanekID;
262 BArea=TranslateArea(g->Bullet[BulletID].Shape, &g->Bullet[BulletID].Pos);
263 for(LilanekID=0; LilanekID<g->noLilaneks; LilanekID++){
264 LArea=TranslateArea(g->Lilanek[LilanekID].Shape, &g->Lilanek[LilanekID].Pos);
265 if(AreaInArea(LArea,BArea))
266 LilanekKilled(g, dtime, BulletID, LilanekID);
267 FreeArea(LArea);
268 LArea=0;
270 FreeArea(BArea);
271 BArea=0;
274 void UpdateBullets(Game *g, double dtime){
275 int BulletID;
276 for(BulletID=0; BulletID<g->noBullets; BulletID++){
277 if(g->Bullet[BulletID].Exists==0)
278 continue; //We won't update non-existending bullets
279 MoveBullet(g, dtime, BulletID);
280 CollideBulletMap(g, dtime, BulletID);
281 CollideBulletLilanek(g, dtime, BulletID);
285 int CheckLilanekvsLilaneks(Game *g, Area *a, int LilanekID){ //returns 0 if he collides with others, 1 if it's OK to move there
286 int i;
287 Area *nb;
288 int rval=1;
290 nb=0;
291 for(i=0; i<g->noLilaneks && rval==1; i++){
292 if(i==LilanekID)
293 continue;
294 nb = TranslateArea(g->Lilanek[i].Shape, &g->Lilanek[i].Pos);
295 if(AreaInArea(nb, a))
296 rval=0;
297 FreeArea(nb);
298 nb=0;
300 return rval;
303 void MoveLilaneks(Game *g, double dtime){
304 int i, steps;
305 Area *pa;
306 Vect va;
307 double dt;
309 pa=0;
310 for(i=0; i<g->noLilaneks; i++){
311 //skip this Lilanek if he doesn't wanna move
312 if(g->Lilanek[i].Move.x == 0.0 && g->Lilanek[i].Move.y == 0.0)
313 continue;
314 for(dt=dtime, steps=0; steps<4; dt/=2.0, steps++){ //TODO: get rid of exact number
315 //make future Area
316 va.x = g->Lilanek[i].Pos.x + dt*g->Lilanek[i].Move.x;
317 va.y = g->Lilanek[i].Pos.y + dt*g->Lilanek[i].Move.y;
318 FreeArea(pa); //we don't want memory leaks
319 pa = TranslateArea(g->Lilanek[i].Shape, &va);
320 //check for collision with map
321 if(AreaInMap(g->Map, pa, 0, 1)==0)
322 continue; //try smaller dt if he collided with map
323 //check for collision with other Lilaneks
324 if(CheckLilanekvsLilaneks(g, pa, i)==0)
325 continue;
326 //move him if we got here
327 g->Lilanek[i].Pos.x += dt*g->Lilanek[i].Move.x;
328 g->Lilanek[i].Pos.y += dt*g->Lilanek[i].Move.y;
329 FreeArea(pa);
330 pa=0;
332 FreeArea(pa); //For sure
333 pa=0;
337 void ParseInput(Game *g, double dtime){
338 int i;
339 Uint8 *keystate;
340 TLilanek *curlil;
341 int wannamove;
343 keystate = SDL_GetKeyState(NULL);
345 for(i=0; i< g->noLilaneks; i++){
346 curlil = &g->Lilanek[i];
347 wannamove=0;
348 // Up;
349 if(keystate[curlil->Keys.Up]){
350 curlil->Orientation = 1;
351 curlil->Move.x = curlil->Speed * Orientations[1].x;
352 curlil->Move.y = curlil->Speed * Orientations[1].y;
353 wannamove=1;
355 // Down;
356 if(keystate[curlil->Keys.Down]){
357 curlil->Orientation = 3;
358 curlil->Move.x = curlil->Speed * Orientations[3].x;
359 curlil->Move.y = curlil->Speed * Orientations[3].y;
360 wannamove=1;
362 // Left;
363 if(keystate[curlil->Keys.Left]){
364 curlil->Orientation = 2;
365 curlil->Move.x = curlil->Speed * Orientations[2].x;
366 curlil->Move.y = curlil->Speed * Orientations[2].y;
367 wannamove=1;
369 // Right;
370 if(keystate[curlil->Keys.Right]){
371 curlil->Orientation = 4;
372 curlil->Move.x = curlil->Speed * Orientations[4].x;
373 curlil->Move.y = curlil->Speed * Orientations[4].y;
374 wannamove=1;
377 if(!wannamove){
378 curlil->Move.x = 0;
379 curlil->Move.y = 0;
381 // Shoot;
382 if(keystate[curlil->Keys.Shoot]){
383 curlil->WannaShoot = 1;
384 }else{
385 curlil->WannaShoot = 0;
387 // Suicide;
388 if(keystate[curlil->Keys.Suicide]){
389 if(curlil->WannaDie != 2){
390 curlil->WannaDie = 1;
392 }else{
393 curlil->WannaDie = 0;
395 // Switch;
396 if(keystate[curlil->Keys.Switch]){
397 if(!curlil->SwitchLock){
398 SwitchNextWeapon(g, i);
399 curlil->SwitchLock = 1;
401 }else{
402 curlil->SwitchLock = 0;
407 void SpawnBullet(Game *g, double dtime, int lid, int bid){
408 Area *LArea, *BArea;
409 TBullet *b, *bt;
410 double vx, vy; //because we need to spawn also mines with no velocity
413 LArea = TranslateArea(g->Lilanek[lid].Shape, &g->Lilanek[lid]. Pos);
414 b = &g->Bullet[bid];
415 bt = &g->BulletTemplate[g->Lilanek[lid].ActiveWeapon];
416 memcpy (b, bt, sizeof(TBullet));
417 b->Exists = 1;
418 b->Pos.x = g->Lilanek[lid].Pos.x+g->Lilanek[lid].BSize.x*0.5;
419 b->Pos.y = g->Lilanek[lid].Pos.y+g->Lilanek[lid].BSize.y*0.5;
420 b->WID = bt->WID;
421 b->Vel.x = Orientations[g->Lilanek[lid].Orientation].x * b->Speed +RandD(-b->Speed*b->SFuzzy, b->Speed*b->SFuzzy);
422 b->Vel.y = Orientations[g->Lilanek[lid].Orientation].y * b->Speed +RandD(-b->Speed*b->SFuzzy, b->Speed*b->SFuzzy);
423 if(DotProduct(&b->Vel, &b->Vel) <=0.01){
424 vx = -1*Orientations[g->Lilanek[lid].Orientation].x;
425 vy = -1*Orientations[g->Lilanek[lid].Orientation].y;
426 }else{
427 vx = b->Vel.x;
428 vy = b->Vel.y;
430 b->lid =lid;
431 while(1){
432 BArea = TranslateArea(b->Shape, &b->Pos);
433 if(!AreaInArea(BArea, LArea))
434 break;
435 b->Pos.x += vx* dtime*0.5;
436 b->Pos.y += vy* dtime*0.5;
438 FreeArea(LArea);
441 void Shoot(Game *g, double dtime, int lid){
442 int bid;
443 int i;
445 for(i=0; i<g->WeaponTemplate[g->Lilanek[lid].ActiveWeapon].Burst; i++){
446 if(g->Lilanek[lid].Ammo[g->Lilanek[lid].ActiveWeapon] == 0)
447 return;
448 for(bid=0; bid<g->noBullets; bid++){
449 if(g->Bullet[bid].Exists)
450 continue;
451 SpawnBullet(g, dtime, lid, bid);
452 g->Lilanek[lid].Ammo[g->Lilanek[lid].ActiveWeapon]--;
453 g->Lilanek[lid].ReloadTime = 0;
454 break;
459 void SwitchNextWeapon(Game *g, int lid){
460 int i;
461 TLilanek *l;
462 l = &g->Lilanek[lid];
463 for(i = 1; i < g->noWID; i++){
464 if(l->Ammo[(l->ActiveWeapon+i)%(g->noWID)]){
465 l->ActiveWeapon = (l->ActiveWeapon+i)%(g->noWID);
466 return;
471 void ShootIfTheyWantTo(Game *g, double dtime){
472 int lid;
474 for(lid=0; lid<g->noLilaneks; lid++){
475 //if(!g->Lilanek[lid].Exists)
476 //continue;
477 if(g->Lilanek[lid].Ammo[g->Lilanek[lid].ActiveWeapon] == 0)
478 SwitchNextWeapon(g,lid);
480 if(g->Lilanek[lid].ReloadTime < g->WeaponTemplate[g->Lilanek[lid].ActiveWeapon].ReloadTime){
481 g->Lilanek[lid].ReloadTime += dtime;
482 }else{
483 if(!g->Lilanek[lid].WannaShoot)
484 continue;
485 Shoot(g, dtime, lid);
490 int UpdateLogic(Game *g,double dtime){
491 DropWeapons(g, dtime);
492 UpdateBullets(g, dtime);
493 ParseInput(g, dtime);
494 MoveLilaneks(g, dtime);
495 PickUpWeapons(g, dtime);
496 ShootIfTheyWantTo(g, dtime);
497 return 0; //TODO: return something useful
500 Game *testgame(){ //return testing game, function for use before we have some menu/loading mechanism
501 Game *g;
502 Poly *p;
503 Area *a;
504 double sq2 = 1/sqrt(2.0);
505 int i;
506 Config conf = GetConfig();
508 g = malloc(sizeof(Game));
509 g->Map = malloc(sizeof(TMap));
510 g->Map->noLayer=2;
511 g->Map->Layer = malloc(sizeof(TMapLayer *)*g->Map->noLayer);
512 g->Map->Layer[0] = malloc(sizeof(TMapLayer));
513 g->Map->Layer[0]->noFArea = 1;
514 g->Map->Layer[0]->FArea = malloc(sizeof(Area *) * g->Map->Layer[0]->noFArea);
515 p = NewRect(4,2.5,3,2);
516 a = NewArea();
517 AddToArea(a, p);
518 FreePoly(p);
519 g->Map->Layer[0]->FArea[0] = a;
521 g->Map->Layer[1] = malloc(sizeof(TMapLayer));
522 g->Map->Layer[1]->noFArea = 1;
523 g->Map->Layer[1]->FArea = malloc(sizeof(Area *) * g->Map->Layer[1]->noFArea);
524 p = NewPoly();
525 AddToPolyXY(p, 9,7);
526 AddToPolyXY(p, 11,9);
527 AddToPolyXY(p, 9,11);
528 AddToPolyXY(p, 7,9);
529 a = NewArea();
530 AddToArea(a, p);
531 FreePoly(p);
532 g->Map->Layer[1]->FArea[0] = a;
533 p = NewRect(1,1,16,15);
534 a = NewArea();
535 AddToArea(a, p);
536 FreePoly(p);
537 g->Map->BoundingArea = a;
538 g->Map->XX = 17;
539 g->Map->YY = 16;
540 g->Map->X = 1;
541 g->Map->Y = 1;
543 g->Map->noSprites = 2;
544 g->Map->Sprites = (Sprite **) malloc(sizeof(Sprite*)*g->Map->noSprites);
545 g->Map->SpritePos = (Vect *) malloc(sizeof(Vect)*g->Map->noSprites);
546 g->Map->SpritePos[0].x = 3.0;
547 g->Map->SpritePos[0].y = 1.0;
548 g->Map->SpritePos[1].x = 6.0;
549 g->Map->SpritePos[1].y = 6.0;
551 g->noWeapons = 8;
552 g->Weapon = malloc(sizeof(TWeapon) * g->noWeapons);
553 if(!g->Weapon){
554 fprintf(stderr, "Cannot allocate memory for Weapons\n");
556 for(i=0; i<g->noWeapons; i++){
557 g->Weapon[i].Exists = 0;
558 g->Weapon[i].Shape = 0;
561 g->noLilaneks = 2;
562 g->Lilanek = malloc(sizeof(TLilanek) * g->noLilaneks);
563 memset(g->Lilanek, 0, sizeof(TLilanek) * g->noLilaneks);
564 g->Lilanek[1].Alive = 0;
565 g->Lilanek[0].BSize.x = 1;
566 g->Lilanek[0].BSize.y = 1;
567 //g->Lilanek[0].Shape = NewRect(0.6,0.2,0.8,1.6);
568 p = NewPoly();
569 AddToPolyXY(p, 1, 0);
570 AddToPolyXY(p, 1.4, 0.2);
571 AddToPolyXY(p, 1.66, 1.38);
572 AddToPolyXY(p, 1.42, 2);
573 AddToPolyXY(p, 0.6, 2);
574 AddToPolyXY(p, 0.4, 1.46);
575 AddToPolyXY(p, 0.66, 0.2);
576 MultiplyPoly(p, 0.5*g->Lilanek[0].BSize.x, 0.5*g->Lilanek[0].BSize.y);
577 a = NewArea();
578 AddToArea(a, p);
579 FreePoly(p);
580 g->Lilanek[0].Shape = a;
581 g->Lilanek[0].Pos.x = 12;
582 g->Lilanek[0].Pos.y = 4;
583 g->Lilanek[0].Speed = 4;
584 g->Lilanek[0].Alive = 0;
585 g->Lilanek[0].Keys.Up = conf.pl1_key_up;
586 g->Lilanek[0].Keys.Down = conf.pl1_key_down;
587 g->Lilanek[0].Keys.Left = conf.pl1_key_left;
588 g->Lilanek[0].Keys.Right = conf.pl1_key_right;
589 g->Lilanek[0].Keys.Shoot = conf.pl1_key_fire;
590 g->Lilanek[0].Keys.Suicide = conf.pl1_key_suicide;
591 g->Lilanek[0].Keys.Switch = conf.pl1_key_switch;
592 g->Lilanek[0].Ammo = malloc(sizeof(int)*g->noWID);
593 for(i=0; i<g->noWID; i++){
594 g->Lilanek[0].Ammo[i] = 0;
596 g->Lilanek[0].ActiveWeapon = 0;
597 SpawnLilanek(g, 0);
599 p = g->Lilanek[0].Shape->p[0];
600 a = NewArea();
601 AddToArea(a, p);
602 g->Lilanek[1].Shape = a;
603 g->Lilanek[1].BSize.x = g->Lilanek[0].BSize.x;
604 g->Lilanek[1].BSize.y = g->Lilanek[0].BSize.y;
605 g->Lilanek[1].Pos.x = 14;
606 g->Lilanek[1].Pos.y = 4;
607 g->Lilanek[1].Speed = 4;
608 g->Lilanek[1].Alive = 0;
609 g->Lilanek[1].Keys.Up = conf.pl2_key_up;
610 g->Lilanek[1].Keys.Down = conf.pl2_key_down;
611 g->Lilanek[1].Keys.Left = conf.pl2_key_left;
612 g->Lilanek[1].Keys.Right = conf.pl2_key_right;
613 g->Lilanek[1].Keys.Shoot = conf.pl2_key_fire;
614 g->Lilanek[1].Keys.Suicide = conf.pl2_key_suicide;
615 g->Lilanek[1].Keys.Switch = conf.pl2_key_switch;
616 g->Lilanek[1].Ammo = malloc(sizeof(int)*g->noWID);
617 for(i=0; i<g->noWID; i++){
618 g->Lilanek[1].Ammo[i] = 0;
620 g->Lilanek[1].ActiveWeapon = 0;
621 SpawnLilanek(g, 1);
623 g->noWID=2;
624 g->WeaponTemplate = malloc(sizeof(TWeapon)*g->noWID);
625 p = NewRect(0,0,0.5,0.5);
626 a = NewArea();
627 AddToArea(a, p);
628 FreePoly(p);
629 g->WeaponTemplate[0].Shape = a;
630 g->WeaponTemplate[0].WID = 0;
631 g->WeaponTemplate[0].Exists = 1;
632 g->WeaponTemplate[0].Ammo = 50;
633 g->WeaponTemplate[0].MaxAmmo = 250;
634 g->WeaponTemplate[0].ReloadTime = 2.1;
635 g->WeaponTemplate[0].Burst = 10;
637 g->BulletTemplate = malloc(sizeof(TBullet) * g->noWID);
638 p = NewRect(0,0,0.1,0.1);
639 a = NewArea();
640 AddToArea(a, p);
641 FreePoly(p);
642 g->BulletTemplate[0].Shape = a;
643 g->BulletTemplate[0].WID = 0;
644 g->BulletTemplate[0].Speed = 20;
645 g->BulletTemplate[0].SFuzzy = 0.040;
646 g->BulletTemplate[0].VFuzzy = 0.000;
648 p = NewRect(0,0,0.5,0.5);
649 a = NewArea();
650 AddToArea(a, p);
651 FreePoly(p);
652 g->WeaponTemplate[1].Shape = a;
653 g->WeaponTemplate[1].WID = 1;
654 g->WeaponTemplate[1].Exists = 1;
655 g->WeaponTemplate[1].Ammo = 3;
656 g->WeaponTemplate[1].MaxAmmo = 6;
657 g->WeaponTemplate[1].ReloadTime = 0.5;
658 g->WeaponTemplate[1].Burst = 1;
660 p = NewRect(0,0,0.5,0.5);
661 a = NewArea();
662 AddToArea(a, p);
663 FreePoly(p);
664 g->BulletTemplate[1].Shape = a;
665 g->BulletTemplate[1].WID = 1;
666 g->BulletTemplate[1].Speed = 0;
667 g->BulletTemplate[1].SFuzzy = 0.0;
668 g->BulletTemplate[1].VFuzzy = 0.0;
670 g->noBullets = 64;
671 g->Bullet = malloc(sizeof(TBullet) * g->noBullets);
672 for(i=0; i<g->noBullets; i++){
673 g->Bullet[i].Exists = 0;
674 g->Bullet[i].Shape = 0;
677 g->PWeapondrop = 0.4;
679 return g;
682 Sprite *lil[5];
683 Sprite *bg;
684 Sprite *kul;
685 Sprite *kulka;
686 Sprite *mine;
687 Sprite *mines;
688 int frames=0;
690 void onExit()
692 GrKill();
693 SDL_Quit();
696 Uint32 callback_fps(Uint32 interval, void *param)
698 SDL_Event event;
699 event.type = SDL_USEREVENT;
700 SDL_PushEvent(&event);
702 return 1000;
705 void Draw(Game *g){
706 int i;
708 QueueDrawSprite(bg, 0.0, 0.0,-1.0);
709 for(i=0; i < g->Map->noSprites; i++)
710 QueueDrawSprite(g->Map->Sprites[i], g->Map->SpritePos[i].x, g->Map->SpritePos[i].y, g->Map->Sprites[i]->z);
711 //Lilaneks
712 QueueDrawSprite(lil[g->Lilanek[0].Orientation], g->Lilanek[0].Pos.x-1.0, g->Lilanek[0].Pos.y-1.0, 1);
713 QueueDrawSprite(lil[g->Lilanek[1].Orientation], g->Lilanek[1].Pos.x-1.0, g->Lilanek[1].Pos.y-1.0, 1);
714 //Weapons
715 for(i=0; i < g->noWeapons; i++)
716 if(g->Weapon[i].Exists)
717 switch(g->Weapon[i].WID){
718 case 0: QueueDrawSprite(kul, g->Weapon[i].Pos.x - 1.0, g->Weapon[i].Pos.y - 1.0,1.0); break;
719 case 1: QueueDrawSprite(mines, g->Weapon[i].Pos.x - 1.0, g->Weapon[i].Pos.y - 1.0,1.0); break;
722 for(i=0; i < g->noBullets; i++)
723 if(g->Bullet[i].Exists)
724 switch(g->Bullet[i].WID){
725 case 0: QueueDrawSprite(kulka, g->Bullet[i].Pos.x - 1.0, g->Bullet[i].Pos.y - 1.0,1.0);break;
726 case 1: QueueDrawSprite(mine, g->Bullet[i].Pos.x - 1.0, g->Bullet[i].Pos.y - 1.0,1.0);break;
731 int InitAll(Game **g){
732 Config conf;
733 conf = GetConfig();
734 SaveConfig();
735 //TODO: odstranit SaveConfig... je to tu jenom kvuli debugovani
738 if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER ) < 0) {
739 fprintf(stderr, "Unable to init SDL: %s\n", SDL_GetError());
740 return 1;
742 atexit(onExit);
744 InitBase();
745 GrInit();
746 *g = testgame();
747 lil[0] = LoadSpriteSVG("graphics/lil.svg", 1.0, 1.0);
748 lil[1] = LoadSpriteSVG("graphics/lilb.svg", 1.0, 1.0);
749 lil[2] = LoadSpriteSVG("graphics/lill.svg", 1.0, 1.0);
750 lil[3] = LoadSpriteSVG("graphics/lil.svg", 1.0, 1.0);
751 lil[4] = LoadSpriteSVG("graphics/lilr.svg", 1.0, 1.0);
752 (*g)->Map->Sprites[0] = LoadSpriteSVG("graphics/prek1.svg", 3.0, 3.0);
753 (*g)->Map->Sprites[1] = LoadSpriteSVG("graphics/prek2.svg", 4.0, 4.0);
754 (*g)->Map->Sprites[0]->z = 1;
755 (*g)->Map->Sprites[1]->z = 1;
756 bg=0;
757 bg = LoadSpriteSVG("graphics/bg.svg", 16.0, 15.0);
758 kul = LoadSpriteSVG("graphics/kul.svg", 0.5, 0.5);
759 kulka = LoadSpriteSVG("graphics/kulka.svg", 0.1, 0.1);
760 mine = LoadSpriteSVG("graphics/mine.svg", 0.5, 0.5);
761 mines = LoadSpriteSVG("graphics/mines.svg", 0.5, 0.5);
763 SDL_AddTimer(1000, callback_fps, NULL);
765 return 0;
768 int GameLoop(Game *g){
769 SDL_Event event;
770 Config conf;
771 double lasttime, dtime;
773 lasttime = SDL_GetTicks()*0.001;
774 while (1) {
775 while (SDL_PollEvent(&event)) {
776 switch (event.type) {
777 case SDL_KEYDOWN:
778 if (event.key.keysym.sym == SDLK_q) {
779 return 0;
781 break;
783 case SDL_QUIT:
784 return 0;
785 break;
787 case SDL_VIDEORESIZE:
788 /* Resize the screen and redraw */
789 conf=GetConfig();
790 conf.screen_width=event.resize.w;
791 conf.screen_height=event.resize.h;
792 SetConfig(conf);
794 InvalidateSprites();
795 break;
797 case SDL_USEREVENT:
798 printf("%d frames\n",frames);
799 frames=0;
800 break;
802 default:
803 break;
806 dtime = SDL_GetTicks()*0.001-lasttime;
807 lasttime += dtime;
808 if(dtime < 0)
809 dtime=0.0;
810 if(dtime > 0.1)
811 dtime=0.1;
812 UpdateLogic(g, dtime*0.5);
813 UpdateLogic(g, dtime*0.5);
814 ClrScr();
815 Draw(g);
816 DrawSprites();
817 frames++;
818 //we don't want to waste cpu...
819 if(frames >=50){
820 SDL_Delay(10);
823 return 0;
826 int main(int argc, char **argv){
827 Game *g;
828 srand(time(0));
829 InitAll(&g);
830 GameLoop(g);
831 return 0;