1 /*
2  * 	@(#) TROJKA main file
3  *	created: 	4.iii.1992
4  * 	modified:	20.iii.1992
5  */
6 
7 
8 #include <stdio.h>
9 #include <curses.h>
10 
11 #include "trojka.h"
12 #include "hiscore.h"
13 
14 static char INFO[] = "@(#) trojka (c) 1989-1995 by Maarten Los";
15 
16 int	play(),
17 	dropblock(),
18 	multscore(),
19 	speedup(),
20 	initialize(),
21 	resetgame(),
22 	resetblock(),
23 	check_speed(),
24 	check_mesg(),
25 	resetfield(),
26 	getopt();
27 
28 struct scorefile *sfile;
29 
30 char	field[VIRT_XSIZE][VIRT_YSIZE];	/* virtual screen */
31 
32 unsigned long
33 	score,
34 	mesg_score,
35 	blocks,
36 	wipes,
37 	mesg_time,
38 	speedbonus;	/* bonus multiplier depending on speed */
39 
40 
41 flag	stopgame,	/* flag quit game */
42 	quit,		/* flag quit trojka */
43 	mesg_showed,
44 	curses_installed;
45 
46 int	shape,		/* index of block */
47 	xpos,           /* virtual coordinates of the falling block */
48 	ypos,		/* conversion to on-screen coordinates takes */
49 	last_xpos,	/* place in 'makeblock()' */
50 	last_ypos,
51 	statx,
52 	x_min, x_max,
53 	mesg_count,	/* cookie-counter */
54 	stacklevel,		/* level of stack */
55 	blockwidth,	/* width of a block in characters */
56 	level,
57 	speed,		/* game speed */
58 	speed_switch,	/* number of fallen blocks the speed is increased */
59 	trojkas,
60 	position,	/* position in the highscore table */
61 	Pause,		/* game speed in milliseconds */
62 	xloc[VIRT_XSIZE],	/* array with the x-coordinates */
63 	yloc[VIRT_YSIZE],
64 	block_count[BLOCKS];
65 
66 
main(argc,argv)67 main(argc, argv)
68 int argc;
69 char **argv;
70 {
71 	sfile = (struct scorefile *)malloc(FILE_SIZE);
72 	if(sfile == NULL)
73 		quit_prog("Not enough memory to hold scores.");
74 	readscores();
75 	getopt(argc, argv);
76 
77 	initcurses();
78 	initialize();
79 
80 	while(!quit) {
81 		titlescreen();
82 		if (!quit) {
83 			speed = (int)selectspeed();
84 			if (!quit) {
85 				resetgame();
86 				build();
87 				refresh();
88 				play();
89 			}
90 		}
91 	}
92 	quit_prog("See you around in the Trojka-zone...");
93 }
94 
95 
play()96 int play()
97 {
98 	resetblock();		/* reset x-y coordinates	*/
99 	showspeed(speed);
100 
101 	speed_switch = SPEED_SWITCH * (speed + 1);
102 	Pause = 200 - (speed + 1)*15;
103 	speedbonus = (unsigned long)(speed+1);
104 
105 	while(!stopgame)
106 	{
107 		wipeblock(last_xpos, last_ypos);
108 		makeblock(xpos, ypos, shape);
109 		move(0,0);
110 		refresh();
111 		last_xpos = xpos;
112 		last_ypos = ypos;
113 
114 		delay(Pause);		/* game speed */
115 
116 		ypos--;
117 
118 		switch(getkey()) {	/* key control */
119 #ifdef HACK
120 		case 't':
121 			score += 10000;
122 			showscore();
123 			break;
124 #endif
125 
126 		case LEFT:
127 		case VILEFT:
128 			if((xpos > 0) && (field[xpos-1][ypos] == CLEAR))
129 				xpos--;
130 			break;
131 
132 		case RIGHT:
133 		case VIRIGHT:
134 			if((xpos < VIRT_XSIZE-1)
135 			&& (field[xpos + 1][ypos] == CLEAR))
136 				xpos++;
137 			break;
138 
139 		case DROP:
140 		case SPACE :
141 		case VIDROP:
142 		case INSDROP:
143 			dropblock();
144 			break;
145 
146 		case QUIT:
147 			stopgame = TRUE;
148 			quit = FALSE;
149 			break;
150 
151 		case REDRAW:
152 			redraw();
153 			break;
154 
155 		case VISPEEDUP:
156 		case SPEEDUP:
157 			speedup();
158 			break;
159 		} /* case */
160 
161 		if (field[xpos][ypos] != CLEAR) {
162 			field[xpos][ypos+1] = shape;
163 			block_count[shape-1]++;
164 /* scan() returns the stacklevel */
165 			if(scan() < PLM_TOP) {
166 				multscore((unsigned long)shape);
167 				blocks++;
168 
169 				check_speed();
170 				check_mesg();
171 
172 				statistics();
173 				showscore();
174 
175 				resetblock();
176 			} else {
177 /* GAME OVER */			wipemesg();
178 				stopgame = TRUE;
179 				quit = FALSE;
180 			}
181 		}
182 	}
183 	gameover();
184 }
185 
186 
dropblock()187 int dropblock()
188 {
189 	score += (unsigned long)((ypos * speedbonus) / 5);
190 
191 	wipeblock(xpos, ypos+1);
192 	while(field[xpos][ypos]==CLEAR)
193 		ypos--;
194 	makeblock(xpos, ypos+1, shape);
195 
196 	refresh();
197 }
198 
199 
multscore(mult)200 int multscore(mult)
201 unsigned long mult;
202 {
203 	score += (unsigned long)((mult * speedbonus + level) / 3);
204 }
205 
206 
speedup()207 int speedup()
208 {
209 	if(speed < MAXSPEED) {
210 		speed++;
211 		showspeed(speed);
212 		speedbonus = (unsigned long)(speed+1);
213 		Pause = 200 - (speed+1)*15;
214 		speed_switch = SPEED_SWITCH * (speed + 1);
215 	}
216 }
217 
218 
initialize()219 int initialize()
220 {
221 	int i;
222 
223 	position = NUMSCORES + 1;
224 
225 	x_min = X_MIN;
226 	x_max = X_MAX;
227 	statx = STATX;
228 	blockwidth = 4;
229 
230 	resetfield();
231 	reset_f();		/* reset shadow buffer in scan.c */
232 
233 	for(i = 0; i < VIRT_XSIZE; i++)
234 		xloc[i] = (i * blockwidth) + x_min;
235 	for(i = PLM_TOP; i >= PLM_BOTTOM; i--)
236 		yloc[i] = (PLM_TOP - i) + 1;
237 
238 	quit = FALSE;
239 }
240 
241 
resetgame()242 int resetgame()
243 {
244 	int i;
245 
246 	setrandom();
247 	resetfield();
248 
249 	for(i = 0; i < BLOCKS; i++)
250 		block_count[i] = 0;
251 	score = 0;
252 	mesg_count = 0;
253 	mesg_score = (unsigned long)MESG_SWITCH;
254 	mesg_time = 0;
255 	blocks = 0;
256 	trojkas = 0;
257 	wipes = 0;
258 	stopgame = FALSE;
259 	quit = FALSE;
260 	level = 1;
261 }
262 
263 
resetblock()264 int resetblock()
265 {
266 	ypos = PLM_TOP;
267 	xpos = VIRT_MIDDLE;
268 	last_xpos = xpos;
269 	last_ypos = ypos;
270 	shape = getrandom(BLOCKS) + 1;
271 }
272 
273 
resetfield()274 int resetfield()
275 {
276 	int x,y;
277 
278 	for(x = 0; x < VIRT_XSIZE; x++)		/* clear virt. field */
279 		for(y = 1; y < VIRT_YSIZE; y++)
280 			field[x][y] = CLEAR;
281 	for(x = 0;x < VIRT_XSIZE; x++)		/* fill bottom-line */
282 		field[x][0] = -1;
283 	stacklevel = 0;
284 }
285 
286 
check_speed()287 int check_speed()
288 {
289 	if (blocks > speed_switch)
290 		speedup();
291 }
292 
293 
check_mesg()294 int check_mesg()
295 {
296 	if((score > mesg_score) && (mesg_count < MESGS) && (stacklevel <= 9))
297 	{
298 		wipemesg();
299 		showmesg(mesg_count++);
300 		mesg_showed = TRUE;
301 		mesg_score =  ((unsigned long)MESG_SWITCH + score);
302 	}
303 	if(mesg_showed) {
304 		mesg_time++;
305 		if(mesg_time > MAX_MESG_TIME) {
306 			wipemesg();
307 			mesg_time = 0;
308 			mesg_showed = 0;
309 		}
310 	}
311 }
312 
313 
getopt(argc,argv)314 int getopt(argc, argv)
315 int argc;
316 char **argv;
317 {
318 	if(argc > 1) {
319 		if(!strcmp(argv[1], "-s"))
320 			scorelist();
321 		else
322 			fprintf(stderr,"Usage: trojka [-s]\n");
323 		exit(0);
324 	}
325 }
326 
327