home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / games / volume18 / gtetris4 / part01 < prev    next >
Encoding:
Internet Message Format  |  1993-09-13  |  53.0 KB

  1. Path: uunet!news.tek.com!news.cna.tek.com!not-for-mail
  2. From: billr@saab.cna.tek.com (Bill Randle)
  3. Newsgroups: comp.sources.games
  4. Subject: v18i053:  gtetris4 - Generic Tetris for X11, V3.0.1, Part01/03 (REPOST)
  5. Date: 30 Aug 1993 07:53:19 -0700
  6. Organization: Tektronix, Inc., Redmond, OR
  7. Lines: 1772
  8. Approved: billr@saab.CNA.TEK.COM
  9. Message-ID: <25t48v$f6f@saab.cna.tek.com>
  10. NNTP-Posting-Host: saab.cna.tek.com
  11. Xref: uunet comp.sources.games:1853
  12.  
  13. Submitted-by: "Q. Alex Zhao" <azhao@cc.gatech.edu>
  14. Posting-number: Volume 18, Issue 53
  15. Archive-name: gtetris4/part01
  16. Supersedes: tetris3: Volume 15, Issue 44-45
  17. Environment: X11R4/5, Xlib
  18.  
  19.     [Another major update to the popular generic tetris game.  -br]
  20.  
  21. #! /bin/sh
  22. # This is a shell archive.  Remove anything before this line, then unpack
  23. # it by saving it into a file and typing "sh file".  To overwrite existing
  24. # files, type "sh file -c".  You can also feed this as standard input via
  25. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  26. # will see the following message at the end:
  27. #        "End of archive 1 (of 3)."
  28. # Contents:  README MANIFEST X11 X11/Xfuncs.h bm-3d bm-plain tetris.c
  29. #   tetris.h utils.c
  30. # Wrapped by billr@saab on Fri Aug 27 12:06:39 1993
  31. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  32. if test -f 'README' -a "${1}" != "-c" ; then 
  33.   echo shar: Will not clobber existing file \"'README'\"
  34. else
  35. echo shar: Extracting \"'README'\" \(2654 characters\)
  36. sed "s/^X//" >'README' <<'END_OF_FILE'
  37. X    GENERIC TETRIS
  38. X    ==============    Yet Another Tetris Game on X, V3.0.1
  39. X
  40. X
  41. XWHY ANOTHER?
  42. X
  43. X    Because this one is simple, easy to build, and portable -- actually
  44. X    the blocks are round-cornered and bigger, more comfortable for your
  45. X    eyes. It only uses Xlib -- no "toolkit" kind of thing. People have
  46. X    tested it on the following platforms:
  47. X
  48. X    Bull DPX/2        System V    ?
  49. X    DEC 5000        Ultrix 4.3    X11R4
  50. X    DEC Alpha AXP        DEC OSF/1 V1.2    ?
  51. X    HP 700            HP-UX 8.0x    X11R5
  52. X                Mt. Xinu 4.3    X11R5
  53. X    IBM RS6000        AIX V3.2    X11R3
  54. X    Intel 486        Esix 4.0.4    ?
  55. X                Linux        ?
  56. X                SCO-ODT 2.0    X11R4/Motif
  57. X    KSR KSR1        KSR OSF/1    X11R5
  58. X    SGI Iris        IRIX 4.0.1    Motif
  59. X    Sun SPARC        SunOS 4.1.x    X11R4, X11R5
  60. X                Solaris 2.1 (*)
  61. X    Sequent S81        DYNIX 3.2.0    X11R5
  62. X                Dynix/ptx    ?
  63. X
  64. X    [Note *] add to link: -L/usr/ucblib -lucb -lelf -R/usr/ucblib
  65. X
  66. X    If your's is not in this list, please let me know -- thanks. The
  67. X    most updated source could be found on ftp.x.org under /contrib.
  68. X
  69. X    A System V port (Sequent Dynix/ptx) has been added by
  70. X    "Hans-Wolfgang Loidl" <hwloidl@risc.uni-linz.ac.at>. The source can
  71. X    be retrieved by anonymous FTP to:
  72. X
  73. X    Host:    melmac.risc.uni-linz.ac.at
  74. X    File:    /pub/linux/upload/misc/gtetris3.taz
  75. X
  76. X
  77. XHOW TO BUILD?
  78. X
  79. X    Edit the Imakefile for appropriate settings of variable SCOREFILE
  80. X    and RANDOM, then do:
  81. X    xmkmf
  82. X    make
  83. X
  84. X    Note: if you don't have 'xmkmf' or the "Makefile" it generates
  85. X    doesn't work well, try:
  86. X    make -f Makefile.std
  87. X
  88. X    "Tetris" is the game. It only lists the top 15 players at the end,
  89. X    each player may has at most three scores. With the option "-s",
  90. X    "tetris" will list all the scores.
  91. X
  92. X
  93. XANYTHING SPECIAL IN PLAYING?
  94. X
  95. X    Use 'j' to move left; 'l' to move right; 'k' to rotate. Left-handed
  96. X    people may want to use 's', 'd', 'f' respectively. Use the space
  97. X    bar to drop a block quickly. Do you want to try the arrow keys?
  98. X
  99. X    Use CTRL-L key combination to redraw -- in case the program messes
  100. X    somthing up.
  101. X
  102. X    As usual, '+' and '-' will speed up or lower down the speed. Note
  103. X    that you don't need to press the SHIFT key -- '=' and '_' also
  104. X    work. The 'b' key can be used to toggle "beep" and 'n' toggles
  105. X    "show next".
  106. X
  107. X    If you press 'p', the game will be paused, and the window will be
  108. X    iconified -- just in case your boss suddenly appears at your door.
  109. X    ;o) When the tetris window loses its focus, it also goes to
  110. X    "paused" mode except it doesn't iconify itself.
  111. X
  112. X    Refer to the man page for detailed command line options.
  113. X
  114. X
  115. XFOUND A BUG?
  116. X
  117. X    Send bug reports (or fixes) to the author:
  118. X
  119. X    Q. Alex Zhao,    azhao@cc.gatech.edu
  120. X    College of Computing
  121. X    Georgia Institute of Technology
  122. X    Atlanta, GA 30332-0280
  123. X
  124. END_OF_FILE
  125. if test 2654 -ne `wc -c <'README'`; then
  126.     echo shar: \"'README'\" unpacked with wrong size!
  127. fi
  128. # end of 'README'
  129. fi
  130. if test -f 'MANIFEST' -a "${1}" != "-c" ; then 
  131.   echo shar: Will not clobber existing file \"'MANIFEST'\"
  132. else
  133. echo shar: Extracting \"'MANIFEST'\" \(1695 characters\)
  134. sed "s/^X//" >'MANIFEST' <<'END_OF_FILE'
  135. X   File Name        Archive #    Description
  136. X-----------------------------------------------------------
  137. X COPYRIGHT                  3    
  138. X Imakefile                  2    
  139. X MANIFEST                   1    This shipping list
  140. X Makefile.std               2    
  141. X README                     1    
  142. X Revisions                  2    
  143. X X11                        1    
  144. X X11/Xfuncproto.h           2    
  145. X X11/Xfuncs.h               1    
  146. X X11/Xos.h                  2    
  147. X X11/Xosdefs.h              2    
  148. X bm-3d                      1    
  149. X bm-3d/rot00.xbm            3    
  150. X bm-3d/rot01.xbm            3    
  151. X bm-3d/rot02.xbm            3    
  152. X bm-3d/rot03.xbm            3    
  153. X bm-3d/rot04.xbm            3    
  154. X bm-3d/rot05.xbm            3    
  155. X bm-3d/rot06.xbm            3    
  156. X bm-3d/rot07.xbm            3    
  157. X bm-3d/rot08.xbm            3    
  158. X bm-3d/rot09.xbm            3    
  159. X bm-3d/rot10.xbm            3    
  160. X bm-3d/rot11.xbm            3    
  161. X bm-3d/rot12.xbm            3    
  162. X bm-3d/rot13.xbm            3    
  163. X bm-3d/rot14.xbm            3    
  164. X bm-3d/rot15.xbm            3    
  165. X bm-plain                   1    
  166. X bm-plain/rop00.xbm         2    
  167. X bm-plain/rop01.xbm         2    
  168. X bm-plain/rop02.xbm         2    
  169. X bm-plain/rop03.xbm         2    
  170. X bm-plain/rop04.xbm         2    
  171. X bm-plain/rop05.xbm         2    
  172. X bm-plain/rop06.xbm         2    
  173. X bm-plain/rop07.xbm         2    
  174. X bm-plain/rop08.xbm         2    
  175. X bm-plain/rop09.xbm         2    
  176. X bm-plain/rop10.xbm         2    
  177. X bm-plain/rop11.xbm         2    
  178. X bm-plain/rop12.xbm         2    
  179. X bm-plain/rop13.xbm         2    
  180. X bm-plain/rop14.xbm         2    
  181. X bm-plain/rop15.xbm         3    
  182. X playing.c                  2    
  183. X tetris.c                   1    
  184. X tetris.h                   1    
  185. X tetris.man                 2    
  186. X ticon.xbm                  2    
  187. X utils.c                    1    
  188. END_OF_FILE
  189. if test 1695 -ne `wc -c <'MANIFEST'`; then
  190.     echo shar: \"'MANIFEST'\" unpacked with wrong size!
  191. fi
  192. # end of 'MANIFEST'
  193. fi
  194. if test ! -d 'X11' ; then
  195.     echo shar: Creating directory \"'X11'\"
  196.     mkdir 'X11'
  197. fi
  198. if test -f 'X11/Xfuncs.h' -a "${1}" != "-c" ; then 
  199.   echo shar: Will not clobber existing file \"'X11/Xfuncs.h'\"
  200. else
  201. echo shar: Extracting \"'X11/Xfuncs.h'\" \(1665 characters\)
  202. sed "s/^X//" >'X11/Xfuncs.h' <<'END_OF_FILE'
  203. X/*
  204. X * $XConsortium: Xfuncs.h,v 1.8 91/04/17 09:27:52 rws Exp $
  205. X * 
  206. X * Copyright 1990 by the Massachusetts Institute of Technology
  207. X *
  208. X * Permission to use, copy, modify, and distribute this software and its
  209. X * documentation for any purpose and without fee is hereby granted, provided 
  210. X * that the above copyright notice appear in all copies and that both that 
  211. X * copyright notice and this permission notice appear in supporting 
  212. X * documentation, and that the name of M.I.T. not be used in advertising
  213. X * or publicity pertaining to distribution of the software without specific, 
  214. X * written prior permission. M.I.T. makes no representations about the 
  215. X * suitability of this software for any purpose.  It is provided "as is"
  216. X * without express or implied warranty.
  217. X *
  218. X */
  219. X
  220. X#ifndef _XFUNCS_H_
  221. X#define _XFUNCS_H_
  222. X
  223. X#include <X11/Xosdefs.h>
  224. X
  225. X#ifdef X_USEBFUNCS
  226. Xvoid bcopy();
  227. Xvoid bzero();
  228. Xint bcmp();
  229. X#else
  230. X#if (__STDC__ && !defined(X_NOT_STDC_ENV) && !defined(sun) && !defined(macII)) || defined(SVR4) || defined(hpux) || defined(_IBMR2)
  231. X#include <string.h>
  232. X#define bcopy(b1,b2,len) memmove(b2, b1, (size_t)(len))
  233. X#define bzero(b,len) memset(b, 0, (size_t)(len))
  234. X#define bcmp(b1,b2,len) memcmp(b1, b2, (size_t)(len))
  235. X#else
  236. X#ifdef sgi
  237. X#include <bstring.h>
  238. X#else
  239. X#ifdef SYSV
  240. X#include <memory.h>
  241. X#if defined(_XBCOPYFUNC) && !defined(macII)
  242. X#define bcopy _XBCOPYFUNC
  243. X#define _XNEEDBCOPYFUNC
  244. X#endif
  245. Xvoid bcopy();
  246. X#define bzero(b,len) memset(b, 0, len)
  247. X#define bcmp(b1,b2,len) memcmp(b1, b2, len)
  248. X#else /* bsd */
  249. Xvoid bcopy();
  250. Xvoid bzero();
  251. Xint bcmp();
  252. X#endif /* SYSV */
  253. X#endif /* sgi */
  254. X#endif /* __STDC__ and relatives */
  255. X#endif /* X_USEBFUNCS */
  256. X
  257. X#endif /* _XFUNCS_H_ */
  258. END_OF_FILE
  259. if test 1665 -ne `wc -c <'X11/Xfuncs.h'`; then
  260.     echo shar: \"'X11/Xfuncs.h'\" unpacked with wrong size!
  261. fi
  262. # end of 'X11/Xfuncs.h'
  263. fi
  264. if test ! -d 'bm-3d' ; then
  265.     echo shar: Creating directory \"'bm-3d'\"
  266.     mkdir 'bm-3d'
  267. fi
  268. if test ! -d 'bm-plain' ; then
  269.     echo shar: Creating directory \"'bm-plain'\"
  270.     mkdir 'bm-plain'
  271. fi
  272. if test -f 'tetris.c' -a "${1}" != "-c" ; then 
  273.   echo shar: Will not clobber existing file \"'tetris.c'\"
  274. else
  275. echo shar: Extracting \"'tetris.c'\" \(12131 characters\)
  276. sed "s/^X//" >'tetris.c' <<'END_OF_FILE'
  277. X/*
  278. X# GENERIC X-WINDOW-BASED TETRIS
  279. X#
  280. X#    tetris.c
  281. X#
  282. X###
  283. X#
  284. X#  Copyright (C) 1992 - 93              Q. Alex Zhao, azhao@cc.gatech.edu
  285. X#
  286. X#            All Rights Reserved
  287. X#
  288. X#  Permission to use, copy, modify, and distribute this software and
  289. X#  its documentation for any purpose and without fee is hereby granted,
  290. X#  provided that the above copyright notice appear in all copies and
  291. X#  that both that copyright notice and this permission notice appear in
  292. X#  supporting documentation, and that the name of the author not be
  293. X#  used in advertising or publicity pertaining to distribution of the
  294. X#  software without specific, written prior permission.
  295. X#
  296. X#  This program is distributed in the hope that it will be "playable",
  297. X#  but WITHOUT ANY WARRANTY; without even the implied warranty of
  298. X#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  299. X#
  300. X*/
  301. X
  302. X#include "tetris.h"
  303. X
  304. X/*** variables ***/
  305. X
  306. Xchar            myDisplayName[256];
  307. XDisplay        *display;
  308. Xint             screen_num;
  309. XVisual         *visual;
  310. XBool            useColor = True;
  311. XColormap        colormap;
  312. XWindow          mainWin, blockWin;
  313. XCursor          theCursor;
  314. XXFontStruct    *bigFont, *tinyFont;
  315. Xunsigned long   fg, bg;
  316. X
  317. XXSizeHints      sizehints, iconsizehints;
  318. XXWMHints        wmhints = {
  319. X    InputHint | StateHint | IconPixmapHint,
  320. X    True,            /* input mode */
  321. X    NormalState,        /* normal */
  322. X    0,                /* icon pixmap */
  323. X    0,                /* icon window */
  324. X    0, 0,            /* icon position */
  325. X    0                /* icon mask pixmap - not used */
  326. X};
  327. X
  328. Xint             range = NUM_THINGS;
  329. XBool            bonusMode = False;
  330. X
  331. Xchar            myHome[FILENAMELEN];
  332. Xint             level = 3, prefilled = 0, score = 0, rows = 0;
  333. XBool            showNext = False, beep = False, use3D = True;
  334. Xscore_t         myscore;
  335. X
  336. Xstatic int      opTableEntries = 17;
  337. Xstatic XrmOptionDescRec opTable[] = {
  338. X    {"-s", "*scoresOnly", XrmoptionNoArg, (caddr_t) "yes"},
  339. X    {"-l", "*startLevel", XrmoptionSepArg, (caddr_t) NULL},
  340. X    {"-p", "*preFilledLines", XrmoptionSepArg, (caddr_t) NULL},
  341. X    {"-showNext", "*showNext", XrmoptionNoArg, (caddr_t) "yes"},
  342. X    {"-beep", "*beep", XrmoptionNoArg, (caddr_t) "yes"},
  343. X    {"-plain", "*plain", XrmoptionNoArg, (caddr_t) "yes"},
  344. X    {"-display", ".display", XrmoptionSepArg, (caddr_t) NULL},
  345. X    {"-geometry", "*geometry", XrmoptionSepArg, (caddr_t) NULL},
  346. X    {"-iconGeometry", "*iconGeometry", XrmoptionSepArg, (caddr_t) NULL},
  347. X    {"-background", "*background", XrmoptionSepArg, (caddr_t) NULL},
  348. X    {"-bg", "*background", XrmoptionSepArg, (caddr_t) NULL},
  349. X    {"-foreground", "*foreground", XrmoptionSepArg, (caddr_t) NULL},
  350. X    {"-fg", "*foreground", XrmoptionSepArg, (caddr_t) NULL},
  351. X    {"-bigFont", "*bigFont", XrmoptionSepArg, (caddr_t) NULL},
  352. X    {"-tinyFont", "*tinyFont", XrmoptionSepArg, (caddr_t) NULL},
  353. X    {"-u", "*playerName", XrmoptionSepArg, (caddr_t) NULL},
  354. X    {"-xrm", NULL, XrmoptionResArg, (caddr_t) NULL}
  355. X};
  356. Xstatic XrmDatabase cmmDB = (XrmDatabase) NULL, rDB = (XrmDatabase) NULL;
  357. X
  358. Xstatic void parseOpenDisp();
  359. Xstatic void Usage();
  360. Xstatic void getDefaults();
  361. X
  362. X/* ------------------------------------------------------------------ */
  363. X
  364. Xvoid
  365. Xmain(argc, argv)
  366. X    int             argc;
  367. X    char           *argv[];
  368. X{
  369. X    (void) fprintf(stderr,
  370. X           "                 GENERIC TETRIS V3.0.0\n");
  371. X    (void) fprintf(stderr,
  372. X     "Copyright (C) 1992-93      Q. Alex Zhao, azhao@cc.gatech.edu\n");
  373. X    (void) fprintf(stderr,
  374. X     "     GENERIC TETRIS comes with ABSOLUTELY NO WARRANTY.\n\n");
  375. X
  376. X    sizehints.flags = PMinSize | PMaxSize | PPosition | PSize | USSize;
  377. X    iconsizehints.flags = PPosition | PSize;
  378. X    iconsizehints.width = iconsizehints.height = 48;
  379. X
  380. X    parseOpenDisp(&argc, argv);
  381. X    getDefaults();
  382. X    inits(argc, argv);
  383. X    playing();
  384. X    /* never come to here */
  385. X}
  386. X
  387. X/* ------------------------------------------------------------------ */
  388. X
  389. Xstatic void
  390. XparseOpenDisp(argc, argv)
  391. X    int            *argc;
  392. X    char           *argv[];
  393. X{
  394. X    struct passwd  *pw;
  395. X    XrmValue        value;
  396. X    char           *str_type[20];
  397. X    XVisualInfo     vtmp, *vinfo;
  398. X    int             n = 1;
  399. X
  400. X    XrmInitialize();
  401. X
  402. X    myDisplayName[0] = '\0';
  403. X
  404. X    XrmParseCommand(&cmmDB, opTable, opTableEntries, "tetris", argc, argv);
  405. X
  406. X    /* check for any arguments left */
  407. X    if (*argc != 1) {
  408. X    Usage(argv[0]);
  409. X    }
  410. X    /* only print out the scores? */
  411. X    if (XrmGetResource(cmmDB, "tetris.scoresOnly", "Tetris.ScoresOnly",
  412. X               str_type, &value) == True) {
  413. X    showScores(0);
  414. X    exit(0);
  415. X    }
  416. X    /* get display now */
  417. X    if (XrmGetResource(cmmDB, "tetris.display", "Tetris.Display",
  418. X               str_type, &value) == True)
  419. X    (void) strncpy(myDisplayName, value.addr, ZLIM(value.size, 255));
  420. X    myDisplayName[255] = '\0';
  421. X
  422. X    if (!(display = XOpenDisplay(myDisplayName))) {
  423. X    (void) fprintf(stderr, "%s: Can't open display '%s'\n",
  424. X               argv[0], XDisplayName(myDisplayName));
  425. X    exit(1);
  426. X    }
  427. X
  428. X    screen_num = DefaultScreen(display);
  429. X    visual = DefaultVisual(display, screen_num);
  430. X    colormap = DefaultColormap(display, screen_num);
  431. X    vtmp.visualid = XVisualIDFromVisual(visual);
  432. X
  433. X    if ((vinfo = XGetVisualInfo(display, VisualIDMask, &vtmp, &n)) != NULL) {
  434. X    if ((vinfo->class == GrayScale) || (vinfo->class == StaticGray)) {
  435. X        useColor = False;
  436. X    }
  437. X    XFree((unsigned char *) vinfo);
  438. X    } else {
  439. X    useColor = False;
  440. X    }
  441. X
  442. X    /* setup user information */
  443. X    (void) gethostname(myscore.myhost, NAMELEN);
  444. X
  445. X    setpwent();
  446. X    pw = getpwuid(getuid());
  447. X    if (pw == NULL) {        /* impossible? */
  448. X    (void) sprintf(myscore.myname, "%d", getuid());
  449. X    myHome[0] = '.';
  450. X    myHome[1] = '/';
  451. X    myHome[2] = '\0';
  452. X    } else {
  453. X    (void) strncpy(myscore.myname, pw->pw_name, NAMELEN);
  454. X    (void) strncpy(myHome, pw->pw_dir, FILENAMELEN);
  455. X    }
  456. X    endpwent();
  457. X    myscore.myname[NAMELEN - 1] = '\0';
  458. X    myscore.myhost[NAMELEN - 1] = '\0';
  459. X    myHome[FILENAMELEN - 1] = '\0';
  460. X}
  461. X
  462. X/* ------------------------------------------------------------------ */
  463. X
  464. Xstatic void
  465. XUsage(argv0)
  466. X    char           *argv0;
  467. X{
  468. X    (void) fprintf(stderr,
  469. X    "Usage: %s [-s] [-l <starting level>]\n", argv0);
  470. X    (void) fprintf(stderr,
  471. X    "   [-p <prefilled rows>] [-plain] [-showNext] [-beep] [-u <name>]\n");
  472. X    (void) fprintf(stderr,
  473. X    "   [-display <display>] [-geometry <geometry>] [-iconGeometry <icon geometry>]\n");
  474. X    (void) fprintf(stderr,
  475. X    "   [-fg <foreground>] [-bg <background>] [-bigFont <font>] [-tinyFont <font>]\n");
  476. X    (void) fprintf(stderr,
  477. X    "   [-xrm <resource specifications>]\n");
  478. X
  479. X    exit(1);
  480. X}
  481. X
  482. X/* ------------------------------------------------------------------ */
  483. X
  484. Xstatic void
  485. XgetDefaults()
  486. X{
  487. X    XrmDatabase     homeDB, serverDB, appDB;
  488. X    char            filenamebuf[FILENAMELEN];
  489. X    char           *filename = &filenamebuf[0];
  490. X    char           *env;
  491. X    char           *classname = "Tetris";
  492. X    char            name[255], geoStr[20], icongeoStr[20];
  493. X    XrmValue        value;
  494. X    char           *str_type[20];
  495. X    int             x, y;
  496. X    unsigned int    w, h;
  497. X    long            flags;
  498. X
  499. X    (void) strcpy(name, "/usr/lib/X11/app-defaults/");
  500. X    (void) strcat(name, classname);
  501. X
  502. X    /* Get application defaults file, if any */
  503. X    appDB = XrmGetFileDatabase(name);
  504. X    (void) XrmMergeDatabases(appDB, &rDB);
  505. X
  506. X    if (XResourceManagerString(display) != NULL) {
  507. X    serverDB = XrmGetStringDatabase(XResourceManagerString(display));
  508. X    } else {
  509. X    (void) strcpy(filename, myHome);
  510. X    (void) strcat(filename, "/.Xdefaults");
  511. X    serverDB = XrmGetFileDatabase(filename);
  512. X    }
  513. X    XrmMergeDatabases(serverDB, &rDB);
  514. X
  515. X    if ((env = getenv("XENVIRONMENT")) == NULL) {
  516. X    int             len;
  517. X
  518. X    env = &filenamebuf[0];
  519. X    (void) strcpy(env, myHome);
  520. X    len = strlen(env);
  521. X    env[len++] = '/';
  522. X    (void) gethostname(env + len, FILENAMELEN - len);
  523. X    }
  524. X    homeDB = XrmGetFileDatabase(env);
  525. X    XrmMergeDatabases(homeDB, &rDB);
  526. X
  527. X    XrmMergeDatabases(cmmDB, &rDB);
  528. X
  529. X    /* starting levels */
  530. X
  531. X    if (XrmGetResource(rDB, "tetris.startLevel", "Tetris.StartLevel",
  532. X               str_type, &value) == True) {
  533. X    if ((sscanf(value.addr, "%d", &level) <= 0) ||
  534. X        (level < 0) || (level >= NUM_LEVELS)) {
  535. X        (void) fprintf(stderr, "Tetris: Invalid level.\n");
  536. X        exit(1);
  537. X    }
  538. X    }
  539. X
  540. X    /* prefilled lines */
  541. X
  542. X    if (XrmGetResource(rDB, "tetris.preFilledLines", "Tetris.PreFilledLines",
  543. X               str_type, &value) == True) {
  544. X    if ((sscanf(value.addr, "%d", &prefilled) <= 0) ||
  545. X        (prefilled < 0) || (prefilled >= ROWS - THINGSIZE)) {
  546. X        (void) fprintf(stderr, "Tetris: Invalid prefilled lines.\n");
  547. X        exit(1);
  548. X    }
  549. X    }
  550. X
  551. X    /* show next */
  552. X
  553. X    if (XrmGetResource(rDB, "tetris.showNext", "Tetris.ShowNext",
  554. X            str_type, &value) == True) {
  555. X    showNext = True;
  556. X    }
  557. X
  558. X    /* bitmaps */
  559. X
  560. X    if (XrmGetResource(rDB, "tetris.plain", "Tetris.Plain",
  561. X            str_type, &value) == True) {
  562. X    use3D = False;
  563. X    }
  564. X
  565. X    /* beep */
  566. X
  567. X    if (XrmGetResource(rDB, "tetris.beep", "Tetris.Beep",
  568. X            str_type, &value) == True) {
  569. X    beep = True;
  570. X    }
  571. X
  572. X    /*** get foreground/background colors ***/
  573. X
  574. X    if (XrmGetResource(rDB, "tetris.foreground", "Tetris.Foreground",
  575. X               str_type, &value) == True) {
  576. X    (void) strncpy(name, value.addr, ZLIM(value.size, 255));
  577. X    name[254] = '\0';
  578. X    fg = getColor(name);
  579. X    } else
  580. X    fg = BlackPixel(display, screen_num);
  581. X
  582. X    if (XrmGetResource(rDB, "tetris.background", "Tetris.Background",
  583. X               str_type, &value) == True) {
  584. X    (void) strncpy(name, value.addr, ZLIM(value.size, 255));
  585. X    name[254] = '\0';
  586. X    bg = getColor(name);
  587. X    } else
  588. X    bg = WhitePixel(display, screen_num);
  589. X
  590. X    if (bg == fg) {
  591. X    bg = WhitePixel(display, screen_num);
  592. X    fg = BlackPixel(display, screen_num);
  593. X    }
  594. X
  595. X    /*** get geometry info ***/
  596. X
  597. X    if (XrmGetResource(rDB, "tetris.geometry", "Tetris.Geometry",
  598. X               str_type, &value) == True) {
  599. X    (void) strncpy(geoStr, value.addr, ZLIM(value.size, 20));
  600. X    geoStr[19] = '\0';
  601. X    } else {
  602. X    geoStr[0] = '\0';
  603. X    }
  604. X
  605. X    flags = XParseGeometry(geoStr, &x, &y, &w, &h);
  606. X    if ((WidthValue | HeightValue) & flags)
  607. X    Usage("tetris");
  608. X
  609. X    if (XValue & flags) {
  610. X    if (XNegative & flags)
  611. X        x = DisplayWidth(display, screen_num) + x - sizehints.width;
  612. X    sizehints.x = x;
  613. X    }
  614. X    if (YValue & flags) {
  615. X    if (YNegative & flags)
  616. X        y = DisplayHeight(display, screen_num) + y - sizehints.height;
  617. X    sizehints.y = y;
  618. X    }
  619. X
  620. X    /*** get icon geometry info ***/
  621. X
  622. X    if (XrmGetResource(rDB, "tetris.iconGeometry", "Tetris.IconGeometry",
  623. X               str_type, &value) == True) {
  624. X    (void) strncpy(icongeoStr, value.addr, ZLIM(value.size, 20));
  625. X    icongeoStr[19] = '\0';
  626. X    } else {
  627. X    icongeoStr[0] = '\0';
  628. X    }
  629. X
  630. X    flags = XParseGeometry(icongeoStr, &x, &y, &w, &h);
  631. X    if ((WidthValue | HeightValue) & flags)
  632. X    Usage("tetris");
  633. X
  634. X    if (XValue & flags) {
  635. X    if (XNegative & flags)
  636. X        x = DisplayWidth(display, screen_num) + x - iconsizehints.width;
  637. X    wmhints.flags |= IconPositionHint;
  638. X    wmhints.icon_x = x;
  639. X    iconsizehints.x = x;
  640. X    }
  641. X    if (YValue & flags) {
  642. X    if (YNegative & flags)
  643. X        y = DisplayHeight(display, screen_num) + y - iconsizehints.height;
  644. X    wmhints.flags |= IconPositionHint;
  645. X    wmhints.icon_y = y;
  646. X    iconsizehints.y = y;
  647. X    }
  648. X
  649. X    /*** get fonts ***/
  650. X
  651. X    if (XrmGetResource(rDB, "tetris.bigFont", "Tetris.BigFont",
  652. X               str_type, &value) == True) {
  653. X    (void) strncpy(name, value.addr, ZLIM(value.size, 255));
  654. X    name[254] = '\0';
  655. X    } else {
  656. X    (void) strcpy(name, BIGFONT);
  657. X    }
  658. X    if ((bigFont = XLoadQueryFont(display, name)) == NULL) {
  659. X    (void) fprintf(stderr, "Tetris: can't open font '%s'.\n", name);
  660. X    exit(1);
  661. X    }
  662. X    if (XrmGetResource(rDB, "tetris.tinyFont", "Tetris.TinyFont",
  663. X               str_type, &value) == True) {
  664. X    (void) strncpy(name, value.addr, ZLIM(value.size, 255));
  665. X    name[254] = '\0';
  666. X    } else {
  667. X    (void) strcpy(name, TINYFONT);
  668. X    }
  669. X    if ((tinyFont = XLoadQueryFont(display, name)) == NULL) {
  670. X    (void) fprintf(stderr, "Tetris: can't open font '%s'.\n", name);
  671. X    exit(1);
  672. X    }
  673. X
  674. X    /* player name */
  675. X
  676. X    if (XrmGetResource(rDB, "tetris.playerName", "Tetris.PlayerName",
  677. X               str_type, &value) == True) {
  678. X    (void) strncpy(myscore.myname, value.addr, ZLIM(value.size, 20));
  679. X    myscore.myname[19] = '\0';
  680. X    }
  681. X
  682. X    /*
  683. X     * clean up
  684. X     */
  685. X    XrmDestroyDatabase(rDB);
  686. X}
  687. X
  688. X/* ------------------------------------------------------------------ */
  689. END_OF_FILE
  690. if test 12131 -ne `wc -c <'tetris.c'`; then
  691.     echo shar: \"'tetris.c'\" unpacked with wrong size!
  692. fi
  693. # end of 'tetris.c'
  694. fi
  695. if test -f 'tetris.h' -a "${1}" != "-c" ; then 
  696.   echo shar: Will not clobber existing file \"'tetris.h'\"
  697. else
  698. echo shar: Extracting \"'tetris.h'\" \(4808 characters\)
  699. sed "s/^X//" >'tetris.h' <<'END_OF_FILE'
  700. X/*
  701. X# GENERIC X-WINDOW-BASED TETRIS
  702. X#
  703. X#    tetris.h
  704. X#
  705. X###
  706. X#
  707. X#  Copyright (C) 1992 - 93              Q. Alex Zhao, azhao@cc.gatech.edu
  708. X#
  709. X#            All Rights Reserved
  710. X#
  711. X#  Permission to use, copy, modify, and distribute this software and
  712. X#  its documentation for any purpose and without fee is hereby granted,
  713. X#  provided that the above copyright notice appear in all copies and
  714. X#  that both that copyright notice and this permission notice appear in
  715. X#  supporting documentation, and that the name of the author not be
  716. X#  used in advertising or publicity pertaining to distribution of the
  717. X#  software without specific, written prior permission.
  718. X#
  719. X#  This program is distributed in the hope that it will be "playable",
  720. X#  but WITHOUT ANY WARRANTY; without even the implied warranty of
  721. X#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  722. X#
  723. X*/
  724. X
  725. X/*** Common headers ***/
  726. X
  727. X#include    <stdio.h>
  728. X#include    <math.h>
  729. X#include    <pwd.h>
  730. X#include    <errno.h>
  731. X
  732. X#include    <X11/Xlib.h>
  733. X#include    <X11/Xutil.h>
  734. X#include    <X11/Xresource.h>
  735. X#include    <X11/cursorfont.h>
  736. X#include    <X11/keysym.h>
  737. X#include    <X11/Xos.h>
  738. X#include    <X11/Xfuncs.h>
  739. X#include    <X11/Xfuncproto.h>
  740. X
  741. X#ifndef    X_NOT_STDC_ENV
  742. X#include    <stdlib.h>
  743. X#else
  744. Xextern char    *getenv(
  745. X#if    NeedFunctionPrototypes
  746. X    char *
  747. X#endif
  748. X);
  749. X#endif
  750. X
  751. X#ifdef    X_NOT_POSIX
  752. Xextern int      getuid(
  753. X#if    NeedFunctionPrototypes
  754. X    void
  755. X#endif
  756. X);
  757. Xextern struct passwd *getpwuid(
  758. X#if    NeedFunctionPrototypes
  759. X    int
  760. X#endif
  761. X);
  762. X#endif
  763. X
  764. X#ifdef    _AIX
  765. X#include    <sys/select.h>
  766. X#endif
  767. X
  768. X/*** for lseek ***/
  769. X
  770. X#ifndef    SEEK_SET
  771. X#define    SEEK_SET    L_SET
  772. X#endif
  773. X
  774. X#ifndef    SEEK_CUR
  775. X#define    SEEK_CUR    L_INCR
  776. X#endif
  777. X
  778. X#ifndef    SEEK_END
  779. X#define    SEEK_END    L_XTND
  780. X#endif
  781. X
  782. X/*** random generator ***/
  783. X
  784. X#if    defined(HAS_48)        /* Use lrand48() and srand48() */
  785. X#define    LRAND()        lrand48()
  786. X#define    SRAND(X)    srand48((long) (X))
  787. Xextern long     lrand48(
  788. X#if    NeedFunctionPrototypes
  789. X    void
  790. X#endif
  791. X);
  792. X
  793. X#else
  794. X#if    defined(HAS_RANDOM)    /* Use random() and srandom() */
  795. X
  796. X#define    LRAND()        random()
  797. X#define    SRAND(X)    srandom((unsigned int) (X))
  798. Xextern long     random(
  799. X#if    NeedFunctionPrototypes
  800. X    void
  801. X#endif
  802. X);
  803. X
  804. X#else                /* Use rand() and srand() */
  805. X
  806. X#define    LRAND()        ((long) rand())
  807. X#define    SRAND(X)    srand(X)
  808. X
  809. X#endif
  810. X#endif
  811. X
  812. X/*** macros ***/
  813. X
  814. X#define    ZLIM(X, Y)    (((int) X) < (Y) ? ((int) X) : (Y))
  815. X
  816. X/*** constants ***/
  817. X
  818. X#ifndef    SCOREFILE
  819. X#define    SCOREFILE    "/usr/games/lib/tetris.scores"
  820. X#endif
  821. X
  822. X#define    BIGFONT        "12x24"
  823. X#define    TINYFONT    "6x12"
  824. X#define    BVOLUME        -90
  825. X#define NUM_FLASHES    16
  826. X
  827. X#define BONUSIN     2500
  828. X#define BONUSOUT    1000
  829. X#define SAMPLERATE  5000000
  830. X
  831. X#define    MILLION        1000000
  832. X#define    MAXSCORES    3
  833. X#define    SHOWSCORES    15
  834. X#define    NAMELEN        12
  835. X#define    FILENAMELEN    1024
  836. X
  837. X#define    MSG_PAUSED    "PAUSED"
  838. X#define    MSG_END        "GAME OVER"
  839. X#define    MSG_TITLE    "TETRIS"
  840. X#define    MSG_AUTHOR    "by Q. Alex Zhao"
  841. X
  842. X#define    NUM_LEVELS    18
  843. X#define    ROWS        20
  844. X#define    COLS        10
  845. X
  846. X#define    BOXSIZE        30
  847. X#define    OFFSET        20
  848. X#define    THINGSIZE    4
  849. X#define    NUM_THINGS    7
  850. X#define    NUM_BTHINGS    12
  851. X#define NUM_BITMAPS    16
  852. X
  853. X/*** types ***/
  854. X
  855. Xtypedef enum {FALL, DROP, ROTATE, LEFT, RIGHT, REFLECT} move_t;
  856. X
  857. Xtypedef struct {
  858. X    char            myname[NAMELEN], myhost[NAMELEN], mydate[27];
  859. X    char            score[10];
  860. X    char            level[4];
  861. X    char            rows[5];
  862. X}               score_t;
  863. X#define    SCORESIZE    sizeof(score_t)
  864. X
  865. Xtypedef struct {
  866. X    int             map[THINGSIZE][THINGSIZE];
  867. X    int             xpos, ypos;
  868. X    int             size, px, py, cid, gx, gy;
  869. X}               thing_t;
  870. X
  871. X/*** variables defined in "tetris.c" ***/
  872. X
  873. Xextern Display *display;
  874. Xextern int      screen_num;
  875. Xextern Visual  *visual;
  876. Xextern Bool     useColor;
  877. Xextern Bool     use3D;
  878. Xextern Colormap colormap;
  879. Xextern Window   mainWin, blockWin;
  880. Xextern Cursor   theCursor;
  881. Xextern XFontStruct *bigFont, *tinyFont;
  882. Xextern unsigned long fg, bg;
  883. X
  884. Xextern XSizeHints sizehints, iconsizehints;
  885. Xextern XWMHints wmhints;
  886. X
  887. Xextern char     myHome[FILENAMELEN];
  888. Xextern int      level, prefilled, score, rows, range;
  889. Xextern Bool     showNext, beep, bonusMode;
  890. Xextern score_t  myscore;
  891. X
  892. X/*** variables defined in "utils.c" ***/
  893. X
  894. Xextern Atom     delw;
  895. X
  896. X/*** variables defined in "playing.c" ***/
  897. X
  898. X/*** functions ***/
  899. X
  900. Xextern unsigned long getColor();
  901. Xextern void     showScores();
  902. Xextern void     inits();
  903. Xextern void     playing();
  904. Xextern void     realTime();
  905. Xextern void     newThing();
  906. Xextern Bool     evGotNewThing();
  907. Xextern void     redrawAll();
  908. Xextern void     drawTitle();
  909. Xextern void     drawStatus();
  910. Xextern void     drawField();
  911. Xextern void     drawThing();
  912. Xextern void     drawThingDiff();
  913. Xextern void     drawNext();
  914. Xextern void     gameOver();
  915. Xextern void     banner();
  916. Xextern void     clearNext();
  917. Xextern void     putBox();
  918. Xextern void     tryMove();
  919. Xextern Bool     atBottom();
  920. Xextern Bool     overlapping();
  921. Xextern int      checkLines();
  922. Xextern void     drawBox();
  923. Xextern int      nrand();
  924. X
  925. END_OF_FILE
  926. if test 4808 -ne `wc -c <'tetris.h'`; then
  927.     echo shar: \"'tetris.h'\" unpacked with wrong size!
  928. fi
  929. # end of 'tetris.h'
  930. fi
  931. if test -f 'utils.c' -a "${1}" != "-c" ; then 
  932.   echo shar: Will not clobber existing file \"'utils.c'\"
  933. else
  934. echo shar: Extracting \"'utils.c'\" \(25559 characters\)
  935. sed "s/^X//" >'utils.c' <<'END_OF_FILE'
  936. X/*
  937. X# GENERIC X-WINDOW-BASED TETRIS
  938. X#
  939. X#    utils.c
  940. X#
  941. X###
  942. X#
  943. X#  Copyright (C) 1992 - 93              Q. Alex Zhao, azhao@cc.gatech.edu
  944. X#
  945. X#            All Rights Reserved
  946. X#
  947. X#  Permission to use, copy, modify, and distribute this software and
  948. X#  its documentation for any purpose and without fee is hereby granted,
  949. X#  provided that the above copyright notice appear in all copies and
  950. X#  that both that copyright notice and this permission notice appear in
  951. X#  supporting documentation, and that the name of the author not be
  952. X#  used in advertising or publicity pertaining to distribution of the
  953. X#  software without specific, written prior permission.
  954. X#
  955. X#  This program is distributed in the hope that it will be "playable",
  956. X#  but WITHOUT ANY WARRANTY; without even the implied warranty of
  957. X#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  958. X#
  959. X*/
  960. X
  961. X#include    "tetris.h"
  962. X
  963. X#include    "ticon.xbm"
  964. X
  965. X#include    "bm-3d/rot00.xbm"
  966. X#include    "bm-3d/rot01.xbm"
  967. X#include    "bm-3d/rot02.xbm"
  968. X#include    "bm-3d/rot03.xbm"
  969. X#include    "bm-3d/rot04.xbm"
  970. X#include    "bm-3d/rot05.xbm"
  971. X#include    "bm-3d/rot06.xbm"
  972. X#include    "bm-3d/rot07.xbm"
  973. X#include    "bm-3d/rot08.xbm"
  974. X#include    "bm-3d/rot09.xbm"
  975. X#include    "bm-3d/rot10.xbm"
  976. X#include    "bm-3d/rot11.xbm"
  977. X#include    "bm-3d/rot12.xbm"
  978. X#include    "bm-3d/rot13.xbm"
  979. X#include    "bm-3d/rot14.xbm"
  980. X#include    "bm-3d/rot15.xbm"
  981. X
  982. X#include    "bm-plain/rop00.xbm"
  983. X#include    "bm-plain/rop01.xbm"
  984. X#include    "bm-plain/rop02.xbm"
  985. X#include    "bm-plain/rop03.xbm"
  986. X#include    "bm-plain/rop04.xbm"
  987. X#include    "bm-plain/rop05.xbm"
  988. X#include    "bm-plain/rop06.xbm"
  989. X#include    "bm-plain/rop07.xbm"
  990. X#include    "bm-plain/rop08.xbm"
  991. X#include    "bm-plain/rop09.xbm"
  992. X#include    "bm-plain/rop10.xbm"
  993. X#include    "bm-plain/rop11.xbm"
  994. X#include    "bm-plain/rop12.xbm"
  995. X#include    "bm-plain/rop13.xbm"
  996. X#include    "bm-plain/rop14.xbm"
  997. X#include    "bm-plain/rop15.xbm"
  998. X
  999. XAtom            delw;
  1000. X
  1001. Xstatic GC       revGC, bigGC, tinyGC, xorGC;
  1002. Xstatic GC       thingGCs[NUM_THINGS];
  1003. X
  1004. Xstatic char    *winName = "GENERIC TETRIS";
  1005. Xstatic char    *iconName = "TETRIS";
  1006. X
  1007. Xstatic int      titleLen, titleWidth, authorLen, authorWidth;
  1008. Xstatic int      titleX, titleY, authorX, authorY;
  1009. Xstatic int      sX;
  1010. Xstatic int      sLevelY, sRowsY, sScoreY;
  1011. X
  1012. Xstatic int      topRWidth, topWidth, topHeight, topMidX, topMidY;
  1013. Xstatic int      frameX, frameY, frameW, frameH;
  1014. X
  1015. Xstatic char    *bitmap_data_3d[NUM_BITMAPS] = {
  1016. X    rot00_bits, rot01_bits, rot02_bits, rot03_bits, rot04_bits, rot05_bits,
  1017. X    rot06_bits, rot07_bits, rot08_bits, rot09_bits, rot10_bits, rot11_bits,
  1018. X    rot12_bits, rot13_bits, rot14_bits, rot15_bits
  1019. X};
  1020. X
  1021. Xstatic char    *bitmap_data_plain[NUM_BITMAPS] = {
  1022. X    rop00_bits, rop01_bits, rop02_bits, rop03_bits, rop04_bits, rop05_bits,
  1023. X    rop06_bits, rop07_bits, rop08_bits, rop09_bits, rop10_bits, rop11_bits,
  1024. X    rop12_bits, rop13_bits, rop14_bits, rop15_bits
  1025. X};
  1026. X
  1027. Xstatic thing_t  possible[NUM_THINGS + NUM_BTHINGS][4] = {
  1028. X    {
  1029. X    {{{0, 0, 0, 0}, {4, 5, 5, 1}, {0, 0, 0, 0}, {0, 0, 0, 0}}, 0, 0, 4, 0, 0, 0, 1, 1},
  1030. X    {{{0, 2, 0, 0}, {0, 10, 0, 0}, {0, 10, 0, 0}, {0, 8, 0, 0}}, 0, 0, 4, 0, 1, 0, 1, 1},
  1031. X    {{{0, 0, 0, 0}, {4, 5, 5, 1}, {0, 0, 0, 0}, {0, 0, 0, 0}}, 0, 0, 4, 0, 2, 0, 1, 1},
  1032. X    {{{0, 2, 0, 0}, {0, 10, 0, 0}, {0, 10, 0, 0}, {0, 8, 0, 0}}, 0, 0, 4, 0, 3, 0, 1, 1}
  1033. X    },
  1034. X
  1035. X    {
  1036. X    {{{0, 2, 0, 0}, {0, 10, 0, 0}, {4, 9, 0, 0}, {0, 0, 0, 0}}, 0, 0, 3, 1, 0, 0, 2, 1},
  1037. X    {{{2, 0, 0, 0}, {12, 5, 1, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}}, 0, 0, 3, 1, 1, 0, 1, 0},
  1038. X    {{{6, 1, 0, 0}, {10, 0, 0, 0}, {8, 0, 0, 0}, {0, 0, 0, 0}}, 0, 0, 3, 1, 2, 0, 0, 0},
  1039. X    {{{4, 5, 3, 0}, {0, 0, 8, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}}, 0, 0, 3, 1, 3, 0, 0, 2}
  1040. X    },
  1041. X
  1042. X    {
  1043. X    {{{2, 0, 0, 0}, {10, 0, 0, 0}, {12, 1, 0, 0}, {0, 0, 0, 0}}, 0, 0, 3, 2, 0, 0, 2, 0},
  1044. X    {{{6, 5, 1, 0}, {8, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}}, 0, 0, 3, 2, 1, 0, 0, 0},
  1045. X    {{{4, 3, 0, 0}, {0, 10, 0, 0}, {0, 8, 0, 0}, {0, 0, 0, 0}}, 0, 0, 3, 2, 2, 0, 0, 1},
  1046. X    {{{0, 0, 2, 0}, {4, 5, 9, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}}, 0, 0, 3, 2, 3, 0, 1, 2}
  1047. X    },
  1048. X
  1049. X    {
  1050. X    {{{0, 2, 0, 0}, {4, 11, 0, 0}, {0, 8, 0, 0}, {0, 0, 0, 0}}, 0, 0, 3, 3, 0, 0, 1, 1},
  1051. X    {{{0, 2, 0, 0}, {4, 13, 1, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}}, 0, 0, 3, 3, 1, 0, 1, 1},
  1052. X    {{{2, 0, 0, 0}, {14, 1, 0, 0}, {8, 0, 0, 0}, {0, 0, 0, 0}}, 0, 0, 3, 3, 2, 0, 1, 0},
  1053. X    {{{4, 7, 1, 0}, {0, 8, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}}, 0, 0, 3, 3, 3, 0, 0, 1}
  1054. X    },
  1055. X
  1056. X    {
  1057. X    {{{2, 0, 0, 0}, {12, 3, 0, 0}, {0, 8, 0, 0}, {0, 0, 0, 0}}, 0, 0, 3, 4, 0, 0, 1, 0},
  1058. X    {{{0, 6, 1, 0}, {4, 9, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}}, 0, 0, 3, 4, 1, 0, 0, 1},
  1059. X    {{{2, 0, 0, 0}, {12, 3, 0, 0}, {0, 8, 0, 0}, {0, 0, 0, 0}}, 0, 0, 3, 4, 2, 0, 1, 1},
  1060. X    {{{0, 6, 1, 0}, {4, 9, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}}, 0, 0, 3, 4, 3, 0, 1, 1}
  1061. X    },
  1062. X
  1063. X    {
  1064. X    {{{0, 2, 0, 0}, {6, 9, 0, 0}, {8, 0, 0, 0}, {0, 0, 0, 0}}, 0, 0, 3, 5, 0, 0, 1, 0},
  1065. X    {{{4, 3, 0, 0}, {0, 12, 1, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}}, 0, 0, 3, 5, 1, 0, 0, 1},
  1066. X    {{{0, 2, 0, 0}, {6, 9, 0, 0}, {8, 0, 0, 0}, {0, 0, 0, 0}}, 0, 0, 3, 5, 2, 0, 1, 1},
  1067. X    {{{4, 3, 0, 0}, {0, 12, 1, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}}, 0, 0, 3, 5, 3, 0, 1, 1}
  1068. X    },
  1069. X
  1070. X    {
  1071. X    {{{6, 3, 0, 0}, {12, 9, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}}, 0, 0, 2, 6, 0, 0, 0, 0},
  1072. X    {{{6, 3, 0, 0}, {12, 9, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}}, 0, 0, 2, 6, 1, 0, 0, 0},
  1073. X    {{{6, 3, 0, 0}, {12, 9, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}}, 0, 0, 2, 6, 2, 0, 0, 0},
  1074. X    {{{6, 3, 0, 0}, {12, 9, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}}, 0, 0, 2, 6, 3, 0, 0, 0}
  1075. X    },
  1076. X
  1077. X    /* bonus mode blocks */
  1078. X
  1079. X    {
  1080. X    {{{0, 0, 0, 2}, {4, 5, 5, 9}, {0, 0, 0, 0}, {0, 0, 0, 0}}, 0, 0, 4, 7, 0, 0, 1, 2},
  1081. X    {{{4, 3, 0, 0}, {0, 10, 0, 0}, {0, 10, 0, 0}, {0, 8, 0, 0}}, 0, 0, 4, 7, 1, 0, 1, 1},
  1082. X    {{{6, 5, 5, 1}, {8, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}}, 0, 0, 4, 7, 2, 0, 0, 1},
  1083. X    {{{2, 0, 0, 0}, {10, 0, 0, 0}, {10, 0, 0, 0}, {12, 1, 0, 0}}, 0, 0, 4, 7, 3, 0, 2, 0}
  1084. X    },
  1085. X
  1086. X    {
  1087. X    {{{2, 0, 0, 0}, {12, 5, 5, 1}, {0, 0, 0, 0}, {0, 0, 0, 0}}, 0, 0, 4, 8, 0, 0, 1, 1},
  1088. X    {{{0, 2, 0, 0}, {0, 10, 0, 0}, {0, 10, 0, 0}, {4, 9, 0, 0}}, 0, 0, 4, 8, 1, 0, 2, 1},
  1089. X    {{{4, 5, 5, 3}, {0, 0, 0, 8}, {0, 0, 0, 0}, {0, 0, 0, 0}}, 0, 0, 4, 8, 2, 0, 0, 2},
  1090. X    {{{6, 1, 0, 0}, {10, 0, 0, 0}, {10, 0, 0, 0}, {8, 0, 0, 0}}, 0, 0, 4, 8, 3, 0, 1, 0}
  1091. X    },
  1092. X
  1093. X    {
  1094. X    {{{0, 2, 0, 0}, {4, 13, 5, 1}, {0, 0, 0, 0}, {0, 0, 0, 0}}, 0, 0, 4, 9, 0, 0, 1, 1},
  1095. X    {{{0, 2, 0, 0}, {0, 10, 0, 0}, {4, 11, 0, 0}, {0, 8, 0, 0}}, 0, 0, 4, 9, 1, 0, 2, 1},
  1096. X    {{{4, 5, 7, 1}, {0, 0, 8, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}}, 0, 0, 4, 9, 2, 0, 0, 2},
  1097. X    {{{2, 0, 0, 0}, {14, 1, 0, 0}, {10, 0, 0, 0}, {8, 0, 0, 0}}, 0, 0, 4, 9, 3, 0, 1, 0}
  1098. X    },
  1099. X
  1100. X    {
  1101. X    {{{0, 0, 2, 0}, {4, 5, 13, 1}, {0, 0, 0, 0}, {0, 0, 0, 0}}, 0, 0, 4, 10, 0, 0, 1, 2},
  1102. X    {{{0, 2, 0, 0}, {4, 11, 0, 0}, {0, 10, 0, 0}, {0, 8, 0, 0}}, 0, 0, 4, 10, 1, 0, 1, 1},
  1103. X    {{{4, 7, 5, 1}, {0, 8, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}}, 0, 0, 4, 10, 2, 0, 0, 1},
  1104. X    {{{2, 0, 0, 0}, {10, 0, 0, 0}, {14, 1, 0, 0}, {8, 0, 0, 0}}, 0, 0, 4, 10, 3, 0, 2, 0}
  1105. X    },
  1106. X
  1107. X    {
  1108. X    {{{4, 7, 1, 0}, {0, 10, 0, 0}, {0, 8, 0, 0}, {0, 0, 0, 0}}, 0, 0, 3, 11, 0, 0, 0, 1},
  1109. X    {{{2, 0, 0, 0}, {14, 5, 1, 0}, {8, 0, 0, 0}, {0, 0, 0, 0}}, 0, 0, 3, 11, 1, 0, 1, 0},
  1110. X    {{{0, 2, 0, 0}, {0, 10, 0, 0}, {4, 13, 1, 0}, {0, 0, 0, 0}}, 0, 0, 3, 11, 2, 0, 2, 1},
  1111. X    {{{0, 0, 2, 0}, {4, 5, 11, 0}, {0, 0, 8, 0}, {0, 0, 0, 0}}, 0, 0, 3, 11, 3, 0, 1, 2}
  1112. X    },
  1113. X
  1114. X    {
  1115. X    {{{2, 0, 0, 0}, {12, 3, 0, 0}, {0, 10, 0, 0}, {0, 8, 0, 0}}, 0, 0, 4, 12, 0, 0, 1, 1},
  1116. X    {{{0, 6, 5, 1}, {4, 9, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}}, 0, 0, 4, 12, 1, 0, 0, 1},
  1117. X    {{{2, 0, 0, 0}, {10, 0, 0, 0}, {12, 3, 0, 0}, {0, 8, 0, 0}}, 0, 0, 4, 12, 2, 0, 2, 0},
  1118. X    {{{0, 0, 6, 1}, {4, 5, 9, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}}, 0, 0, 4, 12, 3, 0, 1, 2}
  1119. X    },
  1120. X
  1121. X    {
  1122. X    {{{4, 3, 0, 0}, {0, 12, 5, 1}, {0, 0, 0, 0}, {0, 0, 0, 0}}, 0, 0, 4, 13, 0, 0, 1, 1},
  1123. X    {{{0, 2, 0, 0}, {0, 10, 0, 0}, {6, 9, 0, 0}, {8, 0, 0, 0}}, 0, 0, 4, 13, 1, 0, 2, 1},
  1124. X    {{{4, 5, 3, 0}, {0, 0, 12, 1}, {0, 0, 0, 0}, {0, 0, 0, 0}}, 0, 0, 4, 13, 2, 0, 0, 2},
  1125. X    {{{0, 2, 0, 0}, {6, 9, 0, 0}, {10, 0, 0, 0}, {8, 0, 0, 0}}, 0, 0, 4, 13, 3, 0, 1, 0}
  1126. X    },
  1127. X
  1128. X    {
  1129. X    {{{2, 0, 0, 0}, {12, 7, 1, 0}, {0, 8, 0, 0}, {0, 0, 0, 0}}, 0, 0, 3, 14, 0, 0, 1, 1},
  1130. X    {{{0, 2, 0, 0}, {0, 14, 1, 0}, {4, 9, 0, 0}, {0, 0, 0, 0}}, 0, 0, 3, 14, 1, 0, 1, 1},
  1131. X    {{{0, 2, 0, 0}, {4, 13, 3, 0}, {0, 0, 8, 0}, {0, 0, 0, 0}}, 0, 0, 3, 14, 2, 0, 1, 1},
  1132. X    {{{0, 6, 1, 0}, {4, 11, 0, 0}, {0, 8, 0, 0}, {0, 0, 0, 0}}, 0, 0, 3, 14, 3, 0, 1, 1}
  1133. X    },
  1134. X
  1135. X    {
  1136. X    {{{4, 3, 0, 0}, {0, 14, 1, 0}, {0, 8, 0, 0}, {0, 0, 0, 0}}, 0, 0, 3, 15, 0, 0, 1, 1},
  1137. X    {{{0, 2, 0, 0}, {6, 13, 1, 0}, {8, 0, 0, 0}, {0, 0, 0, 0}}, 0, 0, 3, 15, 1, 0, 1, 1},
  1138. X    {{{0, 2, 0, 0}, {4, 11, 0, 0}, {0, 12, 1, 0}, {0, 0, 0, 0}}, 0, 0, 3, 15, 2, 0, 1, 1},
  1139. X    {{{0, 0, 2, 0}, {4, 7, 9, 0}, {0, 8, 0, 0}, {0, 0, 0, 0}}, 0, 0, 3, 15, 3, 0, 1, 1}
  1140. X    },
  1141. X
  1142. X    {
  1143. X    {{{6, 7, 1, 0}, {12, 9, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}}, 0, 0, 3, 16, 0, 0, 0, 1},
  1144. X    {{{2, 0, 0, 0}, {14, 3, 0, 0}, {12, 9, 0, 0}, {0, 0, 0, 0}}, 0, 0, 3, 16, 1, 0, 1, 0},
  1145. X    {{{0, 6, 3, 0}, {4, 13, 9, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}}, 0, 0, 3, 16, 2, 0, 1, 1},
  1146. X    {{{6, 3, 0, 0}, {12, 11, 0, 0}, {0, 8, 0, 0}, {0, 0, 0, 0}}, 0, 0, 3, 16, 3, 0, 1, 1}
  1147. X    },
  1148. X
  1149. X    {
  1150. X    {{{6, 3, 0, 0}, {12, 13, 1, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}}, 0, 0, 3, 17, 0, 0, 1, 1},
  1151. X    {{{0, 2, 0, 0}, {6, 11, 0, 0}, {12, 9, 0, 0}, {0, 0, 0, 0}}, 0, 0, 3, 17, 1, 0, 1, 1},
  1152. X    {{{4, 7, 3, 0}, {0, 12, 9, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}}, 0, 0, 3, 17, 2, 0, 0, 1},
  1153. X    {{{6, 3, 0, 0}, {14, 9, 0, 0}, {8, 0, 0, 0}, {0, 0, 0, 0}}, 0, 0, 3, 17, 3, 0, 1, 0}
  1154. X    },
  1155. X
  1156. X    {
  1157. X    {{{0, 2, 0, 0}, {4, 15, 1, 0}, {0, 8, 0, 0}, {0, 0, 0, 0}}, 0, 0, 3, 18, 0, 0, 1, 1},
  1158. X    {{{0, 2, 0, 0}, {4, 15, 1, 0}, {0, 8, 0, 0}, {0, 0, 0, 0}}, 0, 0, 3, 18, 1, 0, 1, 1},
  1159. X    {{{0, 2, 0, 0}, {4, 15, 1, 0}, {0, 8, 0, 0}, {0, 0, 0, 0}}, 0, 0, 3, 18, 2, 0, 1, 1},
  1160. X    {{{0, 2, 0, 0}, {4, 15, 1, 0}, {0, 8, 0, 0}, {0, 0, 0, 0}}, 0, 0, 3, 18, 3, 0, 1, 1}
  1161. X    }
  1162. X};
  1163. X
  1164. Xstatic int      checkUp[NUM_BITMAPS] = {
  1165. X    0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7
  1166. X};
  1167. Xstatic int      checkDown[NUM_BITMAPS] = {
  1168. X    0, 1, 0, 1, 4, 5, 4, 5, 8, 9, 8, 9, 12, 13, 12, 13
  1169. X};
  1170. X
  1171. Xstatic char    *thingFGs[NUM_THINGS] = {
  1172. X    "Red", "ForestGreen", "Blue", "Magenta", "DarkTurquoise", "Brown", "Black"
  1173. X};
  1174. X
  1175. Xstatic Pixmap   pms[NUM_BITMAPS];
  1176. X
  1177. Xstatic thing_t  curThing, nextThing;
  1178. Xstatic struct {
  1179. X    int             pm_num, cid;
  1180. X}               field[ROWS][COLS];
  1181. X
  1182. X/* ------------------------------------------------------------------ */
  1183. X
  1184. Xint
  1185. Xnrand(n)
  1186. X    int             n;
  1187. X{
  1188. X    return (int) (LRAND() % n);
  1189. X}
  1190. X
  1191. X/* ------------------------------------------------------------------ */
  1192. X
  1193. Xunsigned long
  1194. XgetColor(name)
  1195. X    char            name[];
  1196. X{
  1197. X    XColor          tmp;
  1198. X
  1199. X    if (!useColor) {
  1200. X    return BlackPixel(display, screen_num);
  1201. X    }
  1202. X    if (XParseColor(display, colormap, name, &tmp) == 0) {
  1203. X    (void) fprintf(stderr, "Tetris: invalid color '%s'.\n", name);
  1204. X    return BlackPixel(display, screen_num);
  1205. X    }
  1206. X    if (XAllocColor(display, colormap, &tmp) == 0) {
  1207. X    (void) fprintf(stderr, "Tetris: can't allocate color '%s'.\n", name);
  1208. X    return BlackPixel(display, screen_num);
  1209. X    }
  1210. X    return tmp.pixel;
  1211. X}
  1212. X
  1213. X/* ------------------------------------------------------------------ */
  1214. X
  1215. Xvoid
  1216. Xinits(argc, argv)
  1217. X    int             argc;
  1218. X    char           *argv[];
  1219. X{
  1220. X    XSetWindowAttributes att;
  1221. X    unsigned int    attvm;
  1222. X    XTextProperty   wName, iName;
  1223. X    XClassHint      classhints;
  1224. X    XEvent          ev;
  1225. X    XGCValues       gcv;
  1226. X    unsigned long   gcvm;
  1227. X    int             i, j;
  1228. X
  1229. X    SRAND(time(NULL));
  1230. X
  1231. X    for (i = 0; i < COLS; i++)
  1232. X    for (j = 0; j < ROWS; j++)
  1233. X        if ((j >= ROWS - prefilled) && (nrand(2) == 0)) {
  1234. X        field[j][i].pm_num = 0;
  1235. X        field[j][i].cid = nrand(NUM_THINGS);
  1236. X        } else {
  1237. X        field[j][i].pm_num = -1;
  1238. X        field[j][i].cid = 0;
  1239. X        }
  1240. X
  1241. X    titleLen = strlen(MSG_TITLE);
  1242. X    titleWidth = XTextWidth(bigFont, MSG_TITLE, titleLen);
  1243. X    authorLen = strlen(MSG_AUTHOR);
  1244. X    authorWidth = XTextWidth(tinyFont, MSG_AUTHOR, authorLen);
  1245. X
  1246. X    frameW = BOXSIZE * COLS;
  1247. X    frameH = BOXSIZE * ROWS;
  1248. X    topRWidth = BOXSIZE * THINGSIZE + OFFSET * 2;
  1249. X    topHeight = frameH + OFFSET * 2 + 4;
  1250. X    if (titleWidth > topRWidth)
  1251. X    topRWidth = titleWidth;
  1252. X    if (authorWidth > topRWidth)
  1253. X    topRWidth = authorWidth;
  1254. X    topMidX = frameW + OFFSET * 2 + 4;
  1255. X    topMidY = topHeight / 2 + bigFont->ascent;
  1256. X    topWidth = topMidX + topRWidth;
  1257. X    frameX = frameY = OFFSET + 2;
  1258. X
  1259. X    titleX = (topRWidth - titleWidth) / 2 + topMidX;
  1260. X    titleY = OFFSET + 2 + bigFont->ascent;
  1261. X    authorX = (topRWidth - authorWidth) / 2 + topMidX;
  1262. X    authorY = OFFSET + 2 + bigFont->ascent + bigFont->descent + tinyFont->ascent;
  1263. X
  1264. X    sX = topMidX + OFFSET;
  1265. X    sScoreY = topHeight - OFFSET - 2 - tinyFont->descent;
  1266. X    sRowsY = sScoreY - tinyFont->descent - tinyFont->ascent - 2;
  1267. X    sLevelY = sRowsY - tinyFont->descent - tinyFont->ascent - 2;
  1268. X
  1269. X    sizehints.width = (sizehints.min_width =
  1270. X    (sizehints.max_width = topWidth));
  1271. X    sizehints.height = (sizehints.min_height =
  1272. X    (sizehints.max_height = topHeight));
  1273. X
  1274. X    theCursor = XCreateFontCursor(display, XC_exchange);
  1275. X
  1276. X    /* arrow keys */
  1277. X    XRebindKeysym(display, XK_R10, NULL, 0,
  1278. X    (unsigned char *) "j", sizeof(unsigned char));
  1279. X    XRebindKeysym(display, XK_Left, NULL, 0,
  1280. X    (unsigned char *) "j", sizeof(unsigned char));
  1281. X    XRebindKeysym(display, XK_R8, NULL, 0,
  1282. X    (unsigned char *) "k", sizeof(unsigned char));
  1283. X    XRebindKeysym(display, XK_Up, NULL, 0,
  1284. X    (unsigned char *) "k", sizeof(unsigned char));
  1285. X    XRebindKeysym(display, XK_R11, NULL, 0,
  1286. X    (unsigned char *) "k", sizeof(unsigned char));
  1287. X    XRebindKeysym(display, XK_R12, NULL, 0,
  1288. X    (unsigned char *) "l", sizeof(unsigned char));
  1289. X    XRebindKeysym(display, XK_Right, NULL, 0,
  1290. X    (unsigned char *) "l", sizeof(unsigned char));
  1291. X    XRebindKeysym(display, XK_Down, NULL, 0,
  1292. X    (unsigned char *) " ", sizeof(unsigned char));
  1293. X    XRebindKeysym(display, XK_R14, NULL, 0,
  1294. X    (unsigned char *) " ", sizeof(unsigned char));
  1295. X
  1296. X    /* create windows */
  1297. X    attvm = CWBackPixel | CWEventMask | CWDontPropagate | CWCursor;
  1298. X    att.background_pixel = bg;
  1299. X    att.event_mask = ExposureMask | KeyPressMask |
  1300. X    StructureNotifyMask | FocusChangeMask;
  1301. X    att.do_not_propagate_mask = KeyReleaseMask |
  1302. X    ButtonPressMask | ButtonReleaseMask | PointerMotionMask |
  1303. X    ButtonMotionMask | Button1MotionMask | Button2MotionMask |
  1304. X    Button3MotionMask | Button4MotionMask | Button5MotionMask;
  1305. X    att.cursor = theCursor;
  1306. X
  1307. X    mainWin = XCreateWindow(display, DefaultRootWindow(display),
  1308. X    sizehints.x, sizehints.y, topWidth, topHeight, 0,
  1309. X    CopyFromParent, InputOutput, CopyFromParent, attvm, &att);
  1310. X
  1311. X    attvm = CWBackPixel | CWBorderPixel | CWEventMask;
  1312. X    att.border_pixel = fg;
  1313. X    att.event_mask = ExposureMask;
  1314. X
  1315. X    blockWin = XCreateWindow(display, mainWin,
  1316. X    frameX-2, frameY-2, frameW, frameH, 2,
  1317. X    CopyFromParent, InputOutput, CopyFromParent, attvm, &att);
  1318. X
  1319. X    /* WM hints */
  1320. X    XStringListToTextProperty(&winName, 1, &wName);
  1321. X    XStringListToTextProperty(&iconName, 1, &iName);
  1322. X
  1323. X    wmhints.icon_pixmap = XCreateBitmapFromData(display,
  1324. X    mainWin, ticon_bits, ticon_width, ticon_height);
  1325. X    classhints.res_name = "tetris";
  1326. X    classhints.res_class = "Tetris";
  1327. X
  1328. X    XSetWMProperties(display, mainWin, &wName, &iName,
  1329. X    argv, argc, &sizehints, &wmhints, &classhints);
  1330. X
  1331. X    delw = XInternAtom(display, "WM_DELETE_WINDOW", False);
  1332. X    XSetWMProtocols(display, mainWin, &delw, 1);
  1333. X
  1334. X    /* GC's */
  1335. X
  1336. X    gcvm = GCForeground | GCBackground | GCFunction |
  1337. X    GCFont | GCGraphicsExposures;
  1338. X
  1339. X    gcv.function = GXcopy;
  1340. X    gcv.foreground = fg;
  1341. X    gcv.background = bg;
  1342. X    gcv.font = bigFont->fid;
  1343. X    gcv.graphics_exposures = False;
  1344. X    bigGC = XCreateGC(display, mainWin, gcvm, &gcv);
  1345. X
  1346. X    gcv.font = tinyFont->fid;
  1347. X    tinyGC = XCreateGC(display, mainWin, gcvm, &gcv);
  1348. X
  1349. X    gcv.foreground = bg;
  1350. X    gcv.background = fg;
  1351. X    revGC = XCreateGC(display, mainWin, gcvm, &gcv);
  1352. X
  1353. X    gcv.background = bg;
  1354. X    for (i = 0; i < NUM_THINGS; i++) {
  1355. X    gcv.foreground = getColor(thingFGs[i]);
  1356. X    if (gcv.foreground == bg)
  1357. X        gcv.foreground = fg;
  1358. X    thingGCs[i] = XCreateGC(display, blockWin, gcvm, &gcv);
  1359. X    }
  1360. X
  1361. X    gcv.foreground = fg;
  1362. X    gcv.function = GXxor;
  1363. X    xorGC = XCreateGC(display, blockWin, gcvm, &gcv);
  1364. X
  1365. X    /* pixmaps */
  1366. X
  1367. X    if (use3D)
  1368. X    for (i = 0; i < NUM_BITMAPS; i++) {
  1369. X        pms[i] = (Pixmap) XCreateBitmapFromData(display, blockWin,
  1370. X        bitmap_data_3d[i], BOXSIZE, BOXSIZE);
  1371. X    }
  1372. X    else for (i = 0; i < NUM_BITMAPS; i++) {
  1373. X        pms[i] = (Pixmap) XCreateBitmapFromData(display, blockWin,
  1374. X        bitmap_data_plain[i], BOXSIZE, BOXSIZE);
  1375. X    }
  1376. X
  1377. X    /* new things */
  1378. X    newThing();
  1379. X    newThing();
  1380. X
  1381. X    /* the last thing is to wait for mapped */
  1382. X    XMapWindow(display, blockWin);
  1383. X    XMapRaised(display, mainWin);
  1384. X    XNextEvent(display, &ev);
  1385. X}
  1386. X
  1387. X/* ------------------------------------------------------------------ */
  1388. X
  1389. Xvoid
  1390. XnewThing()
  1391. X{
  1392. X    curThing = nextThing;
  1393. X    nextThing = possible[nrand(range)][nrand(4)];
  1394. X    nextThing.xpos = nrand(COLS - nextThing.size + 1);
  1395. X    nextThing.ypos = 2 - nextThing.size;
  1396. X    nextThing.cid = (bonusMode) ? nrand(NUM_THINGS) : nextThing.px;
  1397. X}
  1398. X
  1399. X/* ------------------------------------------------------------------ */
  1400. X
  1401. Xvoid
  1402. XdrawTitle()
  1403. X{
  1404. X    XDrawString(display, mainWin, bigGC,
  1405. X    titleX, titleY, MSG_TITLE, titleLen);
  1406. X    XDrawString(display, mainWin, tinyGC,
  1407. X    authorX, authorY, MSG_AUTHOR, authorLen);
  1408. X}
  1409. X
  1410. X/* ------------------------------------------------------------------ */
  1411. X
  1412. Xvoid
  1413. XdrawStatus()
  1414. X{
  1415. X    char            buf[30];
  1416. X
  1417. X    (void) sprintf(buf, "Score: %d", score);
  1418. X    XDrawImageString(display, mainWin, tinyGC, sX, sScoreY, buf, strlen(buf));
  1419. X
  1420. X    (void) sprintf(buf, "Level: %d    ", level);
  1421. X    XDrawImageString(display, mainWin, tinyGC, sX, sLevelY, buf, strlen(buf));
  1422. X
  1423. X    (void) sprintf(buf, "Rows: %d", rows);
  1424. X    XDrawImageString(display, mainWin, tinyGC, sX, sRowsY, buf, strlen(buf));
  1425. X}
  1426. X
  1427. X/* ------------------------------------------------------------------ */
  1428. X
  1429. Xvoid
  1430. XdrawBox(win, pmid, cid, x, y)
  1431. X    Window          win;
  1432. X    int             pmid, cid, x, y;
  1433. X{
  1434. X    XCopyPlane(display, pms[pmid], win, thingGCs[cid], 0, 0,
  1435. X    BOXSIZE, BOXSIZE, x, y, (unsigned long) 1);
  1436. X}
  1437. X
  1438. X/* ------------------------------------------------------------------ */
  1439. X
  1440. Xstatic void
  1441. XclearBox(x, y)
  1442. X    int             x, y;
  1443. X{
  1444. X    XFillRectangle(display, blockWin, revGC, x, y, BOXSIZE, BOXSIZE);
  1445. X}
  1446. X
  1447. X/* ------------------------------------------------------------------ */
  1448. X
  1449. Xvoid
  1450. XdrawField()
  1451. X{
  1452. X    int             i, j;
  1453. X
  1454. X    for (i = 0; i < COLS; i++)
  1455. X    for (j = 0; j < ROWS; j++)
  1456. X        if (field[j][i].pm_num >= 0)
  1457. X        drawBox(blockWin, field[j][i].pm_num, field[j][i].cid,
  1458. X            i * BOXSIZE, j * BOXSIZE);
  1459. X}
  1460. X
  1461. X/* ------------------------------------------------------------------ */
  1462. X
  1463. Xvoid
  1464. XdrawThing()
  1465. X{
  1466. X    int             i, j;
  1467. X
  1468. X    for (i = 0; i < curThing.size; i++)
  1469. X    for (j = 0; j < curThing.size; j++)
  1470. X        if ((curThing.ypos + j >= 0) && curThing.map[j][i])
  1471. X        drawBox(blockWin, curThing.map[j][i], curThing.cid,
  1472. X            (curThing.xpos + i) * BOXSIZE,
  1473. X            (curThing.ypos + j) * BOXSIZE);
  1474. X}
  1475. X
  1476. X/* ------------------------------------------------------------------ */
  1477. X
  1478. Xvoid
  1479. XdrawThingDiff(old)
  1480. X    thing_t        *old;
  1481. X{
  1482. X    int             i, j, ox, oy;
  1483. X
  1484. X    for (i = 0; i < curThing.size; i++)
  1485. X    for (j = 0; j < curThing.size; j++)
  1486. X        if ((curThing.ypos + j >= 0) && curThing.map[j][i])
  1487. X        drawBox(blockWin, curThing.map[j][i], curThing.cid,
  1488. X            (curThing.xpos + i) * BOXSIZE,
  1489. X            (curThing.ypos + j) * BOXSIZE);
  1490. X
  1491. X    for (i = 0; i < curThing.size; i++)
  1492. X    for (j = 0; j < curThing.size; j++) {
  1493. X        ox = old->xpos + i - curThing.xpos;
  1494. X        oy = old->ypos + j - curThing.ypos;
  1495. X        if ((old->ypos + j >= 0) && old->map[j][i] && 
  1496. X            ((ox < 0) || (ox >= curThing.size) ||
  1497. X            (oy < 0) || (oy >= curThing.size) ||
  1498. X            !curThing.map[oy][ox]))
  1499. X        clearBox((old->xpos + i) * BOXSIZE, (old->ypos + j) * BOXSIZE);
  1500. X    }
  1501. X}
  1502. X
  1503. X/* ------------------------------------------------------------------ */
  1504. X
  1505. Xvoid
  1506. XdrawNext()
  1507. X{
  1508. X    int             x, y;
  1509. X    int             i, j;
  1510. X
  1511. X    x = topMidX + (topRWidth - nextThing.size * BOXSIZE) / 2;
  1512. X    y = topMidY - nextThing.size * BOXSIZE / 2;
  1513. X    for (i = 0; i < nextThing.size; i++)
  1514. X    for (j = 0; j < nextThing.size; j++)
  1515. X        if (nextThing.map[j][i])
  1516. X        drawBox(mainWin, nextThing.map[j][i], nextThing.cid,
  1517. X        x + i * BOXSIZE, y + j * BOXSIZE);
  1518. X}
  1519. X
  1520. X/* ------------------------------------------------------------------ */
  1521. X
  1522. Xvoid
  1523. XclearNext()
  1524. X{
  1525. X    XFillRectangle(display, mainWin, revGC,
  1526. X    topMidX, topMidY - BOXSIZE * 2, topRWidth, BOXSIZE * 4);
  1527. X}
  1528. X
  1529. X/* ------------------------------------------------------------------ */
  1530. X
  1531. Xvoid
  1532. Xbanner(msg)
  1533. X    char            msg[];
  1534. X{
  1535. X    int             mlen = strlen(msg);
  1536. X    int             w = XTextWidth(bigFont, msg, mlen);
  1537. X    int             x = (topRWidth - w)/2 + topMidX;
  1538. X
  1539. X    clearNext();
  1540. X    XFillRectangle(display, mainWin, revGC,
  1541. X    x - 60, topMidY - bigFont->ascent - 5,
  1542. X    w + 120, bigFont->ascent + bigFont->descent + 10);
  1543. X    XDrawString(display, mainWin, bigGC, x, topMidY, msg, mlen);
  1544. X}
  1545. X
  1546. X/* ------------------------------------------------------------------ */
  1547. X
  1548. Xvoid
  1549. XputBox()
  1550. X{
  1551. X    int             i, j;
  1552. X    int             x = curThing.xpos, y = curThing.ypos;
  1553. X
  1554. X    for (i = 0; i < curThing.size; i++)
  1555. X    for (j = 0; j < curThing.size; j++)
  1556. X        if ((y + j >= 0) && curThing.map[j][i]) {
  1557. X        field[y + j][x + i].pm_num = curThing.map[j][i];
  1558. X        field[y + j][x + i].cid = curThing.cid;
  1559. X        }
  1560. X}
  1561. X
  1562. X/* ------------------------------------------------------------------ */
  1563. X
  1564. XBool
  1565. Xoverlapping()
  1566. X{
  1567. X    int             i, j;
  1568. X    int             x = curThing.xpos, y = curThing.ypos;
  1569. X
  1570. X    for (i = 0; i < curThing.size; i++)
  1571. X    for (j = 0; j < curThing.size; j++)
  1572. X        if (curThing.map[j][i]) {
  1573. X        if ((y + j >= ROWS) || (x + i < 0) || (x + i >= COLS))
  1574. X            return True;
  1575. X        if ((y + j >= 0) && (field[y + j][x + i].pm_num >= 0))
  1576. X            return True;
  1577. X        }
  1578. X
  1579. X    return False;
  1580. X}
  1581. X
  1582. X/* ------------------------------------------------------------------ */
  1583. X
  1584. XBool
  1585. XatBottom()
  1586. X{
  1587. X    int             i, j;
  1588. X    int             x = curThing.xpos, y = curThing.ypos;
  1589. X
  1590. X    for (i = 0; i < curThing.size; i++)
  1591. X    for (j = 0; j < curThing.size; j++)
  1592. X        if ((y + j >= 0) && curThing.map[j][i]) {
  1593. X        if ((y + j >= ROWS - 1) || (x + i < 0) || (x + i >= COLS))
  1594. X            return True;
  1595. X        if (field[y + j + 1][x + i].pm_num >= 0)
  1596. X            return True;
  1597. X        }
  1598. X
  1599. X    return False;
  1600. X}
  1601. X
  1602. X/* ------------------------------------------------------------------ */
  1603. X
  1604. Xvoid
  1605. XtryMove(move)
  1606. X    move_t          move;
  1607. X{
  1608. X    thing_t         old;
  1609. X    Bool            canMove = False;
  1610. X
  1611. X    old = curThing;
  1612. X
  1613. X    switch (move) {
  1614. X    case FALL:
  1615. X    curThing.ypos ++;
  1616. X    break;
  1617. X
  1618. X    case DROP:
  1619. X    do {
  1620. X        curThing.ypos ++;
  1621. X        score += level + prefilled;
  1622. X    } while (!overlapping());
  1623. X    curThing.ypos --;
  1624. X    score += (bonusMode ? 3 : 1) * level;
  1625. X    break;
  1626. X
  1627. X    case ROTATE:
  1628. X    curThing = possible[old.px][(old.py + 1) % 4];
  1629. X    /* xpos, ypos, cid got overwritten */
  1630. X    curThing.xpos = old.xpos + old.gy - curThing.gy;
  1631. X    curThing.ypos = old.ypos + old.gx - curThing.gx;
  1632. X    curThing.cid = old.cid;
  1633. X    break;
  1634. X
  1635. X    case LEFT:
  1636. X    curThing.xpos --;
  1637. X    break;
  1638. X
  1639. X    case RIGHT:
  1640. X    curThing.xpos ++;
  1641. X    break;
  1642. X
  1643. X    case REFLECT:
  1644. X    break;
  1645. X    }
  1646. X
  1647. X    if (overlapping()) {
  1648. X    if (move == ROTATE) {
  1649. X        while (!canMove && (curThing.xpos + curThing.size >= COLS)) {
  1650. X        curThing.xpos --;
  1651. X        canMove = !overlapping();
  1652. X            }
  1653. X        while (!canMove && (curThing.xpos < 0)) {
  1654. X        curThing.xpos ++;
  1655. X        canMove = !overlapping();
  1656. X            }
  1657. X    }
  1658. X    } else
  1659. X        canMove = True;
  1660. X
  1661. X    if (canMove)
  1662. X    drawThingDiff(&old);
  1663. X    else
  1664. X    curThing = old;
  1665. X}
  1666. X
  1667. X/* ------------------------------------------------------------------ */
  1668. X
  1669. Xint
  1670. XcheckLines()
  1671. X{
  1672. X    int             lSet[ROWS], nset = 0;
  1673. X    int             i, j, y;
  1674. X
  1675. X    for (j = 0; j < ROWS; j++) {
  1676. X    lSet[j] = 0;
  1677. X    for (i = 0; i < COLS; i++)
  1678. X        if (field[j][i].pm_num >= 0)
  1679. X        lSet[j] ++;
  1680. X    if (lSet[j] == COLS)
  1681. X        nset ++;
  1682. X    }
  1683. X
  1684. X    if (nset) {
  1685. X    for (i = 0; i < ((NUM_FLASHES / nset) % 2) * 2; i ++) {
  1686. X        for (j = 0; j < ROWS; j++) {
  1687. X        if (lSet[j] == COLS)
  1688. X            XFillRectangle(display, blockWin, xorGC,
  1689. X            0, j * BOXSIZE, frameW, BOXSIZE);
  1690. X        }
  1691. X        XFlush(display);
  1692. X    }
  1693. X
  1694. X    for (j = ROWS-1; j >= 0; j--) {
  1695. X        if (lSet[j] == COLS) {
  1696. X        for (y = j; y > 0; y--)
  1697. X            for (i = 0; i < COLS; i++)
  1698. X            field[y][i] = field[y-1][i];
  1699. X        for (i = 0; i < COLS; i++)
  1700. X            field[0][i].pm_num = -1;
  1701. X
  1702. X        XCopyArea(display, blockWin, blockWin, tinyGC,
  1703. X            0, 0, frameW, j * BOXSIZE, 0, BOXSIZE);
  1704. X        
  1705. X        XFillRectangle(display, blockWin, revGC,
  1706. X            0, 0, frameW, BOXSIZE);
  1707. X
  1708. X        for (i = j; i > 0; i--)
  1709. X            lSet[i] = lSet[i-1];
  1710. X        lSet[0] = 0;
  1711. X
  1712. X        if (j > 0)
  1713. X            for (i = 0; i < COLS; i++) {
  1714. X            int             tmp = field[j][i].pm_num;
  1715. X            if ((tmp >= 0) && (tmp != checkDown[tmp])) {
  1716. X                field[j][i].pm_num = checkDown[tmp];
  1717. X                drawBox(blockWin, field[j][i].pm_num,
  1718. X                field[j][i].cid, i * BOXSIZE, j * BOXSIZE);
  1719. X            }
  1720. X            }
  1721. X
  1722. X        j++;
  1723. X
  1724. X        if (j < ROWS)
  1725. X            for (i = 0; i < COLS; i++) {
  1726. X            int             tmp = field[j][i].pm_num;
  1727. X            if ((tmp >= 0) && (tmp != checkUp[tmp])) {
  1728. X                field[j][i].pm_num = checkUp[tmp];
  1729. X                drawBox(blockWin, field[j][i].pm_num,
  1730. X                field[j][i].cid, i * BOXSIZE, j * BOXSIZE);
  1731. X            }
  1732. X            }
  1733. X
  1734. X        XFlush(display);
  1735. X        }
  1736. X    }
  1737. X
  1738. X    if (beep) XBell(display, BVOLUME);
  1739. X    XSync(display, False);
  1740. X    }
  1741. X
  1742. X    return nset;
  1743. X}
  1744. X
  1745. X/* ------------------------------------------------------------------ */
  1746. X
  1747. Xvoid
  1748. XrealTime(tv)
  1749. X    struct timeval *tv;
  1750. X{
  1751. X    while (tv->tv_usec < 0) {
  1752. X    tv->tv_sec --;
  1753. X    tv->tv_usec += MILLION;
  1754. X    }
  1755. X    while (tv->tv_usec >= MILLION) {
  1756. X    tv->tv_sec ++;
  1757. X    tv->tv_usec -= MILLION;
  1758. X    }
  1759. X}
  1760. X
  1761. X/* ------------------------------------------------------------------ */
  1762. END_OF_FILE
  1763. if test 25559 -ne `wc -c <'utils.c'`; then
  1764.     echo shar: \"'utils.c'\" unpacked with wrong size!
  1765. fi
  1766. # end of 'utils.c'
  1767. fi
  1768. echo shar: End of archive 1 \(of 3\).
  1769. cp /dev/null ark1isdone
  1770. MISSING=""
  1771. for I in 1 2 3 ; do
  1772.     if test ! -f ark${I}isdone ; then
  1773.     MISSING="${MISSING} ${I}"
  1774.     fi
  1775. done
  1776. if test "${MISSING}" = "" ; then
  1777.     echo You have unpacked all 3 archives.
  1778.     rm -f ark[1-9]isdone
  1779. else
  1780.     echo You still need to unpack the following archives:
  1781.     echo "        " ${MISSING}
  1782. fi
  1783. ##  End of shell archive.
  1784. exit 0
  1785.