home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / HACKSRC.ZIP / MSDOS.C < prev    next >
Text File  |  1985-10-27  |  14KB  |  650 lines

  1. /* An assortment of MSDOS functions.
  2.  */
  3.  
  4. #include <stdio.h>
  5. #include "hack.h"
  6.  
  7. #ifdef MSDOS
  8. #include <dos.h>
  9.  
  10. getuid()
  11. {
  12.     return 1;
  13. }
  14.  
  15. char *
  16. getlogin()
  17. {
  18.     return ((char *) NULL);
  19. }
  20.  
  21. #define VIDEO 0x10
  22. int display_page = -1;
  23.  
  24. void
  25. fastat(x, y, ch)
  26. register xchar x,y;
  27. char ch;
  28. {
  29.     union REGS inregs;
  30.  
  31.     if(!ch) {
  32.         impossible("At gets null at %d %d.", x, y);
  33.         return;
  34.     }
  35.     if (display_page < 0) {
  36.         inregs.h.ah = 15;
  37.         int86(VIDEO, &inregs, &inregs);
  38.         display_page = inregs.h.bh;
  39.     }
  40.     if (x != curx || y != cury) {
  41.         inregs.h.ah = 2;
  42.         inregs.h.dl = x - 1;
  43.         inregs.h.dh = y + 1;
  44.         inregs.h.bh = display_page;
  45.         int86(VIDEO, &inregs, &inregs);
  46.         curx = x;
  47.         cury = y;
  48.     }
  49.     inregs.h.ah = 14;
  50.     inregs.h.al = ch;
  51.     inregs.h.bh = display_page;
  52.     inregs.x.cx = 1;
  53.     int86(VIDEO, &inregs, &inregs);
  54.     curx++;
  55. }
  56.  
  57. tgetch()
  58. {
  59.     char ch;
  60. #ifdef DGK
  61.     if (flags.BIOSok)
  62.         ch = BIOSgetch();
  63.     else
  64. #endif DGK
  65.         ch = getch();
  66.     return ((ch == '\r') ? '\n' : ch);
  67. }
  68.  
  69.  
  70. #ifdef DGK
  71. #include <sys/types.h>
  72. #include <sys/stat.h>
  73. #include <sys/utime.h>
  74. #include <ctype.h>
  75. #include <fcntl.h>
  76.  
  77. #undef creat    /* Note that creat() is used once in this file, but
  78.          * the disk free space doesn't need not be checked as
  79.          * it will have already been checked.  Thus the undef
  80.          * can occur here.
  81.          */
  82.  
  83. #define LEVELS    "level.00"
  84. #define BONES    "bones.00"
  85. #define Sprintf (void) sprintf
  86.  
  87. extern char hackdir[], levels[], SAVEF[], bones[], permbones[];
  88. extern int ramdisk;
  89.  
  90. #ifdef SHELL
  91. #include <process.h>
  92. dosh()
  93. {
  94.     char *comspec, *getenv();
  95.     extern char orgdir[];
  96.  
  97.     if (comspec = getenv("COMSPEC")) {
  98.         end_screen();
  99.         clear_screen();
  100.         puts("To return to HACK, type \"exit\" at the DOS prompt.");
  101.         fflush(stdout);
  102.         chdirx(orgdir, 0);
  103.         if (spawnl(P_WAIT, comspec, NULL)) {
  104.             printf("\nCan't execute COMSPEC \"%s\"!\n", comspec);
  105.             flags.toplin = 0;
  106.             more();
  107.         }
  108.         chdirx(hackdir, 0);
  109.         start_screen();
  110.         docrt();
  111.     }
  112.     return(0);
  113. }
  114. #endif SHELL
  115.  
  116. /* Map the keypad to equivalent character output.  If scroll lock is turned
  117.  * on, run without stopping at interesting branches (like YUHJKLBN keys), if
  118.  * it is off, run with stopping at branches (like ^Y^U^H^J^K^L^B^N keys).
  119.  */
  120. #define KEYPADHI    83
  121. #define KEYPADLOW    71
  122. #define CTRL(ch)    (ch ^ 0x40)
  123. #define KEYBRD    0x16
  124. #define iskeypad(x)    (KEYPADLOW <= (x) && (x) <= KEYPADHI)
  125. #define SHIFT        (0x1 | 0x2)
  126. #define CONTROL        0x4
  127. static struct {
  128.     char normal, shift, ctrl;
  129.     } keypad[KEYPADHI - KEYPADLOW + 1] = {
  130.             {'y', 'Y', CTRL('Y')},    /* 7 */
  131.             {'k', 'K', CTRL('K')},    /* 8 */
  132.             {'u', 'U', CTRL('U')},    /* 9 */
  133.             {'m', 'M', 'M'},    /* - */
  134.             {'h', 'H', CTRL('H')},    /* 4 */
  135.             {'.', '.', '.'},    /* 5 */
  136.             {'l', 'L', CTRL('L')},    /* 6 */
  137.             {'p', 'P', CTRL('P')},    /* + */
  138.             {'b', 'B', CTRL('B')},    /* 1 */
  139.             {'j', 'J', CTRL('J')},    /* 2 */
  140.             {'n', 'N', CTRL('N')},    /* 3 */
  141.             {'i', 'I', 'I'},    /* Ins */
  142.             {':', ',', ','}        /* Del */
  143.             };
  144. static char
  145. BIOSgetch()
  146. {
  147.     char scan, shift_state, ch;
  148.     union REGS inregs, outregs;
  149.  
  150.     do {
  151.         inregs.h.ah = 0;
  152.         int86(KEYBRD, &inregs, &outregs);
  153.     } while (outregs.x.ax == 0);
  154.     ch = outregs.h.al;
  155.     scan = outregs.h.ah;
  156.     inregs.h.ah = 2;
  157.     int86(KEYBRD, &inregs, &outregs);
  158.     shift_state = outregs.h.al;
  159.  
  160.     if (iskeypad(scan))
  161.         if (shift_state & SHIFT)
  162.             ch = keypad[scan - KEYPADLOW].shift;
  163.         else if (shift_state & CONTROL)
  164.             ch = keypad[scan - KEYPADLOW].ctrl;
  165.         else
  166.             ch = keypad[scan - KEYPADLOW].normal;
  167.     return (ch);
  168. }
  169.  
  170. dotogglepickup()
  171. {
  172.     flags.pickup = !flags.pickup;
  173.     pline("Pickup: %s.", flags.pickup ? "ON" : "OFF");
  174.     return (0);
  175. }
  176.  
  177. /* from objects.h
  178. char obj_symbols[] = {
  179.     ILLOBJ_SYM, AMULET_SYM, FOOD_SYM, WEAPON_SYM, TOOL_SYM,
  180.     BALL_SYM, CHAIN_SYM, ROCK_SYM, ARMOR_SYM, POTION_SYM, SCROLL_SYM,
  181.     WAND_SYM, RING_SYM, GEM_SYM, 0 };
  182.  */
  183. extern char obj_symbols[];
  184. static char *names[] = {"Illegal objects", "Amulets", "Edibles", "Weapons",
  185.             "Tools", "Iron balls", "Chains", "Rocks", "Armor",
  186.             "Potions", "Scrolls", "Wands", "Rings", "Gems"};
  187. char *
  188. let_to_name(let)
  189. char let;
  190. {
  191.     char *pos = index(obj_symbols, let);
  192.     extern char *HI, *HE;
  193.     /* buffer size is len(HI) + len(HE) + max len(names[]) + 1 */
  194.     static char buf[4 + 4 + 15 + 1];
  195.  
  196.     if (pos == NULL)
  197.         pos = obj_symbols;
  198.     Sprintf(buf, "%s%s%s", HI, names[pos - obj_symbols], HE);
  199.     return (buf);
  200. }
  201.  
  202. /* After changing the value of flags.invlet_constant, make the current
  203.  * inventory letters the fixed ones. -dgk
  204.  */
  205. void
  206. fixinv()
  207. {
  208.     struct obj *otmp;
  209.     extern int lastinvnr;
  210.     char ilet = 'a';
  211.  
  212.     for(otmp = invent; otmp; otmp = otmp->nobj) {
  213.         otmp->invlet = ilet;
  214.         if (++ilet > 'z') ilet = 'A';
  215.     }
  216.     lastinvnr = 51;
  217. }
  218.  
  219. /* construct the string  file.level 
  220.  * This assumes there is space on the end of 'file' to append
  221.  * a two digit number.  This is true for 'bones' and 'level'
  222.  * but be careful if you use it for other things -dgk
  223.  */
  224. void
  225. name_file(file, level)
  226. char *file;
  227. int level;
  228. {
  229.     char *tf;
  230.     
  231.     if (tf = rindex(file, '.'))
  232.         Sprintf(tf+1, "%d", level);
  233. }
  234.  
  235. long
  236. freediskspace(path)
  237. char *path;
  238. {
  239.     int drive = 0;
  240.     union    REGS    inregs;
  241.     union    REGS    outregs;
  242.  
  243.     inregs.h.ah = 0x36;    /* get free space -- DOS 2.0 page D-33 */
  244.     if (path[0] && path[1] == ':')
  245.         drive = (toupper(path[0]) - 'A') + 1;
  246.     inregs.h.dl = drive;
  247.     intdos(&inregs, &outregs);
  248.     if (outregs.x.ax == 0xFFFF)
  249.         return (-1);        /* bad drive number */
  250.     return ((long) outregs.x.bx * outregs.x.cx * outregs.x.ax);
  251. }
  252.  
  253. long
  254. filesize(file)
  255. char *file;
  256. {
  257.     struct stat buf;
  258.  
  259.     if (stat(file, &buf) == 0)
  260.         return (buf.st_size);
  261.     else
  262.         return (-1L);
  263. }
  264.  
  265. long
  266. all_files_size(path)
  267. char *path;
  268. {
  269.     register int level;
  270.     long size, tmp;
  271.     char buf[PATHLEN];
  272.  
  273.     strcpy(buf, path);
  274.     for (level = 1, size = 0; level <= MAXLEVEL; level++) {
  275.         name_file(buf, level);
  276.         tmp = filesize(buf);
  277.         if (tmp > 0)
  278.             size += tmp;
  279.     }
  280.     return (size);
  281. }
  282.  
  283. void
  284. copybones(mode)
  285. int mode;
  286. {
  287.     register int fd, level;
  288.     char from[PATHLEN], to[PATHLEN];
  289.     long sizes[MAXLEVEL + 1];
  290.     extern boolean level_exists[];
  291.  
  292.     if (!ramdisk)
  293.         return;
  294.     strcpy(to, (mode == TOPERM) ? permbones : bones);
  295.     strcpy(from, (mode == TOPERM) ? bones : permbones);
  296.  
  297.     for (level = 1; level <= MAXLEVEL; level++) {
  298.         name_file(from, level);
  299.         sizes[level] = filesize(from);    /* -1 if file doesn't exist */
  300.         name_file(to, level);
  301.         (void) unlink(to);    /* remove old bones files in 'to' */
  302.     }
  303.     for (level = 1; level <= MAXLEVEL; level++) {
  304.         if (sizes[level] == -1L)
  305.             continue;
  306.         name_file(from, level);
  307.         name_file(to, level);
  308.         if (sizes[level] > freediskspace(to)) {
  309.             fprintf(stderr,
  310.                 "Not enough room to copy file '%s' to '%s'.\n",
  311.                 from, to);
  312.             goto cleanup;
  313.         }
  314.         /* We use savelev and getlev to move the bones files around,
  315.          * but savelev sets level_exists[] TRUE for this level, so
  316.          * we have to set it back FALSE again.
  317.          */
  318.         if ((fd = open(from, 0)) < 0) {
  319.             fprintf(stderr, "Warning: can't open '%s'.\n", from);
  320.             continue;
  321.         } else {
  322.             sizes[level] = 0;    /* 'from' bones exists */
  323.             getlev(fd, 0, level);
  324.             (void) close(fd);
  325.             if ((fd = creat(to, FMASK)) < 0) {
  326.                 fprintf(stderr,
  327.                     "Warning: can't create '%s'.\n", to);
  328.                 continue;
  329.             } else {
  330.                 savelev(fd, level);
  331.                 (void) close(fd);
  332.                 level_exists[level] = FALSE;    /* see above */
  333.             }
  334.         }
  335.     }
  336.     /* If we are copying bones files back to permanent storage, unlink
  337.      * the bones files in the LEVELS directory.
  338.      */
  339.     if (mode == TOPERM)
  340.         for (level = 1; level <= MAXLEVEL; level++) {
  341.             if (sizes[level] == -1)
  342.                 continue;
  343.             name_file(from, level);
  344.             (void) unlink(from);
  345.         }
  346.     return;
  347.  
  348. cleanup:
  349.     /* Ran out of disk space!  Unlink the "to" files and issue an
  350.      * appropriate message.
  351.      */
  352.     for (level = 1; level <= MAXLEVEL; level++)
  353.         if (sizes[level] == 0) {
  354.             name_file(to, level);
  355.             (void) unlink(to);
  356.         }
  357.     fprintf(stderr, "There is not enough room in ");
  358.     if (mode == TOPERM) {
  359.         fprintf(stderr, "permanent storage for bones files!\n");
  360.         fprintf(stderr,
  361.             "Bones will be left in LEVELS directory '%s'!\n",
  362.             levels[0] ? levels : ".");
  363.             return;
  364.     } else {
  365.         fprintf(stderr,    "LEVELS directory '%s' to copy bones files!\n",
  366.             levels[0] ? levels : ".");
  367.         getreturn("to quit");
  368.         settty("Be seeing you ...\n");
  369.         exit(0);
  370.     }
  371. }
  372.  
  373. saveDiskPrompt(start)
  374. int start;
  375. {
  376.     extern saveprompt;
  377.     char buf[BUFSIZ];
  378.     int i, newname = FALSE;
  379.  
  380.     if (saveprompt) {
  381.         remember_topl();
  382.         home();
  383.         cl_end();
  384.         printf("If save file is on a SAVE disk, put that disk in now.\n");
  385.         cl_end();
  386.         printf("Name of save file (default: '%s'%s) ? ", SAVEF,
  387.             start ? "" : ", <Esc> aborts save");
  388.         fflush(stdout);
  389.         getlin(buf);
  390.         if (!start && buf[0] == '\033') {
  391.             home();
  392.             cl_end();
  393.             curs(1, 2);
  394.             cl_end();
  395.             return 0;
  396.         }
  397.         for (i = 0; buf[i]; i++)
  398.             if (!isspace(buf[i])) {
  399.                 strncpy(SAVEF, buf, PATHLEN);
  400.                 break;
  401.             }
  402.     }
  403.     return 1;
  404. }
  405.  
  406. /* Prompt for the game disk, then check if you can access the record file.
  407.  * If not, warn the player.
  408.  */
  409. void
  410. gameDiskPrompt()
  411. {
  412.     FILE    *fp;
  413.     extern saveprompt;
  414.  
  415.     if (saveprompt) {
  416.         fputc('\n', stderr);
  417.         getreturn("when the GAME disk is ready");
  418.     }
  419.     if ((fp = fopen(RECORD, "r")))    /* check for GAME disk */
  420.         fclose(fp);
  421.     else {
  422.         fprintf(stderr,
  423.             "\n\nWARNING: I can't find record file '%s'!\n",
  424.              RECORD);
  425.         fprintf(stderr,
  426.             "If the GAME disk is not in, put it in now.\n");
  427.         getreturn("to continue");
  428.     }
  429. }
  430.  
  431. #define CONFIGFILE    "hack103.cnf"
  432. void
  433. read_config_file()
  434. {
  435.     char    config[FILENAME], tmp_ramdisk[PATHLEN], tmp_levels[PATHLEN];
  436.     char    buf[BUFSZ], *bufp;
  437.     FILE    *fp;
  438.     extern    char plname[];
  439.     extern    int saveprompt;
  440.  
  441.     tmp_ramdisk[0] = 0;
  442.     tmp_levels[0] = 0;
  443.     strcpy(config, hackdir);
  444.     append_slash(config);
  445.     strcat(config, CONFIGFILE);
  446.     if (!(fp = fopen(config, "r"))) {
  447.         fprintf(stderr, "Warning: no configuration file '%s'!\n",
  448.             config);
  449.         getreturn("to continue");
  450.         return;
  451.     }
  452.     while (fgets(buf, BUFSZ, fp)) {
  453.         if (*buf == '#')        /* comment first character */
  454.             continue;
  455.  
  456.         /* remove any trailing whitespace
  457.          */
  458.         bufp = index(buf, '\n');
  459.         while (bufp > buf && isspace(*bufp))
  460.             bufp--;
  461.         if (bufp == buf)
  462.             continue;        /* skip all-blank lines */
  463.         else
  464.             *(bufp + 1) = 0;    /* 0 terminate line */
  465.  
  466.         /* find the '=' separating option name from option value
  467.          */
  468.         if (!(bufp = strchr(buf, '='))) {
  469.             fprintf(stderr, "Bad option line: '%s'\n", buf);
  470.             getreturn("to continue");
  471.             continue;
  472.         }
  473.         
  474.         /* move past whitespace between '=' and option value
  475.          */
  476.         while (isspace(*++bufp))
  477.             ;
  478.  
  479.         /* Now go through the possible configurations
  480.          */
  481.         if (!strncmp(buf, "RAMDISK", 3)) {
  482.             strncpy(tmp_ramdisk, bufp, PATHLEN);
  483.  
  484.         } else if (!strncmp(buf, "LEVELS", 4)) {
  485.             strncpy(tmp_levels, bufp, PATHLEN);
  486.  
  487.         } else if (!strncmp(buf, "OPTIONS", 4)) {
  488.             parseoptions(bufp, TRUE);
  489.             if (plname[0])        /* If a name was given */
  490.                 plnamesuffix();    /* set the character class */
  491.  
  492.         } else if (!strncmp(buf, "SAVE", 4)) {
  493.             char *ptr;
  494.             if (ptr = index(bufp, ';')) {
  495.                 *ptr = '\0';
  496.                 if (*(ptr+1) == 'n' || *(ptr+1) == 'N')
  497.                     saveprompt = FALSE;
  498.             }
  499.             (void) strncpy(SAVEF, bufp, PATHLEN);
  500.             append_slash(SAVEF);
  501.  
  502.         } else if (!strncmp(buf, "GRAPHICS", 4)) {
  503.             struct symbols s;
  504.  
  505.             if (sscanf(bufp, "%u%u%u%u%u%u%u%u%u", &s.vwall,
  506.                     &s.hwall, &s.tlcorn, &s.trcorn, &s.blcorn,
  507.                     &s.brcorn, &s.door, &s.room, &s.corr) == 9)
  508.                 symbol = s;
  509.             else {
  510.                 fprintf(stderr,
  511.                     "GRAPHICS did not contain 9 values\n");
  512.                 getreturn("to continue");
  513.             }
  514.  
  515.         } else if (!strncmp(buf, "DISPLAY", 4)) {
  516.             /* There was a variable called DISPLAY which never
  517.              * work very well and was too confusing.  Leave this
  518.              * code in here for now for 'backward compatibility'.
  519.              */
  520.             ;
  521.  
  522.         } else {
  523.             fprintf(stderr, "Bad option line: '%s'\n", buf);
  524.             getreturn("to continue");
  525.         }
  526.     }
  527.     fclose(fp);
  528.  
  529.     strcpy(permbones, tmp_levels);
  530.     if (tmp_ramdisk[0]) {
  531.         strcpy(levels, tmp_ramdisk);
  532.         if (strcmpi(permbones, levels))        /* if not identical */
  533.             ramdisk = TRUE;
  534.     } else
  535.         strcpy(levels, tmp_levels);
  536.     strcpy(bones, levels);
  537. }
  538.  
  539. void
  540. set_lock_and_bones()
  541. {
  542.     if (!ramdisk) {
  543.         strcpy(levels, permbones);
  544.         strcpy(bones, permbones);
  545.     }
  546.     append_slash(bones);
  547.     strcat(bones, BONES);
  548.     append_slash(permbones);
  549.     strcat(permbones, BONES);
  550.     strcpy(lock, levels);
  551.     append_slash(lock);
  552.     strcat(lock, LEVELS);
  553. }
  554.  
  555. void
  556. append_slash(name)
  557. char *name;
  558. {
  559.     char *ptr;
  560.  
  561.     if (!name[0])
  562.         return;
  563.     ptr = name + (strlen(name) - 1);
  564.     if (*ptr != '\\' && *ptr != '/' && *ptr != ':') {
  565.         *(ptr + 1) = '\\';
  566.         *(ptr + 2) = 0;
  567.     }
  568. }
  569.  
  570.  
  571. check_then_creat(file, pmode)
  572. char *file;
  573. int pmode;
  574. {
  575.     long freespace = freediskspace(file);
  576.     extern boolean restoring;
  577.  
  578.     if (freespace < 0)
  579.         return (-1);
  580.     if (!restoring && freespace < 8000L) {
  581.         pline("HACK is almost out of disk space for making levels!");
  582.         pline("You should save the game now.  Save this game [y/n] ?");
  583.         fflush(stdout);
  584.         if (getchar() == 'y')
  585.             dosave();
  586.         return(-1);    /* In case he decides not to save don't let him
  587.                  * change levels
  588.                  */
  589.     }
  590.     return( creat(file, pmode));
  591. }
  592.  
  593. void
  594. getreturn(str)
  595. char *str;
  596. {
  597.     int ch;
  598.  
  599.     fprintf(stderr, "Hit <RETURN> %s.", str);
  600.     while ((ch = getchar()) != '\n')
  601.         putch(ch);
  602. }
  603.  
  604. #define SELECTDISK    0xE
  605. void
  606. chdrive(str)
  607. char *str;
  608. {
  609.     char *ptr;
  610.     union REGS inregs;
  611.     char drive;
  612.  
  613.     if ((ptr = index(str, ':')) != NULL) {
  614.         drive = toupper(*(ptr - 1));
  615.         inregs.h.ah = SELECTDISK;
  616.         inregs.h.dl = drive - 'A';
  617.         intdos(&inregs, &inregs);
  618.     }
  619. }
  620.  
  621. #endif DGK
  622.  
  623. /* Do a chdir back to the original directory
  624.  */
  625. #undef exit
  626. #if defined(MSDOS) && defined(LINT_ARGS)
  627. void
  628. #endif
  629. msexit(code)
  630. {
  631. #ifdef CHDIR
  632.     extern char orgdir[];
  633. #endif CHDIR
  634.  
  635. #ifdef DGK
  636.     fflush(stdout);
  637.     if (ramdisk)
  638.         copybones(TOPERM);
  639. #endif DGK
  640. #ifdef CHDIR
  641.     chdir(orgdir);    /* do the chdir, but not with chdirx */
  642. #    ifdef DGK
  643.         chdrive(orgdir);
  644. #    endif DGK
  645. #endif CHDIR
  646.     exit(code);
  647. }
  648.  
  649. #endif MSDOS