home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / games / volume16 / nethck31 / part93 < prev    next >
Encoding:
Internet Message Format  |  1993-02-05  |  58.2 KB

  1. Path: uunet!news.tek.com!master!saab!billr
  2. From: billr@saab.CNA.TEK.COM (Bill Randle)
  3. Newsgroups: comp.sources.games
  4. Subject: v16i101:  nethack31 - display oriented dungeons & dragons (Ver. 3.1), Part93/108
  5. Message-ID: <4466@master.CNA.TEK.COM>
  6. Date: 5 Feb 93 22:02:49 GMT
  7. Sender: news@master.CNA.TEK.COM
  8. Lines: 2211
  9. Approved: billr@saab.CNA.TEK.COM
  10. Xref: uunet comp.sources.games:1652
  11.  
  12. Submitted-by: izchak@linc.cis.upenn.edu (Izchak Miller)
  13. Posting-number: Volume 16, Issue 101
  14. Archive-name: nethack31/Part93
  15. Supersedes: nethack3p9: Volume 10, Issue 46-108
  16. Environment: Amiga, Atari, Mac, MS-DOS, OS2, Unix, VMS, X11
  17.  
  18.  
  19.  
  20. #! /bin/sh
  21. # This is a shell archive.  Remove anything before this line, then unpack
  22. # it by saving it into a file and typing "sh file".  To overwrite existing
  23. # files, type "sh file -c".  You can also feed this as standard input via
  24. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  25. # will see the following message at the end:
  26. #        "End of archive 93 (of 108)."
  27. # Contents:  dat/cmdhelp include/rm.h src/bones.c
  28. #   sys/amiga/splitter/loader.c sys/share/pcmain.c win/X11/wintext.c
  29. # Wrapped by billr@saab on Wed Jan 27 16:09:25 1993
  30. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  31. if test -f 'dat/cmdhelp' -a "${1}" != "-c" ; then 
  32.   echo shar: Will not clobber existing file \"'dat/cmdhelp'\"
  33. else
  34. echo shar: Extracting \"'dat/cmdhelp'\" \(4641 characters\)
  35. sed "s/^X//" >'dat/cmdhelp' <<'END_OF_FILE'
  36. X^       Show the type of a trap
  37. X^[      Cancel command
  38. X^A      Redo the previous command
  39. X^C      Quit the game
  40. X^D      Kick something (usually a door)
  41. X^E      Search a room (available in debug mode only)
  42. X^F      Map the level (available in debug mode only)
  43. X^G      Create a monster (available in debug mode only)
  44. X^I      Identify all items (available in debug mode only)
  45. X^O      Show location of special levels (available in debug mode only)
  46. X^P      Show previous message printed out
  47. X^R      Redraw screen
  48. X^T      Teleport around level
  49. X^V      Teleport between levels (available in debug mode only)
  50. X^W      Wish (available in debug mode only)
  51. X^X      Show your intrinsic attributes (in debug or explore mode only)
  52. X^Z      Suspend game (only if defined)
  53. Xa       Apply (use) a tool
  54. XA       Remove all Armor
  55. Xb       Go southwest 1 space
  56. XB       Go southwest until you are on top of something
  57. X^B      Go southwest until you are near something
  58. Xc       Close a door
  59. XC       Call (name) a particular monster
  60. Xd       Drop an item
  61. XD       Drop specific item types
  62. Xe       Eat something
  63. XE       Engrave writing on the floor
  64. Xg       Followed by direction, move until you are near something
  65. XG       Followed by direction, same as control-direction
  66. Xh       Go west 1 space
  67. XH       Go west until you are on top of something
  68. X^H      Go west until you are near something
  69. Xi       Show your inventory
  70. XI       Inventory specific item types
  71. Xj       Go south 1 space (or if number_pad is on, jump to another location)
  72. XJ       Go south until you are on top of something
  73. X^J      Go south until you are near something
  74. Xk       Go north 1 space (or if number_pad is on, kick something)
  75. XK       Go north until you are on top of something
  76. X^K      Go north until you are near something
  77. Xl       Go east 1 space (or if number_pad is on, loot a box on the floor)
  78. XL       Go east until you are on top of something
  79. X^L      Go east until you are near something
  80. Xm       Followed by direction, move without picking anything up
  81. XM       Followed by direction, move a distance without picking anything up
  82. Xn       Go southeast 1 space
  83. XN       Go southeast until you are on something (if number_pad, name an object)
  84. X^N      Go southeast until you are near something
  85. Xo       Open a door
  86. XO       Set options (O? explains options)
  87. Xp       Pay your shopping bill
  88. XP       Put on an accessory (ring, amulet, etc)
  89. Xq       Quaff (drink) something
  90. XQ       Quit the game
  91. Xr       Read a scroll (or spell book, if defined)
  92. XR       Remove an accessory (ring, amulet, etc)
  93. Xs       Search for traps and secret doors
  94. XS       Save the game
  95. Xt       Throw something
  96. XT       Take off one piece of armor
  97. Xu       Go northeast 1 space (or if number_pad is on, untrap something)
  98. XU       Go northeast until you are on top of something
  99. X^U      Go northeast until you are near something
  100. Xv       Show version
  101. XV       Show long version and game history
  102. Xw       Wield (put in use) a weapon
  103. XW       Wear a piece of armor
  104. Xx       List known spells (only if defined)
  105. XX       Enter explore (discovery) mode (only if defined)
  106. Xy       Go northwest 1 space
  107. XY       Go northwest until you are on top of something
  108. X^Y      Go northwest until you are near something
  109. Xz       Zap a wand
  110. XZ       Zap (cast) a spell (only if defined)
  111. X<       Go up a staircase
  112. X>       Go down a staircase
  113. X/       Show what type of thing a symbol corresponds to
  114. X?       Give a help message
  115. X&       Tell what a command does
  116. X!       Do a shell escape (only if defined)
  117. X\       Show what object types have been discovered
  118. X.       Rest one move while doing nothing
  119. X        Rest one move while doing nothing (if rest_on_space option is on)
  120. X:       Look at what is on the floor
  121. X@       Toggle the pickup option on/off
  122. X)       Show the weapon currently wielded
  123. X[       Show the armor currently worn
  124. X=       Show the ring(s) currently worn
  125. X"       Show the amulet currently worn
  126. X(       Show the tools currently in use
  127. X$       Count your gold
  128. X+       List known spells (only if defined)
  129. X#       Perform an extended command
  130. XM-a     Adjust inventory letters (the fixinv option must be on to do this)
  131. XM-c     Talk to someone
  132. XM-d     Dip an object into something
  133. XM-f     Force a lock
  134. XM-i     Invoke an object's special powers
  135. XM-j     Jump to another location
  136. XM-l     Loot a box on the floor
  137. XM-m     Use a monster's special ability (only if defined)
  138. XM-n     Name an item or type of object
  139. XM-o     Offer a sacrifice to the gods
  140. XM-p     Pray to the gods for help
  141. XM-r     Rub a lamp
  142. XM-s     Sit down
  143. XM-t     Turn undead
  144. XM-u     Untrap something (usually a trapped object)
  145. XM-v     Print compile time options for this version of NetHack
  146. XM-w     Wipe off your face
  147. END_OF_FILE
  148. if test 4641 -ne `wc -c <'dat/cmdhelp'`; then
  149.     echo shar: \"'dat/cmdhelp'\" unpacked with wrong size!
  150. fi
  151. # end of 'dat/cmdhelp'
  152. fi
  153. if test -f 'include/rm.h' -a "${1}" != "-c" ; then 
  154.   echo shar: Will not clobber existing file \"'include/rm.h'\"
  155. else
  156. echo shar: Extracting \"'include/rm.h'\" \(10031 characters\)
  157. sed "s/^X//" >'include/rm.h' <<'END_OF_FILE'
  158. X/*    SCCS Id: @(#)rm.h    3.1    92/09/01          */
  159. X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  160. X/* NetHack may be freely redistributed.  See license for details. */
  161. X
  162. X#ifndef RM_H
  163. X#define RM_H
  164. X
  165. X/*
  166. X * The dungeon presentation graphics code and data structures were rewritten
  167. X * and generalized for NetHack's release 2 by Eric S. Raymond (eric@snark)
  168. X * building on Don G. Kneller's MS-DOS implementation.  See drawing.c for
  169. X * the code that permits the user to set the contents of the symbol structure.
  170. X *
  171. X * The door representation was changed by Ari Huttunen(ahuttune@niksula.hut.fi)
  172. X */
  173. X
  174. X/*
  175. X * TLCORNER    TDWALL        TRCORNER
  176. X * +-         -+-         -+
  177. X * |           |            |
  178. X *
  179. X * TRWALL    CROSSWALL    TLWALL        HWALL
  180. X * |           |           |
  181. X * +-         -+-         -+        ---
  182. X * |           |           |
  183. X *
  184. X * BLCORNER    TUWALL        BRCORNER    VWALL
  185. X * |           |           |        |
  186. X * +-         -+-         -+        |
  187. X */
  188. X
  189. X/* Level location types */
  190. X#define STONE        0
  191. X#define VWALL        1
  192. X#define HWALL        2
  193. X#define TLCORNER    3
  194. X#define TRCORNER    4
  195. X#define BLCORNER    5
  196. X#define BRCORNER    6
  197. X#define CROSSWALL    7    /* For pretty mazes and special levels */
  198. X#define TUWALL        8
  199. X#define TDWALL        9
  200. X#define TLWALL        10
  201. X#define TRWALL        11
  202. X#define DBWALL        12
  203. X#define SDOOR        13
  204. X#define SCORR        14
  205. X#define POOL        15
  206. X#define MOAT        16    /* pool that doesn't boil, adjust messages */
  207. X#define WATER        17
  208. X#define DRAWBRIDGE_UP    18
  209. X#define LAVAPOOL    19
  210. X#define DOOR        20
  211. X#define CORR        21
  212. X#define ROOM        22
  213. X#define STAIRS        23
  214. X#define LADDER        24
  215. X#define FOUNTAIN    25
  216. X#define THRONE        26
  217. X#define SINK        27
  218. X#define ALTAR        28
  219. X#define ICE        29
  220. X#define DRAWBRIDGE_DOWN    30
  221. X#define AIR        31
  222. X#define CLOUD        32
  223. X
  224. X#define INVALID_TYPE    127
  225. X
  226. X/*
  227. X * Avoid using the level types in inequalities:
  228. X * these types are subject to change.
  229. X * Instead, use one of the macros below.
  230. X */
  231. X#define IS_WALL(typ)    ((typ) && (typ) <= DBWALL)
  232. X#define IS_STWALL(typ)    ((typ) <= DBWALL)    /* STONE <= (typ) <= DBWALL */
  233. X#define IS_ROCK(typ)    ((typ) < POOL)        /* absolutely nonaccessible */
  234. X#define IS_DOOR(typ)    ((typ) == DOOR)
  235. X#define ACCESSIBLE(typ)    ((typ) >= DOOR)        /* good position */
  236. X#define IS_ROOM(typ)    ((typ) >= ROOM)        /* ROOM, STAIRS, furniture.. */
  237. X#define ZAP_POS(typ)    ((typ) >= POOL)
  238. X#define SPACE_POS(typ)    ((typ) > DOOR)
  239. X#define IS_POOL(typ)    ((typ) >= POOL && (typ) <= DRAWBRIDGE_UP)
  240. X#define IS_THRONE(typ)    ((typ) == THRONE)
  241. X#define IS_FOUNTAIN(typ) ((typ) == FOUNTAIN)
  242. X#define IS_SINK(typ)    ((typ) == SINK)
  243. X#define IS_ALTAR(typ)    ((typ) == ALTAR)
  244. X#define IS_DRAWBRIDGE(typ) ((typ) == DRAWBRIDGE_UP || (typ) == DRAWBRIDGE_DOWN)
  245. X#define IS_FURNITURE(typ) ((typ) >= STAIRS && (typ) <= ALTAR)
  246. X#define IS_AIR(typ)    ((typ) == AIR || (typ) == CLOUD)
  247. X#define IS_SOFT(typ)    ((typ) == AIR || (typ) == CLOUD || IS_POOL(typ))
  248. X
  249. X/*
  250. X * The screen symbols may be the default or defined at game startup time.
  251. X * See drawing.c for defaults.
  252. X * Note: {ibm|dec}_graphics[] arrays (also in drawing.c) must be kept in synch.
  253. X */
  254. X#define S_stone        0
  255. X#define S_vwall        1
  256. X#define S_hwall        2
  257. X#define S_tlcorn    3
  258. X#define S_trcorn    4
  259. X#define S_blcorn    5
  260. X#define S_brcorn    6
  261. X#define S_crwall    7
  262. X#define S_tuwall    8
  263. X#define S_tdwall    9
  264. X#define S_tlwall    10
  265. X#define S_trwall    11
  266. X#define S_ndoor        12
  267. X#define S_vodoor    13
  268. X#define S_hodoor    14
  269. X#define S_vcdoor    15    /* closed door, vertical wall */
  270. X#define S_hcdoor    16    /* closed door, horizontal wall */
  271. X#define S_room        17
  272. X#define S_corr        18
  273. X#define S_litcorr    19
  274. X#define S_upstair    20
  275. X#define S_dnstair    21
  276. X#define S_upladder    22
  277. X#define S_dnladder    23
  278. X#define S_trap        24
  279. X#define S_web        25
  280. X#define S_altar        26
  281. X#define S_throne    27
  282. X#define S_sink        28
  283. X#define S_fountain    29
  284. X#define S_pool        30
  285. X#define S_ice        31
  286. X#define S_lava        32
  287. X#define S_vodbridge    33
  288. X#define S_hodbridge    34
  289. X#define S_vcdbridge    35    /* closed drawbridge, vertical wall */
  290. X#define S_hcdbridge    36    /* closed drawbridge, horizontal wall */
  291. X#define S_air        37
  292. X#define S_cloud        38
  293. X#define S_water        39
  294. X#define S_vbeam        40    /* The 4 zap beam symbols.  Do NOT separate. */
  295. X#define S_hbeam        41    /* To change order or add, see function     */
  296. X#define S_lslant    42    /* zapdir_to_glyph() in display.c.        */
  297. X#define S_rslant    43
  298. X#define S_digbeam    44    /* dig beam symbol */
  299. X#define S_flashbeam    45    /* camera flash symbol */
  300. X#define S_boomleft    46    /* thrown boomerang, open left, e.g ')'    */
  301. X#define S_boomright    47    /* thrown boomerand, open right, e.g. '('  */
  302. X#define S_ss1        48    /* 4 magic shield glyphs */
  303. X#define S_ss2        49
  304. X#define S_ss3        50
  305. X#define S_ss4        51
  306. X
  307. X/* The 8 swallow symbols.  Do NOT separate.  To change order or add, see */
  308. X/* the function swallow_to_glyph() in display.c.             */
  309. X#define S_sw_tl        52    /* swallow top left [1]            */
  310. X#define S_sw_tc        53    /* swallow top center [2]    Order:    */
  311. X#define S_sw_tr        54    /* swallow top right [3]        */
  312. X#define S_sw_ml        55    /* swallow middle left [4]    1 2 3    */
  313. X#define S_sw_mr        56    /* swallow middle right [6]    4 5 6    */
  314. X#define S_sw_bl        57    /* swallow bottom left [7]    7 8 9    */
  315. X#define S_sw_bc        58    /* swallow bottom center [8]        */
  316. X#define S_sw_br        59    /* swallow bottom right [9]        */
  317. X
  318. X#define S_explode1    60    /* explosion top left            */
  319. X#define S_explode2    61    /* explosion top center            */
  320. X#define S_explode3    62    /* explosion top right         Ex.    */
  321. X#define S_explode4    63    /* explosion middle left        */
  322. X#define S_explode5    64    /* explosion middle center     /-\    */
  323. X#define S_explode6    65    /* explosion middle right     |@|    */
  324. X#define S_explode7    66    /* explosion bottom left     \-/    */
  325. X#define S_explode8    67    /* explosion bottom center        */
  326. X#define S_explode9    68    /* explosion bottom right        */
  327. X
  328. X#define MAXPCHARS    69    /* maximum number of mapped characters */
  329. X
  330. Xstruct symdef {
  331. X    uchar sym;
  332. X    const char  *explanation;
  333. X#ifdef TEXTCOLOR
  334. X    uchar color;
  335. X#endif
  336. X};
  337. X
  338. Xextern const struct symdef defsyms[MAXPCHARS];    /* defaults */
  339. Xextern uchar showsyms[MAXPCHARS];
  340. X
  341. X/*
  342. X * Graphics sets for display symbols
  343. X */
  344. X#define ASCII_GRAPHICS    0    /* regular characters: '-', '+', &c */
  345. X#define IBM_GRAPHICS    1    /* PC graphic characters */
  346. X#define DEC_GRAPHICS    2    /* VT100 line drawing characters */
  347. X#define MAC_GRAPHICS    3    /* Macintosh drawing characters */
  348. X
  349. X/*
  350. X * The 5 possible states of doors
  351. X */
  352. X
  353. X#define D_NODOOR    0
  354. X#define D_BROKEN    1
  355. X#define D_ISOPEN    2
  356. X#define D_CLOSED    4
  357. X#define D_LOCKED    8
  358. X#define D_TRAPPED    16
  359. X
  360. X/*
  361. X * The 3 possible alignments for altars
  362. X */
  363. X#ifndef ALIGN_H
  364. X#include "align.h"        /* defines the "AM_" values */
  365. X#endif
  366. X
  367. X/*
  368. X * Some altars are considered as shrines, so we need a flag.
  369. X */
  370. X#define AM_SHRINE    8
  371. X
  372. X/*
  373. X * Thrones should only be looted once.
  374. X */
  375. X#define T_LOOTED    1
  376. X
  377. X/*
  378. X * Fountains have limits, and special warnings.
  379. X */
  380. X#define F_LOOTED    1
  381. X#define F_WARNED    2
  382. X
  383. X/*
  384. X * Sinks have 3 different types of loot that shouldn't be abused
  385. X */
  386. X#define S_LPUDDING    1
  387. X#define S_LDWASHER    2
  388. X#define S_LRING        4
  389. X
  390. X/*
  391. X * The four directions for a DrawBridge.
  392. X */
  393. X#define DB_NORTH    0
  394. X#define DB_SOUTH    1
  395. X#define DB_EAST        2
  396. X#define DB_WEST        3
  397. X#define DB_DIR        3    /* mask for direction */
  398. X
  399. X/*
  400. X * What's under a drawbridge.
  401. X */
  402. X#define DB_MOAT        0
  403. X#define DB_LAVA        4
  404. X#define DB_ICE        8
  405. X#define DB_FLOOR    16
  406. X#define DB_UNDER    28    /* mask for underneath */
  407. X
  408. X/*
  409. X * Some walls may be non diggable.
  410. X */
  411. X#define W_DIGGABLE    0
  412. X#define W_NONDIGGABLE    1
  413. X#define W_REPAIRED    2
  414. X
  415. X/*
  416. X * Ladders (in Vlad's tower) may be up or down.
  417. X */
  418. X#define LA_UP        1
  419. X#define LA_DOWN        2
  420. X
  421. X/*
  422. X * Room areas may be iced pools
  423. X */
  424. X#define ICED_POOL    8
  425. X#define ICED_MOAT    16
  426. X
  427. X/*
  428. X * The structure describing a coordinate position.
  429. X * Before adding fields, remember that this will significantly affect
  430. X * the size of temporary files and save files.
  431. X */
  432. Xstruct rm {
  433. X    int glyph;        /* what the hero thinks is there */
  434. X    schar typ;        /* what is really there */
  435. X    Bitfield(seen,1);    /* speed hack for room walls on corridors */
  436. X    Bitfield(lit,1);    /* speed hack for lit rooms */
  437. X    Bitfield(flags,5);    /* extra information for typ */
  438. X    Bitfield(horizontal,1);    /* wall/door/etc is horiz. (more typ info) */
  439. X    Bitfield(waslit,1);    /* remember if a location was lit */
  440. X    Bitfield(roomno,6);    /* room # for special rooms */
  441. X    Bitfield(edge,1);    /* marks boundaries for special rooms*/
  442. X};
  443. X
  444. X#define doormask    flags
  445. X#define altarmask    flags
  446. X#define diggable    flags
  447. X#define ladder        flags
  448. X#define drawbridgemask    flags
  449. X#define looted        flags
  450. X#define icedpool    flags
  451. X
  452. X#define blessedftn      horizontal  /* a fountain that grants attribs */
  453. X
  454. Xstruct damage {
  455. X    struct damage *next;
  456. X    long when, cost;
  457. X    coord place;
  458. X    schar typ;
  459. X};
  460. X
  461. Xstruct levelflags {
  462. X    uchar    nfountains;    /* Number of fountains on level */
  463. X    uchar    nsinks;        /* Number of sinks on the level */
  464. X    /* Several flags that give hints about what's on the level */
  465. X    Bitfield(has_shop, 1);
  466. X    Bitfield(has_vault, 1);
  467. X    Bitfield(has_zoo, 1);
  468. X    Bitfield(has_court, 1);
  469. X    Bitfield(has_morgue, 1);
  470. X    Bitfield(has_beehive, 1);
  471. X#ifdef ARMY
  472. X    Bitfield(has_barracks, 1);
  473. X#endif
  474. X    Bitfield(has_temple, 1);
  475. X    Bitfield(has_swamp, 1);
  476. X    Bitfield(noteleport,1);
  477. X    Bitfield(hardfloor,1);
  478. X    Bitfield(nommap,1);
  479. X    Bitfield(hero_memory,1);    /* hero has memory */
  480. X    Bitfield(shortsighted,1);    /* monsters are shortsighted */
  481. X    Bitfield(is_maze_lev,1);
  482. X    Bitfield(is_cavernous_lev,1);
  483. X};
  484. X
  485. Xtypedef struct
  486. X{
  487. X    struct rm        locations[COLNO][ROWNO];
  488. X#ifndef MICROPORT_BUG
  489. X    struct obj        *objects[COLNO][ROWNO];
  490. X    struct monst    *monsters[COLNO][ROWNO];
  491. X#else
  492. X    struct obj        *objects[1][ROWNO];
  493. X    char        *yuk1[COLNO-1][ROWNO];
  494. X    struct monst    *monsters[1][ROWNO];
  495. X    char        *yuk2[COLNO-1][ROWNO];
  496. X#endif
  497. X    struct obj        *objlist;
  498. X    struct monst    *monlist;
  499. X    struct damage    *damagelist;
  500. X    struct levelflags    flags;
  501. X}
  502. Xdlevel_t;
  503. X
  504. Xextern dlevel_t    level;    /* structure describing the current level */
  505. X
  506. X/*
  507. X * Macros for compatibility with old code. Someday these will go away.
  508. X */
  509. X#define levl        level.locations
  510. X#define fobj        level.objlist
  511. X#define fmon        level.monlist
  512. X
  513. X#define OBJ_AT(x,y)    (level.objects[x][y] != (struct obj *)0)
  514. X/*
  515. X * Macros for encapsulation of level.monsters references.
  516. X */
  517. X#define MON_AT(x,y)    (level.monsters[x][y] != (struct monst *)0)
  518. X#define place_monster(m,x,y)    ((m)->mx=(x),(m)->my=(y),\
  519. X                 level.monsters[(m)->mx][(m)->my]=(m))
  520. X#define place_worm_seg(m,x,y)    level.monsters[x][y] = m
  521. X#define remove_monster(x,y)    level.monsters[x][y] = (struct monst *)0
  522. X#define m_at(x,y)        level.monsters[x][y]
  523. X
  524. X#endif /* RM_H */
  525. END_OF_FILE
  526. if test 10031 -ne `wc -c <'include/rm.h'`; then
  527.     echo shar: \"'include/rm.h'\" unpacked with wrong size!
  528. fi
  529. # end of 'include/rm.h'
  530. fi
  531. if test -f 'src/bones.c' -a "${1}" != "-c" ; then 
  532.   echo shar: Will not clobber existing file \"'src/bones.c'\"
  533. else
  534. echo shar: Extracting \"'src/bones.c'\" \(9436 characters\)
  535. sed "s/^X//" >'src/bones.c' <<'END_OF_FILE'
  536. X/*    SCCS Id: @(#)bones.c    3.1    93/01/07    */
  537. X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985,1993. */
  538. X/* NetHack may be freely redistributed.  See license for details. */
  539. X
  540. X#include "hack.h"
  541. X#include "lev.h"
  542. X
  543. X#ifdef MFLOPPY
  544. Xextern char bones[];    /* from files.c */
  545. Xextern long bytes_counted;
  546. X#endif
  547. X
  548. Xstatic boolean FDECL(no_bones_level, (d_level *));
  549. X#ifdef TUTTI_FRUTTI
  550. Xstatic void FDECL(goodfruit, (int));
  551. X#endif
  552. Xstatic void FDECL(resetobjs,(struct obj *,BOOLEAN_P));
  553. Xstatic void FDECL(drop_upon_death, (struct monst *, struct obj *));
  554. X
  555. Xstatic boolean
  556. Xno_bones_level(lev)
  557. Xd_level *lev;
  558. X{
  559. X    extern d_level save_dlevel;        /* in do.c */
  560. X    s_level *sptr;
  561. X
  562. X    if (ledger_no(&save_dlevel)) assign_level(lev, &save_dlevel);
  563. X
  564. X    return (((sptr = Is_special(lev)) && !sptr->boneid)
  565. X        || !dungeons[lev->dnum].boneid
  566. X           /* no bones on the last or multiway branch levels */
  567. X           /* in any dungeon (level 1 isn't multiway).       */
  568. X        || Is_botlevel(lev) || (Is_branchlev(lev) && lev->dlevel > 1)
  569. X           /* no bones in the invocation level               */
  570. X        || (In_hell(lev) && lev->dlevel == dunlevs_in_dungeon(lev) - 1)
  571. X        );
  572. X}
  573. X
  574. X#ifdef TUTTI_FRUTTI
  575. Xstatic void
  576. Xgoodfruit(id)
  577. Xint id;
  578. X{
  579. X    register struct fruit *f;
  580. X
  581. X    for(f=ffruit; f; f=f->nextf) {
  582. X        if(f->fid == -id) {
  583. X            f->fid = id;
  584. X            return;
  585. X        }
  586. X    }
  587. X}
  588. X#endif
  589. X
  590. Xstatic void
  591. Xresetobjs(ochain,restore)
  592. Xstruct obj *ochain;
  593. Xboolean restore;
  594. X{
  595. X    struct obj *otmp;
  596. X
  597. X    for (otmp = ochain; otmp; otmp = otmp->nobj) {
  598. X        if (otmp->cobj)
  599. X            resetobjs(otmp->cobj,restore);
  600. X
  601. X        if (((otmp->otyp != CORPSE || otmp->corpsenm < PM_ARCHEOLOGIST)
  602. X            && otmp->otyp != STATUE)
  603. X            && (!otmp->oartifact ||
  604. X                (exist_artifact(otmp->otyp,ONAME(otmp)) && restore))) {
  605. X            otmp->oartifact = 0;
  606. X            otmp->onamelth = 0;
  607. X            *ONAME(otmp) = '\0';
  608. X        } else if (otmp->oartifact && restore)
  609. X            artifact_exists(otmp,ONAME(otmp),TRUE);
  610. X        if (!restore) {
  611. X            /* resetting the o_id's after getlev has carefully
  612. X             * created proper new ones via restobjchn is a Bad
  613. X             * Idea */
  614. X            otmp->o_id = 0;
  615. X            if(objects[otmp->otyp].oc_uses_known) otmp->known = 0;
  616. X            otmp->dknown = otmp->bknown = 0;
  617. X            otmp->rknown = 0;
  618. X            otmp->invlet = 0;
  619. X#ifdef TUTTI_FRUTTI
  620. X            if(otmp->otyp == SLIME_MOLD) goodfruit(otmp->spe);
  621. X#endif
  622. X#ifdef MAIL
  623. X            if (otmp->otyp == SCR_MAIL) otmp->spe = 1;
  624. X#endif
  625. X#ifdef POLYSELF
  626. X            if (otmp->otyp == EGG) otmp->spe = 0;
  627. X#endif
  628. X            if(otmp->otyp == AMULET_OF_YENDOR) {
  629. X                /* no longer the actual amulet */
  630. X                otmp->otyp = FAKE_AMULET_OF_YENDOR;
  631. X                curse(otmp);
  632. X            }
  633. X            if(otmp->otyp == CANDELABRUM_OF_INVOCATION) {
  634. X                if(otmp->spe > 0) { /* leave candles, if any */
  635. X                    otmp->otyp = WAX_CANDLE;
  636. X                otmp->age = 50L;  /* assume used */
  637. X                otmp->quan = (long)otmp->spe;
  638. X                otmp->lamplit = 0;
  639. X                otmp->spe = 0;
  640. X                } else obfree(otmp, (struct obj *)0);
  641. X            }
  642. X            if(otmp->otyp == BELL_OF_OPENING) otmp->otyp = BELL;
  643. X            if(otmp->otyp == SPE_BOOK_OF_THE_DEAD) {
  644. X                otmp->otyp = SPE_MAGIC_MISSILE +
  645. X                                rn2(SPE_BLANK_PAPER -
  646. X                          SPE_MAGIC_MISSILE + 1);
  647. X                curse(otmp);
  648. X            }
  649. X        }
  650. X    }            
  651. X}
  652. X
  653. Xstatic void
  654. Xdrop_upon_death(mtmp, cont)
  655. Xstruct monst *mtmp;
  656. Xstruct obj *cont;
  657. X{
  658. X    struct obj *otmp = invent;
  659. X    while(otmp) {
  660. X        otmp->owornmask = 0;
  661. X        otmp->lamplit = 0;
  662. X#ifdef TUTTI_FRUTTI
  663. X        if(otmp->otyp == SLIME_MOLD) goodfruit(otmp->spe);
  664. X#endif
  665. X        if(rn2(5)) curse(otmp);
  666. X        if(!mtmp && !cont) place_object(otmp, u.ux, u.uy);
  667. X        if(!otmp->nobj) {
  668. X            if (mtmp) {
  669. X                otmp->nobj = mtmp->minvent;
  670. X                mtmp->minvent = invent;
  671. X            } else if (cont) {
  672. X                otmp->nobj = cont->cobj;
  673. X                cont->cobj = invent;
  674. X            } else {
  675. X                otmp->nobj = fobj;
  676. X                fobj = invent;
  677. X            }
  678. X            invent = 0;    /* superfluous */
  679. X            break;
  680. X        }
  681. X        otmp = otmp->nobj;
  682. X    }
  683. X    if(u.ugold) {
  684. X        if (mtmp) mtmp->mgold = u.ugold;
  685. X        else mkgold(u.ugold, u.ux, u.uy);
  686. X    }
  687. X}
  688. X
  689. X/* save bones and possessions of a deceased adventurer */
  690. Xvoid
  691. Xsavebones()
  692. X{
  693. X    register int fd, x, y;
  694. X    register struct trap *ttmp;
  695. X    register struct monst *mtmp, *mtmp2;
  696. X#ifdef TUTTI_FRUTTI
  697. X    struct fruit *f;
  698. X#endif
  699. X    char *bonesid;
  700. X
  701. X    if(ledger_no(&u.uz) <= 0 || ledger_no(&u.uz) > maxledgerno()) return;
  702. X    if(no_bones_level(&u.uz)) return; /* no bones for specific levels */
  703. X    if(!rn2(1 + (depth(&u.uz)>>2)) /* fewer ghosts on low levels */
  704. X#ifdef WIZARD
  705. X        && !wizard
  706. X#endif
  707. X        ) return;
  708. X#ifdef EXPLORE_MODE
  709. X    /* don't let multiple restarts generate multiple copies of objects
  710. X     * in bones files */
  711. X    if(discover) return;
  712. X#endif
  713. X
  714. X    fd = open_bonesfile(&u.uz, &bonesid);
  715. X    if (fd >= 0) {
  716. X        (void) close(fd);
  717. X        compress_bonesfile();
  718. X#ifdef WIZARD
  719. X        if(wizard)
  720. X            pline("Bones file already exists.");
  721. X#endif
  722. X        return;
  723. X    }
  724. X
  725. X#ifdef WALKIES
  726. X    unleash_all();
  727. X#endif
  728. X    /* in case these characters are not in their home bases */
  729. X    mtmp2 = fmon;
  730. X    while((mtmp = mtmp2)) {
  731. X        mtmp2 = mtmp->nmon;
  732. X        if(mtmp->iswiz || mtmp->data == &mons[PM_MEDUSA]) mongone(mtmp);
  733. X    }
  734. X#ifdef TUTTI_FRUTTI
  735. X    /* mark all fruits as nonexistent; when we come to them we'll mark
  736. X     * them as existing (using goodfruit())
  737. X     */
  738. X    for(f=ffruit; f; f=f->nextf) f->fid = -f->fid;
  739. X#endif
  740. X
  741. X    /* check iron balls separately--maybe they're not carrying it */
  742. X    if (uball) uball->owornmask = uchain->owornmask = 0;
  743. X
  744. X    /* dispose of your possessions, usually cursed */
  745. X    if (u.ugrave_arise == -2) {
  746. X        struct obj *otmp;
  747. X
  748. X        /* embed your possessions in your statue */
  749. X        otmp = mk_named_object(STATUE,
  750. X#ifdef POLYSELF
  751. X                    u.mtimedone ? uasmon :
  752. X#endif
  753. X                    player_mon(), 
  754. X                    u.ux, u.uy, plname,
  755. X                    (int)strlen(plname));
  756. X        if (!otmp) return;
  757. X        drop_upon_death(mtmp = (struct monst *)0, otmp);
  758. X    } else if (u.ugrave_arise == -1) {
  759. X        /* drop everything */
  760. X        drop_upon_death((struct monst *)0, (struct obj *)0);
  761. X        /* trick makemon() into allowing monster creation
  762. X         * on your location
  763. X         */
  764. X        in_mklev = TRUE;
  765. X        mtmp = makemon(&mons[PM_GHOST], u.ux, u.uy);
  766. X        in_mklev = FALSE;
  767. X        if (!mtmp) return;
  768. X        Strcpy((char *) mtmp->mextra, plname);
  769. X    } else {
  770. X        /* give your possessions to the monster you become */
  771. X        in_mklev = TRUE;
  772. X        mtmp = makemon(&mons[u.ugrave_arise], u.ux, u.uy);
  773. X        in_mklev = FALSE;
  774. X        if (!mtmp) return;
  775. X        mtmp = christen_monst(mtmp, plname);
  776. X        newsym(u.ux, u.uy);
  777. X        Your("body rises from the dead as %s...",
  778. X            an(mons[u.ugrave_arise].mname));
  779. X        display_nhwindow(WIN_MESSAGE, FALSE);
  780. X        drop_upon_death(mtmp, (struct obj *)0);
  781. X#ifdef MUSE
  782. X        m_dowear(mtmp, TRUE);
  783. X#endif
  784. X    }
  785. X    if (mtmp) {
  786. X        mtmp->m_lev = (u.ulevel ? u.ulevel : 1);
  787. X        mtmp->mhp = mtmp->mhpmax = u.uhpmax;
  788. X        mtmp->msleep = 1;
  789. X    }
  790. X    for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
  791. X        resetobjs(mtmp->minvent,FALSE);
  792. X        mtmp->m_id = 0;
  793. X        mtmp->mlstmv = 0L;
  794. X        if(mtmp->mtame) mtmp->mtame = mtmp->mpeaceful = 0;
  795. X    }
  796. X    for(ttmp = ftrap; ttmp; ttmp = ttmp->ntrap) {
  797. X            if(ttmp->ttyp == MAGIC_PORTAL) deltrap(ttmp);
  798. X        ttmp->tseen = 0;
  799. X    }
  800. X    resetobjs(fobj,FALSE);
  801. X
  802. X    /* Clear all memory from the level. */
  803. X    for(x=0; x<COLNO; x++) for(y=0; y<ROWNO; y++) {
  804. X        levl[x][y].seen = levl[x][y].waslit = 0;
  805. X        levl[x][y].glyph = cmap_to_glyph(S_stone);
  806. X    }
  807. X
  808. X    fd = create_bonesfile(&u.uz, &bonesid);
  809. X    if(fd < 0) {
  810. X#ifdef WIZARD
  811. X        if(wizard)
  812. X            pline("Cannot create bones file - create failed");
  813. X#endif
  814. X        return;
  815. X    }
  816. X
  817. X    bufon(fd);
  818. X#ifdef MFLOPPY  /* check whether there is room */
  819. X    savelev(fd, ledger_no(&u.uz), COUNT_SAVE);
  820. X# ifdef TUTTI_FRUTTI
  821. X    /* this is in the opposite order from the real save, but savelev()
  822. X     * initializes bytes_counted to 0, so doing savefruitchn() first is
  823. X     * useless; the extra bflush() at the end of savelev() may increase
  824. X     * bytes_counted by a couple over what the real usage will be
  825. X     */
  826. X    savefruitchn(fd, COUNT_SAVE);
  827. X    bflush(fd);
  828. X# endif
  829. X    if (bytes_counted > freediskspace(bones)) {    /* not enough room */
  830. X# ifdef WIZARD
  831. X        if (wizard)
  832. X            pline("Insufficient space to create bones file.");
  833. X# endif
  834. X        (void) close(fd);
  835. X        delete_bonesfile(&u.uz);
  836. X        return;
  837. X    }
  838. X    co_false();    /* make sure bonesid and savefruitchn get written */
  839. X#endif /* MFLOPPY */
  840. X
  841. X    bwrite(fd, (genericptr_t) bonesid, 7);    /* DD.nnn */
  842. X#ifdef TUTTI_FRUTTI
  843. X    savefruitchn(fd, WRITE_SAVE | FREE_SAVE);
  844. X#endif
  845. X    savelev(fd, ledger_no(&u.uz), WRITE_SAVE | FREE_SAVE);
  846. X    bclose(fd);
  847. X    compress_bonesfile();
  848. X}
  849. X
  850. Xint
  851. Xgetbones()
  852. X{
  853. X    register int fd;
  854. X    register int ok;
  855. X    char *bonesid, oldbonesid[7];
  856. X
  857. X#ifdef EXPLORE_MODE
  858. X    if(discover)        /* save bones files for real games */
  859. X        return(0);
  860. X#endif
  861. X    /* wizard check added by GAN 02/05/87 */
  862. X    if(rn2(3)    /* only once in three times do we find bones */
  863. X#ifdef WIZARD
  864. X        && !wizard
  865. X#endif
  866. X        ) return(0);
  867. X    if(no_bones_level(&u.uz)) return(0);
  868. X    fd = open_bonesfile(&u.uz, &bonesid);
  869. X    if (fd < 0) return(0);
  870. X
  871. X    if((ok = uptodate(fd)) != 0){
  872. X#ifdef WIZARD
  873. X        if(wizard)  {
  874. X            if(yn("Get bones?") == 'n') {
  875. X                (void) close(fd);
  876. X                compress_bonesfile();
  877. X                return(0);
  878. X            }
  879. X        }
  880. X#endif
  881. X        minit();    /* ZEROCOMP */
  882. X        mread(fd, (genericptr_t) oldbonesid, 7);    /* DD.nnn */
  883. X        if (strcmp(bonesid, oldbonesid)) {
  884. X#ifdef WIZARD
  885. X            if (wizard) {
  886. X                pline("This is bones level '%s', not '%s'!",
  887. X                    oldbonesid, bonesid);
  888. X                ok = FALSE;    /* won't die of trickery */
  889. X            }
  890. X#endif
  891. X            trickery();
  892. X        } else {
  893. X            register struct monst *mtmp;
  894. X
  895. X            getlev(fd, 0, 0, TRUE);
  896. X
  897. X            /* to correctly reset named artifacts on the level */
  898. X            for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
  899. X                resetobjs(mtmp->minvent,TRUE);
  900. X            resetobjs(fobj,TRUE);
  901. X        }
  902. X    }
  903. X    (void) close(fd);
  904. X
  905. X#ifdef WIZARD
  906. X    if(wizard) {
  907. X        if(yn("Unlink bones?") == 'n') {
  908. X            compress_bonesfile();
  909. X            return(ok);
  910. X        }
  911. X    }
  912. X#endif
  913. X    if (!delete_bonesfile(&u.uz)) {
  914. X        pline("Cannot unlink bones.");
  915. X        return(0);
  916. X    }
  917. X    return(ok);
  918. X}
  919. X
  920. X/*bones.c*/
  921. END_OF_FILE
  922. if test 9436 -ne `wc -c <'src/bones.c'`; then
  923.     echo shar: \"'src/bones.c'\" unpacked with wrong size!
  924. fi
  925. # end of 'src/bones.c'
  926. fi
  927. if test -f 'sys/amiga/splitter/loader.c' -a "${1}" != "-c" ; then 
  928.   echo shar: Will not clobber existing file \"'sys/amiga/splitter/loader.c'\"
  929. else
  930. echo shar: Extracting \"'sys/amiga/splitter/loader.c'\" \(9595 characters\)
  931. sed "s/^X//" >'sys/amiga/splitter/loader.c' <<'END_OF_FILE'
  932. X/*     SCCS Id: @(#)loader.c 3.1    93/01/08
  933. X/*    Copyright (c) Kenneth Lorber, Bethesda, Maryland 1992, 1993 */
  934. X/* NetHack may be freely redistributed.  See license for details. */
  935. X
  936. X/*
  937. X * Amiga split binary runtime system
  938. X */
  939. X
  940. X/*#define LDEBUG         /* turn on debugging I/O */
  941. X#define SDEBUG        /* static primary array allocation */
  942. X/*#define NOCLEAN        /* turn off $ovl_memchain code */
  943. X/*#define NOSPLIT        /* debug: load an unsplit binary(run ONCE!)*/
  944. X#define MULTI            /* real file reading code */
  945. X/*#define PARANOID        /* check for refs off end that might be OK */
  946. X#define CACHE            /* deal with cache flushing */
  947. X
  948. Xunsigned long xx;
  949. Xlong *yy;
  950. X
  951. X#include "split.h"
  952. X
  953. X#ifdef SPLIT
  954. X
  955. X#include <stdio.h>        /* for spanic - should change */
  956. X#include <exec/types.h>
  957. X#include <exec/memory.h>
  958. X#include <libraries/dosextens.h>
  959. X#include <proto/dos.h>
  960. X#include <proto/exec.h>
  961. X#include <dos.h>            /* NOT libraries/dos.h! */
  962. X#include "amiout.h"
  963. X
  964. X#include "multi.h"
  965. X
  966. X#define F_LOAD 0
  967. X#define F_RELOAD 1
  968. X
  969. X#define HT(x)    ((x) & ~MEM_OBJ_EXTEND)
  970. X
  971. Xvoid *$ovl_AllocMem(unsigned int);
  972. Xvoid spanic(char *);            /* think about this!!!! */
  973. Xvoid exit(int);
  974. X
  975. X#ifdef SDEBUG
  976. Xunsigned long *$ovl_hunktable[500];    /* 223 as of 10/21/92 */
  977. X#else
  978. Xunsigned long *(*$ovl_hunktable)[];
  979. Xint $ovl_hunktablesize;
  980. X#endif
  981. X
  982. X#ifndef NOCLEAN
  983. XBPTR $ovlmemchain=0;
  984. X#endif
  985. XBPTR ovlfile=0;
  986. XBPTR fh;
  987. XULONG database;
  988. X
  989. XBPTR s_LoadSeg(char *);
  990. Xvoid s_UnLoadSeg(void);
  991. XBPTR load_code(int,char *);
  992. Xvoid load_data(int,char *);
  993. Xunsigned long *load_hunk(BPTR,int,ULONG *);
  994. X
  995. X#ifdef MULTI
  996. Xunion multiopts mo;
  997. X    /* dump these after testing */
  998. X#define Read MultiRead
  999. X#define Close MultiClose
  1000. X#endif
  1001. X
  1002. XBPTR
  1003. Xs_LoadSeg(dir)
  1004. X    char *dir;
  1005. X    {
  1006. X    static BPTR base;
  1007. X    static char never=1;
  1008. X    if(never){
  1009. X#ifdef LDEBUG
  1010. X        fprintf(stderr,"s_LoadSeg waiting\n");
  1011. X        Delay(100);
  1012. X        fprintf(stderr,"going\n");
  1013. X#endif
  1014. X        base=load_code(F_LOAD,dir);
  1015. X#ifndef NOSPLIT
  1016. X        load_data(F_LOAD,dir);
  1017. X        never=0;
  1018. X#endif
  1019. X    }else{
  1020. X        load_data(F_RELOAD,dir);
  1021. X    }
  1022. X#ifdef LDEBUG
  1023. X    fprintf(stderr,"loadseg done! (waiting)\n");
  1024. X    getchar();
  1025. X#endif
  1026. X#ifdef CACHE
  1027. X    {
  1028. X    struct Library *eb=OpenLibrary("exec.library",36);
  1029. X    if(eb){
  1030. X        CacheClearU();
  1031. X        CloseLibrary(eb);
  1032. X    } else {
  1033. X        /* force a context switch and hope for the best */
  1034. X        Delay(1);
  1035. X    }
  1036. X    }
  1037. X#endif
  1038. X    return(base);
  1039. X}
  1040. X
  1041. XBPTR
  1042. Xload_code(dummy,dir)
  1043. X    int dummy;    /* always F_LOAD */
  1044. X    char *dir;    /* direction file */
  1045. X{
  1046. X    ULONG x;
  1047. X    ULONG *xp;
  1048. X    ULONG c,hc;
  1049. X    ULONG r;
  1050. X#ifdef MULTI
  1051. X    mo.r.mor_tag='C';
  1052. X    fh=MultiOpen(dir,MODE_OLDFILE,&mo);
  1053. X#else
  1054. X    fh=Open("s_NetHack.c00",MODE_OLDFILE);
  1055. X#endif
  1056. X    if(fh==0){
  1057. X        fprintf(stderr,"open failed %d\n",IoErr());
  1058. X        spanic("missing code file");
  1059. X    }
  1060. X    Read(fh,&x,4);    /* HUNK_HEADER */
  1061. X    Read(fh,&x,4);    /* 0 */
  1062. X    Read(fh,&hc,4);    /* table size */
  1063. X#ifdef LDEBUG
  1064. X    fprintf(stderr,"hunk count=%d\n",hc);
  1065. X#endif
  1066. X#ifndef SDEBUG
  1067. X    $ovl_hunktable= (long*(*)[])$ovl_AllocMem(hc*4);
  1068. X    $ovl_hunktablesize=hc*4;
  1069. X#endif
  1070. X#ifdef LDEBUG
  1071. X    fprintf(stderr,"table at %08x\n",$ovl_hunktable);
  1072. X#endif
  1073. X    Read(fh,&x,4);    /* F==0 */
  1074. X    Read(fh,&x,4);    /* L==size-1 */
  1075. X    for(c=0;c<hc;c++){
  1076. X        Read(fh,&x,4);
  1077. X#ifdef SDEBUG
  1078. X        xx=$ovl_hunktable[c]=$ovl_AllocMem(x*4);
  1079. X#else
  1080. X        xx=(*$ovl_hunktable)[c]=$ovl_AllocMem(x*4);
  1081. X#endif
  1082. X#ifdef LDEBUG
  1083. X        fprintf(stderr,"t[%d]=%08x, len=%08x\n",c,xx,((long*)xx)[-2]);
  1084. X#endif
  1085. X    }
  1086. X#ifdef LDEBUG
  1087. X    fprintf(stderr,"TABLE LOADED\n");Delay(50);
  1088. X#endif
  1089. X    for(c=0,xp=(unsigned long*)1;xp;c++){
  1090. X#ifdef LDEBUG
  1091. X# ifdef SDEBUG
  1092. X        yy=$ovl_hunktable[c];
  1093. X# else
  1094. X        yy=(*$ovl_hunktable)[c];
  1095. X# endif
  1096. X        fprintf(stderr,"loading hunk %d@%08x len=%08x\n",c,yy,yy[-2]);
  1097. X#endif
  1098. X#ifdef SDEBUG
  1099. X        xp=load_hunk(fh,dummy,$ovl_hunktable[c]);
  1100. X#else
  1101. X        xp=load_hunk(fh,dummy,(*$ovl_hunktable)[c]);
  1102. X#endif
  1103. X    }
  1104. X    database=c-1;    /* first hunk for use for data on each load */
  1105. X    Close(fh);
  1106. X#ifdef LDEBUG
  1107. X# ifdef SDEBUG
  1108. X    fprintf(stderr,"retval=%08x\n",$ovl_hunktable[0]);
  1109. X# else
  1110. X    fprintf(stderr,"retval=%08x\n",(*$ovl_hunktable)[0]);
  1111. X# endif
  1112. X#endif
  1113. X#ifdef SDEBUG
  1114. X    r= (unsigned long) $ovl_hunktable[0];        /* BPTR to seglist */
  1115. X#else
  1116. X    r= (unsigned long) (*$ovl_hunktable)[0];    /* BPTR to seglist */
  1117. X#endif
  1118. X    return (BPTR)(r>>2)-1;
  1119. X}
  1120. X
  1121. Xvoid
  1122. Xload_data(fl,dir)
  1123. X    int fl;
  1124. X    char *dir;
  1125. X{
  1126. X    int c;
  1127. X    unsigned long *x;
  1128. X#ifdef MULTI
  1129. X    mo.r.mor_tag='D';
  1130. X    fh=MultiOpen(dir,MODE_OLDFILE,&mo);
  1131. X#else
  1132. X    fh=Open("s_NetHack.d00",MODE_OLDFILE);
  1133. X#endif
  1134. X            /* doing it this way we don't need the hunk count */
  1135. X    for(c=database,x=(unsigned long*)1;x;c++){
  1136. X#ifdef SDEBUG
  1137. X        x=load_hunk(fh,fl,$ovl_hunktable[c]);
  1138. X#else
  1139. X        x=load_hunk(fh,fl,(*$ovl_hunktable)[c]);
  1140. X#endif
  1141. X    }
  1142. X#ifdef LDEBUG
  1143. X    fprintf(stderr,"end of load_data (waiting)\n");
  1144. X    getchar();
  1145. X#endif
  1146. X    Close(fh);
  1147. X}
  1148. X
  1149. Xunsigned long *
  1150. Xload_hunk(ovlfile,fl,lbase)
  1151. X    BPTR ovlfile;        /* AmigaDOS file handle */
  1152. X    int fl;
  1153. X    ULONG *lbase;
  1154. X{
  1155. X    unsigned long data[2];
  1156. X    unsigned long *where;
  1157. X    unsigned long reloc_type;
  1158. X
  1159. X#ifdef LDEBUG
  1160. X    {
  1161. X    int pos=Seek(ovlfile,0,0);
  1162. X    fprintf(stderr,"load_hunk (fpos=%08x) @%08x len=%08x(%08x)\n",pos,
  1163. X    lbase,lbase[-2],lbase[-2]/4);
  1164. X    }
  1165. X#endif
  1166. X    if(0==Read(ovlfile,data,sizeof(data))){
  1167. X#ifdef LDEBUG
  1168. X        fprintf(stderr,"getchar EOF\n");
  1169. X        getchar();
  1170. X#endif
  1171. X        return(0);    /* EOF */
  1172. X    }
  1173. X#ifdef LDEBUG
  1174. X    fprintf(stderr,"read type=%08x len=%08x(longs)\n",data[0],data[1]);
  1175. X#endif
  1176. X    if( HT(data[0])!=HUNK_CODE &&
  1177. X        HT(data[0])!=HUNK_DATA &&
  1178. X        HT(data[0])!=HUNK_BSS){
  1179. X        fprintf(stderr,"bad data=%08x\n",data[0]);
  1180. X        spanic("ovlfile cookie botch");
  1181. X    }
  1182. X    where=lbase;
  1183. X#if 0
  1184. X                /* clear memory if:
  1185. X                 * 1. not the first time (MEMF_CLEAR'd already)
  1186. X                 * 2. data or bss (just in case)
  1187. X                 * This is just a sanity check since these are
  1188. X                 * the only hunks we should be seeing on reload.
  1189. X                 */
  1190. X    if(fl==F_RELOAD && (HT(data[0])==HUNK_DATA || HT(data[0])==HUNK_BSS)
  1191. X#endif
  1192. X    {
  1193. X        ULONG *p=where;        /* clear memory block */
  1194. X        ULONG c=(where[-2]/4)-1;    /* (len includes ptr) */
  1195. X        if(!TypeOfMem(p))spanic("clearing bogus memory");
  1196. X        while(c--)*p++=0;    /* not memset - use longs for speed */
  1197. X    }
  1198. X
  1199. X    if(HT(data[0])==HUNK_DATA || HT(data[0])==HUNK_CODE){
  1200. X        xx=Read(ovlfile,where,data[1]*4);    /* load the block */
  1201. X        if(xx!=data[1]*4){
  1202. X            fprintf(stderr,"Read(%08x,%08x)->%08x\n",where,
  1203. X              data[1]*4,xx);
  1204. X            spanic("out of data");
  1205. X        }
  1206. X    } else {
  1207. X#ifdef LDEBUG
  1208. X        fprintf(stderr,"BSS - no load\n");
  1209. X#endif
  1210. X    }
  1211. X            /* link/relocate as needed */
  1212. X            /* NB this could be done faster if we keep a buffer of
  1213. X             * relocation information (instead of issuing 4 byte
  1214. X             * Reads)
  1215. X             */
  1216. X    xx=Read(ovlfile,&reloc_type,sizeof(reloc_type));
  1217. X    if(xx!=sizeof(reloc_type))spanic("lost reloc_type");
  1218. X    while(reloc_type!=HUNK_END){
  1219. X        unsigned long reloc_count;
  1220. X        unsigned long reloc_hunk;
  1221. X        unsigned long *base;
  1222. X        unsigned long reloc_offset;
  1223. X        if(reloc_type!=HUNK_RELOC32){
  1224. X            if(reloc_type==HUNK_END)continue;    /* and quit */
  1225. X            fprintf(stderr,"bad data %08x\n",reloc_type);
  1226. X            spanic("ovlfile reloc cookie botch");
  1227. X        }
  1228. X        xx=Read(ovlfile,&reloc_count,sizeof(reloc_count));
  1229. X        if(xx!=sizeof(reloc_count))spanic("lost reloc_count");
  1230. X        while(reloc_count){
  1231. X            xx=Read(ovlfile,&reloc_hunk,sizeof(reloc_hunk));
  1232. X            if(xx!=sizeof(reloc_count))spanic("lost reloc_hunk");
  1233. X#ifdef SDEBUG
  1234. X            base=$ovl_hunktable[reloc_hunk];
  1235. X#else
  1236. X            base=(*$ovl_hunktable)[reloc_hunk];
  1237. X#endif
  1238. X#ifdef LDEBUG
  1239. X            fprintf(stderr,"reloc #%d: hunk #%d@%08x\n",
  1240. X              reloc_count,reloc_hunk,base);
  1241. X#endif
  1242. X            while(reloc_count--){
  1243. X                xx=Read(ovlfile,&reloc_offset,sizeof(long));
  1244. X                if(xx!=sizeof(reloc_count))
  1245. X                    spanic("lost offset");
  1246. X                if(reloc_offset<0 || reloc_offset>where[-2]){
  1247. X                    fprintf(stderr,"where[-2]==%08x\n",
  1248. X                      where[-2]);
  1249. X                    spanic("offset out of hunk");
  1250. X                }
  1251. X                {
  1252. X                ULONG *p=(ULONG*)(((ULONG)where)+reloc_offset);
  1253. X#ifdef PARANOID
  1254. X/* NB - nasty violation of signed/unsigned here */
  1255. X                {
  1256. X                if(*p > base[-2])
  1257. X                  fprintf(stderr,
  1258. X                  "WARNING: offset points outside block\n");
  1259. X                }
  1260. X#endif
  1261. X#ifdef LDEBUG
  1262. X                fprintf(stderr,
  1263. X                  "reloc_offset=%08x where=%08x p=%08x\n",
  1264. X                  reloc_offset,where,p);
  1265. X                fprintf(stderr," current *p=%08x\n",*p);
  1266. X#endif
  1267. X                (*p)+=(unsigned long)base;
  1268. X#ifdef LDEBUG
  1269. X                fprintf(stderr," new *p=%08x\n",*p);
  1270. X#endif
  1271. X                }
  1272. X            }
  1273. X            xx=Read(ovlfile,&reloc_count,sizeof(reloc_count));
  1274. X            if(xx!=sizeof(reloc_count))spanic("lost reloc_count2");
  1275. X        }
  1276. X        xx=Read(ovlfile,&reloc_type,sizeof(reloc_type));
  1277. X        if(xx!=sizeof(reloc_count))spanic("lost reloc_type2");
  1278. X    }
  1279. X    return(where);            /* return execute start point */
  1280. X}
  1281. X
  1282. X/*
  1283. X    -2    len (bytes)
  1284. X    -1    next block
  1285. X     0    data
  1286. X */
  1287. Xvoid *
  1288. X$ovl_AllocMem(len)
  1289. X    unsigned int len;
  1290. X    {
  1291. X    unsigned long *adr;
  1292. X    ULONG length=(len&0x0fffffff);
  1293. X                /* Always clear the memory.  On reload of
  1294. X                 * bss or data we have to do it manually */
  1295. X    adr=AllocMem(length+8,(6&(len>>29))|MEMF_CLEAR);
  1296. X    {
  1297. X        int type=6&(len>>29);
  1298. X        if(    type!=MEMF_CHIP &&
  1299. X            type!=MEMF_FAST &&
  1300. X            type!=MEMF_PUBLIC &&
  1301. X            type != 0
  1302. X        ){
  1303. X            printf("%08x %08x* ",len,type);
  1304. X            spanic("bad memory type");
  1305. X        }
  1306. X    }
  1307. X    if(!adr)spanic("allocation failure");
  1308. X    adr[0]=length;
  1309. X#ifndef NOCLEAN
  1310. X    adr[1]=(unsigned long)$ovlmemchain;    /* list for freeing at end */
  1311. X    $ovlmemchain=((long)adr>>2)+1;    /* BPTR to next ptr */
  1312. X# ifdef LDEBUG
  1313. X    fprintf(stderr,"Alloc: adr[0]=%08x adr[1]=%08x\n",adr[0],adr[1]);
  1314. X# endif
  1315. X#endif
  1316. X    return adr+2;
  1317. X}
  1318. X
  1319. Xvoid
  1320. Xs_UnLoadSeg()
  1321. X{
  1322. X#ifndef NOCLEAN
  1323. X    BPTR p,p1;
  1324. X
  1325. X# ifdef LDEBUG
  1326. X    fprintf(stderr,"starting Free loop: ovlmemchain=%x\n",$ovlmemchain);
  1327. X# endif
  1328. X    for(p=$ovlmemchain;p;p=p1){
  1329. X        p1=*(BPTR *)BADDR(p);
  1330. X# ifdef LDEBUG
  1331. X        fprintf(stderr,"Free(%x,%x)\n",BADDR(p-1),
  1332. X          (*(long *)BADDR(p-1))+8);
  1333. X# endif
  1334. X        FreeMem(BADDR(p-1),(*(long *)BADDR(p-1))+8);
  1335. X    }
  1336. X#endif
  1337. X#ifndef SDEBUG
  1338. X    FreeMem($ovl_hunktable,$ovl_hunktablesize);
  1339. X#endif
  1340. X    return;
  1341. X}
  1342. X
  1343. X/* this needs to be improved and integrated with wb.c */
  1344. Xvoid
  1345. Xspanic(s)
  1346. X    char *s;
  1347. X{
  1348. X    fprintf(stderr,"s_LoadSeg failed: %s\n",s);
  1349. X    getchar();
  1350. X    exit(1);
  1351. X}
  1352. X#endif /* SPLIT */
  1353. END_OF_FILE
  1354. if test 9595 -ne `wc -c <'sys/amiga/splitter/loader.c'`; then
  1355.     echo shar: \"'sys/amiga/splitter/loader.c'\" unpacked with wrong size!
  1356. fi
  1357. # end of 'sys/amiga/splitter/loader.c'
  1358. fi
  1359. if test -f 'sys/share/pcmain.c' -a "${1}" != "-c" ; then 
  1360.   echo shar: Will not clobber existing file \"'sys/share/pcmain.c'\"
  1361. else
  1362. echo shar: Extracting \"'sys/share/pcmain.c'\" \(9810 characters\)
  1363. sed "s/^X//" >'sys/share/pcmain.c' <<'END_OF_FILE'
  1364. X/*    SCCS Id: @(#)pcmain.c    3.1    92/12/04    */
  1365. X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  1366. X/* NetHack may be freely redistributed.  See license for details. */
  1367. X
  1368. X/* main.c - MSDOS, OS/2, ST, and Amiga NetHack */
  1369. X
  1370. X#include "hack.h"
  1371. X
  1372. X#ifndef NO_SIGNAL
  1373. X#include <signal.h>
  1374. X#endif
  1375. X
  1376. X#include <ctype.h>
  1377. X
  1378. X#if !defined(AMIGA) && !defined(GNUDOS)
  1379. X#include <sys\stat.h>
  1380. X#else
  1381. X# ifdef GNUDOS
  1382. X#include <sys/stat.h>
  1383. X# endif
  1384. X#endif
  1385. X
  1386. X#if !defined(LATTICE)
  1387. Xchar orgdir[PATHLEN];
  1388. X#endif
  1389. X
  1390. X#ifdef MFLOPPY
  1391. Xstruct finfo    zfinfo = ZFINFO;
  1392. Xint i;
  1393. X#endif /* MFLOPPY */
  1394. X
  1395. X#ifdef TOS
  1396. Xboolean run_from_desktop = TRUE;    /* should we pause before exiting?? */
  1397. X# ifdef __GNUC__
  1398. Xlong _stksize = 16*1024;
  1399. X# endif
  1400. X#endif
  1401. X
  1402. X#ifdef AMIGA
  1403. Xextern int bigscreen;
  1404. X#endif
  1405. X
  1406. Xstatic void FDECL(process_options,(int argc,char **argv));
  1407. X
  1408. Xint FDECL(main, (int,char **));
  1409. X
  1410. Xconst char *classes = "ABCEHKPRSTVW";
  1411. X
  1412. Xint
  1413. Xmain(argc,argv)
  1414. Xint argc;
  1415. Xchar *argv[];
  1416. X{
  1417. X    register int fd;
  1418. X    register char *dir;
  1419. X#ifdef TOS
  1420. X    long clock_time;
  1421. X    if (*argv[0]) {            /* only a CLI can give us argv[0] */
  1422. X        hname = argv[0];
  1423. X        run_from_desktop = FALSE;
  1424. X    } else
  1425. X#endif
  1426. X        hname = "NetHack";    /* used for syntax messages */
  1427. X
  1428. X    choose_windows(DEFAULT_WINDOW_SYS);
  1429. X
  1430. X#if !defined(AMIGA) && !defined(GNUDOS)
  1431. X    /* Save current directory and make sure it gets restored when
  1432. X     * the game is exited.
  1433. X     */
  1434. X    if (getcwd(orgdir, sizeof orgdir) == NULL)
  1435. X        error("NetHack: current directory path too long");
  1436. X# ifndef NO_SIGNAL
  1437. X    signal(SIGINT, (SIG_RET_TYPE) exit);    /* restore original directory */
  1438. X# endif
  1439. X#endif /* !AMIGA && !GNUDOS */
  1440. X
  1441. X    dir = getenv("NETHACKDIR");
  1442. X    if (dir == NULL)
  1443. X        dir = getenv("HACKDIR");
  1444. X    if (dir != NULL) {
  1445. X        Strcpy(hackdir, dir);
  1446. X#ifdef CHDIR
  1447. X        chdirx (dir, 1);
  1448. X#endif
  1449. X    }
  1450. X#if defined(AMIGA) && defined(CHDIR)
  1451. X    /*
  1452. X     * If we're dealing with workbench, change the directory.  Otherwise
  1453. X     * we could get "Insert disk in drive 0" messages. (Must be done
  1454. X     * before initoptions())....
  1455. X     */
  1456. X    if(argc == 0)
  1457. X        chdirx(HACKDIR, 1);
  1458. X#endif
  1459. X
  1460. X#ifdef MFLOPPY
  1461. X    /* zero "fileinfo" array to prevent crashes on level change */
  1462. X    for (i = 0 ; i <= MAXLEVEL; i++) {
  1463. X        fileinfo[i] = zfinfo;
  1464. X    }
  1465. X#endif /* MFLOPPY */
  1466. X#ifdef AMIGA
  1467. X    ami_argc=argc;
  1468. X    ami_argv=argv;
  1469. X#endif
  1470. X    initoptions();
  1471. X
  1472. X#if defined(TOS) && defined(TEXTCOLOR)
  1473. X    if (flags.BIOS && flags.use_color)
  1474. X        set_colors();
  1475. X#endif
  1476. X    if (!hackdir[0])
  1477. X#if !defined(LATTICE) && !defined(AMIGA)
  1478. X        Strcpy(hackdir, orgdir);
  1479. X#else
  1480. X        Strcpy(hackdir, HACKDIR);
  1481. X#endif
  1482. X    if(argc > 1) {
  1483. X        if (!strncmp(argv[1], "-d", 2) && argv[1][2] != 'e') {
  1484. X        /* avoid matching "-dec" for DECgraphics; since the man page
  1485. X         * says -d directory, hope nobody's using -desomething_else
  1486. X         */
  1487. X        argc--;
  1488. X        argv++;
  1489. X        dir = argv[0]+2;
  1490. X        if(*dir == '=' || *dir == ':') dir++;
  1491. X        if(!*dir && argc > 1) {
  1492. X            argc--;
  1493. X            argv++;
  1494. X            dir = argv[0];
  1495. X        }
  1496. X        if(!*dir)
  1497. X            error("Flag -d must be followed by a directory name.");
  1498. X        Strcpy(hackdir, dir);
  1499. X        } else
  1500. X
  1501. X    /*
  1502. X     * Now we know the directory containing 'record' and
  1503. X     * may do a prscore().
  1504. X     */
  1505. X        if (!strncmp(argv[1], "-s", 2)) {
  1506. X#ifdef CHDIR
  1507. X        chdirx(hackdir,0);
  1508. X#endif
  1509. X        prscore(argc, argv);
  1510. X        exit(0);
  1511. X        }
  1512. X    }
  1513. X
  1514. X    /*
  1515. X     * It seems you really want to play.
  1516. X     */
  1517. X    setrandom();
  1518. X
  1519. X#ifdef TOS
  1520. X    if (comp_times((long)time(&clock_time)))
  1521. X        error("Your clock is incorrectly set!");
  1522. X#endif
  1523. X    u.uhp = 1;    /* prevent RIP on early quits */
  1524. X    u.ux = 0;    /* prevent flush_screen() */
  1525. X
  1526. X    /*
  1527. X     * Find the creation date of this game,
  1528. X     * so as to avoid restoring outdated savefiles.
  1529. X     */
  1530. X    /* gethdate(hname); */
  1531. X
  1532. X    /*
  1533. X     * We cannot do chdir earlier, otherwise gethdate will fail.
  1534. X     */
  1535. X#ifdef CHDIR
  1536. X    chdirx(hackdir,1);
  1537. X#endif
  1538. X
  1539. X    process_options(argc, argv);
  1540. X
  1541. X#ifdef AMIGA
  1542. X    ami_wbench_args();
  1543. X#endif
  1544. X    init_nhwindows();
  1545. X#ifdef MFLOPPY
  1546. X    set_lock_and_bones();
  1547. X# ifndef AMIGA
  1548. X    copybones(FROMPERM);
  1549. X# endif
  1550. X#endif
  1551. X#ifdef WIZARD
  1552. X    if (wizard)
  1553. X        Strcpy(plname, "wizard");
  1554. X    else
  1555. X#endif
  1556. X    if (!*plname)
  1557. X        askname();
  1558. X    plnamesuffix();        /* strip suffix from name; calls askname() */
  1559. X                /* again if suffix was whole name */
  1560. X                /* accepts any suffix */
  1561. X#ifndef MFLOPPY
  1562. X    Strcpy(lock,plname);
  1563. X    Strcat(lock,".99");
  1564. X    regularize(lock);    /* is this necessary? */
  1565. X#endif
  1566. X
  1567. X    /* set up level 0 file to keep game state in */
  1568. X    /* this will have to be expanded to something like the
  1569. X     * UNIX/VMS getlock() to allow networked PCs in any case
  1570. X     */
  1571. X    fd = create_levelfile(0);
  1572. X    if (fd < 0) {
  1573. X        raw_print("Cannot create lock file");
  1574. X    } else {
  1575. X        hackpid = 1;
  1576. X        write(fd, (genericptr_t) &hackpid, sizeof(hackpid));
  1577. X        close(fd);
  1578. X    }
  1579. X#ifdef MFLOPPY
  1580. X        fileinfo[0].where = ACTIVE;
  1581. X#endif
  1582. X
  1583. X    /*
  1584. X     * Initialisation of the boundaries of the mazes
  1585. X     * Both boundaries have to be even.
  1586. X     */
  1587. X
  1588. X    x_maze_max = COLNO-1;
  1589. X    if (x_maze_max % 2)
  1590. X        x_maze_max--;
  1591. X    y_maze_max = ROWNO-1;
  1592. X    if (y_maze_max % 2)
  1593. X        y_maze_max--;
  1594. X
  1595. X    /*
  1596. X     *  Initialize the vision system.  This must be before mklev() on a
  1597. X     *  new game or before a level restore on a saved game.
  1598. X     */
  1599. X    vision_init();
  1600. X
  1601. X    display_gamewindows();
  1602. X
  1603. X    set_savefile_name();
  1604. X
  1605. X    if (
  1606. X#ifdef MFLOPPY
  1607. X# ifdef AMIGA
  1608. X        (FromWBench || saveDiskPrompt(1)) &&
  1609. X# else
  1610. X        saveDiskPrompt(1) &&
  1611. X# endif
  1612. X#endif /* MFLOPPY */
  1613. X        ((fd = open_savefile()) >= 0) &&
  1614. X       /* if not up-to-date, quietly unlink file via false condition */
  1615. X       (uptodate(fd) || ((void)close(fd), delete_savefile()))) {
  1616. X#ifdef WIZARD
  1617. X        /* Since wizard is actually flags.debug, restoring might
  1618. X         * overwrite it.
  1619. X         */
  1620. X        boolean remember_wiz_mode = wizard;
  1621. X#endif
  1622. X#ifndef NO_SIGNAL
  1623. X        (void) signal(SIGINT, (SIG_RET_TYPE) done1);
  1624. X#endif
  1625. X#ifdef NEWS
  1626. X        if(flags.news) display_file(NEWS, FALSE);
  1627. X#endif
  1628. X        pline("Restoring save file...");
  1629. X        mark_synch();    /* flush output */
  1630. X
  1631. X        if(!dorecover(fd))
  1632. X            goto not_recovered;
  1633. X#ifdef WIZARD
  1634. X        if(!wizard && remember_wiz_mode) wizard = TRUE;
  1635. X#endif
  1636. X        pline("Hello %s, welcome back to NetHack!", plname);
  1637. X        check_special_room(FALSE);
  1638. X
  1639. X#ifdef EXPLORE_MODE
  1640. X        if (discover)
  1641. X            You("are in non-scoring discovery mode.");
  1642. X#endif
  1643. X#if defined(EXPLORE_MODE) || defined(WIZARD)
  1644. X        if (discover || wizard) {
  1645. X            if(yn("Do you want to keep the save file?") == 'n'){
  1646. X                (void) delete_savefile();
  1647. X            }
  1648. X#ifdef AMIGA
  1649. X            else
  1650. X                preserve_icon();
  1651. X#endif
  1652. X        }
  1653. X#endif
  1654. X        flags.move = 0;
  1655. X    } else {
  1656. Xnot_recovered:
  1657. X        player_selection();
  1658. X        newgame();
  1659. X        /* give welcome message before pickup messages */
  1660. X        pline("Hello %s, welcome to NetHack!", plname);
  1661. X#ifdef EXPLORE_MODE
  1662. X        if (discover)
  1663. X            You("are in non-scoring discovery mode.");
  1664. X#endif
  1665. X        flags.move = 0;
  1666. X        set_wear();
  1667. X        pickup(1);
  1668. X        read_engr_at(u.ux,u.uy);
  1669. X    }
  1670. X    
  1671. X    flags.moonphase = phase_of_the_moon();
  1672. X    if(flags.moonphase == FULL_MOON) {
  1673. X        You("are lucky!  Full moon tonight.");
  1674. X        change_luck(1);
  1675. X    } else if(flags.moonphase == NEW_MOON) {
  1676. X        pline("Be careful!  New moon tonight.");
  1677. X    }
  1678. X    if(flags.friday13 = friday_13th()) {
  1679. X        pline("Watch out!  Bad things can happen on Friday the 13th.");
  1680. X        change_luck(-1);
  1681. X    }
  1682. X
  1683. X    initrack();
  1684. X#ifndef NO_SIGNAL
  1685. X    (void) signal(SIGINT, SIG_IGN);
  1686. X#endif
  1687. X#ifdef OS2
  1688. X    gettty(); /* somehow ctrl-P gets turned back on during startup ... */
  1689. X#endif
  1690. X
  1691. X    moveloop();
  1692. X    return 0;
  1693. X}
  1694. X
  1695. Xstatic void
  1696. Xprocess_options(argc, argv)
  1697. Xint argc;
  1698. Xchar *argv[];
  1699. X{
  1700. X    /*
  1701. X     * Process options.
  1702. X     */
  1703. X    while(argc > 1 && argv[1][0] == '-'){
  1704. X        argv++;
  1705. X        argc--;
  1706. X        switch(argv[0][1]){
  1707. X#if defined(WIZARD) || defined(EXPLORE_MODE)
  1708. X# ifndef EXPLORE_MODE
  1709. X        case 'X':
  1710. X# endif
  1711. X        case 'D':
  1712. X# ifdef WIZARD
  1713. X            /* Must have "name" set correctly by NETHACK.CNF,
  1714. X             * NETHACKOPTIONS, or -u
  1715. X             * before this flag to enter wizard mode. */
  1716. X#  ifdef KR1ED
  1717. X            if(!strcmp(plname, WIZARD_NAME)) {
  1718. X#  else
  1719. X            if(!strcmp(plname, WIZARD)) {
  1720. X#  endif
  1721. X                wizard = TRUE;
  1722. X                break;
  1723. X            }
  1724. X            /* otherwise fall thru to discover */
  1725. X# endif
  1726. X# ifdef EXPLORE_MODE
  1727. X        case 'X':
  1728. X            discover = TRUE;
  1729. X# endif
  1730. X            break;
  1731. X#endif
  1732. X#ifdef NEWS
  1733. X        case 'n':
  1734. X            flags.news = FALSE;
  1735. X            break;
  1736. X#endif
  1737. X        case 'u':
  1738. X            if(argv[0][2])
  1739. X              (void) strncpy(plname, argv[0]+2, sizeof(plname)-1);
  1740. X            else if(argc > 1) {
  1741. X              argc--;
  1742. X              argv++;
  1743. X              (void) strncpy(plname, argv[0], sizeof(plname)-1);
  1744. X            } else
  1745. X                raw_print("Player name expected after -u");
  1746. X            break;
  1747. X#ifndef AMIGA
  1748. X        case 'I':
  1749. X        case 'i':
  1750. X            if (!strncmpi(argv[0]+1, "IBM", 3))
  1751. X                switch_graphics(IBM_GRAPHICS);
  1752. X            break;
  1753. X        /*  case 'D': */
  1754. X        case 'd':
  1755. X            if (!strncmpi(argv[0]+1, "DEC", 3))
  1756. X                switch_graphics(DEC_GRAPHICS);
  1757. X            break;
  1758. X#endif
  1759. X#ifdef MFLOPPY
  1760. X# ifndef AMIGA
  1761. X        /* Player doesn't want to use a RAM disk
  1762. X         */
  1763. X        case 'r':
  1764. X            ramdisk = FALSE;
  1765. X            break;
  1766. X# endif
  1767. X#endif
  1768. X#ifdef AMIGA
  1769. X            /* interlaced and non-interlaced screens */
  1770. X        case 'L':
  1771. X            bigscreen = 1;
  1772. X            break;
  1773. X        case 'l':
  1774. X            bigscreen = -1;
  1775. X            break;
  1776. X#endif
  1777. X        default:
  1778. X            if (index(classes, toupper(argv[0][1]))) {
  1779. X                /* allow -T for Tourist, etc. */
  1780. X                (void) strncpy(pl_character, argv[0]+1,
  1781. X                           sizeof(pl_character)-1);
  1782. X                break;
  1783. X            } else raw_printf("\nUnknown switch: %s", argv[0]);
  1784. X        case '?':
  1785. X            (void) printf(
  1786. X            "\nUsage: %s [-d dir] -s [-[%s]] [maxrank] [name]...",
  1787. X            hname, classes);
  1788. X            (void) printf("\n       or");
  1789. X            (void) printf("\n       %s [-d dir] [-u name] [-[%s]]",
  1790. X            hname, classes);
  1791. X#if defined(WIZARD) || defined(EXPLORE_MODE)
  1792. X            (void) printf(" [-[DX]]");
  1793. X#endif
  1794. X#ifdef NEWS
  1795. X            (void) printf(" [-n]");
  1796. X#endif
  1797. X#ifdef MFLOPPY
  1798. X# ifndef AMIGA
  1799. X            (void) printf(" [-r]");
  1800. X# endif
  1801. X#endif
  1802. X            putchar('\n');
  1803. X            exit(0);
  1804. X        }
  1805. X    }
  1806. X}
  1807. X
  1808. X#ifdef CHDIR
  1809. Xvoid
  1810. Xchdirx(dir, wr)
  1811. Xchar *dir;
  1812. Xboolean wr;
  1813. X{
  1814. X#ifdef AMIGA
  1815. X    static char thisdir[] = "";
  1816. X#else
  1817. X    static char thisdir[] = ".";
  1818. X#endif
  1819. X    if(dir && chdir(dir) < 0) {
  1820. X        error("Cannot chdir to %s.", dir);
  1821. X    }
  1822. X
  1823. X    /* Change the default drive as well.
  1824. X     */
  1825. X#ifndef AMIGA
  1826. X    chdrive(dir);
  1827. X#endif
  1828. X
  1829. X    /* warn the player if we can't write the record file */
  1830. X    /* perhaps we should also test whether . is writable */
  1831. X    /* unfortunately the access system-call is worthless */
  1832. X    if (wr) check_recordfile(dir ? dir : thisdir);
  1833. X}
  1834. X#endif /* CHDIR */
  1835. X
  1836. X/*pcmain.c*/
  1837. END_OF_FILE
  1838. if test 9810 -ne `wc -c <'sys/share/pcmain.c'`; then
  1839.     echo shar: \"'sys/share/pcmain.c'\" unpacked with wrong size!
  1840. fi
  1841. # end of 'sys/share/pcmain.c'
  1842. fi
  1843. if test -f 'win/X11/wintext.c' -a "${1}" != "-c" ; then 
  1844.   echo shar: Will not clobber existing file \"'win/X11/wintext.c'\"
  1845. else
  1846. echo shar: Extracting \"'win/X11/wintext.c'\" \(9488 characters\)
  1847. sed "s/^X//" >'win/X11/wintext.c' <<'END_OF_FILE'
  1848. X/*    SCCS Id: @(#)wintext.c    3.1    92/3/7
  1849. X/* Copyright (c) Dean Luick, 1992                  */
  1850. X/* NetHack may be freely redistributed.  See license for details. */
  1851. X
  1852. X/*
  1853. X * File for dealing with text windows.
  1854. X * 
  1855. X *     + No global functions.
  1856. X */
  1857. X#include <X11/Intrinsic.h>
  1858. X#include <X11/StringDefs.h>
  1859. X#include <X11/Shell.h>
  1860. X#include <X11/Xos.h>
  1861. X#include <X11/Xaw/AsciiText.h>
  1862. X#include <X11/Xaw/Cardinals.h>
  1863. X
  1864. X#include "hack.h"
  1865. X#include "winX.h"
  1866. X
  1867. X
  1868. X#define TRANSIENT_TEXT    /* text window is a transient window (no positioning) */
  1869. X
  1870. Xstatic const char text_translations[] =
  1871. X    "#override\n\
  1872. X     <BtnDown>: dismiss_text()\n\
  1873. X     <Key>: key_dismiss_text()";
  1874. X
  1875. X/*
  1876. X * Callback used for all text windows.  The window is poped down on any key
  1877. X * or button down event.  It is destroyed if the main nethack code is done
  1878. X * with it.
  1879. X */
  1880. X/*ARGSUSED*/
  1881. Xvoid
  1882. Xdismiss_text(w, event, params, num_params)
  1883. X    Widget w;
  1884. X    XEvent *event;
  1885. X    String *params;
  1886. X    Cardinal *num_params;
  1887. X{
  1888. X    struct xwindow *wp;
  1889. X    struct text_info_t *text_info;
  1890. X    Widget popup = XtParent(w);
  1891. X
  1892. X    wp = find_widget(w);
  1893. X    text_info = wp->text_information;
  1894. X
  1895. X    nh_XtPopdown(popup);
  1896. X
  1897. X    if (text_info->blocked) {
  1898. X    exit_x_event = TRUE;
  1899. X    } else if (text_info->destroy_on_ack) {
  1900. X    destroy_text_window(wp);
  1901. X    }
  1902. X}
  1903. X
  1904. X/* Dismiss when a non-modifier key pressed. */
  1905. Xvoid
  1906. Xkey_dismiss_text(w, event, params, num_params)
  1907. X    Widget w;
  1908. X    XEvent *event;
  1909. X    String *params;
  1910. X    Cardinal *num_params;
  1911. X{
  1912. X    char ch = key_event_to_char((XKeyEvent *) event);
  1913. X    if (ch) dismiss_text(w, event, params, num_params);
  1914. X}
  1915. X
  1916. X/* ARGSUSED */
  1917. Xvoid
  1918. Xadd_to_text_window(wp, attr, str)
  1919. X    struct xwindow *wp;
  1920. X    int attr;    /* currently unused */
  1921. X    const char *str;
  1922. X{
  1923. X    struct text_info_t *text_info = wp->text_information;
  1924. X    int width;
  1925. X
  1926. X    append_text_buffer(&text_info->text, str, FALSE);
  1927. X
  1928. X    /* Calculate text width and save longest line */
  1929. X    width = XTextWidth(text_info->fs, str, (int) strlen(str));
  1930. X    if (width > text_info->max_width)
  1931. X    text_info->max_width = width;
  1932. X}
  1933. X
  1934. Xvoid
  1935. Xdisplay_text_window(wp, blocking)
  1936. X    struct xwindow *wp;
  1937. X    boolean blocking;
  1938. X{
  1939. X    struct text_info_t *text_info;
  1940. X    Arg args[8];
  1941. X    Cardinal num_args;
  1942. X    Dimension width, height;
  1943. X    int nlines;
  1944. X
  1945. X    text_info = wp->text_information;
  1946. X    width  = text_info->max_width + text_info->extra_width;
  1947. X    text_info->blocked = blocking;
  1948. X    text_info->destroy_on_ack = FALSE;
  1949. X
  1950. X    /*
  1951. X     * Calculate the number of lines to use.  First, find the number of
  1952. X     * lines that would fit on the screen.  Next, remove four of these
  1953. X     * lines to give room for a possible window manager titlebar (some
  1954. X     * wm's put a titlebar on transient windows).  Make sure we have
  1955. X     * _some_ lines.  Finally, use the number of lines in the text if
  1956. X     * there are fewer than the max.
  1957. X     */
  1958. X    nlines = (XtScreen(wp->w)->height - text_info->extra_height) /
  1959. X            (text_info->fs->ascent + text_info->fs->descent);
  1960. X    nlines -= 4;
  1961. X    if (nlines <= 0) nlines = 1;
  1962. X
  1963. X    if (nlines > text_info->text.num_lines)
  1964. X    nlines = text_info->text.num_lines;
  1965. X
  1966. X    /* Font height is ascent + descent. */
  1967. X    height = (nlines * (text_info->fs->ascent + text_info->fs->descent))
  1968. X                            + text_info->extra_height;
  1969. X
  1970. X    num_args = 0;
  1971. X
  1972. X    if (nlines < text_info->text.num_lines) {
  1973. X    /* add on width of scrollbar.  Really should look this up,
  1974. X     * but can't until the window is realized.  Chicken-and-egg problem.
  1975. X     */
  1976. X    width += 20;
  1977. X    }
  1978. X
  1979. X    if (width > (Dimension) XtScreen(wp->w)->width) { /* too wide for screen */
  1980. X    /* Back off some amount - we really need to back off the scrollbar */
  1981. X    /* width plus some extra.                       */
  1982. X    width = XtScreen(wp->w)->width - 20;
  1983. X    }
  1984. X    XtSetArg(args[num_args], XtNstring, text_info->text.text);    num_args++;
  1985. X    XtSetArg(args[num_args], XtNwidth,  width);            num_args++;
  1986. X    XtSetArg(args[num_args], XtNheight, height);        num_args++;
  1987. X    XtSetValues(wp->w, args, num_args);
  1988. X
  1989. X#ifdef TRANSIENT_TEXT
  1990. X    XtRealizeWidget(wp->popup);
  1991. X    positionpopup(wp->popup);
  1992. X#endif
  1993. X
  1994. X    nh_XtPopup(wp->popup, XtGrabNone, wp->w);
  1995. X
  1996. X    /* Kludge alert.  Scrollbars are not sized correctly by the Text widget */
  1997. X    /* if added before the window is displayed, so do it afterward. */
  1998. X    num_args = 0;
  1999. X    if (nlines < text_info->text.num_lines) {    /* add vert scrollbar */
  2000. X    XtSetArg(args[num_args], XtNscrollVertical, XawtextScrollAlways);
  2001. X                                num_args++;
  2002. X    }
  2003. X    if (width >= (Dimension) (XtScreen(wp->w)->width-20)) {    /* too wide */
  2004. X    XtSetArg(args[num_args], XtNscrollHorizontal, XawtextScrollAlways);
  2005. X                                num_args++;
  2006. X    }
  2007. X    if (num_args) XtSetValues(wp->w, args, num_args);
  2008. X
  2009. X    /* We want the user to acknowlege. */
  2010. X    if (blocking) {
  2011. X    (void) x_event(EXIT_ON_EXIT);
  2012. X    nh_XtPopdown(wp->popup);
  2013. X    }
  2014. X}
  2015. X
  2016. X
  2017. Xvoid
  2018. Xcreate_text_window(wp)
  2019. X    struct xwindow *wp;
  2020. X{
  2021. X    struct text_info_t *text_info;
  2022. X    Arg args[8];
  2023. X    Cardinal num_args;
  2024. X    Position top_margin, bottom_margin, left_margin, right_margin;
  2025. X
  2026. X    wp->type = NHW_TEXT;
  2027. X
  2028. X    wp->text_information = text_info = 
  2029. X            (struct text_info_t *) alloc(sizeof(struct text_info_t));
  2030. X
  2031. X    init_text_buffer(&text_info->text);
  2032. X    text_info->max_width      = 0;
  2033. X    text_info->extra_width    = 0;
  2034. X    text_info->extra_height   = 0;
  2035. X    text_info->blocked          = FALSE;
  2036. X    text_info->destroy_on_ack = TRUE;    /* Ok to destroy before display */
  2037. X
  2038. X    num_args = 0;
  2039. X    XtSetArg(args[num_args], XtNallowShellResize, True); num_args++;
  2040. X
  2041. X#ifdef TRANSIENT_TEXT
  2042. X    wp->popup = XtCreatePopupShell("text", transientShellWidgetClass,
  2043. X                   toplevel, args, num_args);
  2044. X#else
  2045. X    wp->popup = XtCreatePopupShell("text", topLevelShellWidgetClass,
  2046. X                   toplevel, args, num_args);
  2047. X#endif
  2048. X
  2049. X    num_args = 0;
  2050. X    XtSetArg(args[num_args], XtNdisplayCaret, False);        num_args++;
  2051. X    XtSetArg(args[num_args], XtNresize, XawtextResizeBoth);    num_args++;
  2052. X    XtSetArg(args[num_args], XtNtranslations,
  2053. X        XtParseTranslationTable(text_translations));    num_args++;
  2054. X
  2055. X    wp->w = XtCreateManagedWidget(
  2056. X        killer && WIN_MAP == WIN_ERR ?
  2057. X                  "tombstone" : "text_text", /* name */
  2058. X        asciiTextWidgetClass,
  2059. X        wp->popup,        /* parent widget */
  2060. X        args,            /* set some values */
  2061. X        num_args);        /* number of values to set */
  2062. X
  2063. X    /* Get the font and margin information. */
  2064. X    num_args = 0;
  2065. X    XtSetArg(args[num_args], XtNfont,          &text_info->fs); num_args++;
  2066. X    XtSetArg(args[num_args], XtNtopMargin,    &top_margin);    num_args++;
  2067. X    XtSetArg(args[num_args], XtNbottomMargin, &bottom_margin); num_args++;
  2068. X    XtSetArg(args[num_args], XtNleftMargin,   &left_margin);   num_args++;
  2069. X    XtSetArg(args[num_args], XtNrightMargin,  &right_margin);  num_args++;
  2070. X    XtGetValues(wp->w, args, num_args);
  2071. X
  2072. X    text_info->extra_width  = left_margin + right_margin;
  2073. X    text_info->extra_height = top_margin + bottom_margin;
  2074. X}
  2075. X
  2076. Xvoid
  2077. Xdestroy_text_window(wp)
  2078. X    struct xwindow *wp;
  2079. X{
  2080. X    /* Don't need to pop down, this only called from dismiss_text(). */
  2081. X
  2082. X    struct text_info_t *text_info = wp->text_information;
  2083. X
  2084. X    /*
  2085. X     * If the text window was blocked, then the user has already ACK'ed
  2086. X     * it and we are free to really destroy the window.  Otherwise, don't
  2087. X     * destroy until the user dismisses the window via a key or button
  2088. X     * press.
  2089. X     */
  2090. X    if (text_info->blocked || text_info->destroy_on_ack) {
  2091. X    XtDestroyWidget(wp->popup);
  2092. X    free_text_buffer(&text_info->text);
  2093. X    free((char *) text_info);
  2094. X    wp->type = NHW_NONE;    /* allow reuse */
  2095. X    } else {
  2096. X    text_info->destroy_on_ack = TRUE;    /* destroy on next ACK */
  2097. X    }
  2098. X}
  2099. X
  2100. X
  2101. X/* text buffer routines ---------------------------------------------------- */
  2102. X
  2103. X/* Append a line to the text buffer. */
  2104. Xvoid
  2105. Xappend_text_buffer(tb, str, concat)
  2106. X    struct text_buffer *tb;
  2107. X    const char *str;
  2108. X    boolean concat;
  2109. X{
  2110. X    char *copy;
  2111. X    int length;
  2112. X
  2113. X    if (!tb->text) panic("append_text_buffer:  null text buffer");
  2114. X
  2115. X    if (str) {
  2116. X        length = strlen(str);
  2117. X    } else {
  2118. X    length = 0;
  2119. X    }
  2120. X
  2121. X    if (length + tb->text_last + 1 >= tb->text_size) {
  2122. X    /* we need to go to a bigger buffer! */
  2123. X#ifdef VERBOSE
  2124. X    printf("append_text_buffer: text buffer growing from %d to %d bytes\n",
  2125. X                tb->text_size, 2*tb->text_size);
  2126. X#endif
  2127. X    copy = (char *) alloc(tb->text_size*2);
  2128. X    (void) memcpy(copy, tb->text, tb->text_last);
  2129. X    free(tb->text);
  2130. X    tb->text = copy;
  2131. X    tb->text_size *= 2;
  2132. X    }
  2133. X
  2134. X    if (tb->num_lines) {    /* not first --- append a newline */
  2135. X    char appchar = '\n';
  2136. X
  2137. X    if(concat && !index("!.?'\")", tb->text[tb->text_last-1])) {
  2138. X        appchar = ' ';
  2139. X        tb->num_lines--; /* offset increment at end of function */
  2140. X    }
  2141. X
  2142. X    *(tb->text + tb->text_last) = appchar;
  2143. X    tb->text_last++;
  2144. X    }
  2145. X
  2146. X    if (str) {
  2147. X    (void) memcpy((tb->text+tb->text_last), str, length+1);
  2148. X    if(length) {
  2149. X        /* Remove all newlines. Otherwise we have a confused line count. */
  2150. X        copy = (tb->text+tb->text_last);
  2151. X        while (copy = index(copy, '\n'))
  2152. X        *copy = ' ';
  2153. X    }
  2154. X
  2155. X    tb->text_last += length;
  2156. X    }
  2157. X    tb->text[tb->text_last] = '\0';
  2158. X    tb->num_lines++;
  2159. X}
  2160. X
  2161. X/* Initialize text buffer. */
  2162. Xvoid
  2163. Xinit_text_buffer(tb)
  2164. X    struct text_buffer *tb;
  2165. X{
  2166. X    tb->text      = (char *) alloc(START_SIZE);
  2167. X    tb->text[0]   = '\0';
  2168. X    tb->text_size = START_SIZE;
  2169. X    tb->text_last = 0;
  2170. X    tb->num_lines = 0;
  2171. X}
  2172. X
  2173. X/* Empty the text buffer */
  2174. Xvoid
  2175. Xclear_text_buffer(tb)
  2176. X    struct text_buffer *tb;
  2177. X{
  2178. X    tb->text_last = 0;
  2179. X    tb->text[0]   = '\0';
  2180. X    tb->num_lines = 0;
  2181. X}
  2182. X
  2183. X/* Free up allocated memory. */
  2184. Xvoid
  2185. Xfree_text_buffer(tb)
  2186. X    struct text_buffer *tb;
  2187. X{
  2188. X    free(tb->text);
  2189. X    tb->text = (char *) 0;
  2190. X    tb->text_size = 0;
  2191. X    tb->text_last = 0;
  2192. X    tb->num_lines = 0;
  2193. X}
  2194. END_OF_FILE
  2195. if test 9488 -ne `wc -c <'win/X11/wintext.c'`; then
  2196.     echo shar: \"'win/X11/wintext.c'\" unpacked with wrong size!
  2197. fi
  2198. # end of 'win/X11/wintext.c'
  2199. fi
  2200. echo shar: End of archive 93 \(of 108\).
  2201. cp /dev/null ark93isdone
  2202. MISSING=""
  2203. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 \
  2204. 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 \
  2205. 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 \
  2206. 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 \
  2207. 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 \
  2208. 101 102 103 104 105 106 107 108 ; do
  2209.     if test ! -f ark${I}isdone ; then
  2210.     MISSING="${MISSING} ${I}"
  2211.     fi
  2212. done
  2213. if test "${MISSING}" = "" ; then
  2214.     echo You have unpacked all 108 archives.
  2215.     echo "Now execute 'rebuild.sh'"
  2216.     rm -f ark10[0-8]isdone ark[1-9]isdone ark[1-9][0-9]isdone
  2217. else
  2218.     echo You still need to unpack the following archives:
  2219.     echo "        " ${MISSING}
  2220. fi
  2221. ##  End of shell archive.
  2222. exit 0
  2223.