24 }TKeyBinding
;//TODO: s/int/real data type for a key
27 Vect Pos
; //where he is
28 Vect Move
; //how he want to move
29 Vect BSize
; //Size of bounding rect
30 Area
*Shape
; //how fat he is
31 //Area *TrShape; //translated Shape -- don't optimize yet
32 int Frags
; //no comment
34 double Speed
; //meters per second
35 int Orientation
; //1-up 2-left 3-down 4-right 0-down
36 int WannaShoot
; //1-want 0-don't want
37 double ReloadTime
; //time from last shot
38 int WannaDie
; //1-want suicide 2-died and still holding suicide 0-don't want
39 double AnimationTime
; //in seconds
54 int Exists
; // 0- doesn't exist 1-exists
65 Vect Vel
; //velocity i m/s
66 double Speed
; //for Templates
67 double Range
; //How far it can travel
69 int lid
; //who shoot this bullet?
70 int Exists
; // 0- doesn't exist 1-exists
71 double SFuzzy
; // Fuzzy factor for spawning 0-1 :)
72 double VFuzzy
; // Fuzzy factor for traveling 0-1 :)
77 TMap
*Map
; //where we are playing
78 TLilanek
*Lilanek
; //our heroes-ehm bad guys
81 TWeapon
*Weapon
; //Weapons lying on floor
83 TWeapon
*WeaponTemplate
;
84 TBullet
*BulletTemplate
;
85 int noWID
; //biggest WID, also number of WeaponTemplates
88 double PWeapondrop
; // Probability of weapon drop per second
118 void SwitchNextWeapon(Game
*g
, int lid
);
124 Orientations
[1].y
=-1;
125 Orientations
[2].x
=-1;
136 void SpawnLilanek(Game
*g
, int lid
){
145 for(tries
=0; tries
<1000; tries
++){ //TODO: remove exact number
146 Pos
.x
= RandD(0,g
->Map
->XX
);
147 Pos
.y
= RandD(0,g
->Map
->YY
);
149 tp
= TranslateArea(g
->Lilanek
[lid
].Shape
, &Pos
);
150 printf("%s\n", Area2String(tp
));
151 if(!AreaInMap(g
->Map
, tp
,0,1)){
155 for(olid
=0; olid
< g
->noLilaneks
; olid
++){
158 if(!g
->Lilanek
[olid
].Alive
){
161 oltp
= TranslateArea(g
->Lilanek
[olid
].Shape
, &g
->Lilanek
[olid
].Pos
);
162 if(AreaInArea(tp
, oltp
)){
172 g
->Lilanek
[lid
].Pos
.x
= Pos
.x
;
173 g
->Lilanek
[lid
].Pos
.y
= Pos
.y
;
174 g
->Lilanek
[lid
].Alive
= 1;
182 int RandWID(Game
*g
) {
183 int SumRandWeight
= 0;
186 for (i
=0; i
< g
->noWID
; i
++) {
187 SumRandWeight
+= g
->WeaponTemplate
[i
].RandomWeight
;
189 j
= RandI(0, SumRandWeight
);
190 for (i
=0; i
< g
->noWID
; i
++) {
191 j
-= g
->WeaponTemplate
[i
].RandomWeight
;
198 void DropWeapon(Game
*g
, int weapon
){
204 for(tries
=0; tries
<100; tries
++){ //TODO: remove exact number
205 Pos
.x
= RandD(0,g
->Map
->XX
);
206 Pos
.y
= RandD(0,g
->Map
->YY
);
208 tp
= TranslateArea(g
->WeaponTemplate
[WID
].Shape
, &Pos
);
209 if(AreaInMap(g
->Map
, tp
, 0, g
->Map
->noLayer
)){
212 memcpy(&g
->Weapon
[weapon
], &g
->WeaponTemplate
[WID
], sizeof(TWeapon
));
213 g
->Weapon
[weapon
].Shape
= g
->WeaponTemplate
[WID
].Shape
;
214 g
->Weapon
[weapon
].Pos
.x
= Pos
.x
;
215 g
->Weapon
[weapon
].Pos
.y
= Pos
.y
;
216 g
->Weapon
[weapon
].WID
= WID
;
217 g
->Weapon
[weapon
].Exists
= 1;
225 void DropWeapons(Game
*g
, double dtime
){
228 if( RandD(0.0, 1.0) >= (g
->PWeapondrop
*dtime
))
230 for(i
=0; i
< g
->noWeapons
; i
++){
231 if(g
->Weapon
[i
].Exists
)continue; //we don't like teleporting weapons :)
233 printf("A Weapon drop!\n");
235 break; //spawn max one weapon per update
239 void WeaponPickedUp(Game
*g
, double dtime
, int lid
, int wid
){
243 l
= &g
->Lilanek
[lid
];
246 l
->Ammo
[w
->WID
] += w
->Ammo
;
247 if(l
->Ammo
[w
->WID
] > w
->MaxAmmo
)
248 l
->Ammo
[w
->WID
] = w
->MaxAmmo
;
249 printf("Ammo: %d\n",l
->Ammo
[w
->WID
]);
250 l
->ActiveWeapon
= w
->WID
;
251 printf("AW: %d\n",l
->ActiveWeapon
);
258 void PickUpWeapons(Game
*g
, double dtime
){
262 for(lid
=0; lid
<g
->noLilaneks
; lid
++){
263 LArea
= TranslateArea(g
->Lilanek
[lid
].Shape
, &g
->Lilanek
[lid
].Pos
);
264 for(wid
=0; wid
< g
->noWeapons
; wid
++){
265 if(!g
->Weapon
[wid
].Exists
)
267 WArea
= TranslateArea(g
->Weapon
[wid
].Shape
, &g
->Weapon
[wid
].Pos
);
268 if(!AreaInArea( WArea
, LArea
)){
272 WeaponPickedUp(g
, dtime
, lid
, wid
);
279 void BulletExplodes(Game
*g
, int i
){
280 g
->Bullet
[i
].Exists
=0;
285 void MoveBullet(Game
*g
, double dtime
, int i
){
288 dp
.x
= g
->Bullet
[i
].Pos
.x
;
289 dp
.y
= g
->Bullet
[i
].Pos
.y
;
290 ff
= g
->Bullet
[i
].Speed
*g
->Bullet
[i
].VFuzzy
;
291 g
->Bullet
[i
].Pos
.x
+= (g
->Bullet
[i
].Vel
.x
+= RandD(-ff
,ff
))* dtime
;
292 g
->Bullet
[i
].Pos
.y
+= (g
->Bullet
[i
].Vel
.y
+= RandD(-ff
,ff
))* dtime
;
293 dp
.x
-= g
->Bullet
[i
].Pos
.x
;
294 dp
.y
-= g
->Bullet
[i
].Pos
.y
;
295 g
->Bullet
[i
].Range
-= sqrt(DotProduct(&dp
, &dp
));
298 void CollideBulletMap(Game
*g
, double dtime
, int i
){
301 p
=TranslateArea(g
->Bullet
[i
].Shape
, &g
->Bullet
[i
].Pos
);
302 if(AreaInMap(g
->Map
, p
, 1,1)==0)
303 BulletExplodes(g
, i
);
307 void BloodColorFunc(double temp
, SDL_Color
*c
)
309 SDL_Color col
={255,255,255,255};
310 col
.r
*=(0.5+0.5*temp
);
313 //col.unused *=temp*temp;
314 if (c
!= 0) memcpy(c
, &col
, sizeof(SDL_Color
));
317 void BloodParticles(Game
*g
, double dtime
, int lid
)
324 for(i
= 0; i
< 5; i
++){
325 p
= malloc(sizeof(Particle
));
326 memset(p
, 0, sizeof(Particle
));
327 a
= RandD(0.0, 20.0);
329 p
->x
= g
->Lilanek
[lid
].Pos
.x
-g
->Lilanek
[lid
].BSize
.x
*0.5;
330 p
->y
= g
->Lilanek
[lid
].Pos
.y
-g
->Lilanek
[lid
].BSize
.y
*0.5;
332 p
->vx
= v
*sin(a
) + g
->Lilanek
[lid
].Move
.x
;
333 p
->vy
= v
*cos(a
) + g
->Lilanek
[lid
].Move
.y
;
338 p
->tf
= &BloodColorFunc
;
344 void LilanekKilled(Game
*g
, double dtime
, int BulletID
, int LilanekID
){
346 g
->Bullet
[BulletID
].Exists
= 0;
347 g
->Lilanek
[LilanekID
].Deaths
++;
348 if (LilanekID
!= g
->Bullet
[BulletID
].lid
) {
349 g
->Lilanek
[g
->Bullet
[BulletID
].lid
].Frags
++;
351 g
->Lilanek
[g
->Bullet
[BulletID
].lid
].Frags
--;
353 BloodParticles(g
, dtime
, LilanekID
);
354 SpawnLilanek(g
, LilanekID
);
355 for(i
=0; i
<g
->noWID
; i
++){
356 g
->Lilanek
[LilanekID
].Ammo
[i
] = 0;
361 #define NO_EXPLOSIONS 10 //MAGIC_NUMBER
362 #define EXPLOSION_SPEED 5 //MAGIC_NUMBER
363 #define EXPLOSION_RANGE 1.0 //MAGIC_NUMBER
365 void SpawnExplosions(Game
*g
, double dtime
, int BulletID
){
372 Pos
.x
= g
->Bullet
[BulletID
].Pos
.x
;
373 Pos
.y
= g
->Bullet
[BulletID
].Pos
.y
;
374 for(i
=0; i
<NO_EXPLOSIONS
; i
++){
375 for(bid
=0; bid
<g
->noBullets
; bid
++){
376 if(g
->Bullet
[bid
].Exists
)
381 b
->Vel
.x
= RandD(0.0, 1.0)*(RandI(0,100)>50?-1:1);
382 b
->Vel
.y
= RandD(0.0, 1.0)*(RandI(0,100)>50?-1:1);
384 speed
= RandD(0.3, 1.0)*EXPLOSION_SPEED
;
389 b
->lid
= g
->Bullet
[BulletID
].lid
;
393 b
->Range
= EXPLOSION_RANGE
;
394 b
->Shape
= g
->Bullet
[BulletID
].Shape
;
395 printf("%lf ", speed
);
399 g
->Bullet
[BulletID
].Exists
= 0;
403 void CollideBulletLilanek(Game
*g
, double dtime
, int BulletID
){
407 BArea
=TranslateArea(g
->Bullet
[BulletID
].Shape
, &g
->Bullet
[BulletID
].Pos
);
408 for(LilanekID
=0; LilanekID
<g
->noLilaneks
; LilanekID
++){
409 LArea
=TranslateArea(g
->Lilanek
[LilanekID
].Shape
, &g
->Lilanek
[LilanekID
].Pos
);
410 if(AreaInArea(LArea
,BArea
)){
411 //if it is a mine, spawn an explosion instead of killing instantly
412 if(g
->Bullet
[BulletID
].WID
== 1){
413 SpawnExplosions(g
, dtime
, BulletID
);
415 LilanekKilled(g
, dtime
, BulletID
, LilanekID
);
425 void UpdateBullets(Game
*g
, double dtime
){
427 for(BulletID
=0; BulletID
<g
->noBullets
; BulletID
++){
428 if(g
->Bullet
[BulletID
].Exists
==0)
429 continue; //We won't update non-existending bullets
430 MoveBullet(g
, dtime
, BulletID
);
431 if(g
->Bullet
[BulletID
].Range
< 0){
432 g
->Bullet
[BulletID
].Exists
= 0;
435 CollideBulletMap(g
, dtime
, BulletID
);
436 CollideBulletLilanek(g
, dtime
, BulletID
);
440 int CheckLilanekvsLilaneks(Game
*g
, Area
*a
, int LilanekID
){ //returns 0 if he collides with others, 1 if it's OK to move there
446 for(i
=0; i
<g
->noLilaneks
&& rval
==1; i
++){
449 nb
= TranslateArea(g
->Lilanek
[i
].Shape
, &g
->Lilanek
[i
].Pos
);
450 if(AreaInArea(nb
, a
))
458 void MoveLilaneks(Game
*g
, double dtime
){
465 for(i
=0; i
<g
->noLilaneks
; i
++){
466 //skip this Lilanek if he doesn't wanna move
467 if(g
->Lilanek
[i
].Move
.x
== 0.0 && g
->Lilanek
[i
].Move
.y
== 0.0)
469 for(dt
=dtime
, steps
=0; steps
<4; dt
/=2.0, steps
++){ //TODO: get rid of exact number
471 va
.x
= g
->Lilanek
[i
].Pos
.x
+ dt
*g
->Lilanek
[i
].Move
.x
;
472 va
.y
= g
->Lilanek
[i
].Pos
.y
+ dt
*g
->Lilanek
[i
].Move
.y
;
473 FreeArea(pa
); //we don't want memory leaks
474 pa
= TranslateArea(g
->Lilanek
[i
].Shape
, &va
);
475 //check for collision with map
476 if(AreaInMap(g
->Map
, pa
, 0, 1)==0)
477 continue; //try smaller dt if he collided with map
478 //check for collision with other Lilaneks
479 if(CheckLilanekvsLilaneks(g
, pa
, i
)==0)
481 //move him if we got here
482 g
->Lilanek
[i
].Pos
.x
+= dt
*g
->Lilanek
[i
].Move
.x
;
483 g
->Lilanek
[i
].Pos
.y
+= dt
*g
->Lilanek
[i
].Move
.y
;
487 FreeArea(pa
); //For sure
492 void ParseInput(Game
*g
, double dtime
){
498 keystate
= SDL_GetKeyState(NULL
);
511 for(i
=0; i
< g
->noLilaneks
; i
++){
512 curlil
= &g
->Lilanek
[i
];
515 if(keystate
[curlil
->Keys
.Up
]){
516 curlil
->Orientation
= 1;
517 curlil
->Move
.x
= curlil
->Speed
* Orientations
[1].x
;
518 curlil
->Move
.y
= curlil
->Speed
* Orientations
[1].y
;
522 if(keystate
[curlil
->Keys
.Down
]){
523 curlil
->Orientation
= 3;
524 curlil
->Move
.x
= curlil
->Speed
* Orientations
[3].x
;
525 curlil
->Move
.y
= curlil
->Speed
* Orientations
[3].y
;
529 if(keystate
[curlil
->Keys
.Left
]){
530 curlil
->Orientation
= 2;
531 curlil
->Move
.x
= curlil
->Speed
* Orientations
[2].x
;
532 curlil
->Move
.y
= curlil
->Speed
* Orientations
[2].y
;
536 if(keystate
[curlil
->Keys
.Right
]){
537 curlil
->Orientation
= 4;
538 curlil
->Move
.x
= curlil
->Speed
* Orientations
[4].x
;
539 curlil
->Move
.y
= curlil
->Speed
* Orientations
[4].y
;
548 if(keystate
[curlil
->Keys
.Shoot
]){
549 curlil
->WannaShoot
= 1;
551 curlil
->WannaShoot
= 0;
554 if(keystate
[curlil
->Keys
.Suicide
]){
555 if(curlil
->WannaDie
!= 2){
556 curlil
->WannaDie
= 1;
559 curlil
->WannaDie
= 0;
562 if(keystate
[curlil
->Keys
.Switch
]){
563 if(!curlil
->SwitchLock
){
564 SwitchNextWeapon(g
, i
);
565 curlil
->SwitchLock
= 1;
568 curlil
->SwitchLock
= 0;
573 void SpawnBullet(Game
*g
, double dtime
, int lid
, int bid
){
576 double vx
, vy
; //because we need to spawn also mines with no velocity
579 LArea
= TranslateArea(g
->Lilanek
[lid
].Shape
, &g
->Lilanek
[lid
]. Pos
);
581 bt
= &g
->BulletTemplate
[g
->Lilanek
[lid
].ActiveWeapon
];
582 memcpy (b
, bt
, sizeof(TBullet
));
584 b
->Pos
.x
= g
->Lilanek
[lid
].Pos
.x
+g
->Lilanek
[lid
].BSize
.x
*0.5;
585 b
->Pos
.y
= g
->Lilanek
[lid
].Pos
.y
+g
->Lilanek
[lid
].BSize
.y
*0.5;
587 b
->Range
= bt
->Range
;
588 b
->Vel
.x
= Orientations
[g
->Lilanek
[lid
].Orientation
].x
* b
->Speed
+RandD(-b
->Speed
*b
->SFuzzy
, b
->Speed
*b
->SFuzzy
);
589 b
->Vel
.y
= Orientations
[g
->Lilanek
[lid
].Orientation
].y
* b
->Speed
+RandD(-b
->Speed
*b
->SFuzzy
, b
->Speed
*b
->SFuzzy
);
590 if(DotProduct(&b
->Vel
, &b
->Vel
) <=0.01){
591 vx
= -1*Orientations
[g
->Lilanek
[lid
].Orientation
].x
;
592 vy
= -1*Orientations
[g
->Lilanek
[lid
].Orientation
].y
;
599 BArea
= TranslateArea(b
->Shape
, &b
->Pos
);
600 if(!AreaInArea(BArea
, LArea
))
602 b
->Pos
.x
+= vx
* dtime
*0.5;
603 b
->Pos
.y
+= vy
* dtime
*0.5;
608 void DustColorFunc(double temp
, SDL_Color
*c
)
610 SDL_Color col
={255,255,255,255};
614 col
.unused
*=temp
*temp
;
615 if (c
!= 0) memcpy(c
, &col
, sizeof(SDL_Color
));
618 void ShootParticles(Game
*g
, double dtime
, int lid
)
625 for(i
= 1; i
< 10; i
++){
626 p
= malloc(sizeof(Particle
));
627 memset(p
, 0, sizeof(Particle
));
628 a
= RandD(0.0, 2*M_PI
);
630 p
->x
= g
->Lilanek
[lid
].Pos
.x
-g
->Lilanek
[lid
].BSize
.x
*0.5;
631 p
->y
= g
->Lilanek
[lid
].Pos
.y
-g
->Lilanek
[lid
].BSize
.y
*0.5;
633 p
->vx
= v
*sin(a
) + g
->Lilanek
[lid
].Move
.x
;
634 p
->vy
= v
*cos(a
) + g
->Lilanek
[lid
].Move
.y
;
638 p
->tf
= &DustColorFunc
;
643 void Shoot(Game
*g
, double dtime
, int lid
){
647 for(i
=0; i
<g
->WeaponTemplate
[g
->Lilanek
[lid
].ActiveWeapon
].Burst
; i
++){
648 if(g
->Lilanek
[lid
].Ammo
[g
->Lilanek
[lid
].ActiveWeapon
] == 0)
650 for(bid
=0; bid
<g
->noBullets
; bid
++){
651 if(g
->Bullet
[bid
].Exists
)
653 SpawnBullet(g
, dtime
, lid
, bid
);
654 g
->Lilanek
[lid
].Ammo
[g
->Lilanek
[lid
].ActiveWeapon
]--;
655 g
->Lilanek
[lid
].ReloadTime
= 0;
659 ShootParticles(g
, dtime
, lid
);
660 switch(g
->Lilanek
[lid
].ActiveWeapon
){
661 case 0: PlaySound(s_shoot
); break;
662 case 1: PlaySound(s_mine
); break;
663 case 2: PlaySound(s_shoot
); break;
668 void SwitchNextWeapon(Game
*g
, int lid
){
671 l
= &g
->Lilanek
[lid
];
672 for(i
= 1; i
< g
->noWID
; i
++){
673 if(l
->Ammo
[(l
->ActiveWeapon
+i
)%(g
->noWID
)]){
674 l
->ActiveWeapon
= (l
->ActiveWeapon
+i
)%(g
->noWID
);
680 void ShootIfTheyWantTo(Game
*g
, double dtime
){
683 for(lid
=0; lid
<g
->noLilaneks
; lid
++){
684 //if(!g->Lilanek[lid].Exists)
686 if(g
->Lilanek
[lid
].Ammo
[g
->Lilanek
[lid
].ActiveWeapon
] == 0)
687 SwitchNextWeapon(g
,lid
);
689 if(g
->Lilanek
[lid
].ReloadTime
< g
->WeaponTemplate
[g
->Lilanek
[lid
].ActiveWeapon
].ReloadTime
){
690 g
->Lilanek
[lid
].ReloadTime
+= dtime
;
692 if(!g
->Lilanek
[lid
].WannaShoot
)
694 Shoot(g
, dtime
, lid
);
699 int UpdateLogic(Game
*g
,double dtime
){
701 DropWeapons(g
, dtime
);
702 UpdateBullets(g
, dtime
);
704 ParseInput(g
, dtime
);
706 MoveLilaneks(g
, dtime
);
707 PickUpWeapons(g
, dtime
);
708 ShootIfTheyWantTo(g
, dtime
);
710 return 0; //TODO: return something useful
713 Game
*testgame(){ //return testing game, function for use before we have some menu/loading mechanism
718 Config conf
= GetConfig();
720 g
= malloc(sizeof(Game
));
721 memset(g
, 0, sizeof(Game
));
723 g
->Map
= malloc(sizeof(TMap
));
725 g
->Map
->Layer
= malloc(sizeof(TMapLayer
*)*g
->Map
->noLayer
);
726 g
->Map
->Layer
[0] = malloc(sizeof(TMapLayer
));
727 g
->Map
->Layer
[0]->noFArea
= 1;
728 g
->Map
->Layer
[0]->FArea
= malloc(sizeof(Area
*) * g
->Map
->Layer
[0]->noFArea
);
729 p
= NewRect(4,2.5,3,2);
733 g
->Map
->Layer
[0]->FArea
[0] = a
;
735 g
->Map
->Layer
[1] = malloc(sizeof(TMapLayer
));
736 g
->Map
->Layer
[1]->noFArea
= 1;
737 g
->Map
->Layer
[1]->FArea
= malloc(sizeof(Area
*) * g
->Map
->Layer
[1]->noFArea
);
739 AddToPolyXY(p
, 0.30, 0.41);
740 AddToPolyXY(p
, 0.73, 0.41);
741 AddToPolyXY(p
, 0.77, 0.79);
742 AddToPolyXY(p
, 0.65, 0.955);
743 AddToPolyXY(p
, 0.365, 0.965);
744 AddToPolyXY(p
, 0.235, 0.785);
745 MultiplyPoly(p
, 4, 4);
746 pp
= TranslatePolyXY(p
, 7, 7);
751 g
->Map
->Layer
[1]->FArea
[0] = a
;
752 p
= NewRect(1,1,16,15);
756 g
->Map
->BoundingArea
= a
;
762 SetParticleBoundingBox(0,0,16,15);
766 g
->Map
->noSprites
= 2;
767 g
->Map
->Sprites
= (Sprite
**) malloc(sizeof(Sprite
*)*g
->Map
->noSprites
);
768 g
->Map
->SpritePos
= (Vect
*) malloc(sizeof(Vect
)*g
->Map
->noSprites
);
769 g
->Map
->SpritePos
[0].x
= 3.0;
770 g
->Map
->SpritePos
[0].y
= 1.0;
771 g
->Map
->SpritePos
[1].x
= 6.0;
772 g
->Map
->SpritePos
[1].y
= 6.0;
775 g
->Weapon
= malloc(sizeof(TWeapon
) * g
->noWeapons
);
777 fprintf(stderr
, "Cannot allocate memory for Weapons\n");
779 for(i
=0; i
<g
->noWeapons
; i
++){
780 g
->Weapon
[i
].Exists
= 0;
781 g
->Weapon
[i
].Shape
= 0;
785 g
->Lilanek
= malloc(sizeof(TLilanek
) * g
->noLilaneks
);
786 memset(g
->Lilanek
, 0, sizeof(TLilanek
) * g
->noLilaneks
);
787 g
->Lilanek
[0].BSize
.x
= 1;
788 g
->Lilanek
[0].BSize
.y
= 1;
789 //g->Lilanek[0].Shape = NewRect(0.6,0.2,0.8,1.6);
791 AddToPolyXY(p
, 1, 0);
792 AddToPolyXY(p
, 1.4, 0.2);
793 AddToPolyXY(p
, 1.66, 1.38);
794 AddToPolyXY(p
, 1.42, 2);
795 AddToPolyXY(p
, 0.6, 2);
796 AddToPolyXY(p
, 0.4, 1.46);
797 AddToPolyXY(p
, 0.66, 0.2);
798 MultiplyPoly(p
, 0.5*g
->Lilanek
[0].BSize
.x
, 0.5*g
->Lilanek
[0].BSize
.y
);
802 g
->Lilanek
[0].Shape
= a
;
803 g
->Lilanek
[0].Pos
.x
= 12;
804 g
->Lilanek
[0].Pos
.y
= 4;
805 g
->Lilanek
[0].Speed
= 4;
806 g
->Lilanek
[0].Alive
= 0;
807 g
->Lilanek
[0].Keys
.Up
= conf
.pl1_key_up
;
808 g
->Lilanek
[0].Keys
.Down
= conf
.pl1_key_down
;
809 g
->Lilanek
[0].Keys
.Left
= conf
.pl1_key_left
;
810 g
->Lilanek
[0].Keys
.Right
= conf
.pl1_key_right
;
811 g
->Lilanek
[0].Keys
.Shoot
= conf
.pl1_key_fire
;
812 g
->Lilanek
[0].Keys
.Suicide
= conf
.pl1_key_suicide
;
813 g
->Lilanek
[0].Keys
.Switch
= conf
.pl1_key_switch
;
814 g
->Lilanek
[0].Ammo
= malloc(sizeof(int)*g
->noWID
);
815 for(i
=0; i
<g
->noWID
; i
++){
816 g
->Lilanek
[0].Ammo
[i
] = 0;
818 g
->Lilanek
[0].ActiveWeapon
= 0;
820 SDL_Color red
= {255,211,211,255};
822 g
->Lilanek
[0].Color
= red
;
823 strcpy(g
->Lilanek
[0].Name
, redn
);
825 g
->Lilanek
[1].Alive
= 0; // little hack for SpawnLilanek to work
828 p
= g
->Lilanek
[0].Shape
->p
[0];
831 g
->Lilanek
[1].Shape
= a
;
832 g
->Lilanek
[1].BSize
.x
= g
->Lilanek
[0].BSize
.x
;
833 g
->Lilanek
[1].BSize
.y
= g
->Lilanek
[0].BSize
.y
;
834 g
->Lilanek
[1].Pos
.x
= 14;
835 g
->Lilanek
[1].Pos
.y
= 4;
836 g
->Lilanek
[1].Speed
= 4;
837 g
->Lilanek
[1].Alive
= 0;
838 g
->Lilanek
[1].Keys
.Up
= conf
.pl2_key_up
;
839 g
->Lilanek
[1].Keys
.Down
= conf
.pl2_key_down
;
840 g
->Lilanek
[1].Keys
.Left
= conf
.pl2_key_left
;
841 g
->Lilanek
[1].Keys
.Right
= conf
.pl2_key_right
;
842 g
->Lilanek
[1].Keys
.Shoot
= conf
.pl2_key_fire
;
843 g
->Lilanek
[1].Keys
.Suicide
= conf
.pl2_key_suicide
;
844 g
->Lilanek
[1].Keys
.Switch
= conf
.pl2_key_switch
;
845 g
->Lilanek
[1].Ammo
= malloc(sizeof(int)*g
->noWID
);
846 for(i
=0; i
<g
->noWID
; i
++){
847 g
->Lilanek
[1].Ammo
[i
] = 0;
849 g
->Lilanek
[1].ActiveWeapon
= 0;
851 SDL_Color blue
= {180,180,255, 255};
852 char bluen
[8]="Blue";
853 g
->Lilanek
[1].Color
= blue
;
854 strcpy(g
->Lilanek
[1].Name
, bluen
);
858 g
->WeaponTemplate
= malloc(sizeof(TWeapon
)*g
->noWID
);
859 p
= NewRect(0,0,0.5,0.5);
863 g
->WeaponTemplate
[0].Shape
= a
;
864 g
->WeaponTemplate
[0].WID
= 0;
865 g
->WeaponTemplate
[0].Exists
= 1;
866 g
->WeaponTemplate
[0].Ammo
= 30;
867 g
->WeaponTemplate
[0].MaxAmmo
= 120;
868 g
->WeaponTemplate
[0].ReloadTime
= 0.7;
869 g
->WeaponTemplate
[0].Burst
= 10;
870 g
->WeaponTemplate
[0].RandomWeight
= 10;
872 g
->BulletTemplate
= malloc(sizeof(TBullet
) * g
->noWID
);
875 p
= NewRect(0,0,0.1,0.1);
879 g
->BulletTemplate
[0].Shape
= a
;
880 g
->BulletTemplate
[0].WID
= 0;
881 g
->BulletTemplate
[0].Speed
= 20;
882 g
->BulletTemplate
[0].Range
= 20;
883 g
->BulletTemplate
[0].SFuzzy
= 0.160;
884 g
->BulletTemplate
[0].VFuzzy
= 0.000;
887 p
= NewRect(0,0,0.5,0.5);
891 g
->WeaponTemplate
[1].Shape
= a
;
892 g
->WeaponTemplate
[1].WID
= 1;
893 g
->WeaponTemplate
[1].Exists
= 1;
894 g
->WeaponTemplate
[1].Ammo
= 3;
895 g
->WeaponTemplate
[1].MaxAmmo
= 6;
896 g
->WeaponTemplate
[1].ReloadTime
= 0.5;
897 g
->WeaponTemplate
[1].Burst
= 1;
898 g
->WeaponTemplate
[1].RandomWeight
= 5;
900 p
= NewRect(0,0,0.5,0.5);
904 g
->BulletTemplate
[1].Shape
= a
;
905 g
->BulletTemplate
[1].WID
= 1;
906 g
->BulletTemplate
[1].Speed
= 0;
907 g
->BulletTemplate
[1].Range
= 20;
908 g
->BulletTemplate
[1].SFuzzy
= 0.0;
909 g
->BulletTemplate
[1].VFuzzy
= 0.0;
912 p
= NewRect(0,0,0.5,0.5);
916 g
->WeaponTemplate
[2].Shape
= a
;
917 g
->WeaponTemplate
[2].WID
= 0;
918 g
->WeaponTemplate
[2].Exists
= 1;
919 g
->WeaponTemplate
[2].Ammo
= 10;
920 g
->WeaponTemplate
[2].MaxAmmo
= 50;
921 g
->WeaponTemplate
[2].ReloadTime
= 0.1;
922 g
->WeaponTemplate
[2].Burst
= 1;
923 g
->WeaponTemplate
[2].RandomWeight
= 15;
925 p
= NewRect(0,0,0.1,0.1);
929 g
->BulletTemplate
[2].Shape
= a
;
930 g
->BulletTemplate
[2].WID
= 0;
931 g
->BulletTemplate
[2].Speed
= 20;
932 g
->BulletTemplate
[2].Range
= 20;
933 g
->BulletTemplate
[2].SFuzzy
= 0.040;
934 g
->BulletTemplate
[2].VFuzzy
= 0.010;
937 p
= NewRect(0,0,0.5,0.5);
941 g
->WeaponTemplate
[3].Shape
= a
;
942 g
->WeaponTemplate
[3].WID
= 0;
943 g
->WeaponTemplate
[3].Exists
= 1;
944 g
->WeaponTemplate
[3].Ammo
= 5;
945 g
->WeaponTemplate
[3].MaxAmmo
= 20;
946 g
->WeaponTemplate
[3].ReloadTime
= 1.1;
947 g
->WeaponTemplate
[3].Burst
= 1;
948 g
->WeaponTemplate
[3].RandomWeight
= 10;
950 p
= NewRect(0,0,0.1,0.1);
954 g
->BulletTemplate
[3].Shape
= a
;
955 g
->BulletTemplate
[3].WID
= 0;
956 g
->BulletTemplate
[3].Speed
= 50;
957 g
->BulletTemplate
[3].Range
= 200;
958 g
->BulletTemplate
[3].SFuzzy
= 0.000;
959 g
->BulletTemplate
[3].VFuzzy
= 0.000;
962 g
->Bullet
= malloc(sizeof(TBullet
) * g
->noBullets
);
963 for(i
=0; i
<g
->noBullets
; i
++){
964 g
->Bullet
[i
].Exists
= 0;
965 g
->Bullet
[i
].Shape
= 0;
968 g
->PWeapondrop
= 0.4;
980 Uint32
callback_fps(Uint32 interval
, void *param
)
983 event
.type
= SDL_USEREVENT
;
984 SDL_PushEvent(&event
);
989 SDL_Color
InvertColor(SDL_Color c
) {
1001 QueueDrawSprite(bg
, 0.0, 0.0,-1.0);
1002 for(i
=0; i
< g
->Map
->noSprites
; i
++)
1003 QueueDrawSprite(g
->Map
->Sprites
[i
], g
->Map
->SpritePos
[i
].x
, g
->Map
->SpritePos
[i
].y
, g
->Map
->Sprites
[i
]->z
);
1005 for(i
=0; i
< g
->noLilaneks
; i
++){
1009 c
=g
->Lilanek
[i
].Color
;
1010 if(g
->Lilanek
[i
].ReloadTime
< g
->WeaponTemplate
[g
->Lilanek
[i
].ActiveWeapon
].ReloadTime
){
1016 QueueDrawSpriteColorize(lil
[g
->Lilanek
[i
].Orientation
], g
->Lilanek
[i
].Pos
.x
-1.0, g
->Lilanek
[i
].Pos
.y
-1.0, 1, c
);
1017 QueueDrawSpriteColorize(hud
,16.0,4.0*i
, 1.0, c
);
1018 switch(g
->Lilanek
[i
].ActiveWeapon
){
1019 case 0: QueueDrawSprite(hud_brok
, 16.0, 0.0+4.0*i
,0.0);
1021 case 1: QueueDrawSprite(hud_mine
, 16.0, 0.0+4.0*i
,0.0);
1023 case 2: QueueDrawSprite(hud_kul
, 16.0, 0.0+4.0*i
,0.0);
1025 case 3: QueueDrawSprite(hud_sniper
, 16.0, 0.0+4.0*i
,0.0);
1028 pd
= (double)g
->Lilanek
[i
].Ammo
[g
->Lilanek
[i
].ActiveWeapon
]/(double)g
->WeaponTemplate
[g
->Lilanek
[i
].ActiveWeapon
].MaxAmmo
;
1029 QueueDrawSpriteColorizeStretch(hud_ammo
, 18.0-2.0*pd
, 0.0+4.0*i
,4.0*pd
, 4.0, 2.0,c
);
1030 pd
= (double)g
->Lilanek
[i
].ReloadTime
/(double)g
->WeaponTemplate
[g
->Lilanek
[i
].ActiveWeapon
].ReloadTime
;
1032 QueueDrawSpriteColorizeStretch(hud_reload
, 18.0-2.0*pd
, 0.0+4.0*i
,4.0*pd
, 4.0, 2.0,c
);
1033 snprintf (fragsbuf
, 16, "F: %d", g
->Lilanek
[i
].Frags
);
1034 QueueDrawTextColorize (fragsbuf
, 18.1, 4.0*i
+0.5, 4.0, InvertColor(g
->Lilanek
[i
].Color
));
1035 snprintf (fragsbuf
, 16, "D: %d", g
->Lilanek
[i
].Deaths
);
1036 QueueDrawTextColorize (fragsbuf
, 18.1, 4.0*i
+0.5*2.0, 4.0, InvertColor(g
->Lilanek
[i
].Color
));
1039 for(i
=0; i
< g
->noWeapons
; i
++)
1040 if(g
->Weapon
[i
].Exists
)
1041 switch(g
->Weapon
[i
].WID
){
1042 case 0: QueueDrawSprite(brok
, g
->Weapon
[i
].Pos
.x
- 1.0, g
->Weapon
[i
].Pos
.y
- 1.0,1.0);
1044 case 1: QueueDrawSprite(mines
, g
->Weapon
[i
].Pos
.x
- 1.0, g
->Weapon
[i
].Pos
.y
- 1.0,1.0);
1046 case 2: QueueDrawSprite(kul
, g
->Weapon
[i
].Pos
.x
- 1.0, g
->Weapon
[i
].Pos
.y
- 1.0,1.0);
1048 case 3: QueueDrawSprite(sniper
, g
->Weapon
[i
].Pos
.x
- 1.0, g
->Weapon
[i
].Pos
.y
- 1.0,1.0);
1052 for(i
=0; i
< g
->noBullets
; i
++)
1053 if(g
->Bullet
[i
].Exists
)
1054 switch(g
->Bullet
[i
].WID
){
1055 case 0: QueueDrawSprite(kulka
, g
->Bullet
[i
].Pos
.x
- 1.0, g
->Bullet
[i
].Pos
.y
- 1.0,1.0);break;
1056 case 1: QueueDrawSprite(mine
, g
->Bullet
[i
].Pos
.x
- 1.0, g
->Bullet
[i
].Pos
.y
- 1.0,1.0);break;
1057 case 2: QueueDrawSprite(kulka
, g
->Bullet
[i
].Pos
.x
- 1.0, g
->Bullet
[i
].Pos
.y
- 1.0,1.0);break;
1058 case -1: QueueDrawSprite(explo
, g
->Bullet
[i
].Pos
.x
- 1.0, g
->Bullet
[i
].Pos
.y
- 1.0,1.0);break;
1063 int InitAll(Game
**g
){
1067 //TODO: odstranit SaveConfig... je to tu jenom kvuli debugovani
1070 if (SDL_Init(SDL_INIT_VIDEO
| SDL_INIT_TIMER
|SDL_INIT_AUDIO
) < 0) {
1071 fprintf(stderr
, "Unable to init SDL: %s\n", SDL_GetError());
1081 printf(PATH_GRAPHICS
"lil.svg");
1082 lil
[0] = LoadSpriteSVG(PATH_GRAPHICS
"lil.svg", 1.0, 1.0);
1083 lil
[1] = LoadSpriteSVG(PATH_GRAPHICS
"lilb.svg", 1.0, 1.0);
1084 lil
[2] = LoadSpriteSVG(PATH_GRAPHICS
"lill.svg", 1.0, 1.0);
1085 lil
[3] = LoadSpriteSVG(PATH_GRAPHICS
"lil.svg", 1.0, 1.0);
1086 lil
[4] = LoadSpriteSVG(PATH_GRAPHICS
"lilr.svg", 1.0, 1.0);
1087 (*g
)->Map
->Sprites
[0] = LoadSpriteSVG(PATH_GRAPHICS
"prek1.svg", 3.0, 3.0);
1088 (*g
)->Map
->Sprites
[1] = LoadSpriteSVG(PATH_GRAPHICS
"prek2.svg", 4.0, 4.0);
1089 (*g
)->Map
->Sprites
[0]->z
= 1;
1090 (*g
)->Map
->Sprites
[1]->z
= 1;
1092 bg
= LoadSpriteSVG(PATH_GRAPHICS
"bg.svg", 16.0, 15.0);
1093 kul
= LoadSpriteSVG(PATH_GRAPHICS
"kul.svg", 0.5, 0.5);
1094 explo
= LoadSpriteSVG(PATH_GRAPHICS
"exp.svg", 0.5, 0.5);
1095 dust
= LoadSpriteSVG(PATH_GRAPHICS
"dust.svg", 0.5, 0.5);
1096 blood
= LoadSpriteSVG(PATH_GRAPHICS
"blood.svg", 0.5, 0.5);
1097 brok
= LoadSpriteSVG(PATH_GRAPHICS
"brok.svg", 0.5, 0.5);
1098 sniper
= LoadSpriteSVG(PATH_GRAPHICS
"sniper.svg", 0.5, 0.5);
1099 kulka
= LoadSpriteSVG(PATH_GRAPHICS
"kulka.svg", 0.1, 0.1);
1100 mine
= LoadSpriteSVG(PATH_GRAPHICS
"mine.svg", 0.5, 0.5);
1101 mines
= LoadSpriteSVG(PATH_GRAPHICS
"mines.svg", 0.5, 0.5);
1102 hud
= LoadSpriteSVG(PATH_GRAPHICS
"hud.svg", 4.0, 4.0);
1103 hud_mine
= LoadSpriteSVG(PATH_GRAPHICS
"mines.svg", 2.2, 2.2);
1104 hud_kul
= LoadSpriteSVG(PATH_GRAPHICS
"kul.svg", 2.2, 2.2);
1105 hud_brok
= LoadSpriteSVG(PATH_GRAPHICS
"brok.svg", 2.2, 2.2);
1106 hud_sniper
= LoadSpriteSVG(PATH_GRAPHICS
"sniper.svg", 2.2, 2.2);
1107 hud_ammo
= LoadSpriteSVG(PATH_GRAPHICS
"hud_ammo.svg", 4.0, 4.0);
1108 hud_reload
= LoadSpriteSVG(PATH_GRAPHICS
"hud_reload.svg", 4.0, 4.0);
1110 s_die
= LoadSound(PATH_SOUNDS
"die.wav");
1111 s_bonus
= LoadSound(PATH_SOUNDS
"bonus.wav");
1112 s_expl
= LoadSound(PATH_SOUNDS
"expl.wav");
1113 s_shoot
= LoadSound(PATH_SOUNDS
"shoot.wav");
1114 s_mine
= LoadSound(PATH_SOUNDS
"mine.wav");
1116 SDL_AddTimer(1000, callback_fps
, NULL
);
1121 int GameLoop(Game
*g
){
1124 double lasttime
, dtime
;
1126 lasttime
= SDL_GetTicks()*0.001;
1128 while (SDL_PollEvent(&event
)) {
1129 switch (event
.type
) {
1131 if (event
.key
.keysym
.sym
== SDLK_q
) {
1140 case SDL_VIDEORESIZE
:
1141 /* Resize the screen and redraw */
1143 conf
.screen_width
=event
.resize
.w
;
1144 conf
.screen_height
=event
.resize
.h
;
1147 InvalidateSprites();
1151 printf("%d frames\n",frames
);
1159 dtime
= SDL_GetTicks()*0.001-lasttime
;
1165 UpdateLogic(g
, dtime
*0.5);
1166 UpdateLogic(g
, dtime
*0.5);
1169 UpdateAndQueueDrawParticles(dtime
);
1172 //we don't want to waste cpu...
1180 int main(int argc
, char **argv
){