Changeset ebe70f1 in mainline
- Timestamp:
- 2009-06-09T11:10:31Z (15 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- f3afd24
- Parents:
- 080ad7f
- Location:
- uspace/app/tetris
- Files:
-
- 1 deleted
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/tetris/input.c
r080ad7f rebe70f1 37 37 38 38 /** @addtogroup tetris 39 * @{ 39 * @{ 40 40 */ 41 41 /** @file … … 93 93 * 94 94 */ 95 int 96 rwait(struct timeval *tvp) 95 int rwait(struct timeval *tvp) 97 96 { 98 97 struct timeval starttv, endtv, *s; 99 98 static ipc_call_t charcall; 100 99 ipcarg_t rc; 101 100 102 101 /* 103 102 * Someday, select() will do this for us. … … 111 110 } else 112 111 s = NULL; 113 112 114 113 if (!lastchar) { 115 114 again: … … 118 117 CONSOLE_GET_EVENT, &charcall); 119 118 } 119 120 120 if (!s) 121 121 async_wait_for(getchar_inprog, &rc); … … 125 125 return (0); 126 126 } 127 127 128 getchar_inprog = 0; 128 if (rc) {129 if (rc) 129 130 stop("end of file, help"); 130 }131 131 132 if (IPC_GET_ARG1(charcall) == KEY_RELEASE) 132 133 goto again; 133 134 134 135 lastchar = IPC_GET_ARG4(charcall); 135 136 } 137 136 138 if (tvp) { 137 139 /* since there is input, we may not have timed out */ 138 140 (void) gettimeofday(&endtv, NULL); 139 141 TV_SUB(&endtv, &starttv); 140 TV_SUB(tvp, &endtv); 142 TV_SUB(tvp, &endtv); /* adjust *tvp by elapsed time */ 141 143 } 142 return (1); 144 145 return 1; 143 146 } 144 147 … … 147 150 * Eat any input that might be available. 148 151 */ 149 void 150 tsleep(void) 152 void tsleep(void) 151 153 { 152 154 struct timeval tv; 153 155 154 156 tv.tv_sec = 0; 155 157 tv.tv_usec = fallrate; … … 164 166 * getchar with timeout. 165 167 */ 166 int 167 tgetchar(void) 168 int tgetchar(void) 168 169 { 169 170 static struct timeval timeleft; 170 171 char c; 171 172 172 173 /* 173 174 * Reset timeleft to fallrate whenever it is not positive. … … 180 181 */ 181 182 if (!TV_POS(&timeleft)) { 182 faster(); 183 faster(); /* go faster */ 183 184 timeleft.tv_sec = 0; 184 185 timeleft.tv_usec = fallrate; 185 186 } 187 186 188 if (!rwait(&timeleft)) 187 return (-1); 189 return -1; 190 188 191 c = lastchar; 189 192 lastchar = '\0'; 190 return ((int) (unsigned char)c);193 return ((int) (unsigned char) c); 191 194 } 192 195 193 196 /** @} 194 197 */ 195 -
uspace/app/tetris/input.h
r080ad7f rebe70f1 37 37 38 38 /** @addtogroup tetris 39 * @{ 39 * @{ 40 40 */ 41 41 /** @file 42 42 */ 43 43 44 intrwait(struct timeval *);45 inttgetchar(void);46 voidtsleep(void);44 extern int rwait(struct timeval *); 45 extern int tgetchar(void); 46 extern void tsleep(void); 47 47 48 48 /** @} 49 49 */ 50 -
uspace/app/tetris/scores.c
r080ad7f rebe70f1 37 37 38 38 /** @addtogroup tetris 39 * @{ 39 * @{ 40 40 */ 41 41 /** @file … … 49 49 * Major whacks since then. 50 50 */ 51 51 52 #include <errno.h> 52 /* #include <err.h> */53 /* #include <fcntl.h> */54 /* #include <pwd.h> */55 53 #include <stdio.h> 56 /* #include <stdlib.h> */57 54 #include <string.h> 58 55 #include <io/console.h> … … 60 57 #include <vfs/vfs.h> 61 58 #include <stdlib.h> 62 /* #include <time.h> */ 63 /* #include <term.h> */ 64 /* #include <unistd.h> */ 65 /* #include <sys/param.h> */ 66 /* #include <sys/stat.h> */ 67 /* #include <sys/types.h> */ 68 69 #include "pathnames.h" 59 #include <fcntl.h> 60 #include <err.h> 61 #include <time.h> 62 70 63 #include "screen.h" 71 64 #include "tetris.h" … … 80 73 * that level. 81 74 */ 82 #define NUMSPOTS (MAXHISCORES + 1) 83 #define NLEVELS (MAXLEVEL + 1) 84 85 /* static time_t now; */ 86 /* static int nscores; */ 87 /* static int gotscores; */ 88 /* static struct highscore scores[NUMSPOTS]; */ 75 76 #define NUMSPOTS (MAXHISCORES + 1) 77 #define NLEVELS (MAXLEVEL + 1) 78 89 79 static struct highscore scores[NUMSPOTS]; 90 80 91 /* static int checkscores(struct highscore *, int); */ 92 /* static int cmpscores(const void *, const void *); */ 93 /* static void getscores(FILE **); */ 94 /* static void printem(int, int, struct highscore *, int, const char *); */ 95 /* static char *thisuser(void); */ 81 /** Copy from hiscore table score with index src to dest 82 * 83 */ 84 static void copyhiscore(int dest, int src) 85 { 86 str_cpy(scores[dest].hs_name, STR_BOUNDS(MAXLOGNAME) + 1, 87 scores[src].hs_name); 88 scores[dest].hs_score = scores[src].hs_score; 89 scores[dest].hs_level = scores[src].hs_level; 90 } 96 91 97 92 void showscores(int firstgame) … … 103 98 printf("\tRank \tLevel \tName\t points\n"); 104 99 printf("\t========================================================\n"); 105 for (i = 0; i < NUMSPOTS - 1; i++) { 106 printf("\t%6d %6d %-16s %20d\n", i+1, scores[i].hs_level, scores[i].hs_name, scores[i].hs_score); 107 } 100 101 for (i = 0; i < NUMSPOTS - 1; i++) 102 printf("\t%6d %6d %-16s %20d\n", 103 i + 1, scores[i].hs_level, scores[i].hs_name, scores[i].hs_score); 104 108 105 if (!firstgame) { 109 106 printf("\t========================================================\n"); 110 printf("\t Last %6d %-16s %20d\n", scores[NUMSPOTS - 1].hs_level, scores[NUMSPOTS - 1].hs_name, scores[NUMSPOTS - 1].hs_score); 107 printf("\t Last %6d %-16s %20d\n", 108 scores[NUMSPOTS - 1].hs_level, scores[NUMSPOTS - 1].hs_name, scores[NUMSPOTS - 1].hs_score); 111 109 } 110 112 111 printf("\n\n\n\n\tPress any key to return to main menu."); 113 112 getchar(); 114 113 } 115 114 116 /** Copy from hiscore table score with index src to dest117 *118 */119 static void copyhiscore(int dest, int src)120 {121 str_cpy(scores[dest].hs_name, STR_BOUNDS(MAXLOGNAME) + 1,122 scores[src].hs_name);123 scores[dest].hs_score = scores[src].hs_score;124 scores[dest].hs_level = scores[src].hs_level;125 }126 127 115 void insertscore(int score, int level) 128 116 { 129 int i,j; 117 int i; 118 int j; 130 119 size_t off; 131 120 console_event_t ev; 132 121 133 122 clear_screen(); 134 moveto(10 123 moveto(10, 10); 135 124 puts("Insert your name: "); 136 125 str_cpy(scores[NUMSPOTS - 1].hs_name, STR_BOUNDS(MAXLOGNAME) + 1, 137 126 "Player"); 138 i = 6; off = 6; 139 127 i = 6; 128 off = 6; 129 140 130 moveto(10 , 28); 141 printf("%s%.*s",scores[NUMSPOTS - 1].hs_name,MAXLOGNAME-i,"........................................"); 142 131 printf("%s%.*s", scores[NUMSPOTS - 1].hs_name, MAXLOGNAME-i, 132 "........................................"); 133 143 134 while (1) { 144 135 fflush(stdout); 145 136 if (!console_get_event(fphone(stdin), &ev)) 146 137 exit(1); 147 138 148 139 if (ev.type == KEY_RELEASE) 149 140 continue; 150 141 151 142 if (ev.key == KC_ENTER || ev.key == KC_NENTER) 152 143 break; 153 144 154 145 if (ev.key == KC_BACKSPACE) { 155 146 if (i > 0) { 156 147 wchar_t uc; 157 148 158 149 --i; 159 150 while (off > 0) { … … 165 156 break; 166 157 } 167 158 168 159 scores[NUMSPOTS - 1].hs_name[off] = '\0'; 169 160 } … … 178 169 } 179 170 180 moveto(10 , 28); 181 printf("%s%.*s",scores[NUMSPOTS - 1].hs_name,MAXLOGNAME-i,"........................................"); 171 moveto(10, 28); 172 printf("%s%.*s", scores[NUMSPOTS - 1].hs_name, MAXLOGNAME - i, 173 "........................................"); 182 174 } 183 175 184 scores[NUMSPOTS - 1].hs_score = score; 176 scores[NUMSPOTS - 1].hs_score = score; 185 177 scores[NUMSPOTS - 1].hs_level = level; 186 178 187 i = NUMSPOTS -1;179 i = NUMSPOTS - 1; 188 180 while ((i > 0) && (scores[i - 1].hs_score < score)) 189 181 i--; 190 191 for (j = NUMSPOTS - 2; j > i; j--) { 192 copyhiscore(j,j-1); 182 183 for (j = NUMSPOTS - 2; j > i; j--) 184 copyhiscore(j, j-1); 185 186 copyhiscore(i, NUMSPOTS - 1); 187 } 188 189 void initscores(void) 190 { 191 int i; 192 for (i = 0; i < NUMSPOTS; i++) { 193 str_cpy(scores[i].hs_name, STR_BOUNDS(MAXLOGNAME) + 1, "HelenOS Team"); 194 scores[i].hs_score = (NUMSPOTS - i) * 200; 195 scores[i].hs_level = (i + 1 > MAXLEVEL ? MAXLEVEL : i + 1); 193 196 } 194 copyhiscore(i, NUMSPOTS - 1); 195 } 196 197 void initscores(void) 198 { 199 int i; 200 for(i = 0; i < NUMSPOTS; i++) { 201 str_cpy(scores[i].hs_name, STR_BOUNDS(MAXLOGNAME) + 1, "HelenOS Team"); 202 scores[i].hs_score = (NUMSPOTS - i) * 200; 203 scores[i].hs_level = (i + 1 > MAXLEVEL?MAXLEVEL:i + 1); 204 } 205 } 206 207 /* 208 * Read the score file. Can be called from savescore (before showscores) 209 * or showscores (if savescore will not be called). If the given pointer 210 * is not NULL, sets *fpp to an open file pointer that corresponds to a 211 * read/write score file that is locked with LOCK_EX. Otherwise, the 212 * file is locked with LOCK_SH for the read and closed before return. 213 * 214 * Note, we assume closing the stdio file releases the lock. 215 */ 216 /* static void */ 217 /* getscores(FILE **fpp) */ 218 /* { */ 219 /* int sd, mint, lck, mask, i; */ 220 /* char *mstr, *human; */ 221 /* FILE *sf; */ 222 223 /* if (fpp != NULL) { */ 224 /* mint = O_RDWR | O_CREAT; */ 225 /* mstr = "r+"; */ 226 /* human = "read/write"; */ 227 /* lck = LOCK_EX; */ 228 /* } else { */ 229 /* mint = O_RDONLY; */ 230 /* mstr = "r"; */ 231 /* human = "reading"; */ 232 /* lck = LOCK_SH; */ 233 /* } */ 234 /* setegid(egid); */ 235 /* mask = umask(S_IWOTH); */ 236 /* sd = open(_PATH_SCOREFILE, mint, 0666); */ 237 /* (void)umask(mask); */ 238 /* setegid(gid); */ 239 /* if (sd < 0) { */ 240 /* if (fpp == NULL) { */ 241 /* nscores = 0; */ 242 /* return; */ 243 /* } */ 244 /* err(1, "cannot open %s for %s", _PATH_SCOREFILE, human); */ 245 /* } */ 246 /* setegid(egid); */ 247 /* if ((sf = fdopen(sd, mstr)) == NULL) */ 248 /* err(1, "cannot fdopen %s for %s", _PATH_SCOREFILE, human); */ 249 /* setegid(gid); */ 250 251 /* /\* */ 252 /* * Grab a lock. */ 253 /* *\/ */ 254 /* if (flock(sd, lck)) */ 255 /* warn("warning: score file %s cannot be locked", */ 256 /* _PATH_SCOREFILE); */ 257 258 /* nscores = fread(scores, sizeof(scores[0]), MAXHISCORES, sf); */ 259 /* if (ferror(sf)) */ 260 /* err(1, "error reading %s", _PATH_SCOREFILE); */ 261 /* for (i = 0; i < nscores; i++) */ 262 /* if (scores[i].hs_level < MINLEVEL || */ 263 /* scores[i].hs_level > MAXLEVEL) */ 264 /* errx(1, "scorefile %s corrupt", _PATH_SCOREFILE); */ 265 266 /* if (fpp) */ 267 /* *fpp = sf; */ 268 /* else */ 269 /* (void)fclose(sf); */ 270 /* } */ 271 272 void 273 savescore(int level) 274 { 275 return; 276 } 277 /* struct highscore *sp; */ 278 /* int i; */ 279 /* int change; */ 280 /* FILE *sf; */ 281 /* const char *me; */ 282 283 /* getscores(&sf); */ 284 /* gotscores = 1; */ 285 /* (void)time(&now); */ 286 287 /* /\* */ 288 /* * Allow at most one score per person per level -- see if we */ 289 /* * can replace an existing score, or (easiest) do nothing. */ 290 /* * Otherwise add new score at end (there is always room). */ 291 /* *\/ */ 292 /* change = 0; */ 293 /* me = thisuser(); */ 294 /* for (i = 0, sp = &scores[0]; i < nscores; i++, sp++) { */ 295 /* if (sp->hs_level != level || str_cmp(sp->hs_name, me) != 0) */ 296 /* continue; */ 297 /* if (score > sp->hs_score) { */ 298 /* (void)printf("%s bettered %s %d score of %d!\n", */ 299 /* "\nYou", "your old level", level, */ 300 /* sp->hs_score * sp->hs_level); */ 301 /* sp->hs_score = score; /\* new score *\/ */ 302 /* sp->hs_time = now; /\* and time *\/ */ 303 /* change = 1; */ 304 /* } else if (score == sp->hs_score) { */ 305 /* (void)printf("%s tied %s %d high score.\n", */ 306 /* "\nYou", "your old level", level); */ 307 /* sp->hs_time = now; /\* renew it *\/ */ 308 /* change = 1; /\* gotta rewrite, sigh *\/ */ 309 /* } /\* else new score < old score: do nothing *\/ */ 310 /* break; */ 311 /* } */ 312 /* if (i >= nscores) { */ 313 /* strlcpy(sp->hs_name, me, sizeof sp->hs_name); */ 314 /* sp->hs_level = level; */ 315 /* sp->hs_score = score; */ 316 /* sp->hs_time = now; */ 317 /* nscores++; */ 318 /* change = 1; */ 319 /* } */ 320 321 /* if (change) { */ 322 /* /\* */ 323 /* * Sort & clean the scores, then rewrite. */ 324 /* *\/ */ 325 /* nscores = checkscores(scores, nscores); */ 326 /* rewind(sf); */ 327 /* if (fwrite(scores, sizeof(*sp), nscores, sf) != nscores || */ 328 /* fflush(sf) == EOF) */ 329 /* warnx("error writing %s: %s\n\t-- %s", */ 330 /* _PATH_SCOREFILE, strerror(errno), */ 331 /* "high scores may be damaged"); */ 332 /* } */ 333 /* (void)fclose(sf); /\* releases lock *\/ */ 334 /* } */ 335 336 /* 337 * Get login name, or if that fails, get something suitable. 338 * The result is always trimmed to fit in a score. 339 */ 340 /* static char * */ 341 /* thisuser(void) */ 342 /* { */ 343 /* const char *p; */ 344 /* struct passwd *pw; */ 345 /* static char u[sizeof(scores[0].hs_name)]; */ 346 347 /* if (u[0]) */ 348 /* return (u); */ 349 /* p = getlogin(); */ 350 /* if (p == NULL || *p == '\0') { */ 351 /* pw = getpwuid(getuid()); */ 352 /* if (pw != NULL) */ 353 /* p = pw->pw_name; */ 354 /* else */ 355 /* p = " ???"; */ 356 /* } */ 357 /* strlcpy(u, p, sizeof(u)); */ 358 /* return (u); */ 359 /* } */ 360 361 /* 362 * Score comparison function for qsort. 363 * 364 * If two scores are equal, the person who had the score first is 365 * listed first in the highscore file. 366 */ 367 /* static int */ 368 /* cmpscores(const void *x, const void *y) */ 369 /* { */ 370 /* const struct highscore *a, *b; */ 371 /* long l; */ 372 373 /* a = x; */ 374 /* b = y; */ 375 /* l = (long)b->hs_level * b->hs_score - (long)a->hs_level * a->hs_score; */ 376 /* if (l < 0) */ 377 /* return (-1); */ 378 /* if (l > 0) */ 379 /* return (1); */ 380 /* if (a->hs_time < b->hs_time) */ 381 /* return (-1); */ 382 /* if (a->hs_time > b->hs_time) */ 383 /* return (1); */ 384 /* return (0); */ 385 /* } */ 386 387 /* 388 * If we've added a score to the file, we need to check the file and ensure 389 * that this player has only a few entries. The number of entries is 390 * controlled by MAXSCORES, and is to ensure that the highscore file is not 391 * monopolised by just a few people. People who no longer have accounts are 392 * only allowed the highest score. Scores older than EXPIRATION seconds are 393 * removed, unless they are someone's personal best. 394 * Caveat: the highest score on each level is always kept. 395 */ 396 /* static int */ 397 /* checkscores(struct highscore *hs, int num) */ 398 /* { */ 399 /* struct highscore *sp; */ 400 /* int i, j, k, numnames; */ 401 /* int levelfound[NLEVELS]; */ 402 /* struct peruser { */ 403 /* char *name; */ 404 /* int times; */ 405 /* } count[NUMSPOTS]; */ 406 /* struct peruser *pu; */ 407 408 /* /\* */ 409 /* * Sort so that highest totals come first. */ 410 /* * */ 411 /* * levelfound[i] becomes set when the first high score for that */ 412 /* * level is encountered. By definition this is the highest score. */ 413 /* *\/ */ 414 /* qsort((void *)hs, nscores, sizeof(*hs), cmpscores); */ 415 /* for (i = MINLEVEL; i < NLEVELS; i++) */ 416 /* levelfound[i] = 0; */ 417 /* numnames = 0; */ 418 /* for (i = 0, sp = hs; i < num;) { */ 419 /* /\* */ 420 /* * This is O(n^2), but do you think we care? */ 421 /* *\/ */ 422 /* for (j = 0, pu = count; j < numnames; j++, pu++) */ 423 /* if (str_cmp(sp->hs_name, pu->name) == 0) */ 424 /* break; */ 425 /* if (j == numnames) { */ 426 /* /\* */ 427 /* * Add new user, set per-user count to 1. */ 428 /* *\/ */ 429 /* pu->name = sp->hs_name; */ 430 /* pu->times = 1; */ 431 /* numnames++; */ 432 /* } else { */ 433 /* /\* */ 434 /* * Two ways to keep this score: */ 435 /* * - Not too many (per user), still has acct, & */ 436 /* * score not dated; or */ 437 /* * - High score on this level. */ 438 /* *\/ */ 439 /* if ((pu->times < MAXSCORES && */ 440 /* getpwnam(sp->hs_name) != NULL && */ 441 /* sp->hs_time + EXPIRATION >= now) || */ 442 /* levelfound[sp->hs_level] == 0) */ 443 /* pu->times++; */ 444 /* else { */ 445 /* /\* */ 446 /* * Delete this score, do not count it, */ 447 /* * do not pass go, do not collect $200. */ 448 /* *\/ */ 449 /* num--; */ 450 /* for (k = i; k < num; k++) */ 451 /* hs[k] = hs[k + 1]; */ 452 /* continue; */ 453 /* } */ 454 /* } */ 455 /* levelfound[sp->hs_level] = 1; */ 456 /* i++, sp++; */ 457 /* } */ 458 /* return (num > MAXHISCORES ? MAXHISCORES : num); */ 459 /* } */ 460 461 /* 462 * Show current scores. This must be called after savescore, if 463 * savescore is called at all, for two reasons: 464 * - Showscores munches the time field. 465 * - Even if that were not the case, a new score must be recorded 466 * before it can be shown anyway. 467 */ 468 /* 469 void 470 showscores(int level) 471 { 472 return; 473 } 474 */ 475 /* struct highscore *sp; */ 476 /* int i, n, c; */ 477 /* const char *me; */ 478 /* int levelfound[NLEVELS]; */ 479 480 /* if (!gotscores) */ 481 /* getscores((FILE **)NULL); */ 482 /* (void)printf("\n\t\t Tetris High Scores\n"); */ 483 484 /* /\* */ 485 /* * If level == 0, the person has not played a game but just asked for */ 486 /* * the high scores; we do not need to check for printing in highlight */ 487 /* * mode. If SOstr is null, we can't do highlighting anyway. */ 488 /* *\/ */ 489 /* me = level && SOstr ? thisuser() : NULL; */ 490 491 /* /\* */ 492 /* * Set times to 0 except for high score on each level. */ 493 /* *\/ */ 494 /* for (i = MINLEVEL; i < NLEVELS; i++) */ 495 /* levelfound[i] = 0; */ 496 /* for (i = 0, sp = scores; i < nscores; i++, sp++) { */ 497 /* if (levelfound[sp->hs_level]) */ 498 /* sp->hs_time = 0; */ 499 /* else { */ 500 /* sp->hs_time = 1; */ 501 /* levelfound[sp->hs_level] = 1; */ 502 /* } */ 503 /* } */ 504 505 /* /\* */ 506 /* * Page each screenful of scores. */ 507 /* *\/ */ 508 /* for (i = 0, sp = scores; i < nscores; sp += n) { */ 509 /* n = 20; */ 510 /* if (i + n > nscores) */ 511 /* n = nscores - i; */ 512 /* printem(level, i + 1, sp, n, me); */ 513 /* if ((i += n) < nscores) { */ 514 /* (void)printf("\nHit RETURN to continue."); */ 515 /* (void)fflush(stdout); */ 516 /* while ((c = getchar()) != '\n') */ 517 /* if (c == EOF) */ 518 /* break; */ 519 /* (void)printf("\n"); */ 520 /* } */ 521 /* } */ 522 523 /* if (nscores == 0) */ 524 /* printf("\t\t\t - none to date.\n"); */ 525 /* } */ 526 527 /* static void */ 528 /* printem(int level, int offset, struct highscore *hs, int n, const char *me) */ 529 /* { */ 530 /* struct highscore *sp; */ 531 /* int row, highlight, i; */ 532 /* char buf[100]; */ 533 /* #define TITLE "Rank Score Name (points/level)" */ 534 /* #define TITL2 "==========================================================" */ 535 536 /* printf("%s\n%s\n", TITLE, TITL2); */ 537 538 /* highlight = 0; */ 539 540 /* for (row = 0; row < n; row++) { */ 541 /* sp = &hs[row]; */ 542 /* (void)snprintf(buf, sizeof(buf), */ 543 /* "%3d%c %6d %-31s (%6d on %d)\n", */ 544 /* row + offset, sp->hs_time ? '*' : ' ', */ 545 /* sp->hs_score * sp->hs_level, */ 546 /* sp->hs_name, sp->hs_score, sp->hs_level); */ 547 /* /\* Print leaders every three lines *\/ */ 548 /* if ((row + 1) % 3 == 0) { */ 549 /* for (i = 0; i < sizeof(buf); i++) */ 550 /* if (buf[i] == ' ') */ 551 /* buf[i] = '_'; */ 552 /* } */ 553 /* /\* */ 554 /* * Highlight if appropriate. This works because */ 555 /* * we only get one score per level. */ 556 /* *\/ */ 557 /* if (me != NULL && */ 558 /* sp->hs_level == level && */ 559 /* sp->hs_score == score && */ 560 /* str_cmp(sp->hs_name, me) == 0) { */ 561 /* putpad(SOstr); */ 562 /* highlight = 1; */ 563 /* } */ 564 /* (void)printf("%s", buf); */ 565 /* if (highlight) { */ 566 /* putpad(SEstr); */ 567 /* highlight = 0; */ 568 /* } */ 569 /* } */ 570 /* } */ 197 } 571 198 572 199 /** @} 573 200 */ 574 -
uspace/app/tetris/scores.h
r080ad7f rebe70f1 35 35 * @(#)scores.h 8.1 (Berkeley) 5/31/93 36 36 */ 37 37 38 /** @addtogroup tetris 38 * @{ 39 * @{ 39 40 */ 40 41 /** @file … … 45 46 * Tetris scores. 46 47 */ 48 47 49 #include <sys/time.h> 48 50 #include <string.h> 49 51 50 #define MAXLOGNAME 16 52 #define MAXLOGNAME 16 53 #define MAXHISCORES 10 54 #define MAXSCORES 9 /* maximum high score entries per person */ 55 #define EXPIRATION (5L * 365 * 24 * 60 * 60) 56 51 57 struct highscore { 52 char hs_name[STR_BOUNDS(MAXLOGNAME) + 1];/* login name */53 int hs_score;/* raw score */54 int hs_level;/* play level */55 // time_t hs_time;/* time at game end */58 char hs_name[STR_BOUNDS(MAXLOGNAME) + 1]; /* login name */ 59 int hs_score; /* raw score */ 60 int hs_level; /* play level */ 61 time_t hs_time; /* time at game end */ 56 62 }; 57 63 58 #define MAXHISCORES 10 59 //#define MAXSCORES 9 /* maximum high score entries per person */ 60 //#define EXPIRATION (5L * 365 * 24 * 60 * 60) 61 62 void savescore(int); 63 void showscores(int); 64 void insertscore(int score, int level); 65 void initscores(void); 64 extern void showscores(int); 65 extern void initscores(void); 66 extern void insertscore(int score, int level); 66 67 67 68 /** @} 68 69 */ 69 -
uspace/app/tetris/screen.c
r080ad7f rebe70f1 37 37 38 38 /** @addtogroup tetris 39 * @{ 39 * @{ 40 40 */ 41 41 /** @file … … 57 57 #include <io/console.h> 58 58 59 static cell curscreen[B_SIZE]; /* 1 => standout (or otherwise marked) */ 59 #define STOP (B_COLS - 3) 60 61 static cell curscreen[B_SIZE]; /* non-zero => standout (or otherwise marked) */ 60 62 static int curscore; 61 static int isset; /* true => terminal is in game mode */ 63 static int isset; /* true => terminal is in game mode */ 64 65 static const struct shape *lastshape; 62 66 63 67 … … 72 76 } 73 77 74 static void start_standout( void)75 { 76 console_set_rgb_color(fphone(stdout), 0xf0f0f0, 0);78 static void start_standout(uint32_t color) 79 { 80 console_set_rgb_color(fphone(stdout), 0xf0f0f0, color); 77 81 } 78 82 … … 91 95 * Clear the screen, forgetting the current contents in the process. 92 96 */ 93 void 94 scr_clear(void) 95 { 96 97 void scr_clear(void) 98 { 97 99 resume_normal(); 98 100 console_clear(fphone(stdout)); 99 101 curscore = -1; 100 memset( (char *)curscreen, 0, sizeof(curscreen));102 memset(curscreen, 0, sizeof(curscreen)); 101 103 } 102 104 … … 104 106 * Set up screen 105 107 */ 106 void 107 scr_init(void) 108 void scr_init(void) 108 109 { 109 110 console_cursor_visibility(fphone(stdout), 0); … … 127 128 * Set up screen mode. 128 129 */ 129 void 130 scr_set(void) 130 void scr_set(void) 131 131 { 132 132 winsize_t ws; 133 134 Rows = 0, Cols = 0; 133 134 Rows = 0; 135 Cols = 0; 136 135 137 if (get_display_size(&ws) == 0) { 136 138 Rows = ws.ws_row; 137 139 Cols = ws.ws_col; 138 140 } 139 if (Rows < MINROWS || Cols < MINCOLS) { 141 142 if ((Rows < MINROWS) || (Cols < MINCOLS)) { 140 143 char smallscr[55]; 141 144 142 145 snprintf(smallscr, sizeof(smallscr), 143 146 "the screen is too small (must be at least %dx%d)", … … 146 149 } 147 150 isset = 1; 148 151 149 152 scr_clear(); 150 153 } … … 153 156 * End screen mode. 154 157 */ 155 void 156 scr_end(void) 157 { 158 } 159 160 void 161 stop(char *why) 162 { 163 158 void scr_end(void) 159 { 160 console_cursor_visibility(fphone(stdout), 1); 161 } 162 163 void stop(char *why) 164 { 164 165 if (isset) 165 166 scr_end(); 167 166 168 errx(1, "aborting: %s", why); 167 169 } 168 170 169 170 171 /* 171 172 * Update the screen. 172 173 */ 173 void 174 scr_update(void) 175 { 176 cell *bp, *sp; 177 cell so, cur_so = 0; 178 int i, ccol, j; 179 static const struct shape *lastshape; 180 181 /* always leave cursor after last displayed point */ 174 void scr_update(void) 175 { 176 cell *bp; 177 cell *sp; 178 cell so; 179 cell cur_so = 0; 180 int i; 181 int j; 182 int ccol; 183 184 /* Always leave cursor after last displayed point */ 182 185 curscreen[D_LAST * B_COLS - 1] = -1; 183 186 184 187 if (score != curscore) { 185 188 moveto(0, 0); … … 187 190 curscore = score; 188 191 } 189 190 /* draw preview of next pattern */191 if ( showpreview&& (nextshape != lastshape)) {192 193 /* Draw preview of next pattern */ 194 if ((showpreview) && (nextshape != lastshape)) { 192 195 int i; 193 static int r =5, c=2;196 static int r = 5, c = 2; 194 197 int tr, tc, t; 195 198 196 199 lastshape = nextshape; 197 198 /* clean */200 201 /* Clean */ 199 202 resume_normal(); 200 moveto(r-1, c-1); putstr(" "); 201 moveto(r, c-1); putstr(" "); 202 moveto(r+1, c-1); putstr(" "); 203 moveto(r+2, c-1); putstr(" "); 204 205 moveto(r-3, c-2); 203 moveto(r - 1, c - 1); 204 putstr(" "); 205 moveto(r, c - 1); 206 putstr(" "); 207 moveto(r + 1, c - 1); 208 putstr(" "); 209 moveto(r + 2, c - 1); 210 putstr(" "); 211 212 moveto(r - 3, c - 2); 206 213 putstr("Next shape:"); 207 208 /* draw */209 start_standout( );214 215 /* Draw */ 216 start_standout(nextshape->color); 210 217 moveto(r, 2 * c); 211 218 putstr(" "); … … 213 220 t = c + r * B_COLS; 214 221 t += nextshape->off[i]; 215 222 216 223 tr = t / B_COLS; 217 224 tc = t % B_COLS; 218 225 219 226 moveto(tr, 2*tc); 220 227 putstr(" "); … … 222 229 resume_normal(); 223 230 } 224 231 225 232 bp = &board[D_FIRST * B_COLS]; 226 233 sp = &curscreen[D_FIRST * B_COLS]; … … 230 237 if (*sp == (so = *bp)) 231 238 continue; 239 232 240 *sp = so; 233 241 if (i != ccol) { … … 238 246 moveto(RTOD(j), CTOD(i)); 239 247 } 248 240 249 if (so != cur_so) { 241 250 if (so) 242 start_standout( );251 start_standout(so); 243 252 else 244 253 resume_normal(); … … 246 255 } 247 256 putstr(" "); 248 257 249 258 ccol = i + 1; 250 259 /* … … 256 265 * the next cell is a different color. 257 266 */ 258 #define STOP (B_COLS - 3) 259 if ( i > STOP || sp[1] != bp[1] || so != bp[1])267 268 if ((i > STOP) || (sp[1] != bp[1]) || (so != bp[1])) 260 269 continue; 270 261 271 if (sp[2] != bp[2]) 262 272 sp[1] = -1; 263 else if ( i < STOP && so == bp[2] && sp[3] != bp[3]) {273 else if ((i < STOP) && (so == bp[2]) && (sp[3] != bp[3])) { 264 274 sp[2] = -1; 265 275 sp[1] = -1; … … 267 277 } 268 278 } 279 269 280 if (cur_so) 270 281 resume_normal(); 271 fflush(stdout); 272 } 273 274 /* 275 * Write a message (set!=0), or clear the same message (set==0). 282 283 fflush(stdout); 284 } 285 286 /* 287 * Write a message (set != 0), or clear the same message (set == 0). 276 288 * (We need its length in case we have to overwrite with blanks.) 277 289 */ 278 void 279 scr_msg(char *s, int set) 280 { 281 290 void scr_msg(char *s, int set) 291 { 282 292 int l = str_size(s); 283 293 284 294 moveto(Rows - 2, ((Cols - l) >> 1) - 1); 295 285 296 if (set) 286 297 putstr(s); … … 292 303 /** @} 293 304 */ 294 -
uspace/app/tetris/screen.h
r080ad7f rebe70f1 37 37 38 38 /** @addtogroup tetris 39 * @{ 39 * @{ 40 40 */ 41 41 /** @file … … 43 43 44 44 /* 45 * putpad() is for padded strings with count =1.45 * putpad() is for padded strings with count = 1. 46 46 */ 47 #define putpad(s)tputs(s, 1, put)47 #define putpad(s) tputs(s, 1, put) 48 48 49 49 #include <sys/types.h> … … 57 57 extern winsize_t winsize; 58 58 59 void moveto(int r, int c);60 void clear_screen(void);59 extern void moveto(int r, int c); 60 extern void clear_screen(void); 61 61 62 int put(int); /* just calls putchar; for tputs */ 63 void scr_clear(void); 64 void scr_end(void); 65 void scr_init(void); 66 void scr_msg(char *, int); 67 void scr_set(void); 68 void scr_update(void); 62 /* just calls putchar; for tputs */ 63 extern int put(int); 64 extern void scr_clear(void); 65 extern void scr_end(void); 66 extern void scr_init(void); 67 extern void scr_msg(char *, int); 68 extern void scr_set(void); 69 extern void scr_update(void); 69 70 70 71 /** @} 71 72 */ 72 -
uspace/app/tetris/shapes.c
r080ad7f rebe70f1 37 37 38 38 /** @addtogroup tetris 39 * @{ 39 * @{ 40 40 */ 41 41 /** @file … … 51 51 #include "tetris.h" 52 52 53 #define TL -B_COLS-1/* top left */54 #define TC -B_COLS/* top center */55 #define TR -B_COLS+1/* top right */56 #define ML -1/* middle left */57 #define MR 1/* middle right */58 #define BL B_COLS-1/* bottom left */59 #define BC B_COLS/* bottom center */60 #define BR B_COLS+1/* bottom right */53 #define TL (-B_COLS - 1) /* top left */ 54 #define TC (-B_COLS) /* top center */ 55 #define TR (-B_COLS + 1) /* top right */ 56 #define ML -1 /* middle left */ 57 #define MR 1 /* middle right */ 58 #define BL (B_COLS - 1) /* bottom left */ 59 #define BC B_COLS /* bottom center */ 60 #define BR (B_COLS + 1) /* bottom right */ 61 61 62 62 const struct shape shapes[] = { 63 /* 0*/ { 7, 7, { TL, TC, MR }},64 /* 1*/ { 8, 8, { TC, TR, ML }},65 /* 2*/ { 9, 11, { ML, MR, BC }},66 /* 3*/ { 3, 3, { TL, TC, ML }},67 /* 4*/ { 12, 14, { ML, BL, MR }},68 /* 5*/ { 15, 17, { ML, BR, MR }},69 /* 6*/ { 18, 18, { ML, MR, 2 } },/* sticks out */70 /* 7*/ { 0, 0, { TC, ML, BL }},71 /* 8*/ { 1, 1, { TC, MR, BR }},72 /* 9*/ { 10, 2, { TC, MR, BC }},73 /* 10*/ { 11, 9, { TC, ML, MR }},74 /* 11*/ { 2, 10, { TC, ML, BC }},75 /* 12*/ { 13, 4, { TC, BC, BR }},76 /* 13*/ { 14, 12, { TR, ML, MR }},77 /* 14*/ { 4, 13, { TL, TC, BC }},78 /* 15*/ { 16, 5, { TR, TC, BC }},79 /* 16*/ { 17, 15, { TL, MR, ML }},80 /* 17*/ { 5, 16, { TC, BC, BL }},81 /* 18*/ { 6, 6, { TC, BC, 2*B_COLS } }/* sticks out */63 /* 0 */ { 7, 7, { TL, TC, MR }, 0xff042d}, 64 /* 1 */ { 8, 8, { TC, TR, ML }, 0xff9304}, 65 /* 2 */ { 9, 11, { ML, MR, BC }, 0xbeff04}, 66 /* 3 */ { 3, 3, { TL, TC, ML }, 0x63ff04}, 67 /* 4 */ { 12, 14, { ML, BL, MR }, 0xce04ff}, 68 /* 5 */ { 15, 17, { ML, BR, MR }, 0xff04cf}, 69 /* 6 */ { 18, 18, { ML, MR, 2 }, 0x7604ff}, /* sticks out */ 70 /* 7 */ { 0, 0, { TC, ML, BL }, 0xff042d}, 71 /* 8 */ { 1, 1, { TC, MR, BR }, 0xff9304}, 72 /* 9 */ { 10, 2, { TC, MR, BC }, 0xbeff04}, 73 /* 10 */ { 11, 9, { TC, ML, MR }, 0xbeff04}, 74 /* 11 */ { 2, 10, { TC, ML, BC }, 0xbeff04}, 75 /* 12 */ { 13, 4, { TC, BC, BR }, 0xce04ff}, 76 /* 13 */ { 14, 12, { TR, ML, MR }, 0xce04ff}, 77 /* 14 */ { 4, 13, { TL, TC, BC }, 0xce04ff}, 78 /* 15 */ { 16, 5, { TR, TC, BC }, 0xff04cf}, 79 /* 16 */ { 17, 15, { TL, MR, ML }, 0xff04cf}, 80 /* 17 */ { 5, 16, { TC, BC, BL }, 0xff04cf}, 81 /* 18 */ { 6, 6, { TC, BC, 2 * B_COLS }, 0x7604ff} /* sticks out */ 82 82 }; 83 83 … … 86 86 * taking the current board into account. 87 87 */ 88 int 89 fits_in(const struct shape *shape, int pos) 88 int fits_in(const struct shape *shape, int pos) 90 89 { 91 90 int *o = shape->off; 92 93 if ( board[pos] || board[pos + *o++] || board[pos + *o++]||94 board[pos + *o])91 92 if ((board[pos]) || (board[pos + *o++]) || (board[pos + *o++]) || 93 (board[pos + *o])) 95 94 return 0; 95 96 96 return 1; 97 97 } … … 101 101 * if `onoff' is 1, and off if `onoff' is 0. 102 102 */ 103 void 104 place(const struct shape *shape, int pos, int onoff) 103 void place(const struct shape *shape, int pos, int onoff) 105 104 { 106 105 int *o = shape->off; 107 108 board[pos] = onoff ;109 board[pos + *o++] = onoff ;110 board[pos + *o++] = onoff ;111 board[pos + *o] = onoff ;106 107 board[pos] = onoff ? shape->color : 0x000000; 108 board[pos + *o++] = onoff ? shape->color : 0x000000; 109 board[pos + *o++] = onoff ? shape->color : 0x000000; 110 board[pos + *o] = onoff ? shape->color : 0x000000; 112 111 } 113 112 114 113 /** @} 115 114 */ 116 -
uspace/app/tetris/tetris.c
r080ad7f rebe70f1 37 37 38 38 /** @addtogroup tetris Tetris 39 * @brief 40 * @{ 39 * @brief Tetris ported from OpenBSD 40 * @{ 41 41 */ 42 42 /** @file 43 43 */ 44 44 45 #ifndef lint46 45 static const char copyright[] = 47 "@(#) Copyright (c) 1992, 1993\n\ 48 The Regents of the University of California. All rights reserved.\n"; 49 #endif /* not lint */ 50 51 /* 52 * Tetris (or however it is spelled). 53 */ 46 "@(#) Copyright (c) 1992, 1993\n" 47 "\tThe Regents of the University of California. All rights reserved.\n"; 54 48 55 49 #include <sys/time.h> 56 50 #include <sys/types.h> 57 58 51 #include <err.h> 59 52 #include <stdio.h> … … 61 54 #include <string.h> 62 55 #include <unistd.h> 56 #include <getopt.h> 63 57 64 58 #include "input.h" … … 67 61 #include "tetris.h" 68 62 69 cell board[B_SIZE]; 70 int Rows, Cols; 63 cell board[B_SIZE]; 64 65 int Rows; 66 int Cols; 67 71 68 const struct shape *curshape; 72 69 const struct shape *nextshape; 73 long fallrate; 74 int score; 75 //gid_t gid, egid; 76 char key_msg[100]; 77 int showpreview, classic; 78 79 static void elide(void); 80 static void setup_board(void); 81 const struct shape *randshape(void); 82 void onintr(int); 83 void usage(void); 70 71 long fallrate; 72 int score; 73 char key_msg[100]; 74 int showpreview; 75 int classic; 76 77 static void elide(void); 78 static void setup_board(void); 79 static const struct shape *randshape(void); 80 81 static void usage(void); 82 83 static int firstgame = 1; 84 84 85 85 /* 86 * Set up the initial board. 87 * along with another (hidden) row underneath that. 86 * Set up the initial board. The bottom display row is completely set, 87 * along with another (hidden) row underneath that. Also, the left and 88 88 * right edges are set. 89 89 */ 90 static void 91 setup_board(void) 90 static void setup_board(void) 92 91 { 93 92 int i; 94 cell *p; 95 96 p = board; 93 cell *p = board; 94 97 95 for (i = B_SIZE; i; i--) 98 *p++ = i <= (2 * B_COLS) || (i % B_COLS) < 2;96 *p++ = (i <= (2 * B_COLS) || (i % B_COLS) < 2) ? 0x0000ff : 0x000000; 99 97 } 100 98 … … 102 100 * Elide any full active rows. 103 101 */ 104 static void 105 elide(void) 102 static void elide(void) 106 103 { 107 104 int rows = 0; 108 int i, j, base; 105 int i; 106 int j; 107 int base; 109 108 cell *p; 110 109 111 110 for (i = A_FIRST; i < A_LAST; i++) { 112 111 base = i * B_COLS + 1; … … 114 113 for (j = B_COLS - 2; *p++ != 0;) { 115 114 if (--j <= 0) { 116 /* this row is to be elided */115 /* This row is to be elided */ 117 116 rows++; 118 memset(&board[base], 0, B_COLS - 2); 117 memset(&board[base], 0, sizeof(cell) * (B_COLS - 2)); 118 119 119 scr_update(); 120 120 tsleep(); 121 121 122 while (--base != 0) 122 123 board[base + B_COLS] = board[base]; 124 123 125 scr_update(); 124 126 tsleep(); 127 125 128 break; 126 129 } 127 130 } 128 131 } 132 129 133 switch (rows) { 130 134 case 1: … … 145 149 } 146 150 147 const struct shape * 148 randshape(void) 149 { 150 const struct shape *tmp; 151 int i, j; 152 153 tmp = &shapes[random() % 7]; 154 j = random() % 4; 151 const struct shape *randshape(void) 152 { 153 const struct shape *tmp = &shapes[random() % 7]; 154 int i; 155 int j = random() % 4; 156 155 157 for (i = 0; i < j; i++) 156 tmp = &shapes[classic? tmp->rotc : tmp->rot]; 158 tmp = &shapes[classic ? tmp->rotc : tmp->rot]; 159 157 160 return (tmp); 158 161 } … … 161 164 { 162 165 struct timeval tv; 163 166 164 167 gettimeofday(&tv, NULL); 165 168 srandom(tv.tv_sec + tv.tv_usec / 100000); … … 168 171 static void tetris_menu_draw(int level) 169 172 { 170 clear_screen(); 171 moveto(5,10); 172 puts("Tetris\n\n"); 173 174 moveto(8,10); 175 printf("Level = %d (press keys 1 - 9 to change)",level); 176 moveto(9,10); 177 printf("Preview is %s (press 'p' to change)", (showpreview?"on ":"off")); 178 moveto(12,10); 179 printf("Press 'h' to show hiscore table."); 180 moveto(13,10); 181 printf("Press 's' to start game."); 182 moveto(14,10); 183 printf("Press 'q' to quit game."); 184 moveto(20,10); 185 printf("In game controls:"); 186 moveto(21,0); 187 puts(key_msg); 188 } 189 190 static int tetris_menu(int *level) 191 { 192 static int firstgame = 1; 193 int i; 194 /* if (showpreview == 0) 195 (void)printf("Your score: %d point%s x level %d = %d\n", 196 score, score == 1 ? "" : "s", level, score * level); 197 else { 198 (void)printf("Your score: %d point%s x level %d x preview penalty %0.3f = %d\n", 199 score, score == 1 ? "" : "s", level, (double)PRE_PENALTY, 200 (int)(score * level * PRE_PENALTY)); 201 score = score * PRE_PENALTY; 202 } 203 savescore(level); 204 205 showscores(level); 206 207 printf("\nHit 's' to new game, 'q' to quit.\n"); 208 */ 173 clear_screen(); 174 moveto(5, 10); 175 puts("Tetris\n\n"); 176 177 moveto(8, 10); 178 printf("Level = %d (press keys 1 - 9 to change)", level); 179 moveto(9, 10); 180 printf("Preview is %s (press 'p' to change)", (showpreview ? "on ": "off")); 181 moveto(12, 10); 182 printf("Press 'h' to show hiscore table."); 183 moveto(13, 10); 184 printf("Press 's' to start game."); 185 moveto(14, 10); 186 printf("Press 'q' to quit game."); 187 moveto(20, 10); 188 printf("In game controls:"); 189 moveto(21, 0); 190 puts(key_msg); 191 } 192 193 static int tetris_menu(int *level) 194 { 209 195 tetris_menu_draw(*level); 210 196 while (1) { 211 212 i = getchar(); 197 int i = getchar(); 213 198 214 199 switch(i) { 215 200 case 'p': 216 201 showpreview = !showpreview; 217 moveto(9, 21);202 moveto(9, 21); 218 203 if (showpreview) 219 204 printf("on "); 220 205 else 221 206 printf("off"); 222 223 207 break; 224 208 case 'h': … … 236 220 case '4': 237 221 case '5': 238 case '6': 222 case '6': 239 223 case '7': 240 224 case '8': 241 225 case '9': 242 226 *level = i - '0'; 243 moveto(8, 18);227 moveto(8, 18); 244 228 printf("%d", *level); 245 229 break; 246 230 } 247 231 } 248 249 } 250 251 int 252 main(int argc, char *argv[]) 253 { 254 int pos, c; 232 } 233 234 int main(int argc, char *argv[]) 235 { 236 int pos; 237 int c; 255 238 char *keys; 256 239 int level = 2; 257 240 char key_write[6][10]; 258 int i, j; 259 241 int i; 242 int j; 243 int ch; 244 260 245 keys = "jkl pq"; 261 262 // gid = getgid(); 263 // egid = getegid(); 264 // setegid(gid); 265 246 266 247 classic = 0; 267 248 showpreview = 1; 268 269 /* while ((ch = getopt(argc, argv, "ck:l:ps")) != -1) */ 270 /* switch(ch) { */ 271 /* case 'c': */ 272 /* /\* */ 273 /* * this means: */ 274 /* * - rotate the other way; */ 275 /* * - no reverse video. */ 276 /* *\/ */ 277 /* classic = 1; */ 278 /* break; */ 279 /* case 'k': */ 280 /* if (str_size(keys = optarg) != 6) */ 281 /* usage(); */ 282 /* break; */ 283 /* case 'l': */ 284 /* level = (int)strtonum(optarg, MINLEVEL, MAXLEVEL, */ 285 /* &errstr); */ 286 /* if (errstr) */ 287 /* errx(1, "level must be from %d to %d", */ 288 /* MINLEVEL, MAXLEVEL); */ 289 /* break; */ 290 /* case 'p': */ 291 /* showpreview = 1; */ 292 /* break; */ 293 /* case 's': */ 294 /* showscores(0); */ 295 /* exit(0); */ 296 /* default: */ 297 /* usage(); */ 298 /* } */ 299 300 /* argc -= optind; */ 301 /* argv += optind; */ 302 303 /* if (argc) */ 304 /* usage(); */ 305 306 307 249 250 while ((ch = getopt(argc, argv, "ck:ps")) != -1) 251 switch(ch) { 252 case 'c': 253 /* 254 * this means: 255 * - rotate the other way 256 * - no reverse video 257 */ 258 classic = 1; 259 break; 260 case 'k': 261 if (str_size(keys = optarg) != 6) 262 usage(); 263 break; 264 case 'p': 265 showpreview = 1; 266 break; 267 case 's': 268 showscores(0); 269 exit(0); 270 default: 271 usage(); 272 } 273 274 argc -= optind; 275 argv += optind; 276 277 if (argc) 278 usage(); 279 308 280 for (i = 0; i <= 5; i++) { 309 for (j = i +1; j <= 5; j++) {281 for (j = i + 1; j <= 5; j++) { 310 282 if (keys[i] == keys[j]) 311 283 errx(1, "duplicate command keys specified."); 312 284 } 285 313 286 if (keys[i] == ' ') 314 str_cpy(key_write[i], sizeof key_write[i], "<space>");287 str_cpy(key_write[i], sizeof(key_write[i]), "<space>"); 315 288 else { 316 289 key_write[i][0] = keys[i]; … … 318 291 } 319 292 } 320 321 snprintf(key_msg, sizeof key_msg,322 "%s - left %s - rotate %s - right %s - drop %s - pause %s - quit",323 324 325 293 294 snprintf(key_msg, sizeof(key_msg), 295 "%s - left %s - rotate %s - right %s - drop %s - pause %s - quit", 296 key_write[0], key_write[1], key_write[2], key_write[3], 297 key_write[4], key_write[5]); 298 326 299 scr_init(); 327 300 initscores(); … … 331 304 scr_clear(); 332 305 setup_board(); 333 306 334 307 srandomdev(); 335 308 scr_set(); 336 337 pos = A_FIRST *B_COLS + (B_COLS/2)-1;309 310 pos = A_FIRST * B_COLS + (B_COLS / 2) - 1; 338 311 nextshape = randshape(); 339 312 curshape = randshape(); 340 313 341 314 scr_msg(key_msg, 1); 342 343 for (;;) {315 316 while (1) { 344 317 place(curshape, pos, 1); 345 318 scr_update(); … … 354 327 continue; 355 328 } 356 329 357 330 /* 358 331 * Put up the current shape `permanently', … … 362 335 score++; 363 336 elide(); 364 337 365 338 /* 366 339 * Choose a new shape. If it does not fit, … … 369 342 curshape = nextshape; 370 343 nextshape = randshape(); 371 pos = A_FIRST*B_COLS + (B_COLS/2)-1; 344 pos = A_FIRST * B_COLS + (B_COLS / 2) - 1; 345 372 346 if (!fits_in(curshape, pos)) 373 347 break; 374 continue; 375 } 376 348 349 continue; 350 } 351 377 352 /* 378 353 * Handle command keys. … … 382 357 break; 383 358 } 359 384 360 if (c == keys[4]) { 385 361 static char msg[] = 386 362 "paused - press RETURN to continue"; 387 363 388 364 place(curshape, pos, 1); 389 365 do { … … 392 368 scr_msg(msg, 1); 393 369 (void) fflush(stdout); 394 } while (rwait((struct timeval *)NULL) == -1); 370 } while (rwait((struct timeval *) NULL) == -1); 371 395 372 scr_msg(msg, 0); 396 373 scr_msg(key_msg, 1); … … 398 375 continue; 399 376 } 377 400 378 if (c == keys[0]) { 401 379 /* move left */ … … 404 382 continue; 405 383 } 384 406 385 if (c == keys[1]) { 407 386 /* turn */ 408 const struct shape *new = &shapes[409 classic? curshape->rotc : curshape->rot];410 387 const struct shape *new = 388 &shapes[classic ? curshape->rotc : curshape->rot]; 389 411 390 if (fits_in(new, pos)) 412 391 curshape = new; 413 392 continue; 414 393 } 394 415 395 if (c == keys[2]) { 416 396 /* move right */ … … 419 399 continue; 420 400 } 401 421 402 if (c == keys[3]) { 422 403 /* move to bottom */ … … 427 408 continue; 428 409 } 410 429 411 if (c == '\f') { 430 412 scr_clear(); … … 435 417 scr_clear(); 436 418 insertscore(score, level); 437 score =0;419 score = 0; 438 420 } 439 421 440 422 scr_clear(); 441 printf("\n\n\n\t\tGame over.\n"); 442 /* 443 while ((i = getchar()) != '\n') 444 if (i == EOF) 445 break 446 */ 423 printf("\nGame over.\n"); 447 424 scr_end(); 448 425 449 426 return 0; 450 427 } 451 428 452 /* void */ 453 /* onintr(int signo) */ 454 /* { */ 455 /* scr_clear(); /\* XXX signal race *\/ */ 456 /* scr_end(); /\* XXX signal race *\/ */ 457 /* _exit(0); */ 458 /* } */ 459 460 void 461 usage(void) 462 { 463 (void)fprintf(stderr, "usage: tetris [-ps] [-k keys] [-l level]\n"); 429 void usage(void) 430 { 431 fprintf(stderr, "usage: tetris [-ps] [-k keys]\n"); 464 432 exit(1); 465 433 } … … 467 435 /** @} 468 436 */ 469 -
uspace/app/tetris/tetris.h
r080ad7f rebe70f1 37 37 38 38 /** @addtogroup tetris 39 * @{ 39 * @{ 40 40 */ 41 41 /** @file … … 56 56 */ 57 57 58 /* the board */59 #define B_COLS1260 #define B_ROWS2361 #define B_SIZE(B_ROWS * B_COLS)58 /* The board */ 59 #define B_COLS 12 60 #define B_ROWS 23 61 #define B_SIZE (B_ROWS * B_COLS) 62 62 63 typedef unsigned char cell; 64 extern cell board[B_SIZE]; /* 1 => occupied, 0 => empty */ 63 typedef uint32_t cell; 65 64 66 /* the displayed area (rows) */ 67 #define D_FIRST 1 68 #define D_LAST 22 65 extern cell board[B_SIZE]; /* 1 => occupied, 0 => empty */ 69 66 70 /* the active area (rows) */ 71 #define A_FIRST 1 72 #define A_LAST 21 67 /* The displayed area (rows) */ 68 #define D_FIRST 1 69 #define D_LAST 22 70 71 /* The active area (rows) */ 72 #define A_FIRST 1 73 #define A_LAST 21 73 74 74 75 /* 75 76 * Minimum display size. 76 77 */ 77 #define MINROWS2378 #define MINCOLS4078 #define MINROWS 23 79 #define MINCOLS 40 79 80 80 extern int Rows, Cols; /* current screen size */ 81 /* Current screen size */ 82 extern int Rows; 83 extern int Cols; 81 84 82 85 /* … … 84 87 * As with board coordinates, display coordiates are zero origin. 85 88 */ 86 #define RTOD(x)((x) - 1)87 #define CTOD(x)((x) * 2 + (((Cols - 2 * B_COLS) >> 1) - 1))89 #define RTOD(x) ((x) - 1) 90 #define CTOD(x) ((x) * 2 + (((Cols - 2 * B_COLS) >> 1) - 1)) 88 91 89 92 /* … … 91 94 * are 7 basic shapes, each consisting of four `blots': 92 95 * 93 * X.X X.XX.X94 * X.X X.X X.X.X X.X X.X.X X.X.XX.X.X.X95 * X XX96 * X.X X.X X.X 97 * X.X X.X X.X.X X.X X.X.X X.X.X X.X.X.X 98 * X X X 96 99 * 97 * 0 1 2 3 4 56100 * 0 1 2 3 4 5 6 98 101 * 99 102 * Except for 3 and 6, the center of each shape is one of the blots. 100 * This blot is designated (0, 0). The other three blots can then be103 * This blot is designated (0, 0). The other three blots can then be 101 104 * described as offsets from the center. Shape 3 is the same under 102 105 * rotation, so its center is effectively irrelevant; it has been chosen 103 106 * so that it `sticks out' upward and leftward. Except for shape 6, 104 * all the blots are contained in a box going from (-1, -1) to (+1,+1);107 * all the blots are contained in a box going from (-1, -1) to (+1, +1); 105 108 * shape 6's center `wobbles' as it rotates, so that while it `sticks out' 106 109 * rightward, its rotation---a vertical line---`sticks out' downward. 107 * The containment box has to include the offset (2, 0), making the overall108 * containment box range from offset (-1, -1) to (+2,+1). (This is why110 * The containment box has to include the offset (2, 0), making the overall 111 * containment box range from offset (-1, -1) to (+2, +1). (This is why 109 112 * there is only one row above, but two rows below, the display area.) 110 113 * … … 117 120 * these rows move down to make more room. A new random shape is again 118 121 * introduced at the top of the board, and the whole process repeats. 119 * The game ends when the new shape will not fit at (1, 5).122 * The game ends when the new shape will not fit at (1, 5). 120 123 * 121 124 * While the shapes are falling, the user can rotate them counterclockwise … … 129 132 */ 130 133 struct shape { 131 int rot; /* index of rotated version of this shape */ 132 int rotc; /* -- " -- in classic version */ 133 int off[3]; /* offsets to other blots if center is at (0,0) */ 134 int rot; /* index of rotated version of this shape */ 135 int rotc; /* -- " -- in classic version */ 136 int off[3]; /* offsets to other blots if center is at (0,0) */ 137 uint32_t color; 134 138 }; 135 139 … … 149 153 * but by then the game is utterly impossible. 150 154 */ 151 extern long fallrate; /* less than 1 million; smaller => faster */ 152 #define faster() (fallrate -= fallrate / 3000) 155 extern long fallrate; /* less than 1 million; smaller => faster */ 156 157 #define faster() (fallrate -= fallrate / 3000) 153 158 154 159 /* … … 156 161 * and affects scoring. 157 162 */ 158 #define MINLEVEL1159 #define MAXLEVEL9163 #define MINLEVEL 1 164 #define MAXLEVEL 9 160 165 161 166 /* … … 171 176 * If previewing has been turned on, the score is multiplied by PRE_PENALTY. 172 177 */ 173 #define PRE_PENALTY 0.75178 #define PRE_PENALTY 0.75 174 179 175 extern int score; /* the obvious thing */ 176 //extern gid_t gid, egid; 180 extern int score; /* The obvious thing */ 177 181 178 extern char 179 extern int 180 extern int 182 extern char key_msg[100]; 183 extern int showpreview; 184 extern int classic; 181 185 182 intfits_in(const struct shape *, int);183 voidplace(const struct shape *, int, int);184 voidstop(char *);186 extern int fits_in(const struct shape *, int); 187 extern void place(const struct shape *, int, int); 188 extern void stop(char *); 185 189 186 190 /** @} 187 191 */ 188
Note:
See TracChangeset
for help on using the changeset viewer.