1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <math.h>
5 #include <time.h>
6 
7 #ifdef UNIX
8 
9 #include"xpired_unix.h"
10 
11 #endif
12 
13 #include <SDL.h>
14 #include <SDL_mixer.h>
15 #include <SDL_image.h>
16 #include <SDL_gfxPrimitives.h>
17 
18 #define	ShowFPS 0
19 #define	GCycle 33
20 #define	TextDelay 100
21 #define	DeadDelay 30
22 #define	TURBO 1
23 #define	APPNAME "X-pired"
24 #define VERSION "1.22"
25 
26 // pridame konstanty...
27 #define MaxLevel 100
28 #define MaxLvlSize 20
29 #define MaxSpr 256
30 #define MaxText 10
31 #define MaxStrLenShort 51
32 #define MaxStrLenLong 256
33 #define MaxStrLenXLong 1024
34 
35 #define MaxRecLength 5120
36 
37 #ifdef UNIX
38 
39 	char *SHARE_DIR=SHARE_PREFIX;
40 
41 #else
42 
43 	char *SHARE_DIR=".";
44 
45 #endif
46 
47 char GAME_HOME[MaxStrLenXLong];
48 
49 
50 Uint8	BPP=8;
51 char	FULLSCR=0;
52 Uint8	Shades=128;
53 
54 SDL_Surface *screen,*swapscreen,*TitleS,*Sh=NULL,*PlayerV,*PlayerH,*Player[3][4][20],*SLevel,*SLives,*STime,*SNumbers;
55 
56 char Sound=1,Quit=0,PAlive=20,Left=0,Right=0,Up=0,Down=0,Fire=0,Alt=0,Ctrl=0,Space=0,Setup=0,Passwd[11]="",BEM;
57 int  Level,Lives,PX,PY,PPX,PPY,PF=1,LM=1,DRX1,DRX2,DRY1,DRY2,DRT,DRA=0,DRB[3][4];
58 int  WIDTH=400,HEIGHT=400;
59 char Timed;
60 int Sec;
61 Uint16 UC=0;
62 
63 SDL_Event event;
64 SDL_Joystick *js; // added by Largos for joysticks
65 
66 Mix_Chunk *Snd_Expl,*Snd_Push,*Snd_Burn,*Snd_Fall,*Snd_Beep,*Snd_GameOver,*Snd_Teleport;
67 Mix_Music *Music;
68 int MVolume=64;
69 int SVolume=128;
70 
71 typedef struct T_Txt{
72 	int x,y,a;
73 	char t[MaxStrLenShort];
74 }T_Txt;
75 T_Txt Text[MaxText];
76 
77 
78 typedef struct T_Spr{
79 	SDL_Surface *img,*sha;
80 }T_Spr;
81 
82 T_Spr Spr[MaxSpr];
83 
84 
85 typedef struct T_LElem{
86 	unsigned char	FSpr,FTyp,BSpr,BTyp;
87 	char			x,y,px,py,f,txt;
88 }T_LElem;
89 
90 typedef struct T_Lev{
91 	T_LElem			M[MaxLvlSize][MaxLvlSize];
92 	char			Name[MaxStrLenShort],Pw[MaxStrLenShort];
93 	unsigned int	DL;
94 	SDL_Surface		*Bg;
95 	char			Text[MaxText][MaxStrLenShort];
96 }T_Lev;
97 
98 T_Lev Lvl[MaxLevel];
99 
100 T_Lev ALvl;
101 
102 typedef struct T_RecKey{
103 	Uint32	Tick;
104 	unsigned char	Left:1;
105 	unsigned char	Right:1;
106 	unsigned char	Up:1;
107 	unsigned char	Down:1;
108 	unsigned char	Fire:1;
109 	unsigned char	Quit:3;
110 }T_RecKey;
111 
112 T_RecKey Rec[MaxRecLength];
113 
114 char ConfFName[255];
115 
116 //-END DEF-------------------------------------
117 
118 // --- Music ---
119 
MusicLoopback(void)120 void MusicLoopback(void){
121 //	printf("Module finished...\n");
122 	Mix_PlayMusic(Music,0);
123 	Mix_VolumeMusic(MVolume);
124 }
125 
PlaySample(Mix_Chunk * Snd)126 void PlaySample(Mix_Chunk *Snd){
127 	int Ch;
128 	if (Sound)
129 		if (Mix_PlayChannel(-1,Snd,0)<0){
130 			Ch=Mix_GroupOldest(-1);
131 			Mix_HaltChannel(Ch);
132 			Mix_PlayChannel(Ch,Snd,0);
133 		}
134 }
135 
136 // --- Video ---
137 
VIDEO_INIT()138 void VIDEO_INIT(){
139 Uint32 videoflags;
140 const SDL_VideoInfo *info;
141 
142 	info = SDL_GetVideoInfo();
143 	BPP=info->vfmt->BitsPerPixel;
144 
145 	if(FULLSCR){
146 		videoflags = SDL_SRCALPHA | SDL_FULLSCREEN | SDL_SWSURFACE;
147 	}else{
148 		videoflags = SDL_SRCALPHA;
149 		if (TURBO) videoflags=videoflags | SDL_HWSURFACE | SDL_HWPALETTE;
150 		else videoflags=videoflags | SDL_SWSURFACE;
151 	}
152 
153 
154 	videoflags=videoflags ;
155 
156 	if ( (screen=SDL_SetVideoMode(WIDTH,HEIGHT,BPP,videoflags)) == NULL ) {
157 		fprintf(stderr, "Couldn't set %ix%i video mode: %s\n",WIDTH,HEIGHT,SDL_GetError());
158 		exit(2);
159 	}
160 
161 	SDL_ShowCursor(FULLSCR?SDL_DISABLE:SDL_ENABLE);
162 //	SDL_ShowCursor(SDL_ENABLE);
163 }
164 
165 
ClearSurface(SDL_Surface * Co)166 void ClearSurface(SDL_Surface *Co){
167 Uint32 color;
168 SDL_Rect clip;
169 
170 	clip.x = 0;
171 	clip.y = 0;
172 	clip.w = Co->w;
173 	clip.h = Co->h;
174 
175 	color=SDL_MapRGBA(Co->format, 255,0,255,0);
176 
177 	SDL_FillRect (Co, &clip, color);
178 }
179 
180 
181 // --- Event filter ---
182 
E_FILTER(const SDL_Event * event)183 int E_FILTER(const SDL_Event *event) {
184 
185 	switch( event->type ){
186 	case SDL_KEYDOWN:
187 		if (event->key.keysym.sym==SDLK_LEFT) Left=1;
188 		if (event->key.keysym.sym==SDLK_RIGHT) Right=1;
189 		if (event->key.keysym.sym==SDLK_UP) Up=1;
190 		if (event->key.keysym.sym==SDLK_DOWN) Down=1;
191 		if (event->key.keysym.sym==SDLK_RCTRL) Fire=1;
192 		if (event->key.keysym.sym==SDLK_LCTRL) Fire=1;
193 		if (event->key.keysym.sym==SDLK_LCTRL) Ctrl=1;
194 		if (event->key.keysym.sym==SDLK_SPACE) Space=1;
195 		if (event->key.keysym.sym==SDLK_ESCAPE) Quit=1;
196 		if (event->key.keysym.sym==SDLK_LALT) Alt=1;
197 		if (event->key.keysym.sym==SDLK_RALT) Alt=1;
198 		if (event->key.keysym.sym==SDLK_x && Alt) Quit=2;
199 		if ((event->key.keysym.sym==SDLK_s) && Alt) Setup=1;
200 		if ((event->key.keysym.sym==SDLK_q) && Alt) Quit=2;
201 		if ((event->key.keysym.sym==SDLK_F4) && Alt) Quit=2;
202 		if (Alt&&((event->key.keysym.sym==SDLK_RETURN)||(event->key.keysym.sym==SDLK_f))){
203 			SDL_BlitSurface(screen,NULL,swapscreen,NULL);
204 			FULLSCR=!FULLSCR;
205 			VIDEO_INIT();
206 			SDL_BlitSurface(swapscreen,NULL,screen,NULL);
207 			SDL_UpdateRect(screen,0,0,0,0);
208 		}else
209 			UC=event->key.keysym.unicode;
210 		break;
211 
212 	case SDL_KEYUP:
213 		if (event->key.keysym.sym==SDLK_LEFT) Left=0;
214 		if (event->key.keysym.sym==SDLK_RIGHT) Right=0;
215 		if (event->key.keysym.sym==SDLK_UP) Up=0;
216 		if (event->key.keysym.sym==SDLK_DOWN) Down=0;
217 		if (event->key.keysym.sym==SDLK_RCTRL) Fire=0;
218 		if (event->key.keysym.sym==SDLK_LCTRL) Fire=0;
219 		if (event->key.keysym.sym==SDLK_LCTRL) Ctrl=0;
220 		if (event->key.keysym.sym==SDLK_SPACE) Space=0;
221 		if (event->key.keysym.sym==SDLK_ESCAPE) Quit=0;
222 		if (event->key.keysym.sym==SDLK_LALT) Alt=0;
223 		if (event->key.keysym.sym==SDLK_RALT) Alt=0;
224 		break;
225 
226 	case SDL_JOYAXISMOTION:
227 		if( event->jaxis.axis == 0 ){
228 		// motion was on the horizontal axis
229 		if( event->jaxis.value > 0 ){
230 		// moved left
231 		Left =0;
232 		Right=1;
233 		Up   =0;
234 		Down =0;
235 		}else if( event->jaxis.value < 0 ){
236 		// moved right
237 		Left =1;
238 		Right=0;
239 		Up   =0;
240 		Down =0;
241 		}else{
242 		// released ( the stick is centered )
243 		Left =0;
244 		Right=0;
245 		Up   =0;
246 		Down =0;
247 		}
248 
249 		}else{
250 		// motion was on the vertical axis
251 		if( event->jaxis.value > 0 ){
252 		// moved down
253 		Left =0;
254 		Right=0;
255 		Up   =0;
256 		Down =1;
257 		}else if( event->jaxis.value < 0 ){
258 		// moved up
259 		Left =0;
260 		Right=0;
261 		Up   =1;
262 		Down =0;
263 		}else{
264 		// released ( the stick is centered )
265 		Left =0;
266 		Right=0;
267 		Up   =0;
268 		Down =0;
269 		}
270 		}
271 		break;
272 
273 	case SDL_JOYBUTTONUP:
274 		if( event->jbutton.button == 0 ){
275 			Fire=0;
276 		}else if( event->jbutton.button == 0 ){
277 			Quit=0;
278 		}
279 	break;
280 
281 	case SDL_JOYBUTTONDOWN:
282 		if( event->jbutton.button == 0 ){
283 			Fire=1;
284 		}else if( event->jbutton.button == 1 ){
285 			Quit=1;
286 		}
287 		break;
288 	// add new key event handlers here.
289 
290 
291 	case SDL_QUIT:	//this case needs to drop through to
292 		Quit=2;		// default or the incorrect value will be returned.
293 
294 	default:
295 		return(1);
296 	}
297 	return(0);
298 }
299 
300 
301 
chartoint(char C)302 int chartoint(char C){
303 	return (C>='0'&&C<='9')?(C-'0'):-1;
304 }
305 
306 
307 // --- misc. load/save ---
308 
LoadSprite(SDL_Surface ** Co,char * Soubor,Uint8 sh)309 void LoadSprite(SDL_Surface **Co, char *Soubor, Uint8 sh){
310 	*Co=IMG_Load(Soubor);
311 	if (*Co==NULL) fprintf(stderr,"Error loading %s!\n",Soubor);
312 	else{
313 		SDL_SetColorKey(*Co,SDL_SRCCOLORKEY|SDL_RLEACCEL,SDL_MapRGB((*Co)->format,255,0,255));
314 		if (sh)
315 			SDL_SetAlpha(*Co,SDL_SRCALPHA,sh);
316 		*Co=SDL_DisplayFormat(*Co);
317 	}
318 }
319 
320 
LoadSprites(void)321 void LoadSprites(void){
322 int I,J;
323 SDL_Rect Src;
324 
325 	for (I=0;I<MaxSpr;I++){
326 		Spr[I].img=NULL;
327 		Spr[I].sha=NULL;
328 	}
329 
330 #ifdef UNIX
331 
332   chdir(SHARE_DIR);
333 
334 #endif
335 
336 	TitleS=IMG_Load("./img/title.jpg");
337 	stringRGBA(TitleS,399-strlen(strchr(VERSION,'.'))*8,2,strchr(VERSION,'.'),0x60,0xC0,0x60,128);
338 
339 	LoadSprite(&SLevel,"./img/level.bmp",0);
340 	LoadSprite(&SLives,"./img/lives.bmp",0);
341 	LoadSprite(&STime,"./img/time.bmp",0);
342 	LoadSprite(&SNumbers,"./img/numbers.bmp",0);
343 	LoadSprite(&(Spr['*']).img,"./img/start.bmp",128);
344 	LoadSprite(&(Spr['*']).sha,"./img/shade-player.bmp",0);
345 	LoadSprite(&(Spr['+']).img,"./img/exit.bmp",128);
346 	LoadSprite(&(Spr['+']).sha,"./img/exit-denied.bmp",128);
347 	LoadSprite(&(Spr['%']).img,"./img/retard.bmp",96);
348 	LoadSprite(&(Spr['#']).img,"./img/ice.bmp",128);
349 	LoadSprite(&(Spr['&']).img,"./img/flamable.bmp",150);
350 	LoadSprite(&(Spr['@']).img,"./img/hot.bmp",200);
351 	LoadSprite(&(Spr['T']).img,"./img/teleport.bmp",200);
352 
353 	LoadSprite(&(Spr['X']).img,"./img/wall.bmp",0);
354 	LoadSprite(&(Spr['X']).sha,"./img/shade-square.bmp",0);
355 	LoadSprite(&(Spr['x']).img,"./img/tinywall.bmp",0);
356 	LoadSprite(&(Spr['x']).sha,"./img/shade-square.bmp",0);
357 	LoadSprite(&(Spr['c']).img,"./img/crate.bmp",0);
358 	LoadSprite(&(Spr['c']).sha,"./img/shade-crate.bmp",0);
359 	LoadSprite(&(Spr['o']).img,"./img/barel.bmp",0);
360 	LoadSprite(&(Spr['o']).sha,"./img/shade-round.bmp",0);
361 	LoadSprite(&(Spr['O']).img,"./img/explosive.bmp",0);
362 	LoadSprite(&(Spr['O']).sha,"./img/shade-round.bmp",0);
363 
364 	LoadSprite(&PlayerV,"./img/player-v-legs.bmp",0);
365 	LoadSprite(&PlayerH,"./img/player-h-legs.bmp",0);
366 	for (I=0;I<4;I++)
367 		for (J=0;J<20;J++){
368 			Player[0][I][J]=SDL_CreateRGBSurface(SDL_SRCALPHA,20,20,BPP,screen->format->Rmask,screen->format->Gmask,screen->format->Bmask,screen->format->Amask);
369 			if (Player[0][I][J]==NULL) printf("Error alocating player!!\n");
370 			ClearSurface(Player[0][I][J]);
371 			SDL_SetColorKey(Player[0][I][J],SDL_SRCCOLORKEY|SDL_RLEACCEL,SDL_MapRGB(Player[0][I][J]->format,255,0,255));
372 		}
373 	Src.w=20;
374 	Src.h=20;
375 	for (I=0;I<11;I++){
376 		Src.x=0;
377 		Src.y=I*40;
378 		SDL_BlitSurface(PlayerV,&Src,Player[0][0][(15+I)%20],NULL);
379 		SDL_BlitSurface(PlayerV,&Src,Player[0][0][15-I],NULL);
380 		Src.x=40;
381 		SDL_BlitSurface(PlayerV,&Src,Player[0][1][(15+I)%20],NULL);
382 		SDL_BlitSurface(PlayerV,&Src,Player[0][1][15-I],NULL);
383 	}
384 	for (I=0;I<11;I++){
385 		Src.x=I*40;
386 		Src.y=0;
387 		SDL_BlitSurface(PlayerH,&Src,Player[0][2][(15+I)%20],NULL);
388 		SDL_BlitSurface(PlayerH,&Src,Player[0][2][15-I],NULL);
389 		Src.y=40;
390 		SDL_BlitSurface(PlayerH,&Src,Player[0][3][(15+I)%20],NULL);
391 		SDL_BlitSurface(PlayerH,&Src,Player[0][3][15-I],NULL);
392 	}
393 	SDL_FreeSurface(PlayerV);
394 	SDL_FreeSurface(PlayerH);
395 
396 	LoadSprite(&PlayerV,"./img/player-v-body.bmp",0);
397 	LoadSprite(&PlayerH,"./img/player-h-body.bmp",0);
398 	for (I=0;I<4;I++)
399 		for (J=0;J<20;J++){
400 			Player[1][I][J]=SDL_CreateRGBSurface(SDL_SRCALPHA,20,20,BPP,screen->format->Rmask,screen->format->Gmask,screen->format->Bmask,screen->format->Amask);
401 			if (Player[1][I][J]==NULL) printf("Error alocating player!!\n");
402 			ClearSurface(Player[1][I][J]);
403 			SDL_SetColorKey(Player[1][I][J],SDL_SRCCOLORKEY|SDL_RLEACCEL,SDL_MapRGB(Player[1][I][J]->format,255,0,255));
404 		}
405 	Src.w=20;
406 	Src.h=20;
407 	for (I=0;I<11;I++){
408 		Src.x=0;
409 		Src.y=I*40;
410 		SDL_BlitSurface(PlayerV,&Src,Player[1][0][(15+I)%20],NULL);
411 		SDL_BlitSurface(PlayerV,&Src,Player[1][0][15-I],NULL);
412 		Src.x=40;
413 		SDL_BlitSurface(PlayerV,&Src,Player[1][1][(15+I)%20],NULL);
414 		SDL_BlitSurface(PlayerV,&Src,Player[1][1][15-I],NULL);
415 	}
416 	for (I=0;I<11;I++){
417 		Src.x=I*40;
418 		Src.y=0;
419 		SDL_BlitSurface(PlayerH,&Src,Player[1][2][(15+I)%20],NULL);
420 		SDL_BlitSurface(PlayerH,&Src,Player[1][2][15-I],NULL);
421 		Src.y=40;
422 		SDL_BlitSurface(PlayerH,&Src,Player[1][3][(15+I)%20],NULL);
423 		SDL_BlitSurface(PlayerH,&Src,Player[1][3][15-I],NULL);
424 	}
425 	SDL_FreeSurface(PlayerV);
426 	SDL_FreeSurface(PlayerH);
427 
428 	LoadSprite(&PlayerV,"./img/player-v-push.bmp",0);
429 	LoadSprite(&PlayerH,"./img/player-h-push.bmp",0);
430 	for (I=0;I<4;I++)
431 		for (J=0;J<20;J++){
432 			Player[2][I][J]=SDL_CreateRGBSurface(SDL_SRCALPHA,20,20,BPP,screen->format->Rmask,screen->format->Gmask,screen->format->Bmask,screen->format->Amask);
433 			if (Player[2][I][J]==NULL) printf("Error alocating player!!\n");
434 			ClearSurface(Player[2][I][J]);
435 			SDL_SetColorKey(Player[2][I][J],SDL_SRCCOLORKEY|SDL_RLEACCEL,SDL_MapRGB(Player[2][I][J]->format,255,0,255));
436 		}
437 	Src.w=20;
438 	Src.h=20;
439 	for (I=0;I<11;I++){
440 		Src.x=0;
441 		Src.y=I*40;
442 		SDL_BlitSurface(PlayerV,&Src,Player[2][0][(15+I)%20],NULL);
443 		SDL_BlitSurface(PlayerV,&Src,Player[2][0][15-I],NULL);
444 		Src.x=40;
445 		SDL_BlitSurface(PlayerV,&Src,Player[2][1][(15+I)%20],NULL);
446 		SDL_BlitSurface(PlayerV,&Src,Player[2][1][15-I],NULL);
447 	}
448 	for (I=0;I<11;I++){
449 		Src.x=I*40;
450 		Src.y=0;
451 		SDL_BlitSurface(PlayerH,&Src,Player[2][2][(15+I)%20],NULL);
452 		SDL_BlitSurface(PlayerH,&Src,Player[2][2][15-I],NULL);
453 		Src.y=40;
454 		SDL_BlitSurface(PlayerH,&Src,Player[2][3][(15+I)%20],NULL);
455 		SDL_BlitSurface(PlayerH,&Src,Player[2][3][15-I],NULL);
456 	}
457 	SDL_FreeSurface(PlayerV);
458 	SDL_FreeSurface(PlayerH);
459 
460 
461 	LoadSprite(&(Spr[1]).img,"./img/expl3.bmp",0);
462 	Spr[1].sha=NULL;
463 	LoadSprite(&(Spr[2]).img,"./img/expl2.bmp",0);
464 	Spr[2].sha=NULL;
465 	LoadSprite(&(Spr[3]).img,"./img/expl1.bmp",0);
466 	LoadSprite(&(Spr[3]).sha,"./img/shade-expl1.bmp",0);
467 
468 	LoadSprite(&(Spr[4]).img,"./img/bo-flamable.bmp",0);
469 	Spr[3].sha=NULL;
470 
471 	LoadSprite(&(Spr[5]).img,"./img/fire1.bmp",150);
472 	Spr[5].sha=NULL;
473 	LoadSprite(&(Spr[6]).img,"./img/fire2.bmp",150);
474 	Spr[6].sha=NULL;
475 	LoadSprite(&(Spr[7]).img,"./img/fire3.bmp",150);
476 	Spr[7].sha=NULL;
477 	LoadSprite(&(Spr[8]).img,"./img/fire2.bmp",150);
478 	Spr[8].sha=NULL;
479 
480 	LoadSprite(&(Spr[9]).img,"./img/telee3.bmp",0);
481 	LoadSprite(&(Spr[9]).sha,"./img/shade-t3.bmp",0);
482 	LoadSprite(&(Spr[10]).img,"./img/telee2.bmp",0);
483 	LoadSprite(&(Spr[10]).sha,"./img/shade-t2.bmp",0);
484 	LoadSprite(&(Spr[11]).img,"./img/telee1.bmp",0);
485 	LoadSprite(&(Spr[11]).sha,"./img/shade-t1.bmp",0);
486 
487 	LoadSprite(&(Spr[12]).img,"./img/player-death1.bmp",0);
488 	Spr[12].sha=NULL;
489 	LoadSprite(&(Spr[13]).img,"./img/player-death2.bmp",0);
490 	Spr[13].sha=NULL;
491 	LoadSprite(&(Spr[14]).img,"./img/player-death3.bmp",0);
492 	Spr[14].sha=NULL;
493 	LoadSprite(&(Spr[15]).img,"./img/player-death4.bmp",0);
494 	Spr[15].sha=NULL;
495 
496 	LoadSprite(&(Spr['B']).img,"./img/bem1.bmp",0);
497 	LoadSprite(&(Spr['B']).sha,"./img/shade-bem1.bmp",0);
498 	LoadSprite(&(Spr['C']).img,"./img/bem2.bmp",0);
499 	LoadSprite(&(Spr['C']).sha,"./img/shade-bem2.bmp",0);
500 	LoadSprite(&(Spr['D']).img,"./img/bem3.bmp",0);
501 	LoadSprite(&(Spr['D']).sha,"./img/shade-bem3.bmp",0);
502 	LoadSprite(&(Spr['E']).img,"./img/bem4.bmp",0);
503 	LoadSprite(&(Spr['E']).sha,"./img/shade-bem4.bmp",0);
504 
505 
506 
507 	Snd_Expl=Mix_LoadWAV("./snd/bombex.wav");
508 	Snd_Push=Mix_LoadWAV("./snd/slide.wav");
509 	Snd_Burn=Mix_LoadWAV("./snd/burn.wav");
510 	Snd_Fall=Mix_LoadWAV("./snd/fall.wav");
511 	Snd_Beep=Mix_LoadWAV("./snd/beep.wav");
512 	Snd_Teleport=Mix_LoadWAV("./snd/teleport.wav");
513 	Snd_GameOver=Mix_LoadWAV("./snd/gameover.wav");
514 	Music = Mix_LoadMUS("./snd/smashem.s3m");
515 }
516 
517 
LoadDemo(char * Soubor)518 char LoadDemo(char *Soubor){
519 	FILE *F;
520 	int I=0;
521 	char S[MaxStrLenLong],*SP;
522 
523 	if ((F=fopen(Soubor,"r"))==NULL)
524 		return 0;
525 	while ((!feof(F))&&(I<MaxRecLength)){
526 		fgets(S,MaxStrLenLong-1,F);
527 		if ((SP=strchr(S,'	'))!=NULL){
528 			SP[0]='\0';
529 			Rec[I].Tick=atoi(S);
530 			Rec[I].Up=chartoint(SP[1]);
531 			Rec[I].Down=chartoint(SP[3]);
532 			Rec[I].Left=chartoint(SP[5]);
533 			Rec[I].Right=chartoint(SP[7]);
534 			Rec[I].Fire=chartoint(SP[9]);
535 			Rec[I].Quit=chartoint(SP[11]);
536 			I++;
537 		}
538 	}
539 
540 	fclose (F);
541 	return 1;
542 }
543 
544 
SaveDemo(char * Soubor)545 char SaveDemo(char *Soubor){
546 	FILE *F;
547 	int I=0;
548 
549 	if ((F=fopen(Soubor,"w"))==NULL)
550 		return 0;
551 
552 	while ((I<MaxRecLength)&&((I<1)||(Rec[I-1].Quit!=2))){
553 		fprintf(F,"%d	%d,%d,%d,%d,%d,%d\n",Rec[I].Tick,Rec[I].Up,Rec[I].Down,Rec[I].Left,Rec[I].Right,Rec[I].Fire,Rec[I].Quit);
554 		I++;
555 	}
556 
557 	fclose (F);
558 	return 1;
559 }
560 
561 
LoadConfig(char * Soubor)562 char LoadConfig(char *Soubor){
563 	FILE *F;
564 	char S[MaxStrLenXLong];
565 
566 	if ((F=fopen(Soubor,"r"))==NULL)
567 		return 0;
568 	while (!feof(F)){
569 		fgets (S,MaxStrLenXLong-1,F);
570 		while((strlen(S))&&(S[strlen(S)-1]<' '))
571 			S[strlen(S)-1]='\0';
572 		if ((S[0]!='\0')&&(S[0]!='#')){
573 //			printf("%s\n",S);
574 				if (!strcmp(S,"shades=none"))
575 					Shades=0;
576 				else
577 				if (!strcmp(S,"shades=solid"))
578 					Shades=255;
579 				else
580 				if (!strcmp(S,"shades=transparent"))
581 					Shades=128;
582 				else
583 				if (!strncmp(S,"m_volume=",9))
584 					MVolume=((float)chartoint(S[9])/9.0)*128;
585 				else
586 				if (!strncmp(S,"s_volume=",9))
587 					SVolume=((float)chartoint(S[9])/9.0)*128;
588 				else
589 				if (!strncmp(S,"fullscreen=",11))
590 					FULLSCR=chartoint(S[11]);
591 
592 		}
593 	}
594 	fclose (F);
595 	return 1;
596 }
597 
598 
SaveConfig(char FileName[])599 void SaveConfig(char FileName[]){
600 FILE *F;
601 
602 F=fopen(FileName,"w");
603 fprintf(F,"#	X-pired Configuration File\n");
604 fprintf(F,"\n");
605 fprintf(F,"#	shades: none, transparent, solid (set 'solid' or 'none' to increase performance)\n");
606 if (Shades==0)
607 	fprintf(F,"shades=none\n");
608 if (Shades==128)
609 	fprintf(F,"shades=transparent\n");
610 if (Shades==255)
611 	fprintf(F,"shades=solid\n");
612 fprintf(F,"\n");
613 fprintf(F,"#	music volume: 0-9\n");
614 fprintf(F,"m_volume=%i\n",(int)(((float)MVolume/128.0)*9.0)+1);
615 fprintf(F,"\n");
616 fprintf(F,"#	sound volume: 0-9\n");
617 fprintf(F,"s_volume=%i\n",(int)(((float)SVolume/128.0)*9.0)+1);
618 fprintf(F,"\n");
619 fprintf(F,"#	Fullscreen mode: 0/1\n");
620 fprintf(F,"fullscreen=%i\n",FULLSCR);
621 fprintf(F,"\n");
622 fclose(F);
623 }
624 
625 
LoadLevels(char * Soubor)626 char LoadLevels(char *Soubor){
627 	FILE *F;
628 	char S[MaxStrLenLong],T[MaxStrLenShort];
629 	int I,J,L=-1;
630 
631 	for (I=0;I<100;I++)
632 		Lvl[I].Pw[0]='\0';
633 
634 	I=0;
635 
636 	if ((F=fopen(Soubor,"r"))==NULL)
637 		return 0;
638 	while (!feof(F)){
639 		fgets (S,MaxStrLenLong-1,F);
640 		while ((strlen(S)>0)&&(S[strlen(S)-1]<' '))
641 			S[strlen(S)-1]='\0';
642 		if ((S[0]!='\0')&&(S[0]!='#')){
643 //			printf("%s\n",S);
644 			if ((S[0]=='>')&&(S[strlen(S)-1]=='-')){
645 				L++;
646 				sprintf(Lvl[L].Name,"Level no. %d",L);
647 				Lvl[L].Pw[0]='\0';
648 				Lvl[L].Bg=NULL;
649 				Lvl[L].DL=0;
650 				for (I=0;I<20;I++)
651 					for (J=0;J<20;J++){
652 						Lvl[L].M[I][J].FSpr=' ';
653 						Lvl[L].M[I][J].FTyp=' ';
654 						Lvl[L].M[I][J].BSpr=' ';
655 						Lvl[L].M[I][J].BTyp=' ';
656 						Lvl[L].M[I][J].x=0;
657 						Lvl[L].M[I][J].y=0;
658 						Lvl[L].M[I][J].px=0;
659 						Lvl[L].M[I][J].py=0;
660 						Lvl[L].M[I][J].f=0;
661 						Lvl[L].M[I][J].txt=-1;
662 					}
663 				for (I=0;I<10;I++)
664 					Lvl[L].Text[I][0]='\0';
665 
666 				I=0;
667 //				printf("Level(%d) loaded...\n",L);
668 			}else{// LEVEL
669 				if ((S[1]=='=')&&(chartoint(S[0])>=0))
670 					for (J=2;J<=strlen(S);J++)
671 						Lvl[L].Text[chartoint(S[0])][J-2]=S[J];
672 				else
673 				if (!strncmp(S,"name=",5))
674 					for (J=5;J<=strlen(S);J++)
675 						Lvl[L].Name[J-5]=S[J];
676 				else
677 				if (!strncmp(S,"password=",9))
678 					for (J=9;J<=strlen(S);J++)
679 						Lvl[L].Pw[J-9]=S[J];
680 				else
681 				if (!strncmp(S,"deadline=",5)){
682 					for (J=9;J<=strlen(S);J++)
683 						T[J-9]=S[J];
684 					Lvl[L].DL=atoi(T);
685 				}
686 				else
687 				if (!strncmp(S,"background=",5)){
688 					for (J=11;J<=strlen(S);J++)
689 						T[J-11]=S[J];
690 					Lvl[L].Bg=SDL_DisplayFormat(IMG_Load(T));
691 				}
692 				else
693 				if ((I<20)&&(strlen(S)>=20*7)&&(S[0]==',')){
694 					for (J=0;J<20*7;J+=7){
695 							Lvl[L].M[J/7][I].FTyp=S[J+1];
696 							Lvl[L].M[J/7][I].FSpr=S[J+2];
697 							Lvl[L].M[J/7][I].BTyp=S[J+3];
698 							Lvl[L].M[J/7][I].BSpr=S[J+4];
699 							Lvl[L].M[J/7][I].x=0;
700 							Lvl[L].M[J/7][I].y=0;
701 							Lvl[L].M[J/7][I].px=0;
702 							Lvl[L].M[J/7][I].py=0;
703 							Lvl[L].M[J/7][I].f=chartoint(S[J+5]);
704 							Lvl[L].M[J/7][I].txt=chartoint(S[J+6]);
705 					}
706 					I++;
707 				}
708 			}
709 
710 		}
711 	}
712 	fclose (F);
713 	return 1;
714 }
715 
716 
717 // --- Dirty rectangle ---
718 
DrawSpr(SDL_Surface * Co,SDL_Surface * Kam,int X,int Y)719 void DrawSpr(SDL_Surface *Co,SDL_Surface *Kam,int X,int Y){
720 SDL_Rect Dest;
721 	if (Co==NULL) return;
722 	Dest.x=X;
723 	Dest.y=Y;
724 	Dest.w=Co->w;
725 	Dest.h=Co->h;
726 	SDL_BlitSurface(Co,NULL,Kam,&Dest);
727 }
728 
729 
R_Blit(SDL_Surface * Co,SDL_Surface * Kam,int SX,int SY,int SW,int SH,int X,int Y)730 void R_Blit(SDL_Surface *Co,SDL_Surface *Kam,int SX, int SY, int SW, int SH, int X, int Y){
731 SDL_Rect Src,Dest;
732 	if (Co==NULL) return;
733 	Src.x=SX;
734 	Src.y=SY;
735 	Src.w=SW;
736 	Src.h=SH;
737 	Dest.x=X;
738 	Dest.y=Y;
739 	Dest.w=SW;
740 	Dest.h=SH;
741 	SDL_BlitSurface(Co,&Src,Kam,&Dest);
742 }
743 
744 
DR_RCT(int x1,int y1,int x2,int y2)745 void DR_RCT(int x1, int y1, int x2, int y2){
746 	if ((x1<DRX1)||(DRX1==-1000)) DRX1=x1;
747 	if ((y1<DRY1)||(DRY1==-1000)) DRY1=y1;
748 	if ((x2>DRX2)||(DRX2==-1000)) DRX2=x2;
749 	if ((y2>DRY2)||(DRY2==-1000)) DRY2=y2;
750 	DRT=1;
751 }
752 
753 
DR_SPR(int x,int y,char Sprite)754 void DR_SPR(int x, int y, char Sprite){
755 	if (Spr[Sprite].img!=NULL)
756 		DR_RCT(x,y,x+Spr[Sprite].img->w,y+Spr[Sprite].img->h);
757 //	else
758 //		fprintf(stderr,"%c\n",Sprite);
759 	if (Spr[Sprite].sha!=NULL)
760 		DR_RCT(x,y,x+Spr[Sprite].sha->w,y+Spr[Sprite].sha->h);
761 }
762 
763 
DRNULL(void)764 void DRNULL(void){
765 	DRX1=-1000;
766 	DRY1=-1000;
767 	DRX2=-1000;
768 	DRY2=-1000;
769 	DRT=0;
770 }
771 
772 
773 // --- Messages ---
774 
TextReset(void)775 void TextReset(void){
776 int I;
777 	for (I=0;I<MaxText;I++)
778 		Text[I].t[0]='\0';
779 }
780 
781 
TextDel(void)782 void TextDel(void){
783 int I;
784 	for (I=1;(I<MaxText)&&(Text[I-1].t[0]!='\0');I++){
785 		strcpy(Text[I-1].t,Text[I].t);
786 		Text[I-1].x=Text[I].x;
787 		Text[I-1].y=Text[I].y;
788 		Text[I-1].a=Text[I].a;
789 	}
790 	if (I==MaxText)
791 		Text[MaxText-1].t[0]='\0';
792 }
793 
TextAdd(int x,int y,char Txt[])794 void TextAdd(int x,int y,char Txt[]){
795 int I;
796 	for (I=0;(I<MaxText)&&(Text[I].t[0]!='\0');I++);
797 	if (I==MaxText){
798 		TextDel();
799 		I=MaxText-1;
800 	}
801 	strcpy(Text[I].t,Txt);
802 	Text[I].x=x-strlen(Txt)*4;
803 	if (Text[I].x<0)
804 		Text[I].x=0;
805 	if (Text[I].x+strlen(Txt)*8>WIDTH)
806 		Text[I].x=WIDTH-strlen(Txt)*8;
807 	Text[I].y=y-4;
808 	Text[I].a=TextDelay;
809 }
810 
TextBehave(void)811 void TextBehave(void){
812 int I;
813 for (I=0;(I<MaxText)&&(Text[I].t[0]!='\0');I++){
814 	DR_RCT(Text[I].x,Text[I].y,Text[I].x+strlen(Text[I].t)*8,Text[I].y+9);
815 	if (!(--Text[I].a)){
816 		TextDel();
817 		I--;
818 	}else{
819 		Text[I].y-=TextDelay/Text[I].a;
820 		DR_RCT(Text[I].x,Text[I].y,Text[I].x+strlen(Text[I].t)*8,Text[I].y+9);
821 	}
822 }
823 }
824 
TextDisplay(SDL_Surface * Kam)825 void TextDisplay(SDL_Surface *Kam){
826 int I;
827 	for (I=0;(I<MaxText)&&(Text[I].t[0]!='\0');I++){
828 		stringRGBA(Kam,Text[I].x+1,Text[I].y+1,Text[I].t,0x00,0x00,0x00,64+191*((float)(Text[I].a)/(float)(TextDelay)));
829 		stringRGBA(Kam,Text[I].x,Text[I].y,Text[I].t,0x00,0xFF,0x00,64+191*((float)(Text[I].a)/(float)(TextDelay)));
830 	}
831 }
832 
833 
sgn(int X)834 int sgn(int X){
835 	if (X<0) return -1;
836 	if (X>0) return 1;
837 	return 0;
838 }
839 
840 
shift(int X,int Y)841 char shift(int X,int Y){
842 	if ((ALvl.M[X][Y].FTyp=='c')||(ALvl.M[X][Y].FTyp=='o')||(ALvl.M[X][Y].FTyp=='O')) return 1;
843 	return 0;
844 }
845 
846 
DrawGame(void)847 void DrawGame(void){
848 int I,J,X,Y,W,H;
849 SDL_Rect Rct;
850 
851 //	DR MAGIC....
852 	if (!DRT)
853 		return;
854 
855 	DRX1/=20;
856 	DRY1/=20;
857 	DRX2/=20;
858 	DRY2/=20;
859 	DRX1*=(DRX1>0);
860 	DRY1*=(DRY1>0);
861 	DRX2*=(DRX2>0);
862 	DRY2*=(DRY2>0);
863 	DRX1=(DRX1>19)?19:DRX1;
864 	DRY1=(DRY1>19)?19:DRY1;
865 	DRX2=(DRX2>19)?19:DRX2;
866 	DRY2=(DRY2>19)?19:DRY2;
867 	X=DRX1;
868 	Y=DRY1;
869 	W=DRX2-DRX1+1;
870 	H=DRY2-DRY1+1;
871 	Rct.x=X*20;
872 	Rct.y=Y*20;
873 	Rct.w=W*20;
874 	Rct.h=H*20;
875 	X--;
876 	Y--;
877 	W+=2;
878 	H+=2;
879 	X*=(X>0);
880 	Y*=(Y>0);
881 	if (X+W>20) W=20-X;
882 	if (Y+H>20) H=20-Y;
883 
884 	SDL_BlitSurface(ALvl.Bg,&Rct,screen,&Rct);
885 
886 	if (Shades){
887 		boxRGBA(Sh,Rct.x,Rct.y,Rct.x+Rct.w-1,Rct.y+Rct.h-1,255,0,255,0xFF);
888 		boxRGBA(Sh,0,0,399,14,0,0,0,0xFF);
889 		boxRGBA(Sh,0,15,14,399,0,0,0,0xFF);
890 
891 		for (I=X;I<X+W;I++)
892 			for (J=Y;J<Y+H;J++)
893 				DrawSpr(Spr[ALvl.M[I][J].FSpr].sha,Sh,I*20+ALvl.M[I][J].x,J*20+ALvl.M[I][J].y);
894 		if ((PX>=X)&&(PX<=X+W)&&(PY>=Y)&&(PY<=Y+H))
895 			if ((PAlive<=DeadDelay)||(PAlive%2))
896 				DrawSpr(Spr['*'].sha,Sh,PX*20+PPX,PY*20+PPY);
897 
898 		SDL_BlitSurface(Sh,&Rct,screen,&Rct);
899 	}
900 
901 
902 	for (I=X;I<X+W;I++)
903 		for (J=Y;J<Y+H;J++)
904 			DrawSpr(Spr[ALvl.M[I][J].FSpr].img,screen,I*20+ALvl.M[I][J].x,J*20+ALvl.M[I][J].y);
905 
906 	if ((PX>=X)&&(PX<=X+W)&&(PY>=Y)&&(PY<=Y+H)){
907 		if ((PAlive==DeadDelay)||((PAlive>DeadDelay)&&(PAlive%2))){
908 			DrawSpr(Player[0][(((!PPX)&&(!PPY))*LM)+(PPY>0)+(PPX>0)*2+(PPX<0)*3][(abs(PPX)+abs(PPY))],screen,PX*20+PPX,PY*20+PPY);
909 			if (shift(PX+sgn(PPX),PY+sgn(PPY)))
910 				DrawSpr(Player[2][(((!PPX)&&(!PPY))*LM)+(PPY>0)+(PPX>0)*2+(PPX<0)*3][(abs(PPX)+abs(PPY))],screen,PX*20+PPX,PY*20+PPY);
911 			else
912 				DrawSpr(Player[1][(((!PPX)&&(!PPY))*LM)+(PPY>0)+(PPX>0)*2+(PPX<0)*3][(abs(PPX)+abs(PPY))],screen,PX*20+PPX,PY*20+PPY);
913 		}else
914 		if (PAlive<DeadDelay)
915 			DrawSpr(Spr[15-PAlive/(DeadDelay/4)].img,screen,PX*20+PPX,PY*20+PPY);
916 	}
917 	// Stat: Level---
918 	if ((X<2)&&(Y+H>=19)){
919 		DrawSpr(SLevel,screen,1,400-16);
920 		R_Blit(SNumbers,screen,(Level/10)*11,0,11,15,15,400-16);
921 		R_Blit(SNumbers,screen,(Level%10)*11,0,11,15,26,400-16);
922 	}
923 	// Stat: Lives---
924 	if ((18<=X+W)&&(19<=Y+H)){
925 		DrawSpr(SLives,screen,400-16,400-16);
926 		R_Blit(SNumbers,screen,(Lives/10)*11,0,11,15,400-37,400-16);
927 		R_Blit(SNumbers,screen,(Lives%10)*11,0,11,15,400-26,400-16);
928 	}
929 	// Stat: DeadLine---
930 	if ((ALvl.DL)&&(((9>=X)&&(9<=X+W))||((12<=X+W)&&(12>=X)))&&(19<=Y+H)){
931 		DrawSpr(STime,screen,200-23,400-17);
932 		R_Blit(SNumbers,screen,(ALvl.DL/100)*11,0,11,15,200-9,400-16);
933 		R_Blit(SNumbers,screen,((ALvl.DL%100)/10)*11,0,11,15,200+2,400-16);
934 		R_Blit(SNumbers,screen,(ALvl.DL%10)*11,0,11,15,200+13,400-16);
935 	}
936 
937 	TextDisplay(screen);
938 
939 //	Dirty rectangle visualization:
940 //	rectangleRGBA(screen,Rct.x,Rct.y,Rct.x+Rct.w-1,Rct.y+Rct.h-1,255,255,255,128);
941 
942 	SDL_UpdateRect(screen,Rct.x,Rct.y,Rct.w,Rct.h);
943 	DRNULL();
944 }
945 
946 
bem(int X,int Y)947 char bem(int X,int Y){
948 	if ((X<0)||(Y<0)||(X>19)||(Y>19))	return 0;
949 	if (ALvl.M[X][Y].FTyp=='B')			return 1;
950 	return 0;
951 }
952 
953 
hard(int X,int Y)954 char hard(int X,int Y){
955 	if ((X<0)||(Y<0)||(X>19)||(Y>19)
956 		||(ALvl.M[X][Y].FTyp=='X')||(ALvl.M[X][Y].FTyp=='x')||(ALvl.M[X][Y].FTyp=='B')) return 1;
957 	if ((X==PX)&&(Y==PY)) return 1;
958 	return 0;
959 }
960 
961 
fobj(int X,int Y)962 char fobj(int X,int Y){
963 	if ((X<0)||(Y<0)||(X>19)||(Y>19))
964 		return 0;
965 	if (bem(X,Y)||hard(X,Y)||shift(X,Y))
966 		return 1;
967 	return 0;
968 }
969 
970 
collision(int X,int Y,int pX,int pY)971 char collision(int X, int Y, int pX, int pY){
972 	if ((X+pX<0)||(Y+pY<0)||(X+pX>19)||(Y+pY>19))
973 		return 1;
974 	if (fobj(X+pX,Y+pY)&&((sgn(ALvl.M[X+pX][Y+pY].px)!=pX)||(sgn(ALvl.M[X+pX][Y+pY].py)!=pY)))
975 		return 1;
976 	if ((pX<=0)&&(fobj(X+pX-1,Y+pY))&&(sgn(ALvl.M[X+pX-1][Y+pY].px)>0))
977 		return 1;
978 	if ((pX>=0)&&(fobj(X+pX+1,Y+pY))&&(sgn(ALvl.M[X+pX+1][Y+pY].px)<0))
979 		return 1;
980 	if ((pY<=0)&&(fobj(X+pX,Y+pY-1))&&(sgn(ALvl.M[X+pX][Y+pY-1].py)>0))
981 		return 1;
982 	if ((pY>=0)&&(fobj(X+pX,Y+pY+1))&&(sgn(ALvl.M[X+pX][Y+pY+1].py)<0))
983 		return 1;
984 	return 0;
985 }
986 
987 
push(int PPX,int PPY,int F)988 char push(int PPX,int PPY, int F){
989 	if ((ALvl.M[PX+PPX][PY+PPY].x)||(ALvl.M[PX+PPX][PY+PPY].y)||(!shift(PX+PPX,PY+PPY))
990 		||(shift(PX+2*PPX,PY+2*PPY))||(hard(PX+2*PPX,PY+2*PPY)))
991 		return 0;
992 
993 	if (ALvl.M[PX+PPX][PY+PPY].FTyp=='c'){
994 		PF=1;
995 		F=1;
996 	}
997 
998 	ALvl.M[PX+PPX][PY+PPY].px=PPX;
999 	ALvl.M[PX+PPX][PY+PPY].py=PPY;
1000 	ALvl.M[PX+PPX][PY+PPY].x=PPX*F;
1001 	ALvl.M[PX+PPX][PY+PPY].y=PPY*F;
1002 	ALvl.M[PX+PPX][PY+PPY].f=F;
1003 	if (F>1)
1004 		PlaySample(Snd_Push);
1005 	return 1;
1006 }
1007 
1008 
is_free(int PPX,int PPY)1009 char is_free(int PPX,int PPY){
1010 	if (hard(PX+PPX,PY+PPY)) return 0;
1011 	if (shift(PX+PPX,PY+PPY)&&(sgn(ALvl.M[PX+PPX][PY+PPY].px)==sgn(PPX))&&(sgn(ALvl.M[PX+PPX][PY+PPY].py)==sgn(PPY))) return 1;
1012 	if (shift(PX+PPX,PY+PPY)) return push(PPX,PPY,PF);
1013 	return 1;
1014 }
1015 
1016 
GetTeleport(int * X,int * Y)1017 char GetTeleport(int *X,int *Y){
1018 int I,J;
1019 
1020 	for (I=0;I<=20;I++)
1021 		for (J=(*Y+1)*(I==0);J<20;J++)
1022 			if ((ALvl.M[(*X+I)%20][J].BTyp=='T')&&((ALvl.M[(*X+I)%20][J].FTyp==' ')||(((*X+I)%20==*X)&&(J==*Y)))&&(((*X+I)%20!=PX)||(J!=PY))){
1023 				if (((*X+I)%20==*X)&&(J==*Y))
1024 					return 0;
1025 				*X=(*X+I)%20;
1026 				*Y=J;
1027 				return 1;
1028 			}
1029 	return 0;
1030 }
1031 
TeleportEffect(int X,int Y)1032 void TeleportEffect(int X, int Y){
1033 	PlaySample(Snd_Teleport);
1034 	ALvl.M[X][Y].FSpr=11;
1035 	ALvl.M[X][Y].FTyp=' ';
1036 	ALvl.M[X][Y].f=9;
1037 	ALvl.M[X][Y].x=0;
1038 	ALvl.M[X][Y].y=0;
1039 	ALvl.M[X][Y].px=3;
1040 	ALvl.M[X][Y].py=3;
1041 }
1042 
1043 
MoveObjects(void)1044 void MoveObjects(void){
1045 int I,J,K,L,P;
1046 char BEM2=0;
1047 
1048 	for (I=0;I<MaxLvlSize;I++)
1049 			for (J=0;J<MaxLvlSize;J++) if (ALvl.M[I][J].f)
1050 				if (ALvl.M[I][J].f<3){// SHIFT/SWIFT
1051 					DR_SPR(I*20+ALvl.M[I][J].x,J*20+ALvl.M[I][J].y,ALvl.M[I][J].FSpr);
1052 					if ((!ALvl.M[I][J].x)&&(!ALvl.M[I][J].y)){
1053 						if ((ALvl.M[I][J].f==1)&&(ALvl.M[I][J].BTyp!='T'))
1054 							ALvl.M[I][J].f=0;
1055 
1056 						if (ALvl.M[I][J].BTyp=='@'){
1057 							PlaySample(Snd_Burn);
1058 							DrawSpr(Spr[4].img,ALvl.Bg,I*20,J*20);
1059 							ALvl.M[I][J].BTyp=' ';
1060 							ALvl.M[I][J].FTyp=' ';
1061 							ALvl.M[I][J].f=6;
1062 							ALvl.M[I][J].px=0;
1063 							ALvl.M[I][J].py=0;
1064 						}else
1065 						if (ALvl.M[I][J].BTyp=='%'){
1066 							ALvl.M[I][J].f=0;
1067 							ALvl.M[I][J].px=0;
1068 							ALvl.M[I][J].py=0;
1069 						}else
1070 						if ((ALvl.M[I][J].px||ALvl.M[I][J].py)&&(collision(I,J,sgn(ALvl.M[I][J].px),sgn(ALvl.M[I][J].py)))){
1071 							if ((ALvl.M[I][J].FTyp!='c')&&(ALvl.M[I][J].f>1))
1072 								ALvl.M[I][J].f=4+(ALvl.M[I][J].FTyp=='O');
1073 							ALvl.M[I][J].px=0;
1074 							ALvl.M[I][J].py=0;
1075 						}
1076 					}
1077 					if ((ALvl.M[I][J].px||ALvl.M[I][J].py)&&((abs(ALvl.M[I][J].x+=ALvl.M[I][J].px*ALvl.M[I][J].f)>=20)||(abs(ALvl.M[I][J].y+=ALvl.M[I][J].py*ALvl.M[I][J].f)>=20))){
1078 						if (ALvl.M[I+ALvl.M[I][J].px][J+ALvl.M[I][J].py].BTyp=='T'){// T e l e p o r t
1079 							K=I+ALvl.M[I][J].px;
1080 							L=J+ALvl.M[I][J].py;
1081 							P=GetTeleport(&K,&L);
1082 
1083 							ALvl.M[K][L].FSpr=ALvl.M[I][J].FSpr;
1084 							ALvl.M[K][L].FTyp=ALvl.M[I][J].FTyp;
1085 							ALvl.M[K][L].x=0;
1086 							ALvl.M[K][L].y=0;
1087 
1088 							ALvl.M[K][L].px=ALvl.M[I][J].px;
1089 							ALvl.M[K][L].py=ALvl.M[I][J].py;
1090 							ALvl.M[K][L].f=ALvl.M[I][J].f;
1091 
1092 							if (P)
1093 								TeleportEffect(I+ALvl.M[I][J].px,J+ALvl.M[I][J].py);
1094 						}else{
1095 							ALvl.M[I+ALvl.M[I][J].px][J+ALvl.M[I][J].py].FSpr=ALvl.M[I][J].FSpr;
1096 							ALvl.M[I+ALvl.M[I][J].px][J+ALvl.M[I][J].py].FTyp=ALvl.M[I][J].FTyp;
1097 							ALvl.M[I+ALvl.M[I][J].px][J+ALvl.M[I][J].py].x=0;
1098 							ALvl.M[I+ALvl.M[I][J].px][J+ALvl.M[I][J].py].y=0;
1099 							if (ALvl.M[I][J].f<2){
1100 								ALvl.M[I+ALvl.M[I][J].px][J+ALvl.M[I][J].py].px=0;
1101 								ALvl.M[I+ALvl.M[I][J].px][J+ALvl.M[I][J].py].py=0;
1102 								ALvl.M[I+ALvl.M[I][J].px][J+ALvl.M[I][J].py].f=1;
1103 							}else{
1104 								ALvl.M[I+ALvl.M[I][J].px][J+ALvl.M[I][J].py].px=ALvl.M[I][J].px;
1105 								ALvl.M[I+ALvl.M[I][J].px][J+ALvl.M[I][J].py].py=ALvl.M[I][J].py;
1106 								ALvl.M[I+ALvl.M[I][J].px][J+ALvl.M[I][J].py].f=2;
1107 							}
1108 						}
1109 						ALvl.M[I][J].FSpr=' ';
1110 						ALvl.M[I][J].FTyp=' ';
1111 						ALvl.M[I][J].f=0;
1112 						ALvl.M[I][J].x=0;
1113 						ALvl.M[I][J].y=0;
1114 						ALvl.M[I][J].px=0;
1115 						ALvl.M[I][J].py=0;
1116 					}
1117 					DR_SPR(I*20+ALvl.M[I][J].x,J*20+ALvl.M[I][J].y,ALvl.M[I][J].FSpr);
1118 				}else// EXPLODE/IMPLODE
1119 				if ((ALvl.M[I][J].f>=4)&&(ALvl.M[I][J].f<=6)){
1120 					DR_SPR(I*20+ALvl.M[I][J].x,J*20+ALvl.M[I][J].y,ALvl.M[I][J].FSpr);
1121 					if ((!ALvl.M[I][J].px)&&(!ALvl.M[I][J].py)){
1122 						ALvl.M[I][J].px=4;
1123 						ALvl.M[I][J].py=6;
1124 					}else
1125 					if (!(--ALvl.M[I][J].py)){
1126 						ALvl.M[I][J].py=6;
1127 						if ((ALvl.M[I][J].px==3)&&(ALvl.M[I][J].f<6)){
1128 							PlaySample(Snd_Expl);
1129 							for (K=-1;K<=1;K++)
1130 								for (L=-1;L<=1;L++)
1131 									if ((K||L)&&(I+K>=0)&&(I+K<MaxLvlSize)&&(J+L>=0)&&(J+L<MaxLvlSize))
1132 										if (((ALvl.M[I+K][J+L].FTyp=='o')||(ALvl.M[I+K][J+L].FTyp=='O'))&&((ALvl.M[I+K][J+L].f<4)||(ALvl.M[I+K][J+L].f>6))){
1133 											ALvl.M[I+K][J+L].f=4+(ALvl.M[I+K][J+L].FTyp=='O');
1134 											ALvl.M[I+K][J+L].x+=K;
1135 											ALvl.M[I+K][J+L].y+=L;
1136 											ALvl.M[I+K][J+L].px=0;
1137 											ALvl.M[I+K][J+L].py=0;
1138 										}else
1139 										if ((ALvl.M[I+K][J+L].FTyp=='x')||(ALvl.M[I+K][J+L].FTyp=='c')){
1140 											PlaySample(Snd_Fall);
1141 											ALvl.M[I+K][J+L].f=6;
1142 											ALvl.M[I+K][J+L].x+=K;
1143 											ALvl.M[I+K][J+L].y+=L;
1144 											ALvl.M[I+K][J+L].px=0;
1145 											ALvl.M[I+K][J+L].py=0;
1146 										}else
1147 										if ((ALvl.M[I+K][J+L].FTyp==' ')||(ALvl.M[I+K][J+L].FTyp=='B')){
1148 											if (ALvl.M[I+K][J+L].f==4);
1149 											else
1150 											if (ALvl.M[I+K][J+L].f==5);
1151 											else
1152 											//if (ALvl.M[I+K][J+L].f==6)
1153 												{
1154 												ALvl.M[I+K][J+L].f=6-2*(ALvl.M[I][J].f==5);
1155 												ALvl.M[I+K][J+L].px=0;
1156 												ALvl.M[I+K][J+L].py=0;
1157 												ALvl.M[I+K][J+L].x=0;
1158 												ALvl.M[I+K][J+L].y=0;
1159 												}
1160 										}
1161 						}else
1162 						if (ALvl.M[I][J].px==2){
1163 							for (K=10;K<=20;K+=ALvl.M[I][J].f)
1164 								filledCircleRGBA(ALvl.Bg,I*20+7+rand()%6,J*20+7+rand()%6,K,0,0,0,20-(K*(rand()%2))/2);
1165 							DR_RCT(I*20-5,J*20-5,I*20+19+5,J*20+19+5);
1166 						}
1167 						if (!(ALvl.M[I][J].FSpr=--ALvl.M[I][J].px)){
1168 							ALvl.M[I][J].f=0;
1169 							ALvl.M[I][J].FTyp=' ';
1170 							ALvl.M[I][J].FSpr=' ';
1171 							ALvl.M[I][J].px=0;
1172 							ALvl.M[I][J].py=0;
1173 							ALvl.M[I][J].x=0;
1174 							ALvl.M[I][J].y=0;
1175 							if (ALvl.M[I][J].BTyp=='&')
1176 								ALvl.M[I][J].f=8;
1177 						}
1178 					}
1179 					DR_SPR(I*20+ALvl.M[I][J].x,J*20+ALvl.M[I][J].y,ALvl.M[I][J].FSpr);
1180 				}else// FLAMABLE
1181 				if (ALvl.M[I][J].f==8){
1182 					DR_SPR(I*20,J*20,ALvl.M[I][J].FSpr);
1183 					if (!ALvl.M[I][J].px){
1184 						if ((ALvl.M[I][J].FTyp=='O')){
1185 							ALvl.M[I][J].f=5;
1186 							ALvl.M[I][J].px=0;
1187 							ALvl.M[I][J].py=0;
1188 						}else if ((ALvl.M[I][J].FTyp=='o')){
1189 							ALvl.M[I][J].f=4;
1190 							ALvl.M[I][J].px=0;
1191 							ALvl.M[I][J].py=0;
1192 						}else{
1193 							ALvl.M[I][J].FSpr=6;
1194 							ALvl.M[I][J].px=40;
1195 						}
1196 						PlaySample(Snd_Burn);
1197 					}else
1198 					if (--ALvl.M[I][J].px){
1199 						ALvl.M[I][J].FSpr=5+ALvl.M[I][J].px%4;
1200 						if (ALvl.M[I][J].px==20)
1201 							for (K=-1;K<=1;K++)
1202 								for (L=-1;L<=1;L++)
1203 									if ((I+K>=0)&&(I+K<MaxLvlSize)&&(J+L>=0)&&(J+L<MaxLvlSize))
1204 										if ((ALvl.M[I+K][J+L].BTyp=='&')&&(ALvl.M[I+K][J+L].f!=8)&&((ALvl.M[I+K][J+L].f<4)||(ALvl.M[I+K][J+L].f>6))){
1205 											ALvl.M[I+K][J+L].f=8;
1206 											ALvl.M[I+K][J+L].px=0;
1207 										}
1208 					}else{
1209 						ALvl.M[I][J].FTyp=' ';
1210 						ALvl.M[I][J].FSpr=' ';
1211 						ALvl.M[I][J].BTyp=' ';
1212 						ALvl.M[I][J].BSpr=' ';
1213 						ALvl.M[I][J].f=0;
1214 						ALvl.M[I][J].px=0;
1215 						ALvl.M[I][J].py=0;
1216 						DrawSpr(Spr[4].img,ALvl.Bg,I*20,J*20);
1217 						filledCircleRGBA(ALvl.Bg,I*20+7+rand()%6,J*20+7+rand()%6,13,0,0,0,64);
1218 						DR_RCT(I*20-3,J*20-3,I*20+19+3,J*20+19+3);
1219 					}
1220 					DR_SPR(I*20,J*20,ALvl.M[I][J].FSpr);
1221 //					fprintf(stderr,"at(%d,%d)-t%d-pxy(%d,%d)-xy(%d,%d)\n",I,J,ALvl.M[I][J].f,ALvl.M[I][J].px,ALvl.M[I][J].py,ALvl.M[I][J].x,ALvl.M[I][J].y);
1222 				}else// PARTICLES
1223 				if (ALvl.M[I][J].f==9){
1224 					DR_SPR(I*20,J*20,ALvl.M[I][J].FSpr);
1225 					if (!(ALvl.M[I][J].py-=1)){
1226 						if (!(ALvl.M[I][J].px-=1)){
1227 							ALvl.M[I][J].FSpr=' ';
1228 							ALvl.M[I][J].f=0;
1229 						}else{
1230 							ALvl.M[I][J].FSpr--;
1231 							ALvl.M[I][J].py=3;
1232 						}
1233 					}
1234 					DR_SPR(I*20,J*20,ALvl.M[I][J].FSpr);
1235 				}else// BEM
1236 				if (ALvl.M[I][J].f==10){
1237 					BEM2=1;
1238 					if (!(rand()%50)){
1239 						DR_SPR(I*20,J*20,ALvl.M[I][J].FSpr);
1240 						ALvl.M[I][J].FSpr='B'+rand()%4;
1241 						DR_SPR(I*20,J*20,ALvl.M[I][J].FSpr);
1242 					}
1243 				}else{// WEIRD!!!
1244 					fprintf(stderr,"?! %i at %i,%i\n",ALvl.M[I][J].f,I,J);
1245 					ALvl.M[I][J].f--;
1246 				}
1247 
1248 	if (BEM&&(!BEM2)){
1249 		for (I=0;I<MaxLvlSize;I++)
1250 			for (J=0;J<MaxLvlSize;J++)
1251 				if (ALvl.M[I][J].BTyp=='+'){
1252 					DrawSpr(Spr['+'].img,ALvl.Bg,I*20+ALvl.M[I][J].x,J*20+ALvl.M[I][J].y);
1253 					DR_SPR(I*20,J*20,ALvl.M[I][J].BSpr);
1254 				}
1255 		BEM=BEM2;
1256 	}
1257 }
1258 
1259 
SetLevel(char Lev,char DemoMode)1260 void SetLevel(char Lev,char DemoMode){
1261 int I,J;
1262 char Caption[MaxStrLenLong];
1263 SDL_Rect Rct;
1264 	Level=Lev;
1265 	PPX=0;
1266 	PPY=0;
1267 
1268 	if ((Lvl[Lev].Pw[0]=='\0')||(DemoMode))
1269 		sprintf(Caption,"%s: %s",APPNAME,Lvl[Lev].Name);
1270 	else{
1271 		strcpy(Passwd,Lvl[Lev].Pw);
1272 		sprintf(Caption,"%s: %s [%s]",APPNAME,Lvl[Lev].Name,Lvl[Lev].Pw);
1273 	}
1274 
1275 	SDL_WM_SetCaption(Caption,Caption);
1276 
1277 	BEM=0;
1278 	for (I=0;I<MaxLvlSize;I++)
1279 		for (J=0;J<MaxLvlSize;J++)
1280 			if (Lvl[Lev].M[I][J].FTyp=='B')
1281 				BEM=1;
1282 
1283 	ALvl.DL=Lvl[Lev].DL;
1284 	strcpy(ALvl.Name,Lvl[Lev].Name);
1285 	strcpy(ALvl.Pw,Lvl[Lev].Pw);
1286 	for (I=0;I<MaxLvlSize;I++)
1287 		for (J=0;J<MaxLvlSize;J++){
1288 			if (Lvl[Lev].M[I][J].BTyp=='*'){
1289 				PX=I;
1290 				PY=J;
1291 			}
1292 			ALvl.M[I][J].FTyp=Lvl[Lev].M[I][J].FTyp;
1293 			ALvl.M[I][J].FSpr=Lvl[Lev].M[I][J].FSpr;
1294 			ALvl.M[I][J].BTyp=Lvl[Lev].M[I][J].BTyp;
1295 			ALvl.M[I][J].BSpr=Lvl[Lev].M[I][J].BSpr;
1296 			ALvl.M[I][J].f=Lvl[Lev].M[I][J].f;
1297 			ALvl.M[I][J].txt=Lvl[Lev].M[I][J].txt;
1298 			ALvl.M[I][J].x=0;
1299 			ALvl.M[I][J].y=0;
1300 			ALvl.M[I][J].px=0;
1301 			ALvl.M[I][J].py=0;
1302 			if (ALvl.M[I][J].FTyp=='B')
1303 				ALvl.M[I][J].f=10;
1304 		}
1305 	for (I=0;I<MaxText;I++)
1306 		strcpy(ALvl.Text[I],Lvl[Lev].Text[I]);
1307 
1308 	if (Lvl[Level].Bg!=NULL){
1309 		Rct.w=Lvl[Level].Bg->w;
1310 		Rct.h=Lvl[Level].Bg->h;
1311 		for (I=0;I<WIDTH;I+=Rct.w)
1312 			for (J=0;J<HEIGHT;J+=Rct.h){
1313 				Rct.x=I;
1314 				Rct.y=J;
1315 				SDL_BlitSurface(Lvl[Level].Bg,NULL,ALvl.Bg,&Rct);
1316 			}
1317 	}else
1318 		boxRGBA(ALvl.Bg,0,0,WIDTH-1,HEIGHT-1,0x40,0x40,0x40,0xFF);
1319 
1320 	for (I=0;I<MaxLvlSize;I++)
1321 		for (J=0;J<MaxLvlSize;J++)
1322 			if (!BEM||(ALvl.M[I][J].BTyp!='+'))
1323 				DrawSpr(Spr[ALvl.M[I][J].BSpr].img,ALvl.Bg,I*20+ALvl.M[I][J].x,J*20+ALvl.M[I][J].y);
1324 			else
1325 				DrawSpr(Spr['+'].sha,ALvl.Bg,I*20+ALvl.M[I][J].x,J*20+ALvl.M[I][J].y);
1326 
1327 	ALvl.Bg=SDL_DisplayFormat(ALvl.Bg);
1328 
1329 	TextAdd(PX*20+10,PY*20+10,ALvl.Name);
1330 	DRT=0;
1331 	DRNULL();
1332 	DR_RCT(0,0,399,399);
1333 	Timed=(ALvl.DL>0);
1334 	Sec=1000/GCycle;
1335 }
1336 
1337 
ExplodeLevel(void)1338 void ExplodeLevel(void){
1339 int I,J;
1340 
1341 	for (I=1;I<MaxLvlSize;I+=3)
1342 		for (J=1;J<MaxLvlSize;J+=3)
1343 			ALvl.M[I][J].f=4;
1344 }
1345 
1346 
SystemSetup(void)1347 void SystemSetup(void){
1348 char Menu[3][100]={"Shadows:","Music volume:","Sound volume:"};
1349 char M=0,I;
1350 
1351 	SDL_BlitSurface(screen,NULL,swapscreen,NULL);
1352 	boxRGBA(screen,30,150,369,249,0,128,0,128);
1353 	rectangleRGBA(screen,30,150,369,249,0,190,0,128);
1354 	stringRGBA(screen,32,152,"X-pired 1.0 ------------------------ SetUp",0,255,0,255);
1355 
1356 	while ((!Quit)&&(!Fire)){
1357 		for (I=0;I<3;I++){
1358 			stringRGBA(screen,40,175+30*I,Menu[I],0,200+50*(I==M),0,255);
1359 			boxRGBA(screen,160,175+30*I,359,175+30*I+8,0,64,0,255);
1360 		}
1361 			boxRGBA(screen,160,175+30*0+1,160+((float)Shades/255.0)*200,175+30*0+7,0,128,0,255);
1362 			boxRGBA(screen,160,175+30*1+1,160+((float)MVolume/128.0)*200,175+30*1+7,0,128,0,255);
1363 			boxRGBA(screen,160,175+30*2+1,160+((float)SVolume/128.0)*200,175+30*2+7,0,128,0,255);
1364 
1365 		SDL_UpdateRect(screen,0,0,0,0);
1366 		SDL_Delay(500);
1367 
1368 		do {SDL_PollEvent(&event);} while ((!Fire)&&(!Quit)&&(!Up)&&(!Down)&&(!Left)&&(!Right));
1369 
1370 		if (Up)		if ((--M)<0) M=2;
1371 		if (Down)	if ((++M)>2) M=0;
1372 		if (Right){
1373 			if (M==0){
1374 				if (Shades==0) Shades=128;
1375 				else
1376 				if (Shades==128) Shades=255;
1377 				SDL_FreeSurface(Sh);
1378 				if (Shades){
1379 					Sh=SDL_CreateRGBSurface(SDL_SRCALPHA | SDL_HWSURFACE,WIDTH,HEIGHT,BPP,screen->format->Rmask,screen->format->Gmask,screen->format->Bmask,screen->format->Amask);
1380 					if (Sh==NULL) fprintf(stderr,"SH neni!!\n");
1381 					SDL_SetColorKey(Sh,SDL_SRCCOLORKEY,SDL_MapRGB(Sh->format,255,0,255));
1382 					SDL_SetAlpha(Sh,SDL_SRCALPHA,Shades);
1383 				}
1384 			}
1385 			if ((M==1)&&(MVolume<128)){
1386 				if ((MVolume+=128/9)>128)
1387 					MVolume=128;
1388 				Mix_VolumeMusic(MVolume);
1389 			}
1390 			if ((M==2)&&(SVolume<128)){
1391 				if ((SVolume+=128/9)>128)
1392 					SVolume=128;
1393 				Mix_Volume(-1,SVolume);
1394 				PlaySample(Snd_Push);
1395 			}
1396 		}
1397 		if (Left){
1398 			if (M==0){
1399 				if (Shades==255) Shades=128;
1400 				else
1401 				if (Shades==128) Shades=0;
1402 				SDL_FreeSurface(Sh);
1403 				if (Shades){
1404 					Sh=SDL_CreateRGBSurface(SDL_SRCALPHA | SDL_HWSURFACE,WIDTH,HEIGHT,BPP,screen->format->Rmask,screen->format->Gmask,screen->format->Bmask,screen->format->Amask);
1405 					if (Sh==NULL) fprintf(stderr,"SH neni!!\n");
1406 					SDL_SetColorKey(Sh,SDL_SRCCOLORKEY,SDL_MapRGB(Sh->format,255,0,255));
1407 					SDL_SetAlpha(Sh,SDL_SRCALPHA,Shades);
1408 				}
1409 			}
1410 			if ((M==1)&&(MVolume>0)){
1411 				if ((MVolume-=128/9)<0)
1412 					MVolume=0;
1413 				Mix_VolumeMusic(MVolume);
1414 			}
1415 			if ((M==2)&&(SVolume>0)){
1416 				if ((SVolume-=128/9)<0)
1417 					SVolume=0;
1418 				Mix_Volume(-1,SVolume);
1419 				PlaySample(Snd_Push);
1420 			}
1421 		}
1422 
1423 	}
1424 
1425 	Setup=0;
1426 	Fire=0;
1427 	Quit=0;
1428 	UC=0;
1429 
1430 
1431 	//SaveConfig("./xpired.cfg");
1432 
1433 	SDL_BlitSurface(swapscreen,NULL,screen,NULL);
1434 	SDL_UpdateRect(screen,0,0,0,0);
1435 }
1436 
1437 
Gameplay(char DemoMode)1438 char Gameplay(char DemoMode){
1439 Uint32 Ticks,OldTicks,WT,FR=0,RecTick=0,RecState=1;
1440 int PX2,PY2;
1441 char Sw=0,LLeft=0,LRight=0,LUp=0,LDown=0,LFire=0,LQuit=0;
1442 
1443 	if (DemoMode)
1444 		Level=Rec[0].Tick;
1445 	else
1446 		Rec[0].Tick=Level;
1447 
1448 	Lives=3;
1449 	TextReset();
1450 
1451 do{
1452 	SetLevel(Level,DemoMode);
1453 	Sec=1000/GCycle;
1454 	PAlive=1.5*DeadDelay;
1455 	OldTicks=WT=SDL_GetTicks();
1456 
1457 	do {
1458 
1459 // BOF vykresleni
1460 		DrawGame();
1461 		FR++;
1462 // EOF vykresleni
1463 
1464 		Ticks=SDL_GetTicks();
1465 		if ((ShowFPS)&&(Ticks-OldTicks>=1000)){
1466 			fprintf(stdout,"%d FPS\n",FR);
1467 			FR=0;
1468 			OldTicks=Ticks;
1469 		}
1470 
1471 		if ((WT+GCycle)>Ticks)
1472 			SDL_Delay((WT+GCycle)-Ticks);
1473 		Ticks=SDL_GetTicks();
1474 
1475 // GameState smycka
1476 
1477 		while ((WT+GCycle)<=Ticks){
1478 			RecTick++;
1479 			SDL_PollEvent(&event);
1480 			if (DemoMode){ // Playing
1481 				if ((Quit!=LQuit)||(Left!=LLeft)||(Right!=LRight)||(Up!=LUp)||(Down!=LDown)||(Fire!=LFire))
1482 					Quit=2;
1483 				else
1484 				if (Rec[RecState].Tick==RecTick){
1485 					LLeft=Left=Rec[RecState].Left;
1486 					LRight=Right=Rec[RecState].Right;
1487 					LUp=Up=Rec[RecState].Up;
1488 					LDown=Down=Rec[RecState].Down;
1489 					LFire=Fire=Rec[RecState].Fire;
1490 					LQuit=Quit=Rec[RecState].Quit;
1491 					if (RecState<MaxRecLength-1)
1492 						RecState++;
1493 				}
1494 			}else // Recording
1495 				if ((Left!=LLeft)||(Right!=LRight)||(Up!=LUp)||(Down!=LDown)||(Fire!=LFire)||(Quit!=LQuit)){
1496 					Rec[RecState].Tick=RecTick;
1497 					LLeft=Rec[RecState].Left=Left;
1498 					LRight=Rec[RecState].Right=Right;
1499 					LUp=Rec[RecState].Up=Up;
1500 					LDown=Rec[RecState].Down=Down;
1501 					LFire=Rec[RecState].Fire=Fire;
1502 					LQuit=Rec[RecState].Quit=Quit;
1503 					if (RecState<MaxRecLength-1)
1504 						RecState++;
1505 				}
1506 
1507 			if (Setup && !DemoMode){
1508 				SystemSetup();
1509 				DR_RCT(0,0,399,399);
1510 			}
1511 
1512 			if ((abs(PPX)==19)||(abs(PPY)==19)){
1513 				DR_SPR(PX*20+PPX,PY*20+PPY,'*');
1514 				PX+=sgn(PPX);
1515 				PY+=sgn(PPY);
1516 //				PF=1;
1517 				if ((ALvl.M[PX][PY].BTyp=='T')&&(PPX||PPY)){
1518 					DR_SPR(PX*20,PY*20,'*');
1519 					PX2=PX;
1520 					PY2=PY;
1521 					if (GetTeleport(&PX2,&PY2)){
1522 						TeleportEffect(PX,PY);
1523 						PX=PX2;
1524 						PY=PY2;
1525 					}
1526 					PPX=sgn(PPX);
1527 					PPY=sgn(PPY);
1528 					if (!is_free(PPX,PPY)){
1529 						PPX=0;
1530 						PPY=0;
1531 					}
1532 				}else{
1533 					PPX=0;
1534 					PPY=0;
1535 				}
1536 				DR_SPR(PX*20+PPX,PY*20+PPY,'*');
1537 			}else
1538 			if (PPX||PPY){
1539 				DR_SPR(PX*20+PPX,PY*20+PPY,'*');
1540 				PPX+=PF*sgn(PPX);
1541 				PPY+=PF*sgn(PPY);
1542 				LM=(PPY>0)+(PPX>0)*2+(PPX<0)*3;
1543 				DR_SPR(PX*20+PPX,PY*20+PPY,'*');
1544 			}
1545 
1546 			MoveObjects();
1547 
1548 			if ((PPX==0)&&(PPY==0)&&(PAlive==DeadDelay)){
1549 				if (Fire)
1550 					PF=2;
1551 				else
1552 					PF=1;
1553 				if (ALvl.M[PX][PY].BTyp=='#'){
1554 					PF=2;
1555 					if ((!Left)&&(!Right)&&(!Up)&&(!Down)){
1556 						PPX=-1*(LM==3)+(LM==2);
1557 						PPY=-1*(LM==0)+(LM==1);
1558 						DR_SPR(PX*20,PY*20,'*');
1559 					}
1560 					if (!is_free(PPX,PPY)){
1561 						PPX=0;
1562 						PPY=0;
1563 					}
1564 				}
1565 				if ((Left&&!Right&&!Up&&!Down)||(Left&&Down&&Sw)||(Left&&Up&&!Sw))		if (is_free(-1,0))		{Sw=!Sw;PPX=-1;PPY=0;DR_SPR(PX*20,PY*20,'*');} else Sw=!Sw;
1566 				else
1567 				if ((Right&&!Left&&!Up&&!Down)||(Right&&Down&&!Sw)||(Right&&Up&&Sw))	if (is_free(+1,0))		{Sw=!Sw;PPX=+1;PPY=0;DR_SPR(PX*20,PY*20,'*');} else Sw=!Sw;
1568 				else
1569 				if ((Up&&!Down&&!Left&&!Right)||(Up&&Left&&Sw)||(Up&&Right&&!Sw))		if (is_free(0,-1))		{Sw=!Sw;PPY=-1;PPX=0;DR_SPR(PX*20,PY*20,'*');} else Sw=!Sw;
1570 				else
1571 				if ((Down&&!Up&&!Left&&!Right)||(Down&&Left&&!Sw)||(Down&&Right&&Sw))	if (is_free(0,+1))		{Sw=!Sw;PPY=+1;PPX=0;DR_SPR(PX*20,PY*20,'*');} else Sw=!Sw;
1572 			}
1573 
1574 			if (!BEM&&(ALvl.M[PX][PY].BTyp=='+')){
1575 				Lives+=(Level%2);
1576 				SetLevel(Level+1,DemoMode);
1577 			}
1578 			if ((ALvl.M[PX][PY].txt>=0)&&(ALvl.Text[ALvl.M[PX][PY].txt][0]!='\0')){
1579 				TextAdd(PX*20+10,PY*20+10,ALvl.Text[ALvl.M[PX][PY].txt]);
1580 				ALvl.Text[ALvl.M[PX][PY].txt][0]='\0';
1581 				ALvl.M[PX][PY].txt=-1;
1582 			}
1583 
1584 			//--- SMRT
1585 			// --- SMRT NA PRANI ---
1586 			if (Quit){
1587 				if (PAlive>=DeadDelay){
1588 					PAlive=DeadDelay-1;
1589 					if (Quit==2)
1590 						Lives=0;
1591 					TextAdd(PX*20+10,PY*20+10,"Why?!");
1592 				}
1593 				Quit=0;
1594 			}
1595 			//--- EO SMRT ON DEMAND ---
1596 
1597 			if (PAlive==DeadDelay){
1598 				if ((abs(PPX)>9)||(abs(PPY>9))){
1599 					if ((ALvl.M[PX+sgn(PPX)][PY+sgn(PPY)].f==4)||(ALvl.M[PX+sgn(PPX)][PY+sgn(PPY)].f==6)||(ALvl.M[PX+sgn(PPX)][PY+sgn(PPY)].f==8)){
1600 						PAlive=DeadDelay-1;
1601 						TextAdd(PX*20+10,PY*20+10,"AAAAaaaaaeghr!");
1602 					}
1603 				}else
1604 				if ((ALvl.M[PX][PY].f==4)||(ALvl.M[PX][PY].f==6)||(ALvl.M[PX][PY].f==8)){
1605 						PAlive=DeadDelay-1;
1606 						TextAdd(PX*20+10,PY*20+10,"AAAAaaaaaeghr!");
1607 				}else
1608 				if (ALvl.M[PX][PY].BTyp=='@'){
1609 						PAlive=DeadDelay-1;
1610 						TextAdd(PX*20+10,PY*20+10,"AAAAaaaaaeghr!");
1611 				}else
1612 				if (bem(PX-1,PY-1)||bem(PX,PY-1)||bem(PX+1,PY-1)||bem(PX-1,PY)||bem(PX+1,PY)||bem(PX-1,PY+1)||bem(PX,PY+1)||bem(PX+1,PY+1)){
1613 						PAlive=DeadDelay-1;
1614 						TextAdd(PX*20+10,PY*20+10,"AAAAaaaaaeghr!");
1615 				}
1616 			}
1617 			//--- EO SMRT
1618 
1619 			if ((PAlive!=DeadDelay)&&(PAlive)){
1620 				PAlive--;
1621 				DR_SPR(PX*20+PPX,PY*20+PPY,'*');
1622 			}
1623 
1624 			if (Timed){
1625 				if (!--Sec){
1626 					Sec=1000/GCycle;
1627 					if (--ALvl.DL<=0){
1628 						ALvl.DL=0;
1629 						PAlive--;
1630 						DR_SPR(PX*20+PPX,PY*20+PPY,'*');
1631 						Timed=0;
1632 						ExplodeLevel();
1633 					}
1634 					PlaySample(Snd_Beep);
1635 					DR_RCT(200-26,400-17,200+26,399);
1636 				}
1637 			}
1638 			// ---EOSmrt
1639 
1640 			TextBehave();
1641 
1642 			WT+=GCycle;
1643 		}
1644 	} while (PAlive);
1645 
1646 	Lives--;
1647 
1648 } while (Lives>0);
1649 
1650 	if (DemoMode)
1651 		Left=Right=Up=Down=Fire=Quit=0;
1652 	else
1653 		if (RecState<MaxRecLength-1)
1654 			Rec[RecState+1].Quit=2;
1655 
1656 	PlaySample(Snd_GameOver);
1657 	return 0;
1658 }
1659 
1660 
Title(void)1661 char Title(void){
1662 char Return=-1,M=5,Caption[MaxStrLenLong];
1663 SDL_Rect Src;
1664 Uint32 OldTicks;
1665 
1666 	Src.h=400;
1667 	Src.w=400;
1668 	Src.x=0;
1669 	Src.y=0;
1670 
1671 	sprintf(Caption,"%s %s",APPNAME,VERSION);
1672 	SDL_WM_SetCaption(Caption,APPNAME);
1673 
1674 	OldTicks=SDL_GetTicks();
1675 	SDL_BlitSurface(TitleS,NULL,screen,NULL);
1676 	if (Passwd[0]!='\0'){
1677 		boxRGBA(screen,0,390,399,399,0,255,0,64);
1678 		stringRGBA(screen,200-strlen(Passwd)*4,391,Passwd,10,250,10,128);
1679 	}
1680 	SDL_UpdateRect(screen, 0, 0, 0, 0);
1681 
1682 	while ((Fire)||(Quit==1))
1683 		SDL_PollEvent(&event);
1684 
1685 	SDL_EnableUNICODE(1);
1686 
1687 	while ((Return==-1)){
1688 		UC=0;
1689 		SDL_PollEvent(&event);
1690 
1691 		if (Setup)
1692 			SystemSetup();
1693 
1694 		if ((UC)&&(!Fire)&&(!Quit)){
1695 			if ((UC!=8)&&(UC!=13)&&(strlen(Passwd)<10)){
1696 				Passwd[strlen(Passwd)+1]='\0';
1697 				Passwd[strlen(Passwd)]=UC;
1698 			}else
1699 			if ((UC==8)&&(strlen(Passwd)>0))
1700 				Passwd[strlen(Passwd)-1]='\0';
1701 			if (UC==13)
1702 				Return=1;
1703 				SDL_BlitSurface(TitleS,&Src,screen,NULL);
1704 				if (Passwd[0]!='\0'){
1705 					boxRGBA(screen,0,390,399,399,0,255,0,64);
1706 					stringRGBA(screen,200-strlen(Passwd)*4,391,Passwd,10,250,10,128);
1707 				}
1708 				SDL_UpdateRect(screen, 0, 390, 400, 10);
1709 		}
1710 		if (SDL_GetTicks()-OldTicks>10000){
1711 			Src.y+=M;
1712 			SDL_BlitSurface(TitleS,&Src,screen,NULL);
1713 			if (Passwd[0]!='\0'){
1714 				boxRGBA(screen,0,390,399,399,0,255,0,64);
1715 				stringRGBA(screen,200-strlen(Passwd)*4,391,Passwd,10,250,10,128);
1716 			}
1717 			SDL_UpdateRect(screen, 0, 0, 0, 0);
1718 			if (Src.y==400*(M>0)){
1719 				OldTicks=SDL_GetTicks();
1720 				M*=-1;
1721 			}
1722 		}
1723 		if (Fire)
1724 			Return=1;
1725 		if (Quit)
1726 			Return=0;
1727 	}
1728 
1729 	SDL_EnableUNICODE(0);
1730 
1731 	while (Fire)
1732 		SDL_PollEvent(&event);
1733 
1734 	return Return;
1735 }
1736 
1737 
GetLevelByPasswd(char * Pswd)1738 int GetLevelByPasswd(char *Pswd){
1739 int I;
1740 
1741 	if (Pswd[0]=='\0')
1742 		return 0;
1743 	for (I=MaxLevel-1;(I>0)&&(strcmp(Lvl[I].Pw,Pswd));I--);
1744 
1745 	return I;
1746 }
1747 
1748 
1749 // --------------------
Game(void)1750 void Game(void){
1751 	while (1)
1752 		if (Title()){
1753 			Level=GetLevelByPasswd(Passwd);
1754 			Gameplay(!strcmp(Passwd,"demo"));
1755 		}
1756 		else
1757 			return;
1758 }
1759 
1760 
1761 
1762 // MAIN ---------------------------------
main(int argc,char * argv[])1763 int main(int argc, char *argv[]){
1764   int I;
1765   Uint32 InitFlags;
1766   char buf[255];
1767   char LevelF[255];
1768   char joystick=0;
1769 
1770 #ifdef UNIX
1771 
1772   strcpy(GAME_HOME,getenv("HOME"));
1773   strcat(GAME_HOME,"/.xpired");
1774 
1775 #else
1776 
1777   strcpy(GAME_HOME,".");
1778 
1779 #endif
1780 
1781   sprintf(LevelF,"%s/xpired.lvl",SHARE_DIR);
1782 
1783 // init demo record
1784   Rec[0].Tick=0;
1785   Rec[1].Tick=1;
1786   Rec[1].Quit=2;
1787 
1788 // load demo
1789   sprintf(buf,"%s/xpired.dmo",GAME_HOME);
1790 
1791   if(!LoadDemo(buf)){
1792     sprintf(buf,"%s/xpired.dmo",SHARE_DIR);
1793     LoadDemo(buf);
1794   }
1795 
1796 // load config
1797   sprintf(ConfFName,"%s/xpired.cfg",GAME_HOME);
1798   if(!LoadConfig(ConfFName))
1799     {
1800       sprintf(buf,"%s/xpired.cfg",SHARE_DIR);
1801       LoadConfig(buf);
1802 #ifdef UNIX
1803       if(mkdir(GAME_HOME,0750))
1804 	fprintf(stderr,"Cannot create %s!\n",buf);
1805       else
1806 	SaveConfig(ConfFName);
1807 #endif
1808     }
1809 
1810 
1811   for (I=1;I<argc;I++){
1812     if ((!strcmp("--nosound",argv[I]))||(!strcmp("-n",argv[I]))){
1813       Sound=0;
1814     }else if ((!strcmp("--help",argv[I]))||(!strcmp("-h",argv[I]))){
1815 		fprintf(stdout,"Example of usage: %s --nosound -l levelfile.lvl -d demo.dmo\n",argv[0]);
1816 		fprintf(stdout," Switches:\n");
1817 		fprintf(stdout,"   -j, --joystick      Enable Joystick 0\n");
1818 		fprintf(stdout,"   -f, --fullscreen    Toggle fullscreen/windowed\n");
1819 		fprintf(stdout,"   -n, --nosound       Disable sound\n");
1820 		fprintf(stdout,"   -l  <file>          Load level from <file>\n");
1821 		fprintf(stdout,"   -d  <file>          Use demo record from <file>\n");
1822 		fprintf(stdout,"   --version           Display version no.\n");
1823 		fprintf(stdout,"   -h, --help          Display this help screen\n");
1824 		return 0;
1825     }else if (!strcmp("-l",argv[I])){
1826       strcpy(LevelF,argv[++I]);
1827     }else if (!strcmp("-d",argv[I])){
1828       if (!LoadDemo(argv[++I]))
1829 	fprintf(stderr,"Error loading demo record...\n");
1830     }else if( !strcmp("-f",argv[I]) || !strcmp("--fullscreen",argv[I])){
1831       FULLSCR=!FULLSCR;
1832     }else if (!strcmp("--version",argv[I])){
1833 		fprintf(stdout,"%s ver. %s \n",APPNAME,VERSION);
1834 		return 0;
1835 	}
1836   }
1837   InitFlags=SDL_INIT_VIDEO;
1838   if (Sound)
1839     InitFlags|=SDL_INIT_AUDIO;
1840   if (joystick)
1841 	InitFlags |= SDL_INIT_JOYSTICK;
1842 
1843   if ( SDL_Init(InitFlags) < 0 ) {
1844     fprintf(stderr, "Couldn't initialize SDL: %s\n",SDL_GetError());
1845     exit(1);
1846   }
1847   atexit(SDL_Quit);
1848 
1849   SDL_WM_SetCaption("X-pired says: A moment, please...","X-pired at work");
1850 
1851   if (Sound)
1852     if ( Mix_OpenAudio(22050, AUDIO_S16, 1, 1024) < 0 ){
1853       fprintf(stderr,"Warning: Couldn't set 22050 Hz 16-bit audio\n- Reason: %s\n",SDL_GetError());
1854       Sound=0;
1855     }
1856   if (joystick)
1857 	js = SDL_JoystickOpen(0); // open the first joystick
1858 
1859   //	fprintf(stdout,"SDL awaken!\n");
1860 
1861   sprintf(buf,"%s/img/icon.bmp",SHARE_DIR);
1862   SDL_WM_SetIcon(SDL_LoadBMP(buf), NULL);
1863 
1864 
1865   VIDEO_INIT();
1866   SDL_SetEventFilter(E_FILTER);
1867   SDL_EnableKeyRepeat(0,0);
1868 
1869   LoadSprites();
1870   if (!LoadLevels(LevelF))
1871     fprintf(stderr,"Error loading level file...\n");
1872 
1873 
1874   //	printf("Shades=%d\n",Shades);
1875   //	printf("MVolume=%d\n",MVolume);
1876 
1877   ALvl.Bg=SDL_DisplayFormat(SDL_CreateRGBSurface(SDL_HWSURFACE,WIDTH,HEIGHT,BPP,screen->format->Rmask,screen->format->Gmask,screen->format->Bmask,screen->format->Amask));
1878   if (ALvl.Bg==NULL) fprintf(stderr,"Can't allocate ALvl.BG!\n");
1879 
1880   if (Shades){
1881     Sh=SDL_CreateRGBSurface(SDL_SRCALPHA | SDL_HWSURFACE,WIDTH,HEIGHT,BPP,screen->format->Rmask,screen->format->Gmask,screen->format->Bmask,screen->format->Amask);
1882     if (Sh==NULL) fprintf(stderr,"Can't allocate SH!\n");
1883     SDL_SetColorKey(Sh,SDL_SRCCOLORKEY,SDL_MapRGB(Sh->format,255,0,255));
1884     SDL_SetAlpha(Sh,SDL_SRCALPHA,Shades);
1885   }
1886 
1887   swapscreen=SDL_CreateRGBSurface(SDL_SRCALPHA | SDL_HWSURFACE,WIDTH,HEIGHT,BPP,screen->format->Rmask,screen->format->Gmask,screen->format->Bmask,screen->format->Amask);
1888   if (swapscreen==NULL) fprintf(stderr,"Can't allocate SwapScreen!\n");
1889 
1890   if (Sound){
1891     Mix_Volume(-1,SVolume);
1892     Mix_HookMusicFinished(&MusicLoopback);
1893     Mix_VolumeMusic(MVolume);
1894     Mix_FadeInMusic(Music,0,3000);
1895   }
1896 
1897   Game();
1898 
1899   SaveConfig(ConfFName);
1900   sprintf(buf,"%s/xpired.dmo",GAME_HOME);
1901   SaveDemo(buf);
1902 
1903   if (Sound){
1904     Mix_FadeOutMusic(1000);
1905     SDL_Delay(1000);
1906   }
1907   if( joystick )
1908 	SDL_JoystickClose(js);
1909 
1910   SDL_Quit();
1911   //	fprintf(stdout,"SDL shot down.\n\n");
1912   return 0;
1913 }
1914