blednuti dle moznosti strilet
[Lilanci.git] / ebulanci.c
blob8dc655a58b9d6dd64bbc9a4dc945345a48a02af9
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"
11 typedef struct{
12 int Up;
13 int Down;
14 int Left;
15 int Right;
16 int Shoot;
17 int Suicide;
18 int Switch;
19 }TKeyBinding;//TODO: s/int/real data type for a key
21 typedef struct{
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
28 int Deaths; //R.I.P.
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
35 TKeyBinding Keys;
36 int *Ammo;
37 int ActiveWeapon;
38 int SwitchLock;
39 int Alive;
40 char Name[16];
41 SDL_Color Color;
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, *pp;
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, 0.30, 0.41);
526 AddToPolyXY(p, 0.73, 0.41);
527 AddToPolyXY(p, 0.77, 0.79);
528 AddToPolyXY(p, 0.65, 0.955);
529 AddToPolyXY(p, 0.365, 0.965);
530 AddToPolyXY(p, 0.235, 0.785);
531 MultiplyPoly(p, 4, 4);
532 pp = TranslatePolyXY(p, 7, 7);
533 a = NewArea();
534 AddToArea(a, pp);
535 FreePoly(pp);
536 FreePoly(p);
537 g->Map->Layer[1]->FArea[0] = a;
538 p = NewRect(1,1,16,15);
539 a = NewArea();
540 AddToArea(a, p);
541 FreePoly(p);
542 g->Map->BoundingArea = a;
543 g->Map->XX = 17;
544 g->Map->YY = 16;
545 g->Map->X = 1;
546 g->Map->Y = 1;
548 g->Map->noSprites = 2;
549 g->Map->Sprites = (Sprite **) malloc(sizeof(Sprite*)*g->Map->noSprites);
550 g->Map->SpritePos = (Vect *) malloc(sizeof(Vect)*g->Map->noSprites);
551 g->Map->SpritePos[0].x = 3.0;
552 g->Map->SpritePos[0].y = 1.0;
553 g->Map->SpritePos[1].x = 6.0;
554 g->Map->SpritePos[1].y = 6.0;
556 g->noWeapons = 8;
557 g->Weapon = malloc(sizeof(TWeapon) * g->noWeapons);
558 if(!g->Weapon){
559 fprintf(stderr, "Cannot allocate memory for Weapons\n");
561 for(i=0; i<g->noWeapons; i++){
562 g->Weapon[i].Exists = 0;
563 g->Weapon[i].Shape = 0;
566 g->noLilaneks = 2;
567 g->Lilanek = malloc(sizeof(TLilanek) * g->noLilaneks);
568 memset(g->Lilanek, 0, sizeof(TLilanek) * g->noLilaneks);
569 g->Lilanek[0].BSize.x = 1;
570 g->Lilanek[0].BSize.y = 1;
571 //g->Lilanek[0].Shape = NewRect(0.6,0.2,0.8,1.6);
572 p = NewPoly();
573 AddToPolyXY(p, 1, 0);
574 AddToPolyXY(p, 1.4, 0.2);
575 AddToPolyXY(p, 1.66, 1.38);
576 AddToPolyXY(p, 1.42, 2);
577 AddToPolyXY(p, 0.6, 2);
578 AddToPolyXY(p, 0.4, 1.46);
579 AddToPolyXY(p, 0.66, 0.2);
580 MultiplyPoly(p, 0.5*g->Lilanek[0].BSize.x, 0.5*g->Lilanek[0].BSize.y);
581 a = NewArea();
582 AddToArea(a, p);
583 FreePoly(p);
584 g->Lilanek[0].Shape = a;
585 g->Lilanek[0].Pos.x = 12;
586 g->Lilanek[0].Pos.y = 4;
587 g->Lilanek[0].Speed = 4;
588 g->Lilanek[0].Alive = 0;
589 g->Lilanek[0].Keys.Up = conf.pl1_key_up;
590 g->Lilanek[0].Keys.Down = conf.pl1_key_down;
591 g->Lilanek[0].Keys.Left = conf.pl1_key_left;
592 g->Lilanek[0].Keys.Right = conf.pl1_key_right;
593 g->Lilanek[0].Keys.Shoot = conf.pl1_key_fire;
594 g->Lilanek[0].Keys.Suicide = conf.pl1_key_suicide;
595 g->Lilanek[0].Keys.Switch = conf.pl1_key_switch;
596 g->Lilanek[0].Ammo = malloc(sizeof(int)*g->noWID);
597 for(i=0; i<g->noWID; i++){
598 g->Lilanek[0].Ammo[i] = 0;
600 g->Lilanek[0].ActiveWeapon = 0;
602 SDL_Color red = {255,211,211};
603 char redn[8]="Red";
604 g->Lilanek[0].Color = red;
605 strcpy(g->Lilanek[0].Name, redn);
607 g->Lilanek[1].Alive = 0; // little hack for SpawnLilanek to work
608 SpawnLilanek(g, 0);
610 p = g->Lilanek[0].Shape->p[0];
611 a = NewArea();
612 AddToArea(a, p);
613 g->Lilanek[1].Shape = a;
614 g->Lilanek[1].BSize.x = g->Lilanek[0].BSize.x;
615 g->Lilanek[1].BSize.y = g->Lilanek[0].BSize.y;
616 g->Lilanek[1].Pos.x = 14;
617 g->Lilanek[1].Pos.y = 4;
618 g->Lilanek[1].Speed = 4;
619 g->Lilanek[1].Alive = 0;
620 g->Lilanek[1].Keys.Up = conf.pl2_key_up;
621 g->Lilanek[1].Keys.Down = conf.pl2_key_down;
622 g->Lilanek[1].Keys.Left = conf.pl2_key_left;
623 g->Lilanek[1].Keys.Right = conf.pl2_key_right;
624 g->Lilanek[1].Keys.Shoot = conf.pl2_key_fire;
625 g->Lilanek[1].Keys.Suicide = conf.pl2_key_suicide;
626 g->Lilanek[1].Keys.Switch = conf.pl2_key_switch;
627 g->Lilanek[1].Ammo = malloc(sizeof(int)*g->noWID);
628 for(i=0; i<g->noWID; i++){
629 g->Lilanek[1].Ammo[i] = 0;
631 g->Lilanek[1].ActiveWeapon = 0;
633 SDL_Color blue = {180,180,255};
634 char bluen[8]="Blue";
635 g->Lilanek[1].Color = blue;
636 strcpy(g->Lilanek[1].Name, bluen);
638 SpawnLilanek(g, 1);
640 g->noWID=2;
641 g->WeaponTemplate = malloc(sizeof(TWeapon)*g->noWID);
642 p = NewRect(0,0,0.5,0.5);
643 a = NewArea();
644 AddToArea(a, p);
645 FreePoly(p);
646 g->WeaponTemplate[0].Shape = a;
647 g->WeaponTemplate[0].WID = 0;
648 g->WeaponTemplate[0].Exists = 1;
649 g->WeaponTemplate[0].Ammo = 50;
650 g->WeaponTemplate[0].MaxAmmo = 250;
651 g->WeaponTemplate[0].ReloadTime = 2.1;
652 g->WeaponTemplate[0].Burst = 10;
654 g->BulletTemplate = malloc(sizeof(TBullet) * g->noWID);
655 p = NewRect(0,0,0.1,0.1);
656 a = NewArea();
657 AddToArea(a, p);
658 FreePoly(p);
659 g->BulletTemplate[0].Shape = a;
660 g->BulletTemplate[0].WID = 0;
661 g->BulletTemplate[0].Speed = 20;
662 g->BulletTemplate[0].SFuzzy = 0.040;
663 g->BulletTemplate[0].VFuzzy = 0.000;
665 p = NewRect(0,0,0.5,0.5);
666 a = NewArea();
667 AddToArea(a, p);
668 FreePoly(p);
669 g->WeaponTemplate[1].Shape = a;
670 g->WeaponTemplate[1].WID = 1;
671 g->WeaponTemplate[1].Exists = 1;
672 g->WeaponTemplate[1].Ammo = 3;
673 g->WeaponTemplate[1].MaxAmmo = 6;
674 g->WeaponTemplate[1].ReloadTime = 0.5;
675 g->WeaponTemplate[1].Burst = 1;
677 p = NewRect(0,0,0.5,0.5);
678 a = NewArea();
679 AddToArea(a, p);
680 FreePoly(p);
681 g->BulletTemplate[1].Shape = a;
682 g->BulletTemplate[1].WID = 1;
683 g->BulletTemplate[1].Speed = 0;
684 g->BulletTemplate[1].SFuzzy = 0.0;
685 g->BulletTemplate[1].VFuzzy = 0.0;
687 g->noBullets = 64;
688 g->Bullet = malloc(sizeof(TBullet) * g->noBullets);
689 for(i=0; i<g->noBullets; i++){
690 g->Bullet[i].Exists = 0;
691 g->Bullet[i].Shape = 0;
694 g->PWeapondrop = 0.4;
696 return g;
699 Sprite *lil[5];
700 Sprite *bg;
701 Sprite *kul;
702 Sprite *kulka;
703 Sprite *mine;
704 Sprite *mines;
705 int frames=0;
707 void onExit()
709 GrKill();
710 SDL_Quit();
713 Uint32 callback_fps(Uint32 interval, void *param)
715 SDL_Event event;
716 event.type = SDL_USEREVENT;
717 SDL_PushEvent(&event);
719 return 1000;
722 void Draw(Game *g){
723 int i;
725 QueueDrawSprite(bg, 0.0, 0.0,-1.0);
726 for(i=0; i < g->Map->noSprites; i++)
727 QueueDrawSprite(g->Map->Sprites[i], g->Map->SpritePos[i].x, g->Map->SpritePos[i].y, g->Map->Sprites[i]->z);
728 //Lilaneks
729 for(i=0; i < g->noLilaneks; i++){
730 SDL_Color c;
731 c =g->Lilanek[i].Color;
732 if(g->Lilanek[i].ReloadTime < g->WeaponTemplate[g->Lilanek[i].ActiveWeapon].ReloadTime){
733 c.r *= 0.5;
734 c.g *= 0.5;
735 c.b *= 0.5;
737 QueueDrawSpriteColorize(lil[g->Lilanek[i].Orientation], g->Lilanek[i].Pos.x-1.0, g->Lilanek[i].Pos.y-1.0, 1, c );
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;