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