Added {From|To}Layer to AreaInMap
[Lilanci.git] / ebulanci.c
bloba834b306e8e857373195eec6462cd1f74f95c98d
1 #include <math.h>
2 #include <time.h>
3 #include "geometry.h"
4 #include "util.h"
5 #include "config.h"
6 #include "gr.h"
8 //typedef int Uint8;
9 // We use seconds for measuring time, meters for measuring distance
12 typedef struct{
13 int Up;
14 int Down;
15 int Left;
16 int Right;
17 int Shoot;
18 int Suicide;
19 int Switch;
20 }TKeyBinding;//TODO: s/int/real data type for a key
22 typedef struct{
23 Vect Pos; //where he is
24 Vect Move; //how he want to move
25 Vect BSize; //Size of bounding rect
26 Area *Shape; //how fat he is
27 //Area *TrShape; //translated Shape -- don't optimize yet
28 int Frags; //no comment
29 int Deaths; //R.I.P.
30 double Speed; //meters per second
31 int Orientation; //1-up 2-left 3-down 4-right 0-down
32 int WannaShoot; //1-want 0-don't want
33 double ReloadTime; //time from last shot
34 int WannaDie; //1-want suicide 2-died and still holding suicide 0-don't want
35 double AnimationTime; //in seconds
36 TKeyBinding Keys;
37 int *Ammo;
38 int ActiveWeapon;
39 int SwitchLock;
40 int Alive;
41 }TLilanek;
44 typedef struct{
45 Vect Pos;
46 Area *Shape;
47 int WID; //Weapon ID
48 int Exists; // 0- doesn't exist 1-exists
49 int Ammo;
50 int MaxAmmo;
51 int Burst;
52 double ReloadTime;
53 }TWeapon;
55 typedef struct{
56 Vect Pos;
57 Area *Shape;
58 Vect Vel; //velocity i m/s
59 double Speed; //for Templates
60 int WID; //Weapon ID
61 int lid; //who shoot this bullet?
62 int Exists; // 0- doesn't exist 1-exists
63 double SFuzzy; // Fuzzy factor for spawning 0-1 :)
64 double VFuzzy; // Fuzzy factor for traveling 0-1 :)
65 }TBullet;
67 typedef struct{
68 Area **FArea; //forbidden Area
69 int noFArea; //no used FArea
70 }TMapLayer;
72 typedef struct{
73 TMapLayer **Layer;
74 int noLayer;
75 Area *BoundingArea; // ALL OBJECTS MUST BE IN THIS POLY
76 double XX,YY; //margins for random placement
77 double X,Y; //left top corner MUST be != [0,0]
78 int noSprites;
79 Sprite **Sprites;
80 Vect *SpritePos;
81 }TMap;
83 typedef struct{
84 TMap *Map; //where we are playing
85 TLilanek *Lilanek; //our heroes-ehm bad guys
86 int noLilaneks;
88 TWeapon *Weapon; //Weapons lying on floor
89 int noWeapons;
90 TWeapon *WeaponTemplate;
91 TBullet *BulletTemplate;
92 int noWID; //biggest WID, also number of WeaponTemplates
93 TBullet *Bullet;
94 int noBullets;
95 double PWeapondrop; // Probability of weapon drop per second
96 }Game;
98 Vect Orientations[5];
100 void SwitchNextWeapon(Game *g, int lid);
102 int InitBase(){
103 Orientations[0].x=0;
104 Orientations[0].y=0;
105 Orientations[1].x=0;
106 Orientations[1].y=-1;
107 Orientations[2].x=-1;
108 Orientations[2].y=0;
109 Orientations[3].x=0;
110 Orientations[3].y=1;
111 Orientations[4].x=1;
112 Orientations[4].y=0;
113 //TODO: write code
115 return 0;
118 int AreaInMap(TMap *m, Area *p, int FromLayer, int ToLayer){ //returns 0 if p collides with something in m otherwise 1
119 int i,j;
120 if(!AreaInAreaComp(m->BoundingArea, p)){
121 return 0;
123 for(i = FromLayer; i < m->noLayer && i <= ToLayer; i++){
124 for(j=0; j < m->Layer[i]->noFArea; j++)
125 if(AreaInArea(p, m->Layer[i]->FArea[j]))
126 return 0;
128 return 1;
130 void SpawnLilanek(Game *g, int lid){
131 Vect Pos;
132 int tries;
133 Area *tp, *oltp;
134 int good;
135 int olid;
137 oltp = 0;
138 tp = 0;
139 for(tries=0; tries <1000; tries++){ //TODO: remove exact number
140 Pos.x = RandD(0,g->Map->XX);
141 Pos.y = RandD(0,g->Map->YY);
142 good=1;
143 tp = TranslateArea(g->Lilanek[lid].Shape, &Pos);
144 printf("%s\n", Area2String(tp));
145 if(!AreaInMap(g->Map, tp,0,1)){
146 good=0;
149 for(olid=0; olid < g->noLilaneks; olid++){
150 if(olid == lid)
151 continue;
152 if(!g->Lilanek[olid].Alive){
153 continue;
155 oltp = TranslateArea(g->Lilanek[olid].Shape, &g->Lilanek[olid].Pos);
156 if(AreaInArea(tp, oltp)){
157 good=0;
159 FreeArea(oltp);
160 oltp = 0;
163 if(good){
164 FreeArea(tp);
165 tp=0;
166 g->Lilanek[lid].Pos.x = Pos.x;
167 g->Lilanek[lid].Pos.y = Pos.y;
168 g->Lilanek[lid].Alive = 1;
169 break;
171 FreeArea(tp);
172 tp=0;
176 void DropWeapon(Game *g, int weapon){
177 Vect Pos;
178 int tries;
179 int WID;
180 Area *tp;
182 for(tries=0; tries <100; tries++){ //TODO: remove exact number
183 Pos.x = RandD(0,g->Map->XX);
184 Pos.y = RandD(0,g->Map->YY);
185 WID = RandI(0, g->noWID);
186 tp = TranslateArea(g->WeaponTemplate[WID].Shape, &Pos);
187 if(AreaInMap(g->Map, tp, 0, g->Map->noLayer)){
188 FreeArea(tp);
189 tp=0;
190 memcpy(&g->Weapon[weapon], &g->WeaponTemplate[WID], sizeof(TWeapon));
191 g->Weapon[weapon].Shape = g->WeaponTemplate[WID].Shape;
192 g->Weapon[weapon].Pos.x = Pos.x;
193 g->Weapon[weapon].Pos.y = Pos.y;
194 g->Weapon[weapon].WID = WID;
195 g->Weapon[weapon].Exists = 1;
196 break;
198 FreeArea(tp);
199 tp=0;
203 void DropWeapons(Game *g, double dtime){
204 int i;
205 double r;
207 if( RandD(0.0, 1.0) >= (g->PWeapondrop*dtime))
208 return;
209 for(i=0; i < g->noWeapons; i++){
210 if(g->Weapon[i].Exists)continue; //we don't like teleporting weapons :)
212 printf("A Weapon drop!\n");
213 DropWeapon(g, i);
214 break; //spawn max one weapon per update
218 void WeaponPickedUp(Game *g, double dtime, int lid, int wid){
219 TLilanek *l;
220 TWeapon *w;
222 l = &g->Lilanek[lid];
223 w = &g->Weapon[wid];
225 l->Ammo[w->WID] += w->Ammo;
226 if(l->Ammo[w->WID] > w->MaxAmmo)
227 l->Ammo[w->WID] = w->MaxAmmo;
228 printf("Ammo: %d\n",l->Ammo[w->WID]);
229 l->ActiveWeapon = w->WID;
230 printf("AW: %d\n",l->ActiveWeapon);
232 w->Exists = 0;
233 //TODO: sound effect
236 void PickUpWeapons(Game *g, double dtime){
237 int lid,wid;
238 Area *WArea, *LArea;
240 for(lid=0; lid<g->noLilaneks; lid++){
241 LArea = TranslateArea(g->Lilanek[lid].Shape, &g->Lilanek[lid].Pos);
242 for(wid=0; wid < g->noWeapons; wid++){
243 if(!g->Weapon[wid].Exists)
244 continue;
245 WArea = TranslateArea(g->Weapon[wid].Shape, &g->Weapon[wid].Pos);
246 if(!AreaInArea( WArea, LArea)){
247 FreeArea(WArea);
248 continue;
250 WeaponPickedUp(g, dtime, lid, wid);
251 FreeArea(WArea);
253 FreeArea(LArea);
257 void BulletExplodes(Game *g, int i){
258 g->Bullet[i].Exists=0;
259 //TODO: some effects
262 void MoveBullet(Game *g, double dtime, int i){
263 double ff;
264 ff= g->Bullet[i].Speed*g->Bullet[i].VFuzzy;
265 g->Bullet[i].Pos.x += (g->Bullet[i].Vel.x += RandD(-ff,ff))* dtime;
266 g->Bullet[i].Pos.y += (g->Bullet[i].Vel.y += RandD(-ff,ff))* dtime;
269 void CollideBulletMap(Game *g, double dtime, int i){
270 Area *p;
272 p=TranslateArea(g->Bullet[i].Shape, &g->Bullet[i].Pos);
273 if(AreaInMap(g->Map, p, 1,1)==0)
274 BulletExplodes(g, i);
275 FreeArea(p);
277 void LilanekKilled(Game *g, double dtime, int BulletID, int LilanekID){
278 g->Bullet[BulletID].Exists = 0;
279 g->Lilanek[LilanekID].Deaths ++;
280 g->Lilanek[g->Bullet[BulletID].lid].Frags ++;
281 SpawnLilanek(g, LilanekID);
284 void CollideBulletLilanek(Game *g, double dtime, int BulletID){
285 Area *BArea, *LArea;
286 int LilanekID;
288 BArea=TranslateArea(g->Bullet[BulletID].Shape, &g->Bullet[BulletID].Pos);
289 for(LilanekID=0; LilanekID<g->noLilaneks; LilanekID++){
290 LArea=TranslateArea(g->Lilanek[LilanekID].Shape, &g->Lilanek[LilanekID].Pos);
291 if(AreaInArea(LArea,BArea))
292 LilanekKilled(g, dtime, BulletID, LilanekID);
293 FreeArea(LArea);
294 LArea=0;
296 FreeArea(BArea);
297 BArea=0;
300 void UpdateBullets(Game *g, double dtime){
301 int BulletID;
302 for(BulletID=0; BulletID<g->noBullets; BulletID++){
303 if(g->Bullet[BulletID].Exists==0)
304 continue; //We won't update non-existending bullets
305 MoveBullet(g, dtime, BulletID);
306 CollideBulletMap(g, dtime, BulletID);
307 CollideBulletLilanek(g, dtime, BulletID);
311 int CheckLilanekvsLilaneks(Game *g, Area *a, int LilanekID){ //returns 0 if he collides with others, 1 if it's OK to move there
312 int i;
313 Area *nb;
314 int rval=1;
316 nb=0;
317 for(i=0; i<g->noLilaneks && rval==1; i++){
318 if(i==LilanekID)
319 continue;
320 nb = TranslateArea(g->Lilanek[i].Shape, &g->Lilanek[i].Pos);
321 if(AreaInArea(nb, a))
322 rval=0;
323 FreeArea(nb);
324 nb=0;
326 return rval;
329 void MoveLilaneks(Game *g, double dtime){
330 int i, steps;
331 Area *pa;
332 Vect va;
333 double dt;
335 pa=0;
336 for(i=0; i<g->noLilaneks; i++){
337 //skip this Lilanek if he doesn't wanna move
338 if(g->Lilanek[i].Move.x == 0.0 && g->Lilanek[i].Move.y == 0.0)
339 continue;
340 for(dt=dtime, steps=0; steps<4; dt/=2.0, steps++){ //TODO: get rid of exact number
341 //make future Area
342 va.x = g->Lilanek[i].Pos.x + dt*g->Lilanek[i].Move.x;
343 va.y = g->Lilanek[i].Pos.y + dt*g->Lilanek[i].Move.y;
344 FreeArea(pa); //we don't want memory leaks
345 pa = TranslateArea(g->Lilanek[i].Shape, &va);
346 //check for collision with map
347 if(AreaInMap(g->Map, pa, 0, 1)==0)
348 continue; //try smaller dt if he collided with map
349 //check for collision with other Lilaneks
350 if(CheckLilanekvsLilaneks(g, pa, i)==0)
351 continue;
352 //move him if we got here
353 g->Lilanek[i].Pos.x += dt*g->Lilanek[i].Move.x;
354 g->Lilanek[i].Pos.y += dt*g->Lilanek[i].Move.y;
355 FreeArea(pa);
356 pa=0;
358 FreeArea(pa); //For sure
359 pa=0;
363 void ParseInput(Game *g, double dtime){
364 int i;
365 Uint8 *keystate;
366 TLilanek *curlil;
367 int wannamove;
369 keystate = SDL_GetKeyState(NULL);
371 for(i=0; i< g->noLilaneks; i++){
372 curlil = &g->Lilanek[i];
373 wannamove=0;
374 // Up;
375 if(keystate[curlil->Keys.Up]){
376 curlil->Orientation = 1;
377 curlil->Move.x = curlil->Speed * Orientations[1].x;
378 curlil->Move.y = curlil->Speed * Orientations[1].y;
379 wannamove=1;
381 // Down;
382 if(keystate[curlil->Keys.Down]){
383 curlil->Orientation = 3;
384 curlil->Move.x = curlil->Speed * Orientations[3].x;
385 curlil->Move.y = curlil->Speed * Orientations[3].y;
386 wannamove=1;
388 // Left;
389 if(keystate[curlil->Keys.Left]){
390 curlil->Orientation = 2;
391 curlil->Move.x = curlil->Speed * Orientations[2].x;
392 curlil->Move.y = curlil->Speed * Orientations[2].y;
393 wannamove=1;
395 // Right;
396 if(keystate[curlil->Keys.Right]){
397 curlil->Orientation = 4;
398 curlil->Move.x = curlil->Speed * Orientations[4].x;
399 curlil->Move.y = curlil->Speed * Orientations[4].y;
400 wannamove=1;
403 if(!wannamove){
404 curlil->Move.x = 0;
405 curlil->Move.y = 0;
407 // Shoot;
408 if(keystate[curlil->Keys.Shoot]){
409 curlil->WannaShoot = 1;
410 }else{
411 curlil->WannaShoot = 0;
413 // Suicide;
414 if(keystate[curlil->Keys.Suicide]){
415 if(curlil->WannaDie != 2){
416 curlil->WannaDie = 1;
418 }else{
419 curlil->WannaDie = 0;
421 // Switch;
422 if(keystate[curlil->Keys.Switch]){
423 if(!curlil->SwitchLock){
424 SwitchNextWeapon(g, i);
425 curlil->SwitchLock = 1;
427 }else{
428 curlil->SwitchLock = 0;
433 void SpawnBullet(Game *g, double dtime, int lid, int bid){
434 Area *LArea, *BArea;
435 TBullet *b, *bt;
436 double vx, vy; //because we need to spawn also mines with no velocity
439 LArea = TranslateArea(g->Lilanek[lid].Shape, &g->Lilanek[lid]. Pos);
440 b = &g->Bullet[bid];
441 bt = &g->BulletTemplate[g->Lilanek[lid].ActiveWeapon];
442 memcpy (b, bt, sizeof(TBullet));
443 b->Exists = 1;
444 b->Pos.x = g->Lilanek[lid].Pos.x+g->Lilanek[lid].BSize.x*0.5;
445 b->Pos.y = g->Lilanek[lid].Pos.y+g->Lilanek[lid].BSize.y*0.5;
446 b->WID = bt->WID;
447 b->Vel.x = Orientations[g->Lilanek[lid].Orientation].x * b->Speed +RandD(-b->Speed*b->SFuzzy, b->Speed*b->SFuzzy);
448 b->Vel.y = Orientations[g->Lilanek[lid].Orientation].y * b->Speed +RandD(-b->Speed*b->SFuzzy, b->Speed*b->SFuzzy);
449 if(DotProduct(&b->Vel, &b->Vel) <=0.01){
450 vx = -1*Orientations[g->Lilanek[lid].Orientation].x;
451 vy = -1*Orientations[g->Lilanek[lid].Orientation].y;
452 }else{
453 vx = b->Vel.x;
454 vy = b->Vel.y;
456 b->lid =lid;
457 while(1){
458 BArea = TranslateArea(b->Shape, &b->Pos);
459 if(!AreaInArea(BArea, LArea))
460 break;
461 b->Pos.x += vx* dtime*0.5;
462 b->Pos.y += vy* dtime*0.5;
464 FreeArea(LArea);
467 void Shoot(Game *g, double dtime, int lid){
468 int bid;
469 int i;
471 for(i=0; i<g->WeaponTemplate[g->Lilanek[lid].ActiveWeapon].Burst; i++){
472 if(g->Lilanek[lid].Ammo[g->Lilanek[lid].ActiveWeapon] == 0)
473 return;
474 for(bid=0; bid<g->noBullets; bid++){
475 if(g->Bullet[bid].Exists)
476 continue;
477 SpawnBullet(g, dtime, lid, bid);
478 g->Lilanek[lid].Ammo[g->Lilanek[lid].ActiveWeapon]--;
479 g->Lilanek[lid].ReloadTime = 0;
480 break;
485 void SwitchNextWeapon(Game *g, int lid){
486 int i;
487 TLilanek *l;
488 l = &g->Lilanek[lid];
489 for(i = 1; i < g->noWID; i++){
490 if(l->Ammo[(l->ActiveWeapon+i)%(g->noWID)]){
491 l->ActiveWeapon = (l->ActiveWeapon+i)%(g->noWID);
492 return;
497 void ShootIfTheyWantTo(Game *g, double dtime){
498 int lid;
500 for(lid=0; lid<g->noLilaneks; lid++){
501 //if(!g->Lilanek[lid].Exists)
502 //continue;
503 if(g->Lilanek[lid].Ammo[g->Lilanek[lid].ActiveWeapon] == 0)
504 SwitchNextWeapon(g,lid);
506 if(g->Lilanek[lid].ReloadTime < g->WeaponTemplate[g->Lilanek[lid].ActiveWeapon].ReloadTime){
507 g->Lilanek[lid].ReloadTime += dtime;
508 }else{
509 if(!g->Lilanek[lid].WannaShoot)
510 continue;
511 Shoot(g, dtime, lid);
516 int UpdateLogic(Game *g,double dtime){
517 DropWeapons(g, dtime);
518 UpdateBullets(g, dtime);
519 ParseInput(g, dtime);
520 MoveLilaneks(g, dtime);
521 PickUpWeapons(g, dtime);
522 ShootIfTheyWantTo(g, dtime);
523 return 0; //TODO: return something useful
526 Game *testgame(){ //return testing game, function for use before we have some menu/loading mechanism
527 Game *g;
528 Poly *p;
529 Area *a;
530 double sq2 = 1/sqrt(2.0);
531 int i;
532 Config conf = GetConfig();
534 g = malloc(sizeof(Game));
535 g->Map = malloc(sizeof(TMap));
536 g->Map->noLayer=2;
537 g->Map->Layer = malloc(sizeof(TMapLayer *)*g->Map->noLayer);
538 g->Map->Layer[0] = malloc(sizeof(TMapLayer));
539 g->Map->Layer[0]->noFArea = 1;
540 g->Map->Layer[0]->FArea = malloc(sizeof(Area *) * g->Map->Layer[0]->noFArea);
541 p = NewRect(4,2.5,3,2);
542 a = NewArea();
543 AddToArea(a, p);
544 FreePoly(p);
545 g->Map->Layer[0]->FArea[0] = a;
547 g->Map->Layer[1] = malloc(sizeof(TMapLayer));
548 g->Map->Layer[1]->noFArea = 1;
549 g->Map->Layer[1]->FArea = malloc(sizeof(Area *) * g->Map->Layer[1]->noFArea);
550 p = NewPoly();
551 AddToPolyXY(p, 9,7);
552 AddToPolyXY(p, 11,9);
553 AddToPolyXY(p, 9,11);
554 AddToPolyXY(p, 7,9);
555 a = NewArea();
556 AddToArea(a, p);
557 FreePoly(p);
558 g->Map->Layer[1]->FArea[0] = a;
559 p = NewRect(1,1,16,15);
560 a = NewArea();
561 AddToArea(a, p);
562 FreePoly(p);
563 g->Map->BoundingArea = a;
564 g->Map->XX = 17;
565 g->Map->YY = 16;
566 g->Map->X = 1;
567 g->Map->Y = 1;
569 g->Map->noSprites = 2;
570 g->Map->Sprites = (Sprite **) malloc(sizeof(Sprite*)*g->Map->noSprites);
571 g->Map->SpritePos = (Vect *) malloc(sizeof(Vect)*g->Map->noSprites);
572 g->Map->SpritePos[0].x = 3.0;
573 g->Map->SpritePos[0].y = 1.0;
574 g->Map->SpritePos[1].x = 6.0;
575 g->Map->SpritePos[1].y = 6.0;
577 g->noWeapons = 8;
578 g->Weapon = malloc(sizeof(TWeapon) * g->noWeapons);
579 if(!g->Weapon){
580 fprintf(stderr, "Cannot allocate memory for Weapons\n");
582 for(i=0; i<g->noWeapons; i++){
583 g->Weapon[i].Exists = 0;
584 g->Weapon[i].Shape = 0;
587 g->noWID=2;
588 g->WeaponTemplate = malloc(sizeof(TWeapon)*g->noWID);
589 p = NewRect(0,0,0.5,0.5);
590 a = NewArea();
591 AddToArea(a, p);
592 FreePoly(p);
593 g->WeaponTemplate[0].Shape = a;
594 g->WeaponTemplate[0].WID = 0;
595 g->WeaponTemplate[0].Exists = 1;
596 g->WeaponTemplate[0].Ammo = 50;
597 g->WeaponTemplate[0].MaxAmmo = 150;
598 g->WeaponTemplate[0].ReloadTime = 0.2;
599 g->WeaponTemplate[0].Burst = 24;
601 p = NewRect(0,0,0.5,0.5);
602 a = NewArea();
603 AddToArea(a, p);
604 FreePoly(p);
605 g->WeaponTemplate[1].Shape = a;
606 g->WeaponTemplate[1].WID = 1;
607 g->WeaponTemplate[1].Exists = 1;
608 g->WeaponTemplate[1].Ammo = 3;
609 g->WeaponTemplate[1].MaxAmmo = 6;
610 g->WeaponTemplate[1].ReloadTime = 0.5;
611 g->WeaponTemplate[1].Burst = 1;
613 g->noLilaneks = 2;
614 g->Lilanek = malloc(sizeof(TLilanek) * g->noLilaneks);
615 g->Lilanek[1].Alive = 0;
616 g->Lilanek[0].BSize.x = 1;
617 g->Lilanek[0].BSize.y = 1;
618 //g->Lilanek[0].Shape = NewRect(0.6,0.2,0.8,1.6);
619 p = NewPoly();
620 AddToPolyXY(p, 1, 0);
621 AddToPolyXY(p, 1.4, 0.2);
622 AddToPolyXY(p, 1.66, 1.38);
623 AddToPolyXY(p, 1.42, 2);
624 AddToPolyXY(p, 0.6, 2);
625 AddToPolyXY(p, 0.4, 1.46);
626 AddToPolyXY(p, 0.66, 0.2);
627 MultiplyPoly(p, 0.5*g->Lilanek[0].BSize.x, 0.5*g->Lilanek[0].BSize.y);
628 a = NewArea();
629 AddToArea(a, p);
630 FreePoly(p);
631 g->Lilanek[0].Shape = a;
632 g->Lilanek[0].Pos.x = 12;
633 g->Lilanek[0].Pos.y = 4;
634 g->Lilanek[0].Speed = 4;
635 g->Lilanek[0].Alive = 0;
636 g->Lilanek[0].Keys.Up = conf.pl1_key_up;
637 g->Lilanek[0].Keys.Down = conf.pl1_key_down;
638 g->Lilanek[0].Keys.Left = conf.pl1_key_left;
639 g->Lilanek[0].Keys.Right = conf.pl1_key_right;
640 g->Lilanek[0].Keys.Shoot = conf.pl1_key_fire;
641 g->Lilanek[0].Keys.Suicide = conf.pl1_key_suicide;
642 g->Lilanek[0].Keys.Switch = conf.pl1_key_switch;
643 g->Lilanek[0].Ammo = malloc(sizeof(int)*g->noWID);
644 for(i=0; i<g->noWID; i++){
645 g->Lilanek[0].Ammo[i] = 0;
647 g->Lilanek[0].ActiveWeapon = 0;
648 SpawnLilanek(g, 0);
650 p = g->Lilanek[0].Shape->p[0];
651 a = NewArea();
652 AddToArea(a, p);
653 g->Lilanek[1].Shape = a;
654 g->Lilanek[1].BSize.x = g->Lilanek[0].BSize.x;
655 g->Lilanek[1].BSize.y = g->Lilanek[0].BSize.y;
656 g->Lilanek[1].Pos.x = 14;
657 g->Lilanek[1].Pos.y = 4;
658 g->Lilanek[1].Speed = 4;
659 g->Lilanek[1].Alive = 0;
660 g->Lilanek[1].Keys.Up = conf.pl2_key_up;
661 g->Lilanek[1].Keys.Down = conf.pl2_key_down;
662 g->Lilanek[1].Keys.Left = conf.pl2_key_left;
663 g->Lilanek[1].Keys.Right = conf.pl2_key_right;
664 g->Lilanek[1].Keys.Shoot = conf.pl2_key_fire;
665 g->Lilanek[1].Keys.Suicide = conf.pl2_key_suicide;
666 g->Lilanek[1].Keys.Switch = conf.pl2_key_switch;
667 g->Lilanek[1].Ammo = malloc(sizeof(int)*g->noWID);
668 for(i=0; i<g->noWID; i++){
669 g->Lilanek[1].Ammo[i] = 0;
671 g->Lilanek[1].ActiveWeapon = 0;
672 SpawnLilanek(g, 1);
674 g->BulletTemplate = malloc(sizeof(TBullet) * g->noWID);
675 p = NewRect(0,0,0.1,0.1);
676 a = NewArea();
677 AddToArea(a, p);
678 FreePoly(p);
679 g->BulletTemplate[0].Shape = a;
680 g->BulletTemplate[0].WID = 0;
681 g->BulletTemplate[0].Speed = 20;
682 g->BulletTemplate[0].SFuzzy = 0.20;
683 g->BulletTemplate[0].VFuzzy = 0.15;
685 p = NewRect(0,0,0.5,0.5);
686 a = NewArea();
687 AddToArea(a, p);
688 FreePoly(p);
689 g->BulletTemplate[1].Shape = a;
690 g->BulletTemplate[1].WID = 1;
691 g->BulletTemplate[1].Speed = 0;
692 g->BulletTemplate[1].SFuzzy = 0.0;
693 g->BulletTemplate[1].VFuzzy = 0.0;
695 g->noBullets = 64;
696 g->Bullet = malloc(sizeof(TBullet) * g->noBullets);
697 for(i=0; i<g->noBullets; i++){
698 g->Bullet[i].Exists = 0;
699 g->Bullet[i].Shape = 0;
702 g->PWeapondrop = 0.4;
704 return g;
707 Sprite *lil[5];
708 Sprite *bg;
709 Sprite *kul;
710 Sprite *kulka;
711 Sprite *mine;
712 Sprite *mines;
713 int frames=0;
715 void onExit()
717 GrKill();
718 SDL_Quit();
721 Uint32 callback_fps(Uint32 interval, void *param)
723 SDL_Event event;
724 event.type = SDL_USEREVENT;
725 SDL_PushEvent(&event);
727 return 1000;
730 void Draw(Game *g){
731 int i;
733 QueueDrawSprite(bg, 0.0, 0.0,-1.0);
734 for(i=0; i < g->Map->noSprites; i++)
735 QueueDrawSprite(g->Map->Sprites[i], g->Map->SpritePos[i].x, g->Map->SpritePos[i].y, g->Map->Sprites[i]->z);
736 //Lilaneks
737 QueueDrawSprite(lil[g->Lilanek[0].Orientation], g->Lilanek[0].Pos.x-1.0, g->Lilanek[0].Pos.y-1.0, 1);
738 QueueDrawSprite(lil[g->Lilanek[1].Orientation], g->Lilanek[1].Pos.x-1.0, g->Lilanek[1].Pos.y-1.0, 1);
739 //Weapons
740 for(i=0; i < g->noWeapons; i++)
741 if(g->Weapon[i].Exists)
742 switch(g->Weapon[i].WID){
743 case 0: QueueDrawSprite(kul, g->Weapon[i].Pos.x - 1.0, g->Weapon[i].Pos.y - 1.0,1.0); break;
744 case 1: QueueDrawSprite(mines, g->Weapon[i].Pos.x - 1.0, g->Weapon[i].Pos.y - 1.0,1.0); break;
747 for(i=0; i < g->noBullets; i++)
748 if(g->Bullet[i].Exists)
749 switch(g->Bullet[i].WID){
750 case 0: QueueDrawSprite(kulka, g->Bullet[i].Pos.x - 1.0, g->Bullet[i].Pos.y - 1.0,1.0);break;
751 case 1: QueueDrawSprite(mine, g->Bullet[i].Pos.x - 1.0, g->Bullet[i].Pos.y - 1.0,1.0);break;
756 int InitAll(Game **g){
757 Config conf;
758 conf = GetConfig();
759 SaveConfig();
760 //TODO: odstranit SaveConfig... je to tu jenom kvuli debugovani
763 if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER ) < 0) {
764 fprintf(stderr, "Unable to init SDL: %s\n", SDL_GetError());
765 return 1;
767 atexit(onExit);
769 InitBase();
770 GrInit();
771 *g = testgame();
772 lil[0] = LoadSpriteSVG("graphics/lil.svg", 1.0, 1.0);
773 lil[1] = LoadSpriteSVG("graphics/lilb.svg", 1.0, 1.0);
774 lil[2] = LoadSpriteSVG("graphics/lill.svg", 1.0, 1.0);
775 lil[3] = LoadSpriteSVG("graphics/lil.svg", 1.0, 1.0);
776 lil[4] = LoadSpriteSVG("graphics/lilr.svg", 1.0, 1.0);
777 (*g)->Map->Sprites[0] = LoadSpriteSVG("graphics/prek1.svg", 3.0, 3.0);
778 (*g)->Map->Sprites[1] = LoadSpriteSVG("graphics/prek2.svg", 4.0, 4.0);
779 (*g)->Map->Sprites[0]->z = 1;
780 (*g)->Map->Sprites[1]->z = 1;
781 bg=0;
782 bg = LoadSpriteSVG("graphics/bg.svg", 16.0, 15.0);
783 kul = LoadSpriteSVG("graphics/kul.svg", 0.5, 0.5);
784 kulka = LoadSpriteSVG("graphics/kulka.svg", 0.1, 0.1);
785 mine = LoadSpriteSVG("graphics/mine.svg", 0.5, 0.5);
786 mines = LoadSpriteSVG("graphics/mines.svg", 0.5, 0.5);
788 SDL_AddTimer(1000, callback_fps, NULL);
790 return 0;
793 int GameLoop(Game *g){
794 SDL_Event event;
795 Config conf;
796 double lasttime, dtime;
798 lasttime = SDL_GetTicks()*0.001;
799 while (1) {
800 while (SDL_PollEvent(&event)) {
801 switch (event.type) {
802 case SDL_KEYDOWN:
803 if (event.key.keysym.sym == SDLK_q) {
804 return 0;
806 break;
808 case SDL_QUIT:
809 return 0;
810 break;
812 case SDL_VIDEORESIZE:
813 /* Resize the screen and redraw */
814 conf=GetConfig();
815 conf.screen_width=event.resize.w;
816 conf.screen_height=event.resize.h;
817 SetConfig(conf);
819 InvalidateSprites();
820 break;
822 case SDL_USEREVENT:
823 printf("%d frames\n",frames);
824 frames=0;
825 break;
827 default:
828 break;
831 dtime = SDL_GetTicks()*0.001-lasttime;
832 lasttime += dtime;
833 if(dtime < 0)
834 dtime=0.0;
835 if(dtime > 0.1)
836 dtime=0.1;
837 UpdateLogic(g, dtime*0.5);
838 UpdateLogic(g, dtime*0.5);
839 ClrScr();
840 Draw(g);
841 DrawSprites();
842 frames++;
843 //we don't want to waste cpu...
844 if(frames >=50){
845 SDL_Delay(10);
848 return 0;
851 int main(int argc, char **argv){
852 Game *g;
853 srand(time(0));
854 InitAll(&g);
855 GameLoop(g);
856 return 0;