split some code into separate files
new .h files: hacklib.h selvar.h stairs.h
new .c files: calendar.c, getpos.c, report.c, selvar.c, stairs.c,
strutil.c, wizcmds.c
cleanup of hacklib.c and mdlib.c
hacklib contains functions that do not have to link with the core
relocate wiz commands from cmd.c to wizcmds.c
relocate CRASHREPORT stuff to report.c
relocate getpos stuff from do_name.c to getpos.c
remove temporary struct definition from extern.h
cross-compile PRE-section split into cross-pre1.370 and cross-pre2.370
Windows sys/windows/Makefile.nmake and sys/windows/Makefile.mingw32 and
visual studio project file updates
Unix sys/unix/Makefile.src, sys/unix/Makefile.utl
populate selvar.c and selvar.h
build on MS-DOS (not cross-compile) Makefile updates
for sys/msdos/Makefile.GCC (untested)
vms updates for above (untested)
This commit is contained in:
@@ -55,6 +55,7 @@
|
||||
#include <string.h>
|
||||
#include <signal.h>
|
||||
#include <assert.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#endif /* !__cplusplus */
|
||||
#endif /* CSTD_H */
|
||||
|
||||
@@ -31,15 +31,6 @@ typedef struct s_level { /* special dungeon level element */
|
||||
d_flags flags; /* type flags */
|
||||
} s_level;
|
||||
|
||||
typedef struct stairway { /* basic stairway identifier */
|
||||
coordxy sx, sy; /* x / y location of the stair */
|
||||
d_level tolev; /* where does it go */
|
||||
boolean up; /* up or down? */
|
||||
boolean isladder; /* ladder or stairway? */
|
||||
boolean u_traversed; /* hero has traversed this stair */
|
||||
struct stairway *next;
|
||||
} stairway;
|
||||
|
||||
/* level region types */
|
||||
enum level_region_types {
|
||||
LR_DOWNSTAIR = 0,
|
||||
|
||||
+158
-151
@@ -1,4 +1,4 @@
|
||||
/* NetHack 3.7 extern.h $NHDT-Date: 1708126520 2024/02/16 23:35:20 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1384 $ */
|
||||
/* NetHack 3.7 extern.h $NHDT-Date: 1709675219 2024/03/05 21:46:59 $ $NHDT-Branch: keni-mdlib-followup $:$NHDT-Revision: 1.1400 $ */
|
||||
/* Copyright (c) Steve Creps, 1988. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
|
||||
@@ -81,7 +81,8 @@ extern int FITSint_(long long, const char *, int) NONNULLARG2;
|
||||
extern unsigned FITSuint_(unsigned long long, const char *, int) NONNULLARG2;
|
||||
/* for Strlen() which returns unsigned instead of size_t and panics for
|
||||
strings of length INT_MAX (32K - 1) or longer */
|
||||
extern unsigned Strlen_(const char *, const char *, int) NONNULLPTRS;
|
||||
|
||||
#include "hacklib.h"
|
||||
|
||||
/* This next pre-processor directive covers almost the entire file,
|
||||
* interrupted only occasionally to pick up specific functions as needed. */
|
||||
@@ -281,6 +282,22 @@ extern void all_options_statushilites(strbuf_t *);
|
||||
extern boolean status_hilite_menu(void);
|
||||
#endif /* STATUS_HILITES */
|
||||
|
||||
/* ### calendar.c ### */
|
||||
|
||||
extern time_t getnow(void);
|
||||
extern int getyear(void);
|
||||
#if 0
|
||||
extern char *yymmdd(time_t) NONNULL;
|
||||
#endif
|
||||
extern long yyyymmdd(time_t);
|
||||
extern long hhmmss(time_t);
|
||||
extern char *yyyymmddhhmmss(time_t) NONNULL;
|
||||
extern time_t time_from_yyyymmddhhmmss(char *);
|
||||
extern int phase_of_the_moon(void);
|
||||
extern boolean friday_13th(void);
|
||||
extern int night(void);
|
||||
extern int midnight(void);
|
||||
|
||||
/* ### coloratt.c ### */
|
||||
|
||||
extern char *color_attr_to_str(color_attr *);
|
||||
@@ -403,6 +420,7 @@ extern char yn_function(const char *, const char *, char, boolean);
|
||||
extern char paranoid_ynq(boolean, const char *, boolean);
|
||||
extern boolean paranoid_query(boolean, const char *);
|
||||
extern void makemap_prepost(boolean, boolean);
|
||||
extern const char *ecname_from_fn(int (*)(void));
|
||||
|
||||
/* ### date.c ### */
|
||||
|
||||
@@ -594,12 +612,6 @@ extern void heal_legs(int);
|
||||
|
||||
/* ### do_name.c ### */
|
||||
|
||||
extern char *dxdy_to_dist_descr(coordxy, coordxy, boolean);
|
||||
extern char *coord_desc(coordxy, coordxy, char *, char) NONNULLARG3;
|
||||
extern void auto_describe(coordxy, coordxy);
|
||||
extern boolean getpos_menu(coord *, int) NONNULLARG1;
|
||||
extern int getpos(coord *, boolean, const char *) NONNULLARG1;
|
||||
extern void getpos_sethilite(void(*f)(boolean), boolean(*d)(coordxy,coordxy));
|
||||
extern void new_mgivenname(struct monst *, int) NONNULLARG1;
|
||||
extern void free_mgivenname(struct monst *) NONNULLARG1;
|
||||
extern void new_oname(struct obj *, int) NONNULLARG1;
|
||||
@@ -654,8 +666,6 @@ extern const char *pmname(struct permonst *, int) NONNULLARG1;
|
||||
#endif
|
||||
extern const char *mon_pmname(struct monst *) NONNULLARG1;
|
||||
extern const char *obj_pmname(struct obj *) NONNULLARG1;
|
||||
extern boolean mapxy_valid(coordxy, coordxy);
|
||||
extern boolean gather_locs_interesting(coordxy, coordxy, int);
|
||||
|
||||
/* ### do_wear.c ### */
|
||||
|
||||
@@ -802,23 +812,6 @@ extern void next_level(boolean);
|
||||
extern void prev_level(boolean);
|
||||
extern void u_on_newpos(coordxy, coordxy);
|
||||
extern void u_on_rndspot(int);
|
||||
extern void stairway_add(coordxy, coordxy,
|
||||
boolean, boolean, d_level *) NONNULLPTRS;
|
||||
extern void stairway_print(void);
|
||||
extern void stairway_free_all(void);
|
||||
extern stairway *stairway_at(coordxy, coordxy);
|
||||
extern stairway *stairway_find(d_level *) NONNULLARG1;
|
||||
extern stairway *stairway_find_from(d_level *, boolean) NONNULLARG1;
|
||||
extern stairway *stairway_find_dir(boolean);
|
||||
extern stairway *stairway_find_type_dir(boolean, boolean);
|
||||
extern stairway *stairway_find_special_dir(boolean);
|
||||
extern void u_on_sstairs(int);
|
||||
extern void u_on_upstairs(void);
|
||||
extern void u_on_dnstairs(void);
|
||||
extern boolean On_stairs(coordxy, coordxy);
|
||||
extern boolean On_ladder(coordxy, coordxy);
|
||||
extern boolean On_stairs_up(coordxy, coordxy);
|
||||
extern boolean On_stairs_dn(coordxy, coordxy);
|
||||
extern void get_level(d_level *, int) NONNULLARG1;
|
||||
extern boolean Is_botlevel(d_level *) NONNULLARG1;
|
||||
extern boolean Can_fall_thru(d_level *) NONNULLARG1;
|
||||
@@ -845,8 +838,6 @@ extern unsigned int induced_align(int);
|
||||
extern boolean Invocation_lev(d_level *) NONNULLARG1;
|
||||
extern xint16 level_difficulty(void);
|
||||
extern schar lev_by_name(const char *);
|
||||
extern boolean known_branch_stairs(stairway *);
|
||||
extern char *stairs_description(stairway *, char *, boolean) NONNULLARG1;
|
||||
extern schar print_dungeon(boolean, schar *, xint16 *);
|
||||
extern void print_level_annotation(void);
|
||||
extern int donamelevel(void);
|
||||
@@ -914,6 +905,7 @@ extern void done1(int);
|
||||
extern int done2(void);
|
||||
extern void done_in_by(struct monst *, int) NONNULLARG1;
|
||||
extern void done_object_cleanup(void);
|
||||
extern void NH_abort(char *);
|
||||
#endif /* !MAKEDEFS_C && MDLIB_C && !CPPREGEX_C */
|
||||
#if !defined(CPPREGEX_C)
|
||||
ATTRNORETURN extern void panic(const char *, ...) PRINTF_F(1, 2) NORETURN;
|
||||
@@ -927,17 +919,7 @@ extern struct kinfo *find_delayed_killer(int);
|
||||
extern void dealloc_killer(struct kinfo *);
|
||||
extern void save_killers(NHFILE *) NONNULLARG1;
|
||||
extern void restore_killers(NHFILE *) NONNULLARG1;
|
||||
#ifdef CRASHREPORT
|
||||
extern boolean submit_web_report(int, const char *, const char *);
|
||||
extern void crashreport_init(int, char *[]);
|
||||
extern void crashreport_bidshow(void);
|
||||
extern boolean swr_add_uricoded(const char *, char **, int *, char *);
|
||||
extern int dobugreport(void);
|
||||
#endif
|
||||
extern char *build_english_list(char *) NONNULLARG1;
|
||||
#if defined(PANICTRACE) && !defined(NO_SIGNAL)
|
||||
extern void panictrace_setsignals(boolean);
|
||||
#endif
|
||||
|
||||
/* ### engrave.c ### */
|
||||
|
||||
@@ -1084,6 +1066,17 @@ extern void drinksink(void);
|
||||
extern void dipsink(struct obj *) NONNULLARG1;
|
||||
extern void sink_backs_up(coordxy, coordxy);
|
||||
|
||||
/* ### getpos.c ### */
|
||||
|
||||
extern char *dxdy_to_dist_descr(coordxy, coordxy, boolean);
|
||||
extern char *coord_desc(coordxy, coordxy, char *, char) NONNULLARG3;
|
||||
extern void auto_describe(coordxy, coordxy);
|
||||
extern boolean getpos_menu(coord *, int) NONNULLARG1;
|
||||
extern int getpos(coord *, boolean, const char *) NONNULLARG1;
|
||||
extern void getpos_sethilite(void(*f)(boolean), boolean(*d)(coordxy,coordxy));
|
||||
extern boolean mapxy_valid(coordxy, coordxy);
|
||||
extern boolean gather_locs_interesting(coordxy, coordxy, int);
|
||||
|
||||
/* ### hack.c ### */
|
||||
|
||||
extern boolean is_valid_travelpt(coordxy, coordxy);
|
||||
@@ -1143,96 +1136,21 @@ extern int inv_cnt(boolean);
|
||||
/* sometimes money_cnt(gi.invent) which can be null */
|
||||
extern long money_cnt(struct obj *) NO_NNARGS;
|
||||
extern void spot_checks(coordxy, coordxy, schar);
|
||||
|
||||
/* ### hacklib.c ### */
|
||||
|
||||
extern boolean digit(char);
|
||||
extern boolean letter(char);
|
||||
extern char highc(char);
|
||||
extern char lowc(char);
|
||||
extern char *lcase(char *) NONNULL NONNULLARG1;
|
||||
extern char *ucase(char *) NONNULL NONNULLARG1;
|
||||
extern char *upstart(char *); /* ought to be changed to NONNULL NONNULLARG1
|
||||
* and the code changed to not allow NULL arg */
|
||||
extern char *upwords(char *) NONNULL NONNULLARG1;
|
||||
extern char *mungspaces(char *) NONNULL NONNULLARG1;
|
||||
extern char *trimspaces(char *) NONNULL NONNULLARG1;
|
||||
extern char *strip_newline(char *) NONNULL NONNULLARG1;
|
||||
extern char *eos(char *) NONNULL NONNULLARG1;
|
||||
extern const char *c_eos(const char *) NONNULL NONNULLARG1;
|
||||
extern unsigned Strlen_(const char *, const char *, int) NONNULLPTRS;
|
||||
extern boolean str_start_is(const char *, const char *, boolean) NONNULLPTRS;
|
||||
extern boolean str_end_is(const char *, const char *) NONNULLPTRS;
|
||||
extern int str_lines_maxlen(const char *);
|
||||
extern char *strkitten(char *, char) NONNULL NONNULLARG1;
|
||||
extern void copynchars(char *, const char *, int) NONNULLARG12;
|
||||
extern char chrcasecpy(int, int);
|
||||
extern char *strcasecpy(char *, const char *) NONNULL NONNULLPTRS;
|
||||
extern char *s_suffix(const char *) NONNULL NONNULLARG1;
|
||||
extern char *ing_suffix(const char *) NONNULL NONNULLARG1;
|
||||
extern char *xcrypt(const char *, char *) NONNULL NONNULLPTRS;
|
||||
extern boolean onlyspace(const char *) NONNULLARG1;
|
||||
extern char *tabexpand(char *) NONNULL NONNULLARG1;
|
||||
extern char *visctrl(char) NONNULL;
|
||||
extern char *stripchars(char *, const char *,
|
||||
const char *) NONNULL NONNULLPTRS;
|
||||
extern char *stripdigits(char *) NONNULL NONNULLARG1;
|
||||
extern char *strsubst(char *, const char *, const char *) NONNULL NONNULLPTRS;
|
||||
extern int strNsubst(char *, const char *, const char *, int) NONNULLPTRS;
|
||||
extern const char *findword(const char *, const char *, int,
|
||||
boolean) NONNULLARG2;
|
||||
extern const char *ordin(int) NONNULL;
|
||||
extern char *sitoa(int) NONNULL;
|
||||
extern int sgn(int);
|
||||
extern int rounddiv(long, int);
|
||||
extern int dist2(coordxy, coordxy, coordxy, coordxy);
|
||||
extern int isqrt(int);
|
||||
extern int distmin(coordxy, coordxy, coordxy, coordxy);
|
||||
extern boolean online2(coordxy, coordxy, coordxy, coordxy);
|
||||
extern boolean pmatch(const char *, const char *) NONNULLPTRS;
|
||||
extern boolean pmatchi(const char *, const char *) NONNULLPTRS;
|
||||
/*
|
||||
extern boolean pmatchz(const char *, const char *) NONNULLPTRS;
|
||||
*/
|
||||
#ifndef STRNCMPI
|
||||
extern int strncmpi(const char *, const char *, int) NONNULLPTRS;
|
||||
#endif
|
||||
#ifndef STRSTRI
|
||||
extern char *strstri(const char *, const char *) NONNULLPTRS;
|
||||
#endif
|
||||
extern boolean fuzzymatch(const char *, const char *,
|
||||
const char *, boolean) NONNULLPTRS;
|
||||
extern void init_random(int(*fn)(int));
|
||||
extern void reseed_random(int(*fn)(int));
|
||||
extern time_t getnow(void);
|
||||
extern int getyear(void);
|
||||
#if 0
|
||||
extern char *yymmdd(time_t) NONNULL;
|
||||
#endif
|
||||
extern long yyyymmdd(time_t);
|
||||
extern long hhmmss(time_t);
|
||||
extern char *yyyymmddhhmmss(time_t) NONNULL;
|
||||
extern time_t time_from_yyyymmddhhmmss(char *);
|
||||
extern int phase_of_the_moon(void);
|
||||
extern boolean friday_13th(void);
|
||||
extern int night(void);
|
||||
extern int midnight(void);
|
||||
|
||||
/* ### strutil.c ### */
|
||||
|
||||
extern void strbuf_init(strbuf_t *) NONNULLARG1;
|
||||
extern void strbuf_append(strbuf_t *, const char *) NONNULLPTRS;
|
||||
extern void strbuf_reserve(strbuf_t *, int) NONNULLARG1;
|
||||
extern void strbuf_empty(strbuf_t *) NONNULLARG1;
|
||||
extern void strbuf_nl_to_crlf(strbuf_t *) NONNULLARG1;
|
||||
extern int swapbits(int, int, int);
|
||||
extern void shuffle_int_array(int *, int) NONNULLARG1;
|
||||
/* note: the snprintf CPP wrapper includes the "fmt" argument in "..."
|
||||
(__VA_ARGS__) to allow for zero arguments after fmt */
|
||||
#define Snprintf(str, size, ...) \
|
||||
nh_snprintf(__func__, __LINE__, str, size, __VA_ARGS__)
|
||||
extern void nh_snprintf(const char *func, int line, char *str, size_t size,
|
||||
const char *fmt, ...) PRINTF_F(5, 6);
|
||||
#ifdef ENHANCED_SYMBOLS
|
||||
extern int unicodeval_to_utf8str(int, uint8 *, size_t) NONNULLARG2;
|
||||
#endif
|
||||
extern unsigned Strlen_(const char *, const char *, int) NONNULLPTRS;
|
||||
extern boolean pmatch(const char *, const char *) NONNULLPTRS;
|
||||
extern boolean pmatchi(const char *, const char *) NONNULLPTRS;
|
||||
/*
|
||||
extern boolean pmatchz(const char *, const char *) NONNULLPTRS;
|
||||
*/
|
||||
|
||||
/* ### insight.c ### */
|
||||
|
||||
@@ -2601,6 +2519,26 @@ extern NhRegion *create_gas_cloud_selection(struct selectionvar *, int);
|
||||
extern boolean region_danger(void);
|
||||
extern void region_safety(void);
|
||||
|
||||
/* ### report.c ### */
|
||||
|
||||
#ifdef CRASHREPORT
|
||||
extern const char *get_saved_pline(int);
|
||||
extern boolean submit_web_report(int, const char *, const char *);
|
||||
extern boolean submit_web_report(int, const char *, const char *);
|
||||
extern void crashreport_init(int, char *[]);
|
||||
extern void crashreport_bidshow(void);
|
||||
extern boolean swr_add_uricoded(const char *, char **, int *, char *);
|
||||
extern int dobugreport(void);
|
||||
# ifndef NO_SIGNAL
|
||||
extern void panictrace_handler(int);
|
||||
# endif
|
||||
extern boolean NH_panictrace_libc(void);
|
||||
extern boolean NH_panictrace_gdb(void);
|
||||
#endif
|
||||
#if defined(PANICTRACE) && !defined(NO_SIGNAL)
|
||||
extern void panictrace_setsignals(boolean);
|
||||
#endif
|
||||
|
||||
/* ### restore.c ### */
|
||||
|
||||
extern void inven_inuse(boolean);
|
||||
@@ -2637,6 +2575,9 @@ extern int rnd(int);
|
||||
extern int d(int, int);
|
||||
extern int rne(int);
|
||||
extern int rnz(int);
|
||||
extern void init_random(int(*fn)(int));
|
||||
extern void reseed_random(int(*fn)(int));
|
||||
extern void shuffle_int_array(int *, int) NONNULLARG1;
|
||||
|
||||
/* ### role.c ### */
|
||||
|
||||
@@ -2715,6 +2656,42 @@ extern FILE *getlog(NHFILE *);
|
||||
extern void closelog(NHFILE *);
|
||||
#endif
|
||||
|
||||
/* ### selvar.c ### */
|
||||
|
||||
extern struct selectionvar *selection_new(void);
|
||||
extern void selection_free(struct selectionvar *, boolean) NO_NNARGS;
|
||||
extern void selection_clear(struct selectionvar *, int) NONNULLARG1;
|
||||
extern struct selectionvar *selection_clone(struct selectionvar *) NONNULLARG1;
|
||||
extern void selection_getbounds(struct selectionvar *, NhRect *) NO_NNARGS;
|
||||
extern void selection_recalc_bounds(struct selectionvar *) NONNULLARG1;
|
||||
extern coordxy selection_getpoint(coordxy, coordxy, struct selectionvar *) NO_NNARGS;
|
||||
extern void selection_setpoint(coordxy, coordxy, struct selectionvar *, int);
|
||||
extern struct selectionvar * selection_not(struct selectionvar *);
|
||||
extern struct selectionvar *selection_filter_percent(struct selectionvar *,
|
||||
int);
|
||||
extern struct selectionvar *selection_filter_mapchar(struct selectionvar *,
|
||||
xint16, int);
|
||||
extern int selection_rndcoord(struct selectionvar *, coordxy *, coordxy *,
|
||||
boolean);
|
||||
extern void selection_do_grow(struct selectionvar *, int);
|
||||
extern void set_selection_floodfillchk(int(*)(coordxy, coordxy));
|
||||
extern void selection_floodfill(struct selectionvar *, coordxy, coordxy,
|
||||
boolean);
|
||||
extern void selection_do_ellipse(struct selectionvar *, int, int, int, int,
|
||||
int);
|
||||
extern void selection_do_gradient(struct selectionvar *, long, long, long,
|
||||
long, long, long, long);
|
||||
extern void selection_do_line(coordxy, coordxy, coordxy, coordxy,
|
||||
struct selectionvar *);
|
||||
extern void selection_do_randline(coordxy, coordxy, coordxy, coordxy,
|
||||
schar, schar, struct selectionvar *);
|
||||
extern void selection_iterate(struct selectionvar *, select_iter_func,
|
||||
genericptr_t);
|
||||
extern boolean selection_is_irregular(struct selectionvar *);
|
||||
extern char *selection_size_description(struct selectionvar *, char *);
|
||||
extern struct selectionvar *selection_from_mkroom(struct mkroom *) NO_NNARGS;
|
||||
extern void selection_force_newsyms(struct selectionvar *) NONNULLARG1;
|
||||
|
||||
/* ### sfstruct.c ### */
|
||||
|
||||
extern boolean close_check(int);
|
||||
@@ -2869,6 +2846,7 @@ extern void sound_speak(const char *) NO_NNARGS;
|
||||
/* ### sp_lev.c ### */
|
||||
|
||||
#if !defined(CROSSCOMPILE) || defined(CROSSCOMPILE_TARGET)
|
||||
extern boolean match_maptyps(xint16, xint16);
|
||||
extern void create_des_coder(void);
|
||||
extern void reset_xystart_size(void);
|
||||
extern struct mapfragment *mapfrag_fromstr(char *) NONNULLARG1;
|
||||
@@ -2886,37 +2864,11 @@ extern boolean dig_corridor(coord *, coord *, boolean, schar, schar) NONNULLARG1
|
||||
extern void fill_special_room(struct mkroom *) NO_NNARGS;
|
||||
extern void wallify_map(coordxy, coordxy, coordxy, coordxy);
|
||||
extern boolean load_special(const char *) NONNULLARG1;
|
||||
extern coordxy selection_getpoint(coordxy, coordxy, struct selectionvar *) NO_NNARGS;
|
||||
extern struct selectionvar *selection_new(void);
|
||||
extern void selection_free(struct selectionvar *, boolean) NO_NNARGS;
|
||||
extern void selection_clear(struct selectionvar *, int) NONNULLARG1;
|
||||
extern struct selectionvar *selection_clone(struct selectionvar *) NONNULLARG1;
|
||||
extern void selection_getbounds(struct selectionvar *, NhRect *) NO_NNARGS;
|
||||
extern void selection_recalc_bounds(struct selectionvar *) NONNULLARG1;
|
||||
extern void set_selection_floodfillchk(int(*)(coordxy, coordxy));
|
||||
extern void selection_floodfill(struct selectionvar *, coordxy, coordxy,
|
||||
boolean);
|
||||
extern coordxy random_wdir(void);
|
||||
extern boolean pm_good_location(coordxy, coordxy, struct permonst *) NONNULLARG3;
|
||||
extern void get_location_coord(coordxy *, coordxy *, int, struct mkroom *,
|
||||
long) NONNULLARG12;
|
||||
extern void selection_setpoint(coordxy, coordxy, struct selectionvar *, int);
|
||||
extern struct selectionvar * selection_not(struct selectionvar *);
|
||||
extern struct selectionvar *selection_filter_percent(struct selectionvar *,
|
||||
int);
|
||||
extern int selection_rndcoord(struct selectionvar *, coordxy *, coordxy *,
|
||||
boolean);
|
||||
extern void selection_do_grow(struct selectionvar *, int);
|
||||
extern void selection_do_line(coordxy, coordxy, coordxy, coordxy,
|
||||
struct selectionvar *);
|
||||
extern void selection_do_randline(coordxy, coordxy, coordxy, coordxy,
|
||||
schar, schar, struct selectionvar *);
|
||||
extern struct selectionvar *selection_filter_mapchar(struct selectionvar *,
|
||||
xint16, int);
|
||||
extern void set_floodfillchk_match_under(coordxy);
|
||||
extern void selection_do_ellipse(struct selectionvar *, int, int, int, int,
|
||||
int);
|
||||
extern void selection_do_gradient(struct selectionvar *, long, long, long,
|
||||
long, long, long, long);
|
||||
extern int lspo_reset_level(lua_State *) NO_NNARGS; /* wiz_load_splua NULL */
|
||||
/* lspo_finalize_level() has tests for whether arg1 L is null, and chooses
|
||||
code paths to follow based on that. Also preventing NONNULLARG1 is it
|
||||
@@ -2927,7 +2879,6 @@ extern boolean get_coord(lua_State *, int, lua_Integer *, lua_Integer *) NONNULL
|
||||
extern void cvt_to_abscoord(coordxy *, coordxy *) NONNULLPTRS;
|
||||
extern void cvt_to_relcoord(coordxy *, coordxy *) NONNULLPTRS;
|
||||
extern int nhl_abs_coord(lua_State *) NONNULLARG1;
|
||||
extern struct selectionvar *selection_from_mkroom(struct mkroom *) NO_NNARGS;
|
||||
extern void update_croom(void);
|
||||
extern const char *get_trapname_bytype(int);
|
||||
extern void l_register_des(lua_State *) NONNULLARG1;
|
||||
@@ -2954,6 +2905,27 @@ extern char force_learn_spell(short);
|
||||
extern int num_spells(void);
|
||||
extern void skill_based_spellbook_id(void);
|
||||
|
||||
/* ### stairs.c ### */
|
||||
|
||||
extern void stairway_add(coordxy, coordxy,
|
||||
boolean, boolean, d_level *) NONNULLPTRS;
|
||||
extern void stairway_free_all(void);
|
||||
extern stairway *stairway_at(coordxy, coordxy);
|
||||
extern stairway *stairway_find(d_level *) NONNULLARG1;
|
||||
extern stairway *stairway_find_from(d_level *, boolean) NONNULLARG1;
|
||||
extern stairway *stairway_find_dir(boolean);
|
||||
extern stairway *stairway_find_type_dir(boolean, boolean);
|
||||
extern stairway *stairway_find_special_dir(boolean);
|
||||
extern void u_on_sstairs(int);
|
||||
extern void u_on_upstairs(void);
|
||||
extern void u_on_dnstairs(void);
|
||||
extern boolean On_stairs(coordxy, coordxy);
|
||||
extern boolean On_ladder(coordxy, coordxy);
|
||||
extern boolean On_stairs_up(coordxy, coordxy);
|
||||
extern boolean On_stairs_dn(coordxy, coordxy);
|
||||
extern boolean known_branch_stairs(stairway *);
|
||||
extern char *stairs_description(stairway *, char *, boolean) NONNULLARG1;
|
||||
|
||||
/* ### steal.c ### */
|
||||
|
||||
extern long somegold(long);
|
||||
@@ -3684,6 +3656,41 @@ extern void intervene(void);
|
||||
extern void wizdead(void);
|
||||
extern void cuss(struct monst *) NONNULLARG1;
|
||||
|
||||
/* ### wizcmds.c ### */
|
||||
|
||||
extern int wiz_detect(void);
|
||||
extern int wiz_flip_level(void);
|
||||
extern int wiz_fuzzer(void);
|
||||
extern int wiz_genesis(void);
|
||||
extern int wiz_identify(void);
|
||||
extern int wiz_intrinsic(void);
|
||||
extern int wiz_kill(void);
|
||||
extern int wiz_level_change(void);
|
||||
extern int wiz_level_tele(void);
|
||||
extern int wiz_load_lua(void);
|
||||
extern int wiz_load_splua(void);
|
||||
extern int wiz_makemap(void);
|
||||
extern int wiz_map(void);
|
||||
extern int wiz_migrate_mons(void);
|
||||
extern int wiz_panic(void);
|
||||
extern int wiz_polyself(void);
|
||||
extern int wiz_rumor_check(void);
|
||||
extern int wiz_show_seenv(void);
|
||||
extern int wiz_show_stats(void);
|
||||
extern int wiz_show_vision(void);
|
||||
extern int wiz_show_wmodes(void);
|
||||
extern int wiz_smell(void);
|
||||
extern int wiz_telekinesis(void);
|
||||
extern int wiz_where(void);
|
||||
extern int wiz_wish(void);
|
||||
extern void makemap_remove_mons(void);
|
||||
extern void wiz_levltyp_legend(void);
|
||||
extern void wiz_map_levltyp(void);
|
||||
#if (NH_DEVEL_STATUS != NH_STATUS_RELEASED) || defined(DEBUG)
|
||||
extern int wiz_display_macros(void);
|
||||
extern int wiz_mon_diff(void);
|
||||
#endif
|
||||
|
||||
/* ### worm.c ### */
|
||||
|
||||
extern int get_wormno(void);
|
||||
|
||||
+2
-1
@@ -13,6 +13,7 @@
|
||||
|
||||
#include "align.h"
|
||||
#include "dungeon.h"
|
||||
#include "stairs.h"
|
||||
#include "objclass.h"
|
||||
#include "wintype.h"
|
||||
#include "flag.h"
|
||||
@@ -24,7 +25,6 @@
|
||||
|
||||
#include "botl.h"
|
||||
#include "context.h"
|
||||
#include "dungeon.h"
|
||||
#include "engrave.h"
|
||||
#include "mkroom.h"
|
||||
#include "obj.h"
|
||||
@@ -32,6 +32,7 @@
|
||||
#include "rect.h"
|
||||
#include "region.h"
|
||||
#include "rm.h"
|
||||
#include "selvar.h"
|
||||
#include "sndprocs.h"
|
||||
#include "spell.h"
|
||||
#include "sym.h"
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
/* NetHack 3.7 hacklib.h $NHDT-Date: 1657918089 2022/07/15 20:48:09 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1132 $ */
|
||||
/* Copyright (c) Steve Creps, 1988. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
|
||||
#ifndef HACKLIB_H
|
||||
#define HACKLIB_H
|
||||
|
||||
/*
|
||||
* hacklib true library functions
|
||||
*/
|
||||
extern boolean digit(char);
|
||||
extern boolean letter(char);
|
||||
extern char highc(char);
|
||||
extern char lowc(char);
|
||||
extern char *lcase(char *) NONNULL NONNULLARG1;
|
||||
extern char *ucase(char *) NONNULL NONNULLARG1;
|
||||
extern char *upstart(char *); /* ought to be changed to NONNULL NONNULLARG1
|
||||
* and the code changed to not allow NULL arg */
|
||||
extern char *upwords(char *) NONNULL NONNULLARG1;
|
||||
extern char *mungspaces(char *) NONNULL NONNULLARG1;
|
||||
extern char *trimspaces(char *) NONNULL NONNULLARG1;
|
||||
extern char *strip_newline(char *) NONNULL NONNULLARG1;
|
||||
extern char *eos(char *) NONNULL NONNULLARG1;
|
||||
extern const char *c_eos(const char *) NONNULL NONNULLARG1;
|
||||
extern boolean str_start_is(const char *, const char *, boolean) NONNULLPTRS;
|
||||
extern boolean str_end_is(const char *, const char *) NONNULLPTRS;
|
||||
extern int str_lines_maxlen(const char *);
|
||||
extern char *strkitten(char *, char) NONNULL NONNULLARG1;
|
||||
extern void copynchars(char *, const char *, int) NONNULLARG12;
|
||||
extern char chrcasecpy(int, int);
|
||||
extern char *strcasecpy(char *, const char *) NONNULL NONNULLPTRS;
|
||||
extern char *s_suffix(const char *) NONNULL NONNULLARG1;
|
||||
extern char *ing_suffix(const char *) NONNULL NONNULLARG1;
|
||||
extern char *xcrypt(const char *, char *) NONNULL NONNULLPTRS;
|
||||
extern boolean onlyspace(const char *) NONNULLARG1;
|
||||
extern char *tabexpand(char *) NONNULL NONNULLARG1;
|
||||
extern char *visctrl(char) NONNULL;
|
||||
extern char *stripchars(char *, const char *, const char *) NONNULL NONNULLPTRS;
|
||||
extern char *stripdigits(char *) NONNULL NONNULLARG1;
|
||||
extern char *strsubst(char *, const char *, const char *) NONNULL NONNULLPTRS;
|
||||
extern int strNsubst(char *, const char *, const char *, int) NONNULLPTRS;
|
||||
extern const char *findword(const char *, const char *, int,
|
||||
boolean) NONNULLARG2;
|
||||
extern const char *ordin(int) NONNULL;
|
||||
extern char *sitoa(int) NONNULL;
|
||||
extern int sgn(int);
|
||||
extern int distmin(coordxy, coordxy, coordxy, coordxy);
|
||||
extern int dist2(coordxy, coordxy, coordxy, coordxy);
|
||||
extern int isqrt(int);
|
||||
extern boolean online2(coordxy, coordxy, coordxy, coordxy);
|
||||
#ifndef STRNCMPI
|
||||
extern int strncmpi(const char *, const char *, int) NONNULLPTRS;
|
||||
#endif
|
||||
#ifndef STRSTRI
|
||||
extern char *strstri(const char *, const char *) NONNULLPTRS;
|
||||
#endif
|
||||
#define FITSint(x) FITSint_(x, __func__, __LINE__)
|
||||
extern int FITSint_(long long, const char *, int);
|
||||
#define FITSuint(x) FITSuint_(x, __func__, __LINE__)
|
||||
extern unsigned FITSuint_(unsigned long long, const char *, int);
|
||||
extern int case_insensitive_comp(const char *, const char *);
|
||||
extern boolean fuzzymatch(const char *, const char *,
|
||||
const char *, boolean) NONNULLPTRS;
|
||||
extern int swapbits(int, int, int);
|
||||
/* note: the snprintf CPP wrapper includes the "fmt" argument in "..."
|
||||
(__VA_ARGS__) to allow for zero arguments after fmt */
|
||||
extern void nh_snprintf(const char *func, int line, char *str,
|
||||
size_t size, const char *fmt, ...) PRINTF_F(5, 6);
|
||||
extern void nh_snprintf_w_impossible(const char *func, int line, char *str,
|
||||
size_t size, const char *fmt, ...) PRINTF_F(5, 6);
|
||||
|
||||
#define Snprintf(str, size, ...) \
|
||||
nh_snprintf(__func__, __LINE__, str, size, __VA_ARGS__)
|
||||
|
||||
#if 0
|
||||
/*#define Strlen(s) Strlen_(s, __func__, __LINE__)*/
|
||||
extern unsigned Strlen_(const char *, const char *, int) NONNULLPTRS;
|
||||
#endif
|
||||
extern int unicodeval_to_utf8str(int, uint8 *, size_t);
|
||||
|
||||
|
||||
#endif /* HACKLIB_H */
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
/* NetHack 3.7 selvar.h $NHDT-Date: 1709677544 2024/03/05 22:25:44 $ $NHDT-Branch: keni-mdlib-followup $:$NHDT-Revision: 1.0 $ */
|
||||
/* Copyright (c) 2024 by Pasi Kallinen */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
|
||||
#ifndef SELVAR_H
|
||||
#define SELVAR_H
|
||||
|
||||
typedef void (*select_iter_func)(coordxy, coordxy, genericptr);
|
||||
|
||||
#endif /* SELVAR_H */
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
/* NetHack 3.7 stairs.h $NHDT-Date: 1685863327 2023/06/04 07:22:07 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.47 $ */
|
||||
/* Copyright (c) 2024 by Pasi Kallinen */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
|
||||
#ifndef STAIRS_H
|
||||
#define STAIRS_H
|
||||
|
||||
typedef struct stairway { /* basic stairway identifier */
|
||||
coordxy sx, sy; /* x / y location of the stair */
|
||||
d_level tolev; /* where does it go */
|
||||
boolean up; /* up or down? */
|
||||
boolean isladder; /* ladder or stairway? */
|
||||
boolean u_traversed; /* hero has traversed this stair */
|
||||
struct stairway *next;
|
||||
} stairway;
|
||||
|
||||
#endif /* STAIRS_H */
|
||||
|
||||
+2
-28
@@ -13,17 +13,11 @@
|
||||
#include "nhlua.h"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Some stuff that isn't allocation related but included is this file
|
||||
* so that utility programs can access it more easily since they link
|
||||
* with alloc.{o,obj}.
|
||||
*/
|
||||
|
||||
/*#define FITSint(x) FITSint_(x, __func__, __LINE__)*/
|
||||
extern int FITSint_(LUA_INTEGER, const char *, int) NONNULLARG2;
|
||||
/*#define FITSuint(x) FITSuint_(x, __func__, __LINE__)*/
|
||||
extern unsigned FITSuint_(unsigned long long, const char *, int) NONNULLARG2;
|
||||
/*#define Strlen(s) Strlen_(s, __func__, __LINE__)*/
|
||||
extern unsigned Strlen_(const char *, const char *, int) NONNULLPTRS;
|
||||
|
||||
char *fmt_ptr(const genericptr) NONNULL;
|
||||
|
||||
@@ -256,6 +250,7 @@ dupstr_n(const char *string, unsigned int *lenout)
|
||||
return strcpy((char *) alloc(len + 1), string);
|
||||
}
|
||||
|
||||
|
||||
/* cast to int or panic on overflow; use via macro */
|
||||
int
|
||||
FITSint_(LUA_INTEGER i, const char *file, int line)
|
||||
@@ -277,25 +272,4 @@ FITSuint_(unsigned long long ull, const char *file, int line)
|
||||
return uret;
|
||||
}
|
||||
|
||||
/* strlen() but returns unsigned and panics if string is unreasonably long;
|
||||
used by dlb as well as by nethack */
|
||||
unsigned
|
||||
Strlen_(
|
||||
const char *str,
|
||||
const char *file,
|
||||
int line)
|
||||
{
|
||||
const char *p;
|
||||
size_t len;
|
||||
|
||||
/* strnlen(str, LARGEST_INT) w/o requiring posix.1 headers or libraries */
|
||||
for (p = str, len = 0; len < LARGEST_INT; ++len)
|
||||
if (*p++ == '\0')
|
||||
break;
|
||||
|
||||
if (len == LARGEST_INT)
|
||||
panic("%s:%d string too long", file, line);
|
||||
return (unsigned) len;
|
||||
}
|
||||
|
||||
/*alloc.c*/
|
||||
|
||||
+229
@@ -0,0 +1,229 @@
|
||||
/* NetHack 3.7 calendar.c $NHDT-Date: 1706213796 2024/01/25 20:16:36 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.116 $ */
|
||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||
/*-Copyright (c) Michael Allison, 2007. */
|
||||
/* Copyright (c) Robert Patrick Rankin, 1991 */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
|
||||
#include "hack.h"
|
||||
|
||||
/*
|
||||
* Time routines
|
||||
*
|
||||
* The time is used for:
|
||||
* - seed for rand()
|
||||
* - year on tombstone and yyyymmdd in record file
|
||||
* - phase of the moon (various monsters react to NEW_MOON or FULL_MOON)
|
||||
* - night and midnight (the undead are dangerous at midnight)
|
||||
* - determination of what files are "very old"
|
||||
*/
|
||||
|
||||
/* TIME_type: type of the argument to time(); we actually use &(time_t);
|
||||
you might need to define either or both of these to 'long *' in *conf.h */
|
||||
#ifndef TIME_type
|
||||
#define TIME_type time_t *
|
||||
#endif
|
||||
#ifndef LOCALTIME_type
|
||||
#define LOCALTIME_type time_t *
|
||||
#endif
|
||||
|
||||
static struct tm *getlt(void);
|
||||
|
||||
time_t
|
||||
getnow(void)
|
||||
{
|
||||
time_t datetime = 0;
|
||||
|
||||
(void) time((TIME_type) &datetime);
|
||||
return datetime;
|
||||
}
|
||||
|
||||
static struct tm *
|
||||
getlt(void)
|
||||
{
|
||||
time_t date = getnow();
|
||||
|
||||
return localtime((LOCALTIME_type) &date);
|
||||
}
|
||||
|
||||
int
|
||||
getyear(void)
|
||||
{
|
||||
return (1900 + getlt()->tm_year);
|
||||
}
|
||||
|
||||
|
||||
long
|
||||
yyyymmdd(time_t date)
|
||||
{
|
||||
long datenum;
|
||||
struct tm *lt;
|
||||
|
||||
if (date == 0)
|
||||
lt = getlt();
|
||||
else
|
||||
lt = localtime((LOCALTIME_type) &date);
|
||||
|
||||
/* just in case somebody's localtime supplies (year % 100)
|
||||
rather than the expected (year - 1900) */
|
||||
if (lt->tm_year < 70)
|
||||
datenum = (long) lt->tm_year + 2000L;
|
||||
else
|
||||
datenum = (long) lt->tm_year + 1900L;
|
||||
/* yyyy --> yyyymm */
|
||||
datenum = datenum * 100L + (long) (lt->tm_mon + 1);
|
||||
/* yyyymm --> yyyymmdd */
|
||||
datenum = datenum * 100L + (long) lt->tm_mday;
|
||||
return datenum;
|
||||
}
|
||||
|
||||
long
|
||||
hhmmss(time_t date)
|
||||
{
|
||||
long timenum;
|
||||
struct tm *lt;
|
||||
|
||||
if (date == 0)
|
||||
lt = getlt();
|
||||
else
|
||||
lt = localtime((LOCALTIME_type) &date);
|
||||
|
||||
timenum = lt->tm_hour * 10000L + lt->tm_min * 100L + lt->tm_sec;
|
||||
return timenum;
|
||||
}
|
||||
|
||||
char *
|
||||
yyyymmddhhmmss(time_t date)
|
||||
{
|
||||
long datenum;
|
||||
static char datestr[15];
|
||||
struct tm *lt;
|
||||
|
||||
if (date == 0)
|
||||
lt = getlt();
|
||||
else
|
||||
lt = localtime((LOCALTIME_type) &date);
|
||||
|
||||
/* just in case somebody's localtime supplies (year % 100)
|
||||
rather than the expected (year - 1900) */
|
||||
if (lt->tm_year < 70)
|
||||
datenum = (long) lt->tm_year + 2000L;
|
||||
else
|
||||
datenum = (long) lt->tm_year + 1900L;
|
||||
Snprintf(datestr, sizeof datestr, "%04ld%02d%02d%02d%02d%02d",
|
||||
datenum, lt->tm_mon + 1,
|
||||
lt->tm_mday, lt->tm_hour, lt->tm_min, lt->tm_sec);
|
||||
//debugpline1("yyyymmddhhmmss() produced date string %s", datestr);
|
||||
return datestr;
|
||||
}
|
||||
|
||||
time_t
|
||||
time_from_yyyymmddhhmmss(char *buf)
|
||||
{
|
||||
int k;
|
||||
time_t timeresult = (time_t) 0;
|
||||
struct tm t, *lt;
|
||||
char *d, *p, y[5], mo[3], md[3], h[3], mi[3], s[3];
|
||||
|
||||
if (buf && strlen(buf) == 14) {
|
||||
d = buf;
|
||||
p = y; /* year */
|
||||
for (k = 0; k < 4; ++k)
|
||||
*p++ = *d++;
|
||||
*p = '\0';
|
||||
p = mo; /* month */
|
||||
for (k = 0; k < 2; ++k)
|
||||
*p++ = *d++;
|
||||
*p = '\0';
|
||||
p = md; /* day */
|
||||
for (k = 0; k < 2; ++k)
|
||||
*p++ = *d++;
|
||||
*p = '\0';
|
||||
p = h; /* hour */
|
||||
for (k = 0; k < 2; ++k)
|
||||
*p++ = *d++;
|
||||
*p = '\0';
|
||||
p = mi; /* minutes */
|
||||
for (k = 0; k < 2; ++k)
|
||||
*p++ = *d++;
|
||||
*p = '\0';
|
||||
p = s; /* seconds */
|
||||
for (k = 0; k < 2; ++k)
|
||||
*p++ = *d++;
|
||||
*p = '\0';
|
||||
lt = getlt();
|
||||
if (lt) {
|
||||
t = *lt;
|
||||
t.tm_year = atoi(y) - 1900;
|
||||
t.tm_mon = atoi(mo) - 1;
|
||||
t.tm_mday = atoi(md);
|
||||
t.tm_hour = atoi(h);
|
||||
t.tm_min = atoi(mi);
|
||||
t.tm_sec = atoi(s);
|
||||
timeresult = mktime(&t);
|
||||
}
|
||||
if (timeresult == (time_t) -1)
|
||||
;
|
||||
#if 0
|
||||
TODO: set_debugpline1, debugpline1 -> function pointer
|
||||
debugpline1("time_from_yyyymmddhhmmss(%s) would have returned -1",
|
||||
buf ? buf : "");
|
||||
#endif
|
||||
else
|
||||
return timeresult;
|
||||
}
|
||||
return (time_t) 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* moon period = 29.53058 days ~= 30, year = 365.2422 days
|
||||
* days moon phase advances on first day of year compared to preceding year
|
||||
* = 365.2422 - 12*29.53058 ~= 11
|
||||
* years in Metonic cycle (time until same phases fall on the same days of
|
||||
* the month) = 18.6 ~= 19
|
||||
* moon phase on first day of year (epact) ~= (11*(year%19) + 29) % 30
|
||||
* (29 as initial condition)
|
||||
* current phase in days = first day phase + days elapsed in year
|
||||
* 6 moons ~= 177 days
|
||||
* 177 ~= 8 reported phases * 22
|
||||
* + 11/22 for rounding
|
||||
*/
|
||||
int
|
||||
phase_of_the_moon(void) /* 0-7, with 0: new, 4: full */
|
||||
{
|
||||
struct tm *lt = getlt();
|
||||
int epact, diy, goldn;
|
||||
|
||||
diy = lt->tm_yday;
|
||||
goldn = (lt->tm_year % 19) + 1;
|
||||
epact = (11 * goldn + 18) % 30;
|
||||
if ((epact == 25 && goldn > 11) || epact == 24)
|
||||
epact++;
|
||||
|
||||
return ((((((diy + epact) * 6) + 11) % 177) / 22) & 7);
|
||||
}
|
||||
|
||||
boolean
|
||||
friday_13th(void)
|
||||
{
|
||||
struct tm *lt = getlt();
|
||||
|
||||
/* tm_wday (day of week; 0==Sunday) == 5 => Friday */
|
||||
return (boolean) (lt->tm_wday == 5 && lt->tm_mday == 13);
|
||||
}
|
||||
|
||||
int
|
||||
night(void)
|
||||
{
|
||||
int hour = getlt()->tm_hour;
|
||||
|
||||
return (hour < 6 || hour > 21);
|
||||
}
|
||||
|
||||
int
|
||||
midnight(void)
|
||||
{
|
||||
return (getlt()->tm_hour == 0);
|
||||
}
|
||||
|
||||
/* calendar.c */
|
||||
|
||||
+6
-5
@@ -3,20 +3,21 @@
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
|
||||
#include "config.h"
|
||||
#include "hacklib.h"
|
||||
#ifdef Snprintf
|
||||
#undef Snprintf
|
||||
#endif
|
||||
#define Snprintf(str, size, ...) \
|
||||
nh_snprintf(__func__, __LINE__, str, size, __VA_ARGS__)
|
||||
|
||||
/* these are in extern.h but we don't include hack.h */
|
||||
void populate_nomakedefs(struct version_info *) NONNULLARG1;
|
||||
void free_nomakedefs(void);
|
||||
|
||||
#define Snprintf(str, size, ...) \
|
||||
nh_snprintf(__func__, __LINE__, str, size, __VA_ARGS__)
|
||||
extern void nh_snprintf(const char *func, int line, char *str, size_t size,
|
||||
const char *fmt, ...);
|
||||
extern unsigned long md_ignored_features(void);
|
||||
extern char *mdlib_version_string(char *, const char *);
|
||||
extern char *version_id_string(char *, size_t, const char *);
|
||||
extern char *bannerc_string(char *, size_t, const char *);
|
||||
extern int case_insensitive_comp(const char *, const char *);
|
||||
|
||||
/* nomakedefs_populated: flag for whether 'nomakedefs' should be freed */
|
||||
static int nomakedefs_populated = 0;
|
||||
|
||||
-1144
File diff suppressed because it is too large
Load Diff
-230
@@ -1602,176 +1602,6 @@ u_on_rndspot(int upflag)
|
||||
switch_terrain();
|
||||
}
|
||||
|
||||
void
|
||||
stairway_add(
|
||||
coordxy x, coordxy y,
|
||||
boolean up, boolean isladder,
|
||||
d_level *dest)
|
||||
{
|
||||
stairway *tmp = (stairway *) alloc(sizeof (stairway));
|
||||
|
||||
(void) memset((genericptr_t) tmp, 0, sizeof (stairway));
|
||||
tmp->sx = x;
|
||||
tmp->sy = y;
|
||||
tmp->up = up;
|
||||
tmp->isladder = isladder;
|
||||
tmp->u_traversed = FALSE;
|
||||
assign_level(&(tmp->tolev), dest);
|
||||
tmp->next = gs.stairs;
|
||||
gs.stairs = tmp;
|
||||
}
|
||||
|
||||
void
|
||||
stairway_free_all(void)
|
||||
{
|
||||
stairway *tmp = gs.stairs;
|
||||
|
||||
while (tmp) {
|
||||
stairway *tmp2 = tmp->next;
|
||||
free(tmp);
|
||||
tmp = tmp2;
|
||||
}
|
||||
gs.stairs = NULL;
|
||||
}
|
||||
|
||||
stairway *
|
||||
stairway_at(coordxy x, coordxy y)
|
||||
{
|
||||
stairway *tmp = gs.stairs;
|
||||
|
||||
while (tmp && !(tmp->sx == x && tmp->sy == y))
|
||||
tmp = tmp->next;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
stairway *
|
||||
stairway_find(d_level *fromdlev)
|
||||
{
|
||||
stairway *tmp = gs.stairs;
|
||||
|
||||
while (tmp) {
|
||||
if (tmp->tolev.dnum == fromdlev->dnum
|
||||
&& tmp->tolev.dlevel == fromdlev->dlevel)
|
||||
break; /* return */
|
||||
tmp = tmp->next;
|
||||
}
|
||||
return tmp;
|
||||
}
|
||||
|
||||
stairway *
|
||||
stairway_find_from(d_level *fromdlev, boolean isladder)
|
||||
{
|
||||
stairway *tmp = gs.stairs;
|
||||
|
||||
while (tmp) {
|
||||
if (tmp->tolev.dnum == fromdlev->dnum
|
||||
&& tmp->tolev.dlevel == fromdlev->dlevel
|
||||
&& tmp->isladder == isladder)
|
||||
break; /* return */
|
||||
tmp = tmp->next;
|
||||
}
|
||||
return tmp;
|
||||
}
|
||||
|
||||
stairway *
|
||||
stairway_find_dir(boolean up)
|
||||
{
|
||||
stairway *tmp = gs.stairs;
|
||||
|
||||
while (tmp && !(tmp->up == up))
|
||||
tmp = tmp->next;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
stairway *
|
||||
stairway_find_type_dir(boolean isladder, boolean up)
|
||||
{
|
||||
stairway *tmp = gs.stairs;
|
||||
|
||||
while (tmp && !(tmp->isladder == isladder && tmp->up == up))
|
||||
tmp = tmp->next;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
stairway *
|
||||
stairway_find_special_dir(boolean up)
|
||||
{
|
||||
stairway *tmp = gs.stairs;
|
||||
|
||||
while (tmp) {
|
||||
if (tmp->tolev.dnum != u.uz.dnum && tmp->up != up)
|
||||
return tmp;
|
||||
tmp = tmp->next;
|
||||
}
|
||||
return tmp;
|
||||
}
|
||||
|
||||
/* place you on the special staircase */
|
||||
void
|
||||
u_on_sstairs(int upflag)
|
||||
{
|
||||
stairway *stway = stairway_find_special_dir(upflag);
|
||||
|
||||
if (stway)
|
||||
u_on_newpos(stway->sx, stway->sy);
|
||||
else
|
||||
u_on_rndspot(upflag);
|
||||
}
|
||||
|
||||
/* place you on upstairs (or special equivalent) */
|
||||
void
|
||||
u_on_upstairs(void)
|
||||
{
|
||||
stairway *stway = stairway_find_dir(TRUE);
|
||||
|
||||
if (stway)
|
||||
u_on_newpos(stway->sx, stway->sy);
|
||||
else
|
||||
u_on_sstairs(0); /* destination upstairs implies moving down */
|
||||
}
|
||||
|
||||
/* place you on dnstairs (or special equivalent) */
|
||||
void
|
||||
u_on_dnstairs(void)
|
||||
{
|
||||
stairway *stway = stairway_find_dir(FALSE);
|
||||
|
||||
if (stway)
|
||||
u_on_newpos(stway->sx, stway->sy);
|
||||
else
|
||||
u_on_sstairs(1); /* destination dnstairs implies moving up */
|
||||
}
|
||||
|
||||
boolean
|
||||
On_stairs(coordxy x, coordxy y)
|
||||
{
|
||||
return (stairway_at(x, y) != NULL);
|
||||
}
|
||||
|
||||
boolean
|
||||
On_ladder(coordxy x, coordxy y)
|
||||
{
|
||||
stairway *stway = stairway_at(x, y);
|
||||
|
||||
return (boolean) (stway && stway->isladder);
|
||||
}
|
||||
|
||||
boolean
|
||||
On_stairs_up(coordxy x, coordxy y)
|
||||
{
|
||||
stairway *stway = stairway_at(x, y);
|
||||
|
||||
return (boolean) (stway && stway->up);
|
||||
}
|
||||
|
||||
boolean
|
||||
On_stairs_dn(coordxy x, coordxy y)
|
||||
{
|
||||
stairway *stway = stairway_at(x, y);
|
||||
|
||||
return (boolean) (stway && !stway->up);
|
||||
}
|
||||
|
||||
boolean
|
||||
Is_botlevel(d_level *lev)
|
||||
{
|
||||
@@ -2364,66 +2194,6 @@ tport_menu(
|
||||
return;
|
||||
}
|
||||
|
||||
/* return True if 'sway' is a branch staircase and hero has used these stairs
|
||||
to visit the branch */
|
||||
boolean
|
||||
known_branch_stairs(stairway *sway)
|
||||
{
|
||||
return (sway && sway->tolev.dnum != u.uz.dnum && sway->u_traversed);
|
||||
}
|
||||
|
||||
/* describe staircase 'sway' based on whether hero knows the destination */
|
||||
char *
|
||||
stairs_description(
|
||||
stairway *sway, /* stairs/ladder to describe */
|
||||
char *outbuf, /* result buffer */
|
||||
boolean stcase) /* True: "staircase" or "ladder", always singular;
|
||||
* False: "stairs" or "ladder"; caller needs to deal
|
||||
* with singular vs plural when forming a sentence */
|
||||
{
|
||||
d_level tolev;
|
||||
const char *stairs, *updown;
|
||||
|
||||
tolev = sway->tolev;
|
||||
stairs = sway->isladder ? "ladder" : stcase ? "staircase" : "stairs";
|
||||
updown = sway->up ? "up" : "down";
|
||||
|
||||
if (!known_branch_stairs(sway)) {
|
||||
/* ordinary stairs or branch stairs to not-yet-visited branch */
|
||||
Sprintf(outbuf, "%s %s", stairs, updown);
|
||||
if (sway->u_traversed) {
|
||||
boolean specialdepth = (tolev.dnum == quest_dnum
|
||||
|| single_level_branch(&tolev)); /* knox */
|
||||
int to_dlev = specialdepth ? dunlev(&tolev) : depth(&tolev);
|
||||
|
||||
Sprintf(eos(outbuf), " to level %d", to_dlev);
|
||||
}
|
||||
} else if (u.uz.dnum == 0 && u.uz.dlevel == 1 && sway->up) {
|
||||
/* stairs up from level one are a special case; they are marked
|
||||
as having been traversed because the hero obviously started
|
||||
the game by coming down them, but the remote side varies
|
||||
depending on whether the Amulet is being carried */
|
||||
Sprintf(outbuf, "%s%s %s %s",
|
||||
!u.uhave.amulet ? "" : "branch ",
|
||||
stairs, updown,
|
||||
!u.uhave.amulet ? "out of the dungeon"
|
||||
/* minimize our expectations about what comes next */
|
||||
: (on_level(&tolev, &earth_level)
|
||||
|| on_level(&tolev, &air_level)
|
||||
|| on_level(&tolev, &fire_level)
|
||||
|| on_level(&tolev, &water_level))
|
||||
? "to the Elemental Planes"
|
||||
: "to the end game");
|
||||
} else {
|
||||
/* known branch stairs; tacking on destination level is too verbose */
|
||||
Sprintf(outbuf, "branch %s %s to %s",
|
||||
stairs, updown, gd.dungeons[tolev.dnum].dname);
|
||||
/* dungeons[].dname is capitalized; undo that for "The <Branch>" */
|
||||
(void) strsubst(outbuf, "The ", "the ");
|
||||
}
|
||||
return outbuf;
|
||||
}
|
||||
|
||||
/* Convert a branch type to a string usable by print_dungeon(). */
|
||||
static const char *
|
||||
br_string(int type)
|
||||
|
||||
@@ -37,9 +37,6 @@ static boolean should_query_disclose_option(int, char *);
|
||||
static void dump_plines(void);
|
||||
#endif
|
||||
static void dump_everything(int, time_t);
|
||||
#ifdef CRASHREPORT
|
||||
static const char *get_saved_pline(int);
|
||||
#endif
|
||||
static void fixup_death(int);
|
||||
static int wordcount(char *);
|
||||
static void bel_copy1(char **, char *);
|
||||
@@ -70,673 +67,6 @@ ATTRNORETURN extern void nethack_exit(int) NORETURN;
|
||||
#endif /* !SYSV */
|
||||
#endif /* !AMIGA */
|
||||
|
||||
/* NB: CRASHREPORT implies PANICTRACE */
|
||||
#if defined(PANICTRACE)
|
||||
#include <errno.h>
|
||||
#ifdef PANICTRACE_LIBC
|
||||
#include <execinfo.h>
|
||||
#endif
|
||||
|
||||
/* What do we try to in what order? Tradeoffs:
|
||||
* libc: +no external programs required
|
||||
* -requires newish libc/glibc
|
||||
* -requires -rdynamic
|
||||
* gdb: +gives more detailed information
|
||||
* +works on more OS versions
|
||||
* -requires -g, which may preclude -O on some compilers
|
||||
*
|
||||
* And the UI: if sysopt.crashreporturl, and defined(CRASHREPORT)
|
||||
* we gather the stacktrace (etc) and launch a browser to submit a bug report
|
||||
* otherwise we just use stdout. Requires libc for now.
|
||||
*/
|
||||
#ifdef SYSCF
|
||||
# define SYSOPT_PANICTRACE_GDB sysopt.panictrace_gdb
|
||||
# ifdef PANICTRACE_LIBC
|
||||
# define SYSOPT_PANICTRACE_LIBC sysopt.panictrace_libc
|
||||
# else
|
||||
# define SYSOPT_PANICTRACE_LIBC 0
|
||||
# endif
|
||||
#else
|
||||
# define SYSOPT_PANICTRACE_GDB (nh_getenv("NETHACK_USE_GDB") == 0 ? 0 : 2)
|
||||
# ifdef PANICTRACE_LIBC
|
||||
# define SYSOPT_PANICTRACE_LIBC 1
|
||||
# else
|
||||
# define SYSOPT_PANICTRACE_LIBC 0
|
||||
# endif
|
||||
#endif
|
||||
|
||||
static void NH_abort(char *);
|
||||
#ifndef NO_SIGNAL
|
||||
static void panictrace_handler(int);
|
||||
#endif
|
||||
static boolean NH_panictrace_libc(void);
|
||||
static boolean NH_panictrace_gdb(void);
|
||||
|
||||
#ifndef NO_SIGNAL
|
||||
/* called as signal() handler, so sent at least one arg */
|
||||
/*ARGUSED*/
|
||||
void
|
||||
panictrace_handler(int sig_unused UNUSED)
|
||||
{
|
||||
#define SIG_MSG "\nSignal received.\n"
|
||||
int f2;
|
||||
|
||||
#ifdef CURSES_GRAPHICS
|
||||
if (iflags.window_inited && WINDOWPORT(curses)) {
|
||||
extern void curses_uncurse_terminal(void); /* wincurs.h */
|
||||
|
||||
/* it is risky calling this during a program-terminating signal,
|
||||
but without it the subsequent backtrace is useless because
|
||||
that ends up being scrawled all over the screen; call is
|
||||
here rather than in NH_abort() because panic() calls both
|
||||
exit_nhwindows(), which makes this same call under curses,
|
||||
then NH_abort() and we don't want to call this twice */
|
||||
curses_uncurse_terminal();
|
||||
}
|
||||
#endif
|
||||
|
||||
f2 = (int) write(2, SIG_MSG, sizeof SIG_MSG - 1);
|
||||
nhUse(f2); /* what could we do if write to fd#2 (stderr) fails */
|
||||
NH_abort(NULL); /* ... and we're already in the process of quitting? */
|
||||
}
|
||||
|
||||
void
|
||||
panictrace_setsignals(boolean set)
|
||||
{
|
||||
#define SETSIGNAL(sig) \
|
||||
(void) signal(sig, set ? (SIG_RET_TYPE) panictrace_handler : SIG_DFL);
|
||||
#ifdef SIGILL
|
||||
SETSIGNAL(SIGILL);
|
||||
#endif
|
||||
#ifdef SIGTRAP
|
||||
SETSIGNAL(SIGTRAP);
|
||||
#endif
|
||||
#ifdef SIGIOT
|
||||
SETSIGNAL(SIGIOT);
|
||||
#endif
|
||||
#ifdef SIGBUS
|
||||
SETSIGNAL(SIGBUS);
|
||||
#endif
|
||||
#ifdef SIGFPE
|
||||
SETSIGNAL(SIGFPE);
|
||||
#endif
|
||||
#ifdef SIGSEGV
|
||||
SETSIGNAL(SIGSEGV);
|
||||
#endif
|
||||
#ifdef SIGSTKFLT
|
||||
SETSIGNAL(SIGSTKFLT);
|
||||
#endif
|
||||
#ifdef SIGSYS
|
||||
SETSIGNAL(SIGSYS);
|
||||
#endif
|
||||
#ifdef SIGEMT
|
||||
SETSIGNAL(SIGEMT);
|
||||
#endif
|
||||
#undef SETSIGNAL
|
||||
}
|
||||
#endif /* NO_SIGNAL */
|
||||
|
||||
#ifdef CRASHREPORT
|
||||
#define USED_FOR_CRASHREPORT
|
||||
#else
|
||||
#define USED_FOR_CRASHREPORT UNUSED
|
||||
#endif
|
||||
|
||||
static void
|
||||
NH_abort(char *why USED_FOR_CRASHREPORT)
|
||||
{
|
||||
int gdb_prio = SYSOPT_PANICTRACE_GDB;
|
||||
int libc_prio = SYSOPT_PANICTRACE_LIBC;
|
||||
static volatile boolean aborting = FALSE;
|
||||
|
||||
/* don't execute this code recursively if a second abort is requested
|
||||
while this routine or the code it calls is executing */
|
||||
if (aborting)
|
||||
return;
|
||||
aborting = TRUE;
|
||||
|
||||
#ifdef CRASHREPORT
|
||||
if(!submit_web_report(1, "Panic", why))
|
||||
#endif
|
||||
{
|
||||
#ifndef VMS
|
||||
if (gdb_prio == libc_prio && gdb_prio > 0)
|
||||
gdb_prio++;
|
||||
|
||||
if (gdb_prio > libc_prio) {
|
||||
(void) (NH_panictrace_gdb() || (libc_prio && NH_panictrace_libc()));
|
||||
} else {
|
||||
(void) (NH_panictrace_libc() || (gdb_prio && NH_panictrace_gdb()));
|
||||
}
|
||||
|
||||
#else /* VMS */
|
||||
/* overload otherwise unused priority for debug mode: 1 = show
|
||||
traceback and exit; 2 = show traceback and stay in debugger */
|
||||
/* if (wizard && gdb_prio == 1) gdb_prio = 2; */
|
||||
vms_traceback(gdb_prio);
|
||||
nhUse(libc_prio);
|
||||
|
||||
#endif /* ?VMS */
|
||||
}
|
||||
|
||||
#ifndef NO_SIGNAL
|
||||
panictrace_setsignals(FALSE);
|
||||
#endif
|
||||
NH_abort_;
|
||||
}
|
||||
#undef USED_FOR_CRASHREPORT
|
||||
|
||||
#ifdef CRASHREPORT
|
||||
# include <fcntl.h>
|
||||
# ifdef WIN32
|
||||
# define HASH_PRAGMA_START
|
||||
# define HASH_PRAGMA_END
|
||||
# else
|
||||
# define HASH_PRAGMA_START \
|
||||
_Pragma("GCC diagnostic push"); \
|
||||
_Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
|
||||
# define HASH_PRAGMA_END _Pragma("GCC diagnostic pop");
|
||||
# endif
|
||||
# ifdef MACOS
|
||||
# include <CommonCrypto/CommonDigest.h>
|
||||
# define HASH_CONTEXTPTR(CTXP) \
|
||||
unsigned char tmp[CC_MD4_DIGEST_LENGTH]; \
|
||||
CC_MD4_CTX CTXP ## _; \
|
||||
CC_MD4_CTX *CTXP = &CTXP ## _
|
||||
# define HASH_INIT(ctxp) !CC_MD4_Init(ctxp)
|
||||
# define HASH_UPDATE(ctx, ptr, len) !CC_MD4_Update(ctx, ptr, len)
|
||||
# define HASH_FINISH(ctxp) !CC_MD4_Final(tmp, ctxp)
|
||||
# define HASH_RESULT_SIZE(ctxp) CC_MD4_DIGEST_LENGTH
|
||||
# define HASH_RESULT(ctx, inp) *inp = (unsigned char *) ctx
|
||||
# define HASH_CLEANUP(ctxp)
|
||||
# define HASH_OFLAGS O_RDONLY
|
||||
# define HASH_BINFILE_DECL char *binfile = argv[0];
|
||||
# ifdef BETA
|
||||
# define HASH_BINFILE \
|
||||
if (!binfile || !*binfile) { \
|
||||
/* If this triggers, investigate CFBundleGetMainBundle */ \
|
||||
/* or CFBundleCopyExecutableURL. */ \
|
||||
raw_print( \
|
||||
"BETA warning: crashreport_init called without useful info"); \
|
||||
goto skip; \
|
||||
}
|
||||
# else
|
||||
# define HASH_BINFILE() \
|
||||
if (!binfile || !*binfile) { \
|
||||
goto skip; \
|
||||
}
|
||||
# endif
|
||||
# endif
|
||||
# ifdef __linux__
|
||||
# include "nhmd4.h"
|
||||
# define HASH_CONTEXTPTR(CTXP) \
|
||||
unsigned char tmp[NHMD4_DIGEST_LENGTH]; \
|
||||
NHMD4_CTX CTXP ## _; \
|
||||
NHMD4_CTX *CTXP = &CTXP ## _
|
||||
# define HASH_INIT(ctxp) (nhmd4_init(ctxp), 0)
|
||||
# define HASH_UPDATE(ctx, ptr, len) (nhmd4_update(ctx, ptr, len), 0)
|
||||
# define HASH_FINISH(ctxp) (nhmd4_final(ctxp, tmp), 0)
|
||||
# define HASH_RESULT_SIZE(ctxp) NHMD4_RESULTLEN
|
||||
# define HASH_RESULT(ctx, inp) *inp = tmp
|
||||
# define HASH_CLEANUP(ctxp)
|
||||
# define HASH_OFLAGS O_RDONLY
|
||||
# define HASH_BINFILE_DECL char binfile[PATH_MAX+1];
|
||||
# define HASH_BINFILE() \
|
||||
int len = readlink("/proc/self/exe", binfile, sizeof binfile - 1); \
|
||||
if (len > 0) { \
|
||||
binfile[len] = '\0'; \
|
||||
} else { \
|
||||
goto skip; \
|
||||
}
|
||||
# endif // __linux__
|
||||
# ifdef WIN32
|
||||
/* WIN32 takes too much code and is dependent on OS includes we can't
|
||||
* pull in here, so we call out to code in sys/windows/windsys.c */
|
||||
# define HASH_CONTEXTPTR(CTXP)
|
||||
# define HASH_INIT(ctxp) win32_cr_helper('i', ctxp, NULL, 0)
|
||||
# define HASH_UPDATE(ctxp, ptr, len) win32_cr_helper('u', ctxp, ptr, len)
|
||||
# define HASH_FINISH(ctxp) win32_cr_helper('f', ctxp, NULL, 0)
|
||||
# define HASH_CLEANUP(ctxp) win32_cr_helper('c', ctxp, NULL, 0)
|
||||
# define HASH_RESULT_SIZE(ctxp) win32_cr_helper('s', ctxp, NULL, 0)
|
||||
# define HASH_RESULT(ctxp, inp) win32_cr_helper('r', ctxp, inp, 0)
|
||||
# define HASH_OFLAGS _O_RDONLY | _O_BINARY
|
||||
# define HASH_BINFILE_DECL char *binfile;
|
||||
# define HASH_BINFILE() \
|
||||
if (win32_cr_helper('b', NULL, &binfile, 0)) { \
|
||||
goto skip; \
|
||||
}
|
||||
# endif // WIN32
|
||||
|
||||
/* Binary ID - Use only as a hint to contact.html for recognizing our own
|
||||
binaries. This is easily spoofed! */
|
||||
static char bid[40];
|
||||
|
||||
/* ARGSUSED */
|
||||
void
|
||||
crashreport_init(int argc UNUSED, char *argv[] UNUSED)
|
||||
{
|
||||
static int once = 0;
|
||||
if (once++) /* NetHackW.exe calls us twice */
|
||||
return;
|
||||
HASH_BINFILE_DECL;
|
||||
HASH_PRAGMA_START
|
||||
HASH_CONTEXTPTR(ctxp);
|
||||
if (HASH_INIT(ctxp))
|
||||
goto skip;
|
||||
HASH_BINFILE(); /* Does "goto skip" on error. */
|
||||
|
||||
int fd = open(binfile, HASH_OFLAGS, 0);
|
||||
if (fd == -1) {
|
||||
# ifdef BETA
|
||||
raw_printf("open e=%s", strerror(errno));
|
||||
# endif
|
||||
goto skip;
|
||||
}
|
||||
|
||||
int segsize;
|
||||
unsigned char segment[4096];
|
||||
|
||||
while (0 < (segsize = read(fd, segment, sizeof segment))) {
|
||||
if (HASH_UPDATE(ctxp, segment, segsize))
|
||||
goto skip;
|
||||
}
|
||||
if (segsize < 0) {
|
||||
close(fd);
|
||||
goto skip;
|
||||
}
|
||||
if (HASH_FINISH(ctxp))
|
||||
goto skip;
|
||||
close(fd);
|
||||
|
||||
static const char hex[] = "0123456789abcdef";
|
||||
char *p = bid;
|
||||
unsigned char *in;
|
||||
HASH_RESULT(ctxp, &in);
|
||||
uint8 cnt = (uint8) HASH_RESULT_SIZE(ctxp);
|
||||
/* Just in case, make sure not to overflow the bid buffer.
|
||||
Divide size by 2 because each octet in the hash uses two slots
|
||||
in bid[] when formatted as a pair of hexadecimal digits. */
|
||||
if (cnt >= (uint8) sizeof bid / 2)
|
||||
cnt = (uint8) sizeof bid / 2 - 1;
|
||||
while (cnt) {
|
||||
/* sprintf(p, "%02x", *in++), p += 2; */
|
||||
*p++ = hex[(*in >> 4) & 0x0f];
|
||||
*p++ = hex[*in++ & 0x0f];
|
||||
--cnt;
|
||||
}
|
||||
*p = '\0';
|
||||
return;
|
||||
|
||||
skip:
|
||||
Strcpy(bid, "unknown");
|
||||
HASH_CLEANUP(ctxp);
|
||||
HASH_PRAGMA_END
|
||||
}
|
||||
#undef HASH_CONTEXTPTR
|
||||
#undef HASH_INIT
|
||||
#undef HASH_UPDATE
|
||||
#undef HASH_FINISH
|
||||
#undef HASH_CLEANUP
|
||||
#undef HASH_RESULT
|
||||
#undef HASH_RESULT_SIZE
|
||||
#undef HASH_PRAGMA_START
|
||||
#undef HASH_PRAGMA_END
|
||||
#undef HASH_BINFILE_DECL
|
||||
#undef HASH_BINFILE
|
||||
|
||||
void
|
||||
crashreport_bidshow(void)
|
||||
{
|
||||
#if defined(WIN32) && !defined(WIN32CON)
|
||||
if (0 == win32_cr_helper('D', ctxp, bid, 0))
|
||||
#endif
|
||||
{
|
||||
raw_print(bid);
|
||||
#ifdef WIN32notyet
|
||||
wait_synch();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/* Build a URL with a query string and try to launch a new browser window
|
||||
* to report from panic() or impossible(). Requires libc support for
|
||||
* the stacktrace. Uses memory on the stack to avoid memory allocation
|
||||
* (on most platforms) (but libc can still do anything it wants). */
|
||||
|
||||
// No theoretial limit for URL length but reality is messy.
|
||||
// This should work on all modern platforms.
|
||||
#ifndef MAX_URL
|
||||
# define MAX_URL 8192
|
||||
#endif
|
||||
#ifndef SWR_FRAMES
|
||||
# define SWR_FRAMES 20
|
||||
#endif
|
||||
|
||||
// mark holds the initial eos; if we can't get the value in
|
||||
// then we can remove the whole item if desired. For other
|
||||
// semantics, caller can handle mark.
|
||||
#define SWR_ADD(str) \
|
||||
utmp = strlen(str); \
|
||||
mark = uend; \
|
||||
if (utmp >= urem) \
|
||||
goto full; \
|
||||
strncpy(uend, str, utmp); \
|
||||
uend += utmp; urem -= utmp; \
|
||||
*uend = '\0';
|
||||
|
||||
// NB: on overflow this rolls us back to mark, so if we don't
|
||||
// want to roll back to the last SWR_ADD, update mark before
|
||||
// calling this macro.
|
||||
#define SWR_ADD_URIcoded(str) \
|
||||
if (swr_add_uricoded(str, &uend, &urem, mark)) \
|
||||
goto full;
|
||||
|
||||
/* On overflow, truncate to markp (but only if markp != NULL). */
|
||||
boolean
|
||||
swr_add_uricoded(
|
||||
const char *in,
|
||||
char **out,
|
||||
int *remaining,
|
||||
char *markp)
|
||||
{
|
||||
while (*in) {
|
||||
if (isalnum(*in) || strchr("_-.~", *in)) {
|
||||
**out = *in;
|
||||
(*out)++;
|
||||
(*remaining)--;
|
||||
} else if (*in == ' ') {
|
||||
**out = '+';
|
||||
(*out)++;
|
||||
(*remaining)--;
|
||||
} else {
|
||||
if (*remaining <= 3) {
|
||||
if (markp)
|
||||
*out = markp, *remaining = 0;
|
||||
**out = '\0';
|
||||
return TRUE;
|
||||
}
|
||||
int x = snprintf(*out, *remaining, "%%%02X", *in);
|
||||
*out += x;
|
||||
*remaining -= x;
|
||||
}
|
||||
in++;
|
||||
if (!*remaining) {
|
||||
if (markp)
|
||||
*out = markp, *remaining = 0;
|
||||
**out = '\0';
|
||||
return TRUE;
|
||||
}
|
||||
**out = '\0';
|
||||
}
|
||||
return FALSE; /* normal return */
|
||||
}
|
||||
|
||||
static char url[MAX_URL]; // XXX too bad this isn't allocated as needed
|
||||
static int urem = MAX_URL; // adjusted for gc.crash_urlmax below
|
||||
static char *uend = url;
|
||||
static int utmp; // used inside macros
|
||||
static char *mark; // holds previous terminator (generally)
|
||||
|
||||
boolean
|
||||
submit_web_report(int cos, const char *msg, const char *why)
|
||||
{
|
||||
urem = (gc.crash_urlmax < 0 || gc.crash_urlmax > MAX_URL)
|
||||
? MAX_URL : min(MAX_URL,gc.crash_urlmax);
|
||||
char temp[200];
|
||||
char temp2[200];
|
||||
int countpp = 0; /* pre and post traceback lines */
|
||||
// URL loaded for creating reports to the NetHack DevTeam
|
||||
// CRASHREPORTURL=https://nethack.org/links/cr-37BETA.html
|
||||
if (!sysopt.crashreporturl)
|
||||
return FALSE;
|
||||
SWR_ADD(sysopt.crashreporturl);
|
||||
/* cos - operation, v - version */
|
||||
Snprintf(temp, sizeof temp, "?cos=%d&v=1", cos);
|
||||
SWR_ADD(temp);
|
||||
|
||||
/* msg==NULL for #bugreport */
|
||||
if (msg) {
|
||||
SWR_ADD("&subject=");
|
||||
Snprintf(temp, sizeof temp, "%s report for NetHack %s",
|
||||
msg, version_string(temp2, sizeof temp2 ));
|
||||
SWR_ADD_URIcoded(temp);
|
||||
}
|
||||
|
||||
SWR_ADD("&gitver=");
|
||||
SWR_ADD_URIcoded(getversionstring(temp2, sizeof temp2));
|
||||
|
||||
if (gc.crash_name) {
|
||||
SWR_ADD("&name=");
|
||||
SWR_ADD_URIcoded(gc.crash_name);
|
||||
}
|
||||
|
||||
if(gc.crash_email) {
|
||||
SWR_ADD("&email=");
|
||||
SWR_ADD_URIcoded(gc.crash_email);
|
||||
}
|
||||
// hardware: leave for user
|
||||
// software: leave for user
|
||||
// comments: leave for user
|
||||
|
||||
SWR_ADD("&details=");
|
||||
if (why) {
|
||||
SWR_ADD_URIcoded(why);
|
||||
SWR_ADD_URIcoded("\n");
|
||||
mark = uend;
|
||||
countpp++;
|
||||
}
|
||||
|
||||
SWR_ADD_URIcoded("bid: ");
|
||||
SWR_ADD_URIcoded(bid);
|
||||
SWR_ADD_URIcoded("\n");
|
||||
mark = uend;
|
||||
countpp++;
|
||||
|
||||
int count = 0;
|
||||
if (cos == 1) {
|
||||
#ifdef WIN32
|
||||
count = win32_cr_gettrace(SWR_FRAMES, uend, MAX_URL - (uend - url));
|
||||
uend = eos(url);
|
||||
#else
|
||||
void *bt[SWR_FRAMES];
|
||||
int x;
|
||||
char **info;
|
||||
|
||||
count = backtrace(bt, SIZE(bt));
|
||||
info = backtrace_symbols(bt, count);
|
||||
for (x = 0; x < count; x++) {
|
||||
copynchars(temp, info[x], (int) sizeof temp - 1 - 1); /* \n\0 */
|
||||
/* try to remove up to 16 blank spaces by removing 8 twice */
|
||||
(void) strsubst(temp, " ", "");
|
||||
(void) strsubst(temp, " ", "");
|
||||
(void) strncat(temp, "\n", sizeof temp - 1);
|
||||
# if 0 // __linux__
|
||||
// not needed for MacOS
|
||||
// XXX is it actually needed for linux? TBD
|
||||
Snprintf(temp2, sizeof temp2, "[%02lu]\n", (unsigned long) x);
|
||||
uend--; // remove the \n we added above
|
||||
SWR_ADD_URIcoded(temp2);
|
||||
# endif // linux
|
||||
SWR_ADD_URIcoded(temp);
|
||||
mark = uend;
|
||||
}
|
||||
#endif // !WIN32
|
||||
}
|
||||
|
||||
#ifdef DUMPLOG_CORE
|
||||
// config.h turns this on, but make it easy to turn off if needed
|
||||
if (cos == 1) {
|
||||
int k;
|
||||
SWR_ADD_URIcoded("Latest messages:\n");
|
||||
mark=uend;
|
||||
countpp++;
|
||||
for (k = 0; k < 5; k++) {
|
||||
const char *line = get_saved_pline(k);
|
||||
if (!line)
|
||||
break;
|
||||
SWR_ADD_URIcoded(line);
|
||||
SWR_ADD_URIcoded("\n");
|
||||
countpp++;
|
||||
mark = uend;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// detailrows: Guess since we can't know the
|
||||
// width of the window.
|
||||
SWR_ADD("&detailrows=");
|
||||
Snprintf(temp, sizeof temp, "%d", min(count + countpp, 30));
|
||||
SWR_ADD_URIcoded(temp);
|
||||
|
||||
full:
|
||||
;
|
||||
//printf("URL=%ld '%s'\n",strlen(url),url);
|
||||
#ifdef WIN32
|
||||
int *rv = win32_cr_shellexecute(url);
|
||||
// XXX TESTING
|
||||
printf("ShellExecute returned: %p\n",rv); // >32 is ok
|
||||
#else
|
||||
const char *xargv[] = {
|
||||
CRASHREPORT,
|
||||
url,
|
||||
NULL
|
||||
};
|
||||
int pid = fork();
|
||||
extern char **environ;
|
||||
if (pid == 0) {
|
||||
char err[100];
|
||||
#ifdef CRASHREPORT_EXEC_NOSTDERR
|
||||
/* Keep the output clean - firefox spews useless errors on
|
||||
* my system. */
|
||||
(void) close(2);
|
||||
(void) open("/dev/null", O_WRONLY);
|
||||
#endif
|
||||
|
||||
(void) execve(CRASHREPORT, (char * const *) xargv, environ);
|
||||
Sprintf(err, "Can't start " CRASHREPORT ": %s", strerror(errno));
|
||||
raw_print(err);
|
||||
} else {
|
||||
int status;
|
||||
errno = 0;
|
||||
(void) waitpid(pid, &status, 0);
|
||||
if (status) { /* XXX check could be more precise */
|
||||
#ifdef BETA
|
||||
/* Not useful at the moment. XXX */
|
||||
char err[100];
|
||||
|
||||
Sprintf(err, "pid=%d e=%d status=%0x", wpid, errno, status);
|
||||
raw_print(err);
|
||||
#endif
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
/* free(info); -- Don't risk it. */
|
||||
#endif
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
int
|
||||
dobugreport(void)
|
||||
{
|
||||
if (!submit_web_report(2, NULL, "#bugreport command")) {
|
||||
pline("Unable to send bug report. Please visit %s instead.",
|
||||
(sysopt.crashreporturl && *sysopt.crashreporturl)
|
||||
? sysopt.crashreporturl
|
||||
: "https://www.nethack.org"
|
||||
);
|
||||
}
|
||||
return ECMD_OK;
|
||||
}
|
||||
|
||||
#endif /* CRASHREPORT */
|
||||
#undef SWR_ADD
|
||||
#undef SWR_ADD_URIcoded
|
||||
#undef SWR_FRAMES
|
||||
#undef SWR_HDR
|
||||
#undef SWR_LINES
|
||||
|
||||
/*ARGSUSED*/
|
||||
static boolean
|
||||
NH_panictrace_libc(void)
|
||||
{
|
||||
#if 0 /* XXX how did this get left here? */
|
||||
#ifdef CRASHREPORT
|
||||
if (submit_web_report("Panic", why))
|
||||
return TRUE;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef PANICTRACE_LIBC
|
||||
void *bt[20];
|
||||
int count, x;
|
||||
char **info, buf[BUFSZ];
|
||||
|
||||
raw_print(" Generating more information you may report:\n");
|
||||
count = backtrace(bt, SIZE(bt));
|
||||
info = backtrace_symbols(bt, count);
|
||||
for (x = 0; x < count; x++) {
|
||||
copynchars(buf, info[x], (int) sizeof buf - 1);
|
||||
/* try to remove up to 16 blank spaces by removing 8 twice */
|
||||
(void) strsubst(buf, " ", "");
|
||||
(void) strsubst(buf, " ", "");
|
||||
raw_printf("[%02lu] %s", (unsigned long) x, buf);
|
||||
}
|
||||
/* free(info); -- Don't risk it. */
|
||||
return TRUE;
|
||||
#else
|
||||
return FALSE;
|
||||
#endif /* !PANICTRACE_LIBC */
|
||||
}
|
||||
|
||||
/*
|
||||
* fooPATH file system path for foo
|
||||
* fooVAR (possibly const) variable containing fooPATH
|
||||
*/
|
||||
#ifdef PANICTRACE_GDB
|
||||
# ifdef SYSCF
|
||||
# define GDBVAR sysopt.gdbpath
|
||||
# define GREPVAR sysopt.greppath
|
||||
# else /* SYSCF */
|
||||
# define GDBVAR GDBPATH
|
||||
# define GREPVAR GREPPATH
|
||||
# endif /* SYSCF */
|
||||
#endif /* PANICTRACE_GDB */
|
||||
|
||||
static boolean
|
||||
NH_panictrace_gdb(void)
|
||||
{
|
||||
#ifdef PANICTRACE_GDB
|
||||
/* A (more) generic method to get a stack trace - invoke
|
||||
* gdb on ourself. */
|
||||
const char *gdbpath = GDBVAR;
|
||||
const char *greppath = GREPVAR;
|
||||
char buf[BUFSZ];
|
||||
FILE *gdb;
|
||||
|
||||
if (gdbpath == NULL || gdbpath[0] == 0)
|
||||
return FALSE;
|
||||
if (greppath == NULL || greppath[0] == 0)
|
||||
return FALSE;
|
||||
|
||||
sprintf(buf, "%s -n -q %s %d 2>&1 | %s '^#'",
|
||||
gdbpath, ARGV0, getpid(), greppath);
|
||||
gdb = popen(buf, "w");
|
||||
if (gdb) {
|
||||
raw_print(" Generating more information you may report:\n");
|
||||
fprintf(gdb, "bt\nquit\ny");
|
||||
fflush(gdb);
|
||||
sleep(4); /* ugly */
|
||||
pclose(gdb);
|
||||
return TRUE;
|
||||
} else {
|
||||
return FALSE;
|
||||
}
|
||||
#else
|
||||
return FALSE;
|
||||
#endif /* !PANICTRACE_GDB */
|
||||
}
|
||||
#endif /* PANICTRACE */
|
||||
|
||||
/*
|
||||
* The order of these needs to match the macros in hack.h.
|
||||
*/
|
||||
@@ -1222,31 +552,6 @@ dump_plines(void)
|
||||
}
|
||||
#endif /* DUMPLOG */
|
||||
|
||||
#ifdef CRASHREPORT
|
||||
/* lineno==0 gives the most recent message (e.g.
|
||||
"Do you want to call panic..." if called from #panic) */
|
||||
static const char *
|
||||
get_saved_pline(int lineno)
|
||||
{
|
||||
int p;
|
||||
int limit = DUMPLOG_MSG_COUNT;
|
||||
if (lineno >= DUMPLOG_MSG_COUNT)
|
||||
return NULL;
|
||||
p = (gs.saved_pline_index - 1) % DUMPLOG_MSG_COUNT;
|
||||
|
||||
while (limit--) {
|
||||
if (gs.saved_plines[p]) { /* valid line */
|
||||
if (lineno--) {
|
||||
p = (p - 1 + DUMPLOG_MSG_COUNT) % DUMPLOG_MSG_COUNT;
|
||||
} else {
|
||||
return gs.saved_plines[p];
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
#endif /* CRASHREPORT */
|
||||
|
||||
/*ARGSUSED*/
|
||||
static void
|
||||
dump_everything(
|
||||
@@ -2556,4 +1861,86 @@ build_english_list(char *in)
|
||||
return out;
|
||||
}
|
||||
|
||||
/* What do we try to in what order? Tradeoffs:
|
||||
* libc: +no external programs required
|
||||
* -requires newish libc/glibc
|
||||
* -requires -rdynamic
|
||||
* gdb: +gives more detailed information
|
||||
* +works on more OS versions
|
||||
* -requires -g, which may preclude -O on some compilers
|
||||
*
|
||||
* And the UI: if sysopt.crashreporturl, and defined(CRASHREPORT)
|
||||
* we gather the stacktrace (etc) and launch a browser to submit a bug report
|
||||
* otherwise we just use stdout. Requires libc for now.
|
||||
*/
|
||||
# ifdef SYSCF
|
||||
# define SYSOPT_PANICTRACE_GDB sysopt.panictrace_gdb
|
||||
# ifdef PANICTRACE_LIBC
|
||||
# define SYSOPT_PANICTRACE_LIBC sysopt.panictrace_libc
|
||||
# else
|
||||
# define SYSOPT_PANICTRACE_LIBC 0
|
||||
# endif
|
||||
# else
|
||||
# define SYSOPT_PANICTRACE_GDB (nh_getenv("NETHACK_USE_GDB") == 0 ? 0 : 2)
|
||||
# ifdef PANICTRACE_LIBC
|
||||
# define SYSOPT_PANICTRACE_LIBC 1
|
||||
# else
|
||||
# define SYSOPT_PANICTRACE_LIBC 0
|
||||
# endif
|
||||
# endif
|
||||
|
||||
# ifdef CRASHREPORT
|
||||
#define USED_FOR_CRASHREPORT
|
||||
# else
|
||||
#define USED_FOR_CRASHREPORT UNUSED
|
||||
# endif
|
||||
|
||||
void
|
||||
NH_abort(char *why USED_FOR_CRASHREPORT)
|
||||
{
|
||||
#ifdef PANICTRACE
|
||||
int gdb_prio = SYSOPT_PANICTRACE_GDB;
|
||||
int libc_prio = SYSOPT_PANICTRACE_LIBC;
|
||||
#endif
|
||||
static volatile boolean aborting = FALSE;
|
||||
|
||||
/* don't execute this code recursively if a second abort is requested
|
||||
while this routine or the code it calls is executing */
|
||||
if (aborting)
|
||||
return;
|
||||
aborting = TRUE;
|
||||
|
||||
#ifdef PANICTRACE
|
||||
#ifdef CRASHREPORT
|
||||
if(!submit_web_report(1, "Panic", why))
|
||||
#endif
|
||||
{
|
||||
#ifndef VMS
|
||||
if (gdb_prio == libc_prio && gdb_prio > 0)
|
||||
gdb_prio++;
|
||||
|
||||
if (gdb_prio > libc_prio) {
|
||||
(void) (NH_panictrace_gdb() || (libc_prio && NH_panictrace_libc()));
|
||||
} else {
|
||||
(void) (NH_panictrace_libc() || (gdb_prio && NH_panictrace_gdb()));
|
||||
}
|
||||
|
||||
#else /* VMS */
|
||||
/* overload otherwise unused priority for debug mode: 1 = show
|
||||
traceback and exit; 2 = show traceback and stay in debugger */
|
||||
/* if (wizard && gdb_prio == 1) gdb_prio = 2; */
|
||||
vms_traceback(gdb_prio);
|
||||
nhUse(libc_prio);
|
||||
|
||||
#endif /* ?VMS */
|
||||
}
|
||||
|
||||
#ifndef NO_SIGNAL
|
||||
panictrace_setsignals(FALSE);
|
||||
#endif
|
||||
#endif /* PANICTRACE */
|
||||
NH_abort_;
|
||||
}
|
||||
#undef USED_FOR_CRASHREPORT
|
||||
|
||||
/*end.c*/
|
||||
|
||||
+1140
File diff suppressed because it is too large
Load Diff
+28
@@ -4,6 +4,7 @@
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
|
||||
#include "hack.h"
|
||||
#include "extern.h"
|
||||
|
||||
/* #define DEBUG */ /* uncomment for debugging */
|
||||
|
||||
@@ -4184,4 +4185,31 @@ spot_checks(coordxy x, coordxy y, schar old_typ)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* calculate x/y, rounding as appropriate */
|
||||
int
|
||||
rounddiv(long x, int y)
|
||||
{
|
||||
int r, m;
|
||||
int divsgn = 1;
|
||||
|
||||
if (y == 0)
|
||||
panic("division by zero in rounddiv");
|
||||
else if (y < 0) {
|
||||
divsgn = -divsgn;
|
||||
y = -y;
|
||||
}
|
||||
if (x < 0) {
|
||||
divsgn = -divsgn;
|
||||
x = -x;
|
||||
}
|
||||
r = (int) (x / y);
|
||||
m = x % y;
|
||||
if (2 * m >= y)
|
||||
r++;
|
||||
|
||||
return divsgn * r;
|
||||
}
|
||||
|
||||
|
||||
/*hack.c*/
|
||||
|
||||
+9
-464
@@ -49,39 +49,15 @@
|
||||
int distmin (int, int, int, int)
|
||||
int dist2 (int, int, int, int)
|
||||
boolean online2 (int, int)
|
||||
boolean pmatch (const char *, const char *)
|
||||
boolean pmatchi (const char *, const char *)
|
||||
boolean pmatchz (const char *, const char *)
|
||||
int strncmpi (const char *, const char *, int)
|
||||
char * strstri (const char *, const char *)
|
||||
boolean fuzzymatch (const char *, const char *,
|
||||
const char *, boolean)
|
||||
void setrandom (void)
|
||||
void init_random (fn)
|
||||
void reseed_random (fn)
|
||||
time_t getnow (void)
|
||||
int getyear (void)
|
||||
char * yymmdd (time_t)
|
||||
long yyyymmdd (time_t)
|
||||
long hhmmss (time_t)
|
||||
char * yyyymmddhhmmss (time_t)
|
||||
time_t time_from_yyyymmddhhmmss (char *)
|
||||
int phase_of_the_moon (void)
|
||||
boolean friday_13th (void)
|
||||
int night (void)
|
||||
int midnight (void)
|
||||
void strbuf_init (strbuf *, const char *)
|
||||
void strbuf_append (strbuf *, const char *)
|
||||
void strbuf_reserve (strbuf *, int)
|
||||
void strbuf_empty (strbuf *)
|
||||
void strbuf_nl_to_crlf (strbuf_t *)
|
||||
int swapbits (int, int, int)
|
||||
void shuffle_int_array (int *, int)
|
||||
void nh_snprintf (const char *, int, char *, size_t,
|
||||
const char *, ...)
|
||||
=*/
|
||||
static boolean pmatch_internal(const char *, const char *, boolean,
|
||||
const char *);
|
||||
|
||||
/* is 'c' a digit? */
|
||||
boolean
|
||||
@@ -255,8 +231,10 @@ str_start_is(
|
||||
if (t1 != t2)
|
||||
return FALSE;
|
||||
}
|
||||
#if 0
|
||||
if (n == 0)
|
||||
panic("string too long");
|
||||
#endif
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -676,6 +654,7 @@ sgn(int n)
|
||||
return (n < 0) ? -1 : (n != 0);
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* calculate x/y, rounding as appropriate */
|
||||
int
|
||||
rounddiv(long x, int y)
|
||||
@@ -700,6 +679,7 @@ rounddiv(long x, int y)
|
||||
|
||||
return divsgn * r;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* distance between two points, in moves */
|
||||
int
|
||||
@@ -759,74 +739,6 @@ online2(coordxy x0, coordxy y0, coordxy x1, coordxy y1)
|
||||
return (boolean) (!dy || !dx || dy == dx || dy == -dx);
|
||||
}
|
||||
|
||||
/* guts of pmatch(), pmatchi(), and pmatchz();
|
||||
match a string against a pattern */
|
||||
static boolean
|
||||
pmatch_internal(const char *patrn, const char *strng,
|
||||
boolean ci, /* True => case-insensitive,
|
||||
False => case-sensitive */
|
||||
const char *sk) /* set of characters to skip */
|
||||
{
|
||||
char s, p;
|
||||
/*
|
||||
* Simple pattern matcher: '*' matches 0 or more characters, '?' matches
|
||||
* any single character. Returns TRUE if 'strng' matches 'patrn'.
|
||||
*/
|
||||
pmatch_top:
|
||||
if (!sk) {
|
||||
s = *strng++;
|
||||
p = *patrn++; /* get next chars and pre-advance */
|
||||
} else {
|
||||
/* fuzzy match variant of pmatch; particular characters are ignored */
|
||||
do {
|
||||
s = *strng++;
|
||||
} while (strchr(sk, s));
|
||||
do {
|
||||
p = *patrn++;
|
||||
} while (strchr(sk, p));
|
||||
}
|
||||
if (!p) /* end of pattern */
|
||||
return (boolean) (s == '\0'); /* matches iff end of string too */
|
||||
else if (p == '*') /* wildcard reached */
|
||||
return (boolean) ((!*patrn
|
||||
|| pmatch_internal(patrn, strng - 1, ci, sk))
|
||||
? TRUE
|
||||
: s ? pmatch_internal(patrn - 1, strng, ci, sk)
|
||||
: FALSE);
|
||||
else if ((ci ? lowc(p) != lowc(s) : p != s) /* check single character */
|
||||
&& (p != '?' || !s)) /* & single-char wildcard */
|
||||
return FALSE; /* doesn't match */
|
||||
else /* return pmatch_internal(patrn, strng, ci, sk); */
|
||||
goto pmatch_top; /* optimize tail recursion */
|
||||
}
|
||||
|
||||
/* case-sensitive wildcard match */
|
||||
boolean
|
||||
pmatch(const char *patrn, const char *strng)
|
||||
{
|
||||
return pmatch_internal(patrn, strng, FALSE, (const char *) 0);
|
||||
}
|
||||
|
||||
/* case-insensitive wildcard match */
|
||||
boolean
|
||||
pmatchi(const char *patrn, const char *strng)
|
||||
{
|
||||
return pmatch_internal(patrn, strng, TRUE, (const char *) 0);
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* case-insensitive wildcard fuzzymatch;
|
||||
NEVER WORKED AS INTENDED but fortunately isn't needed */
|
||||
boolean
|
||||
pmatchz(const char *patrn, const char *strng)
|
||||
{
|
||||
/* ignore spaces, tabs (just in case), dashes, and underscores */
|
||||
static const char fuzzychars[] = " \t-_";
|
||||
|
||||
return pmatch_internal(patrn, strng, TRUE, fuzzychars);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef STRNCMPI
|
||||
/* case insensitive counted string comparison */
|
||||
/*{ aka strncasecmp }*/
|
||||
@@ -944,359 +856,6 @@ fuzzymatch(
|
||||
#define LOCALTIME_type time_t *
|
||||
#endif
|
||||
|
||||
static struct tm *getlt(void);
|
||||
|
||||
/* Sets the seed for the random number generator */
|
||||
#ifdef USE_ISAAC64
|
||||
static void set_random(unsigned long seed, int (*)(int));
|
||||
|
||||
static void
|
||||
set_random(unsigned long seed,
|
||||
int (*fn)(int))
|
||||
{
|
||||
init_isaac64(seed, fn);
|
||||
}
|
||||
|
||||
#else /* USE_ISAAC64 */
|
||||
|
||||
/*ARGSUSED*/
|
||||
static void
|
||||
set_random(unsigned long seed,
|
||||
int (*fn)(int) UNUSED)
|
||||
{
|
||||
/*
|
||||
* The types are different enough here that sweeping the different
|
||||
* routine names into one via #defines is even more confusing.
|
||||
*/
|
||||
# ifdef RANDOM /* srandom() from sys/share/random.c */
|
||||
srandom((unsigned int) seed);
|
||||
# else
|
||||
# if defined(__APPLE__) || defined(BSD) || defined(LINUX) \
|
||||
|| defined(ULTRIX) || defined(CYGWIN32) /* system srandom() */
|
||||
# if defined(BSD) && !defined(POSIX_TYPES) && defined(SUNOS4)
|
||||
(void)
|
||||
# endif
|
||||
srandom((int) seed);
|
||||
# else
|
||||
# ifdef UNIX /* system srand48() */
|
||||
srand48((long) seed);
|
||||
# else /* poor quality system routine */
|
||||
srand((int) seed);
|
||||
# endif
|
||||
# endif
|
||||
# endif
|
||||
}
|
||||
|
||||
#endif /* USE_ISAAC64 */
|
||||
|
||||
/* An appropriate version of this must always be provided in
|
||||
port-specific code somewhere. It returns a number suitable
|
||||
as seed for the random number generator */
|
||||
extern unsigned long sys_random_seed(void);
|
||||
|
||||
/*
|
||||
* Initializes the random number generator.
|
||||
* Only call once.
|
||||
*/
|
||||
void
|
||||
init_random(int (*fn)(int))
|
||||
{
|
||||
set_random(sys_random_seed(), fn);
|
||||
}
|
||||
|
||||
/* Reshuffles the random number generator. */
|
||||
void
|
||||
reseed_random(int (*fn)(int))
|
||||
{
|
||||
/* only reseed if we are certain that the seed generation is unguessable
|
||||
* by the players. */
|
||||
if (has_strong_rngseed)
|
||||
init_random(fn);
|
||||
}
|
||||
|
||||
time_t
|
||||
getnow(void)
|
||||
{
|
||||
time_t datetime = 0;
|
||||
|
||||
(void) time((TIME_type) &datetime);
|
||||
return datetime;
|
||||
}
|
||||
|
||||
static struct tm *
|
||||
getlt(void)
|
||||
{
|
||||
time_t date = getnow();
|
||||
|
||||
return localtime((LOCALTIME_type) &date);
|
||||
}
|
||||
|
||||
int
|
||||
getyear(void)
|
||||
{
|
||||
return (1900 + getlt()->tm_year);
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* This routine is no longer used since in 20YY it yields "1YYmmdd". */
|
||||
char *
|
||||
yymmdd(time_t date)
|
||||
{
|
||||
static char datestr[10];
|
||||
struct tm *lt;
|
||||
|
||||
if (date == 0)
|
||||
lt = getlt();
|
||||
else
|
||||
lt = localtime((LOCALTIME_type) &date);
|
||||
|
||||
Sprintf(datestr, "%02d%02d%02d",
|
||||
lt->tm_year, lt->tm_mon + 1, lt->tm_mday);
|
||||
return datestr;
|
||||
}
|
||||
#endif
|
||||
|
||||
long
|
||||
yyyymmdd(time_t date)
|
||||
{
|
||||
long datenum;
|
||||
struct tm *lt;
|
||||
|
||||
if (date == 0)
|
||||
lt = getlt();
|
||||
else
|
||||
lt = localtime((LOCALTIME_type) &date);
|
||||
|
||||
/* just in case somebody's localtime supplies (year % 100)
|
||||
rather than the expected (year - 1900) */
|
||||
if (lt->tm_year < 70)
|
||||
datenum = (long) lt->tm_year + 2000L;
|
||||
else
|
||||
datenum = (long) lt->tm_year + 1900L;
|
||||
/* yyyy --> yyyymm */
|
||||
datenum = datenum * 100L + (long) (lt->tm_mon + 1);
|
||||
/* yyyymm --> yyyymmdd */
|
||||
datenum = datenum * 100L + (long) lt->tm_mday;
|
||||
return datenum;
|
||||
}
|
||||
|
||||
long
|
||||
hhmmss(time_t date)
|
||||
{
|
||||
long timenum;
|
||||
struct tm *lt;
|
||||
|
||||
if (date == 0)
|
||||
lt = getlt();
|
||||
else
|
||||
lt = localtime((LOCALTIME_type) &date);
|
||||
|
||||
timenum = lt->tm_hour * 10000L + lt->tm_min * 100L + lt->tm_sec;
|
||||
return timenum;
|
||||
}
|
||||
|
||||
char *
|
||||
yyyymmddhhmmss(time_t date)
|
||||
{
|
||||
long datenum;
|
||||
static char datestr[15];
|
||||
struct tm *lt;
|
||||
|
||||
if (date == 0)
|
||||
lt = getlt();
|
||||
else
|
||||
lt = localtime((LOCALTIME_type) &date);
|
||||
|
||||
/* just in case somebody's localtime supplies (year % 100)
|
||||
rather than the expected (year - 1900) */
|
||||
if (lt->tm_year < 70)
|
||||
datenum = (long) lt->tm_year + 2000L;
|
||||
else
|
||||
datenum = (long) lt->tm_year + 1900L;
|
||||
Snprintf(datestr, sizeof datestr, "%04ld%02d%02d%02d%02d%02d",
|
||||
datenum, lt->tm_mon + 1,
|
||||
lt->tm_mday, lt->tm_hour, lt->tm_min, lt->tm_sec);
|
||||
debugpline1("yyyymmddhhmmss() produced date string %s", datestr);
|
||||
return datestr;
|
||||
}
|
||||
|
||||
time_t
|
||||
time_from_yyyymmddhhmmss(char *buf)
|
||||
{
|
||||
int k;
|
||||
time_t timeresult = (time_t) 0;
|
||||
struct tm t, *lt;
|
||||
char *d, *p, y[5], mo[3], md[3], h[3], mi[3], s[3];
|
||||
|
||||
if (buf && strlen(buf) == 14) {
|
||||
d = buf;
|
||||
p = y; /* year */
|
||||
for (k = 0; k < 4; ++k)
|
||||
*p++ = *d++;
|
||||
*p = '\0';
|
||||
p = mo; /* month */
|
||||
for (k = 0; k < 2; ++k)
|
||||
*p++ = *d++;
|
||||
*p = '\0';
|
||||
p = md; /* day */
|
||||
for (k = 0; k < 2; ++k)
|
||||
*p++ = *d++;
|
||||
*p = '\0';
|
||||
p = h; /* hour */
|
||||
for (k = 0; k < 2; ++k)
|
||||
*p++ = *d++;
|
||||
*p = '\0';
|
||||
p = mi; /* minutes */
|
||||
for (k = 0; k < 2; ++k)
|
||||
*p++ = *d++;
|
||||
*p = '\0';
|
||||
p = s; /* seconds */
|
||||
for (k = 0; k < 2; ++k)
|
||||
*p++ = *d++;
|
||||
*p = '\0';
|
||||
lt = getlt();
|
||||
if (lt) {
|
||||
t = *lt;
|
||||
t.tm_year = atoi(y) - 1900;
|
||||
t.tm_mon = atoi(mo) - 1;
|
||||
t.tm_mday = atoi(md);
|
||||
t.tm_hour = atoi(h);
|
||||
t.tm_min = atoi(mi);
|
||||
t.tm_sec = atoi(s);
|
||||
timeresult = mktime(&t);
|
||||
}
|
||||
if (timeresult == (time_t) -1) {
|
||||
debugpline1("time_from_yyyymmddhhmmss(%s) would have returned -1",
|
||||
buf ? buf : "");
|
||||
timeresult = (time_t) 0;
|
||||
}
|
||||
}
|
||||
return timeresult;
|
||||
}
|
||||
|
||||
/*
|
||||
* moon period = 29.53058 days ~= 30, year = 365.2422 days
|
||||
* days moon phase advances on first day of year compared to preceding year
|
||||
* = 365.2422 - 12*29.53058 ~= 11
|
||||
* years in Metonic cycle (time until same phases fall on the same days of
|
||||
* the month) = 18.6 ~= 19
|
||||
* moon phase on first day of year (epact) ~= (11*(year%19) + 29) % 30
|
||||
* (29 as initial condition)
|
||||
* current phase in days = first day phase + days elapsed in year
|
||||
* 6 moons ~= 177 days
|
||||
* 177 ~= 8 reported phases * 22
|
||||
* + 11/22 for rounding
|
||||
*/
|
||||
int
|
||||
phase_of_the_moon(void) /* 0-7, with 0: new, 4: full */
|
||||
{
|
||||
struct tm *lt = getlt();
|
||||
int epact, diy, goldn;
|
||||
|
||||
diy = lt->tm_yday;
|
||||
goldn = (lt->tm_year % 19) + 1;
|
||||
epact = (11 * goldn + 18) % 30;
|
||||
if ((epact == 25 && goldn > 11) || epact == 24)
|
||||
epact++;
|
||||
|
||||
return ((((((diy + epact) * 6) + 11) % 177) / 22) & 7);
|
||||
}
|
||||
|
||||
boolean
|
||||
friday_13th(void)
|
||||
{
|
||||
struct tm *lt = getlt();
|
||||
|
||||
/* tm_wday (day of week; 0==Sunday) == 5 => Friday */
|
||||
return (boolean) (lt->tm_wday == 5 && lt->tm_mday == 13);
|
||||
}
|
||||
|
||||
int
|
||||
night(void)
|
||||
{
|
||||
int hour = getlt()->tm_hour;
|
||||
|
||||
return (hour < 6 || hour > 21);
|
||||
}
|
||||
|
||||
int
|
||||
midnight(void)
|
||||
{
|
||||
return (getlt()->tm_hour == 0);
|
||||
}
|
||||
|
||||
/* strbuf_init() initializes strbuf state for use */
|
||||
void
|
||||
strbuf_init(strbuf_t *strbuf)
|
||||
{
|
||||
strbuf->str = NULL;
|
||||
strbuf->len = 0;
|
||||
}
|
||||
|
||||
/* strbuf_append() appends given str to strbuf->str */
|
||||
void
|
||||
strbuf_append(strbuf_t *strbuf, const char *str)
|
||||
{
|
||||
int len = (int) strlen(str) + 1;
|
||||
|
||||
strbuf_reserve(strbuf,
|
||||
len + (strbuf->str ? (int) strlen(strbuf->str) : 0));
|
||||
Strcat(strbuf->str, str);
|
||||
}
|
||||
|
||||
/* strbuf_reserve() ensure strbuf->str has storage for len characters */
|
||||
void
|
||||
strbuf_reserve(strbuf_t *strbuf, int len)
|
||||
{
|
||||
if (strbuf->str == NULL) {
|
||||
strbuf->str = strbuf->buf;
|
||||
strbuf->str[0] = '\0';
|
||||
strbuf->len = (int) sizeof strbuf->buf;
|
||||
}
|
||||
|
||||
if (len > strbuf->len) {
|
||||
char *oldbuf = strbuf->str;
|
||||
|
||||
strbuf->len = len + (int) sizeof strbuf->buf;
|
||||
strbuf->str = (char *) alloc(strbuf->len);
|
||||
Strcpy(strbuf->str, oldbuf);
|
||||
if (oldbuf != strbuf->buf)
|
||||
free((genericptr_t) oldbuf);
|
||||
}
|
||||
}
|
||||
|
||||
/* strbuf_empty() frees allocated memory and set strbuf to initial state */
|
||||
void
|
||||
strbuf_empty(strbuf_t *strbuf)
|
||||
{
|
||||
if (strbuf->str != NULL && strbuf->str != strbuf->buf)
|
||||
free((genericptr_t) strbuf->str);
|
||||
strbuf_init(strbuf);
|
||||
}
|
||||
|
||||
/* strbuf_nl_to_crlf() converts all occurrences of \n to \r\n */
|
||||
void
|
||||
strbuf_nl_to_crlf(strbuf_t *strbuf)
|
||||
{
|
||||
if (strbuf->str) {
|
||||
int len = (int) strlen(strbuf->str);
|
||||
int count = 0;
|
||||
char *cp = strbuf->str;
|
||||
|
||||
while (*cp)
|
||||
if (*cp++ == '\n')
|
||||
count++;
|
||||
if (count) {
|
||||
strbuf_reserve(strbuf, len + count + 1);
|
||||
for (cp = strbuf->str + len + count; count; --cp)
|
||||
if ((*cp = cp[-count]) == '\n') {
|
||||
*--cp = '\r';
|
||||
--count;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* swapbits(val, bita, bitb) swaps bit a with bit b in val */
|
||||
int
|
||||
swapbits(int val, int bita, int bitb)
|
||||
@@ -1306,21 +865,6 @@ swapbits(int val, int bita, int bitb)
|
||||
return (val ^ ((tmp << bita) | (tmp << bitb)));
|
||||
}
|
||||
|
||||
/* randomize the given list of numbers 0 <= i < count */
|
||||
void
|
||||
shuffle_int_array(int *indices, int count)
|
||||
{
|
||||
int i, iswap, temp;
|
||||
|
||||
for (i = count - 1; i > 0; i--) {
|
||||
if ((iswap = rn2(i + 1)) == i)
|
||||
continue;
|
||||
temp = indices[i];
|
||||
indices[i] = indices[iswap];
|
||||
indices[iswap] = temp;
|
||||
}
|
||||
}
|
||||
|
||||
DISABLE_WARNING_FORMAT_NONLITERAL
|
||||
|
||||
/*
|
||||
@@ -1337,7 +881,7 @@ DISABLE_WARNING_FORMAT_NONLITERAL
|
||||
*/
|
||||
void
|
||||
nh_snprintf(
|
||||
const char *func, int line,
|
||||
const char *func UNUSED, int line UNUSED,
|
||||
char *str, size_t size,
|
||||
const char *fmt, ...)
|
||||
{
|
||||
@@ -1348,17 +892,19 @@ nh_snprintf(
|
||||
n = vsnprintf(str, size, fmt, ap);
|
||||
va_end(ap);
|
||||
if (n < 0 || (size_t) n >= size) { /* is there a problem? */
|
||||
#if 0
|
||||
TODO: add set_impossible(), impossible -> func pointer,
|
||||
test funcpointer before call
|
||||
impossible("snprintf %s: func %s, file line %d",
|
||||
(n < 0) ? "format error" : "overflow",
|
||||
func, line);
|
||||
#endif
|
||||
str[size - 1] = '\0'; /* make sure it is nul terminated */
|
||||
}
|
||||
}
|
||||
|
||||
RESTORE_WARNING_FORMAT_NONLITERAL
|
||||
|
||||
#ifdef ENHANCED_SYMBOLS
|
||||
|
||||
/* Unicode routines */
|
||||
|
||||
int
|
||||
@@ -1400,6 +946,5 @@ unicodeval_to_utf8str(int uval, uint8 *buffer, size_t bufsz)
|
||||
*b = '\0'; /* NUL terminate */
|
||||
return 1;
|
||||
}
|
||||
#endif /* ENHANCED_SYMBOLS */
|
||||
|
||||
/*hacklib.c*/
|
||||
|
||||
+6
-23
@@ -27,6 +27,7 @@
|
||||
#include "context.h"
|
||||
#include "flag.h"
|
||||
#include "dlb.h"
|
||||
#include "hacklib.h"
|
||||
#include <ctype.h>
|
||||
/* version information */
|
||||
#ifdef SHORT_FILENAMES
|
||||
@@ -60,7 +61,9 @@ char *bannerc_string(char *, size_t, const char *) NONNULL NONNULLPTRS;
|
||||
int case_insensitive_comp(const char *, const char *) NONNULLPTRS;
|
||||
|
||||
static void make_version(void);
|
||||
#if 0
|
||||
static char *eos(char *) NONNULL NONNULLARG1;
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
static char *mdlib_strsubst(char *, const char *, const char *);
|
||||
@@ -79,6 +82,7 @@ extern int GUILaunched;
|
||||
#endif
|
||||
|
||||
/* these are in extern.h but we don't include hack.h */
|
||||
/* XXX move to new file mdlib.h? */
|
||||
extern void populate_nomakedefs(struct version_info *) NONNULLARG1; /* date.c */
|
||||
extern void free_nomakedefs(void); /* date.c */
|
||||
void runtime_info_init(void);
|
||||
@@ -341,29 +345,6 @@ mdlib_version_string(char *outbuf, const char *delim)
|
||||
extern void nh_snprintf(const char *func, int line, char *str, size_t size,
|
||||
const char *fmt, ...);
|
||||
|
||||
#ifdef MAKEDEFS_C
|
||||
DISABLE_WARNING_FORMAT_NONLITERAL
|
||||
|
||||
void
|
||||
nh_snprintf(const char *func UNUSED, int line UNUSED, char *str, size_t size,
|
||||
const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
int n;
|
||||
|
||||
va_start(ap, fmt);
|
||||
n = vsnprintf(str, size, fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
if (n < 0 || (size_t) n >= size) { /* is there a problem? */
|
||||
str[size-1] = 0; /* make sure it is nul terminated */
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
RESTORE_WARNING_FORMAT_NONLITERAL
|
||||
#endif /* MAKEDEFS_C */
|
||||
|
||||
char *
|
||||
version_id_string(char *outbuf, size_t bufsz, const char *build_date)
|
||||
{
|
||||
@@ -439,6 +420,7 @@ mkstemp(char *template)
|
||||
#endif /* HAS_NO_MKSTEMP */
|
||||
#endif /* MAKEDEFS_C || FOR_RUNTIME */
|
||||
|
||||
#if 0
|
||||
static char *
|
||||
eos(char *str)
|
||||
{
|
||||
@@ -446,6 +428,7 @@ eos(char *str)
|
||||
str++;
|
||||
return str;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
static char *
|
||||
|
||||
+622
@@ -0,0 +1,622 @@
|
||||
/* NetHack 3.7 report.c $NHDT-Date: 1709571806 2024/03/04 17:03:26 $ $NHDT-Branch: keni-mdlib-followup $:$NHDT-Revision: 1.306 $ */
|
||||
/* Copyright (c) Kenneth Lorber, Kensington, Maryland, 2024 */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
|
||||
#include "hack.h"
|
||||
|
||||
/* NB: CRASHREPORT implies PANICTRACE */
|
||||
#ifdef CRASHREPORT
|
||||
|
||||
# ifndef NO_SIGNAL
|
||||
#include <signal.h>
|
||||
# endif
|
||||
#include <ctype.h>
|
||||
# ifndef LONG_MAX
|
||||
#include <limits.h>
|
||||
# endif
|
||||
#include "dlb.h"
|
||||
#include <fcntl.h>
|
||||
|
||||
#include <errno.h>
|
||||
# ifdef PANICTRACE_LIBC
|
||||
#include <execinfo.h>
|
||||
# endif
|
||||
|
||||
# ifndef NO_SIGNAL
|
||||
/* called as signal() handler, so sent at least one arg */
|
||||
/*ARGUSED*/
|
||||
void
|
||||
panictrace_handler(int sig_unused UNUSED)
|
||||
{
|
||||
#define SIG_MSG "\nSignal received.\n"
|
||||
int f2;
|
||||
|
||||
# ifdef CURSES_GRAPHICS
|
||||
if (iflags.window_inited && WINDOWPORT(curses)) {
|
||||
extern void curses_uncurse_terminal(void); /* wincurs.h */
|
||||
|
||||
/* it is risky calling this during a program-terminating signal,
|
||||
but without it the subsequent backtrace is useless because
|
||||
that ends up being scrawled all over the screen; call is
|
||||
here rather than in NH_abort() because panic() calls both
|
||||
exit_nhwindows(), which makes this same call under curses,
|
||||
then NH_abort() and we don't want to call this twice */
|
||||
curses_uncurse_terminal();
|
||||
}
|
||||
# endif
|
||||
|
||||
f2 = (int) write(2, SIG_MSG, sizeof SIG_MSG - 1);
|
||||
nhUse(f2); /* what could we do if write to fd#2 (stderr) fails */
|
||||
NH_abort(NULL); /* ... and we're already in the process of quitting? */
|
||||
}
|
||||
|
||||
void
|
||||
panictrace_setsignals(boolean set)
|
||||
{
|
||||
#define SETSIGNAL(sig) \
|
||||
(void) signal(sig, set ? (SIG_RET_TYPE) panictrace_handler : SIG_DFL);
|
||||
# ifdef SIGILL
|
||||
SETSIGNAL(SIGILL);
|
||||
# endif
|
||||
# ifdef SIGTRAP
|
||||
SETSIGNAL(SIGTRAP);
|
||||
# endif
|
||||
# ifdef SIGIOT
|
||||
SETSIGNAL(SIGIOT);
|
||||
# endif
|
||||
# ifdef SIGBUS
|
||||
SETSIGNAL(SIGBUS);
|
||||
# endif
|
||||
# ifdef SIGFPE
|
||||
SETSIGNAL(SIGFPE);
|
||||
# endif
|
||||
# ifdef SIGSEGV
|
||||
SETSIGNAL(SIGSEGV);
|
||||
# endif
|
||||
# ifdef SIGSTKFLT
|
||||
SETSIGNAL(SIGSTKFLT);
|
||||
# endif
|
||||
# ifdef SIGSYS
|
||||
SETSIGNAL(SIGSYS);
|
||||
# endif
|
||||
# ifdef SIGEMT
|
||||
SETSIGNAL(SIGEMT);
|
||||
# endif
|
||||
#undef SETSIGNAL
|
||||
}
|
||||
# endif /* NO_SIGNAL */
|
||||
|
||||
# ifdef WIN32
|
||||
# define HASH_PRAGMA_START
|
||||
# define HASH_PRAGMA_END
|
||||
# else
|
||||
# define HASH_PRAGMA_START \
|
||||
_Pragma("GCC diagnostic push"); \
|
||||
_Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
|
||||
# define HASH_PRAGMA_END _Pragma("GCC diagnostic pop");
|
||||
# endif
|
||||
# ifdef MACOS
|
||||
#include <CommonCrypto/CommonDigest.h>
|
||||
# define HASH_CONTEXTPTR(CTXP) \
|
||||
unsigned char tmp[CC_MD4_DIGEST_LENGTH]; \
|
||||
CC_MD4_CTX CTXP ## _; \
|
||||
CC_MD4_CTX *CTXP = &CTXP ## _
|
||||
# define HASH_INIT(ctxp) !CC_MD4_Init(ctxp)
|
||||
# define HASH_UPDATE(ctx, ptr, len) !CC_MD4_Update(ctx, ptr, len)
|
||||
# define HASH_FINISH(ctxp) !CC_MD4_Final(tmp, ctxp)
|
||||
# define HASH_RESULT_SIZE(ctxp) CC_MD4_DIGEST_LENGTH
|
||||
# define HASH_RESULT(ctx, inp) *inp = (unsigned char *) ctx
|
||||
# define HASH_CLEANUP(ctxp)
|
||||
# define HASH_OFLAGS O_RDONLY
|
||||
# define HASH_BINFILE_DECL char *binfile = argv[0];
|
||||
# ifdef BETA
|
||||
# define HASH_BINFILE \
|
||||
if (!binfile || !*binfile) { \
|
||||
/* If this triggers, investigate CFBundleGetMainBundle */ \
|
||||
/* or CFBundleCopyExecutableURL. */ \
|
||||
raw_print( \
|
||||
"BETA warning: crashreport_init called without useful info"); \
|
||||
goto skip; \
|
||||
}
|
||||
# else /* BETA */
|
||||
# define HASH_BINFILE() \
|
||||
if (!binfile || !*binfile) { \
|
||||
goto skip; \
|
||||
}
|
||||
# endif /* BETA */
|
||||
# endif /* MACOS */
|
||||
|
||||
# ifdef __linux__
|
||||
#include "nhmd4.h"
|
||||
# define HASH_CONTEXTPTR(CTXP) \
|
||||
unsigned char tmp[NHMD4_DIGEST_LENGTH]; \
|
||||
NHMD4_CTX CTXP ## _; \
|
||||
NHMD4_CTX *CTXP = &CTXP ## _
|
||||
# define HASH_INIT(ctxp) (nhmd4_init(ctxp), 0)
|
||||
# define HASH_UPDATE(ctx, ptr, len) (nhmd4_update(ctx, ptr, len), 0)
|
||||
# define HASH_FINISH(ctxp) (nhmd4_final(ctxp, tmp), 0)
|
||||
# define HASH_RESULT_SIZE(ctxp) NHMD4_RESULTLEN
|
||||
# define HASH_RESULT(ctx, inp) *inp = tmp
|
||||
# define HASH_CLEANUP(ctxp)
|
||||
# define HASH_OFLAGS O_RDONLY
|
||||
# define HASH_BINFILE_DECL char binfile[PATH_MAX+1];
|
||||
# define HASH_BINFILE() \
|
||||
int len = readlink("/proc/self/exe", binfile, sizeof binfile - 1); \
|
||||
if (len > 0) { \
|
||||
binfile[len] = '\0'; \
|
||||
} else { \
|
||||
goto skip; \
|
||||
}
|
||||
# endif // __linux__
|
||||
|
||||
# ifdef WIN32
|
||||
/* WIN32 takes too much code and is dependent on OS includes we can't
|
||||
* pull in here, so we call out to code in sys/windows/windsys.c */
|
||||
# define HASH_CONTEXTPTR(CTXP)
|
||||
# define HASH_INIT(ctxp) win32_cr_helper('i', ctxp, NULL, 0)
|
||||
# define HASH_UPDATE(ctxp, ptr, len) win32_cr_helper('u', ctxp, ptr, len)
|
||||
# define HASH_FINISH(ctxp) win32_cr_helper('f', ctxp, NULL, 0)
|
||||
# define HASH_CLEANUP(ctxp) win32_cr_helper('c', ctxp, NULL, 0)
|
||||
# define HASH_RESULT_SIZE(ctxp) win32_cr_helper('s', ctxp, NULL, 0)
|
||||
# define HASH_RESULT(ctxp, inp) win32_cr_helper('r', ctxp, inp, 0)
|
||||
# define HASH_OFLAGS _O_RDONLY | _O_BINARY
|
||||
# define HASH_BINFILE_DECL char *binfile;
|
||||
# define HASH_BINFILE() \
|
||||
if (win32_cr_helper('b', NULL, &binfile, 0)) { \
|
||||
goto skip; \
|
||||
}
|
||||
# endif // WIN32
|
||||
|
||||
/* Binary ID - Use only as a hint to contact.html for recognizing our own
|
||||
binaries. This is easily spoofed! */
|
||||
static char bid[40];
|
||||
|
||||
/* ARGSUSED */
|
||||
void
|
||||
crashreport_init(int argc UNUSED, char *argv[] UNUSED)
|
||||
{
|
||||
static int once = 0;
|
||||
if (once++) /* NetHackW.exe calls us twice */
|
||||
return;
|
||||
HASH_BINFILE_DECL;
|
||||
HASH_PRAGMA_START
|
||||
HASH_CONTEXTPTR(ctxp);
|
||||
if (HASH_INIT(ctxp))
|
||||
goto skip;
|
||||
HASH_BINFILE(); /* Does "goto skip" on error. */
|
||||
|
||||
int fd = open(binfile, HASH_OFLAGS, 0);
|
||||
if (fd == -1) {
|
||||
# ifdef BETA
|
||||
raw_printf("open e=%s", strerror(errno));
|
||||
# endif
|
||||
goto skip;
|
||||
}
|
||||
|
||||
int segsize;
|
||||
unsigned char segment[4096];
|
||||
|
||||
while (0 < (segsize = read(fd, segment, sizeof segment))) {
|
||||
if (HASH_UPDATE(ctxp, segment, segsize))
|
||||
goto skip;
|
||||
}
|
||||
if (segsize < 0) {
|
||||
close(fd);
|
||||
goto skip;
|
||||
}
|
||||
if (HASH_FINISH(ctxp))
|
||||
goto skip;
|
||||
close(fd);
|
||||
|
||||
static const char hex[] = "0123456789abcdef";
|
||||
char *p = bid;
|
||||
unsigned char *in;
|
||||
HASH_RESULT(ctxp, &in);
|
||||
uint8 cnt = (uint8) HASH_RESULT_SIZE(ctxp);
|
||||
/* Just in case, make sure not to overflow the bid buffer.
|
||||
Divide size by 2 because each octet in the hash uses two slots
|
||||
in bid[] when formatted as a pair of hexadecimal digits. */
|
||||
if (cnt >= (uint8) sizeof bid / 2)
|
||||
cnt = (uint8) sizeof bid / 2 - 1;
|
||||
while (cnt) {
|
||||
/* sprintf(p, "%02x", *in++), p += 2; */
|
||||
*p++ = hex[(*in >> 4) & 0x0f];
|
||||
*p++ = hex[*in++ & 0x0f];
|
||||
--cnt;
|
||||
}
|
||||
*p = '\0';
|
||||
return;
|
||||
|
||||
skip:
|
||||
Strcpy(bid, "unknown");
|
||||
HASH_CLEANUP(ctxp);
|
||||
HASH_PRAGMA_END
|
||||
}
|
||||
|
||||
#undef HASH_CONTEXTPTR
|
||||
#undef HASH_INIT
|
||||
#undef HASH_UPDATE
|
||||
#undef HASH_FINISH
|
||||
#undef HASH_CLEANUP
|
||||
#undef HASH_RESULT
|
||||
#undef HASH_RESULT_SIZE
|
||||
#undef HASH_PRAGMA_START
|
||||
#undef HASH_PRAGMA_END
|
||||
#undef HASH_BINFILE_DECL
|
||||
#undef HASH_BINFILE
|
||||
|
||||
void
|
||||
crashreport_bidshow(void)
|
||||
{
|
||||
# if defined(WIN32) && !defined(WIN32CON)
|
||||
if (0 == win32_cr_helper('D', ctxp, bid, 0))
|
||||
# endif
|
||||
{
|
||||
raw_print(bid);
|
||||
# ifdef WIN32notyet
|
||||
wait_synch();
|
||||
# endif
|
||||
}
|
||||
}
|
||||
|
||||
/* Build a URL with a query string and try to launch a new browser window
|
||||
* to report from panic() or impossible(). Requires libc support for
|
||||
* the stacktrace. Uses memory on the stack to avoid memory allocation
|
||||
* (on most platforms) (but libc can still do anything it wants). */
|
||||
|
||||
// No theoretial limit for URL length but reality is messy.
|
||||
// This should work on all modern platforms.
|
||||
# ifndef MAX_URL
|
||||
# define MAX_URL 8192
|
||||
# endif
|
||||
# ifndef SWR_FRAMES
|
||||
# define SWR_FRAMES 20
|
||||
# endif
|
||||
|
||||
// mark holds the initial eos; if we can't get the value in
|
||||
// then we can remove the whole item if desired. For other
|
||||
// semantics, caller can handle mark.
|
||||
#define SWR_ADD(str) \
|
||||
utmp = strlen(str); \
|
||||
mark = uend; \
|
||||
if (utmp >= urem) \
|
||||
goto full; \
|
||||
strncpy(uend, str, utmp); \
|
||||
uend += utmp; urem -= utmp; \
|
||||
*uend = '\0';
|
||||
|
||||
// NB: on overflow this rolls us back to mark, so if we don't
|
||||
// want to roll back to the last SWR_ADD, update mark before
|
||||
// calling this macro.
|
||||
#define SWR_ADD_URIcoded(str) \
|
||||
if (swr_add_uricoded(str, &uend, &urem, mark)) \
|
||||
goto full;
|
||||
|
||||
/* On overflow, truncate to markp (but only if markp != NULL). */
|
||||
boolean
|
||||
swr_add_uricoded(
|
||||
const char *in,
|
||||
char **out,
|
||||
int *remaining,
|
||||
char *markp)
|
||||
{
|
||||
while (*in) {
|
||||
if (isalnum(*in) || strchr("_-.~", *in)) {
|
||||
**out = *in;
|
||||
(*out)++;
|
||||
(*remaining)--;
|
||||
} else if (*in == ' ') {
|
||||
**out = '+';
|
||||
(*out)++;
|
||||
(*remaining)--;
|
||||
} else {
|
||||
if (*remaining <= 3) {
|
||||
if (markp)
|
||||
*out = markp, *remaining = 0;
|
||||
**out = '\0';
|
||||
return TRUE;
|
||||
}
|
||||
int x = snprintf(*out, *remaining, "%%%02X", *in);
|
||||
*out += x;
|
||||
*remaining -= x;
|
||||
}
|
||||
in++;
|
||||
if (!*remaining) {
|
||||
if (markp)
|
||||
*out = markp, *remaining = 0;
|
||||
**out = '\0';
|
||||
return TRUE;
|
||||
}
|
||||
**out = '\0';
|
||||
}
|
||||
return FALSE; /* normal return */
|
||||
}
|
||||
|
||||
static char url[MAX_URL]; // XXX too bad this isn't allocated as needed
|
||||
static int urem = MAX_URL; // adjusted for gc.crash_urlmax below
|
||||
static char *uend = url;
|
||||
static int utmp; // used inside macros
|
||||
static char *mark; // holds previous terminator (generally)
|
||||
|
||||
boolean
|
||||
submit_web_report(int cos, const char *msg, const char *why)
|
||||
{
|
||||
urem = (gc.crash_urlmax < 0 || gc.crash_urlmax > MAX_URL)
|
||||
? MAX_URL : min(MAX_URL,gc.crash_urlmax);
|
||||
char temp[200];
|
||||
char temp2[200];
|
||||
int countpp = 0; /* pre and post traceback lines */
|
||||
// URL loaded for creating reports to the NetHack DevTeam
|
||||
// CRASHREPORTURL=https://nethack.org/links/cr-37BETA.html
|
||||
if (!sysopt.crashreporturl)
|
||||
return FALSE;
|
||||
SWR_ADD(sysopt.crashreporturl);
|
||||
/* cos - operation, v - version */
|
||||
Snprintf(temp, sizeof temp, "?cos=%d&v=1", cos);
|
||||
SWR_ADD(temp);
|
||||
|
||||
/* msg==NULL for #bugreport */
|
||||
if (msg) {
|
||||
SWR_ADD("&subject=");
|
||||
Snprintf(temp, sizeof temp, "%s report for NetHack %s",
|
||||
msg, version_string(temp2, sizeof temp2 ));
|
||||
SWR_ADD_URIcoded(temp);
|
||||
}
|
||||
|
||||
SWR_ADD("&gitver=");
|
||||
SWR_ADD_URIcoded(getversionstring(temp2, sizeof temp2));
|
||||
|
||||
if (gc.crash_name) {
|
||||
SWR_ADD("&name=");
|
||||
SWR_ADD_URIcoded(gc.crash_name);
|
||||
}
|
||||
|
||||
if(gc.crash_email) {
|
||||
SWR_ADD("&email=");
|
||||
SWR_ADD_URIcoded(gc.crash_email);
|
||||
}
|
||||
// hardware: leave for user
|
||||
// software: leave for user
|
||||
// comments: leave for user
|
||||
|
||||
SWR_ADD("&details=");
|
||||
if (why) {
|
||||
SWR_ADD_URIcoded(why);
|
||||
SWR_ADD_URIcoded("\n");
|
||||
mark = uend;
|
||||
countpp++;
|
||||
}
|
||||
|
||||
SWR_ADD_URIcoded("bid: ");
|
||||
SWR_ADD_URIcoded(bid);
|
||||
SWR_ADD_URIcoded("\n");
|
||||
mark = uend;
|
||||
countpp++;
|
||||
|
||||
int count = 0;
|
||||
if (cos == 1) {
|
||||
# ifdef WIN32
|
||||
count = win32_cr_gettrace(SWR_FRAMES, uend, MAX_URL - (uend - url));
|
||||
uend = eos(url);
|
||||
# else
|
||||
void *bt[SWR_FRAMES];
|
||||
int x;
|
||||
char **info;
|
||||
|
||||
count = backtrace(bt, SIZE(bt));
|
||||
info = backtrace_symbols(bt, count);
|
||||
for (x = 0; x < count; x++) {
|
||||
copynchars(temp, info[x], (int) sizeof temp - 1 - 1); /* \n\0 */
|
||||
/* try to remove up to 16 blank spaces by removing 8 twice */
|
||||
(void) strsubst(temp, " ", "");
|
||||
(void) strsubst(temp, " ", "");
|
||||
(void) strncat(temp, "\n", sizeof temp - 1);
|
||||
# if 0 // __linux__
|
||||
// not needed for MacOS
|
||||
// XXX is it actually needed for linux? TBD
|
||||
Snprintf(temp2, sizeof temp2, "[%02lu]\n", (unsigned long) x);
|
||||
uend--; // remove the \n we added above
|
||||
SWR_ADD_URIcoded(temp2);
|
||||
# endif // linux
|
||||
SWR_ADD_URIcoded(temp);
|
||||
mark = uend;
|
||||
}
|
||||
# endif // !WIN32
|
||||
}
|
||||
|
||||
# ifdef DUMPLOG_CORE
|
||||
// config.h turns this on, but make it easy to turn off if needed
|
||||
if (cos == 1) {
|
||||
int k;
|
||||
SWR_ADD_URIcoded("Latest messages:\n");
|
||||
mark=uend;
|
||||
countpp++;
|
||||
for (k = 0; k < 5; k++) {
|
||||
const char *line = get_saved_pline(k);
|
||||
if (!line)
|
||||
break;
|
||||
SWR_ADD_URIcoded(line);
|
||||
SWR_ADD_URIcoded("\n");
|
||||
countpp++;
|
||||
mark = uend;
|
||||
}
|
||||
}
|
||||
# endif /* DUMPLOG_CORE */
|
||||
|
||||
// detailrows: Guess since we can't know the
|
||||
// width of the window.
|
||||
SWR_ADD("&detailrows=");
|
||||
Snprintf(temp, sizeof temp, "%d", min(count + countpp, 30));
|
||||
SWR_ADD_URIcoded(temp);
|
||||
|
||||
full:
|
||||
;
|
||||
//printf("URL=%ld '%s'\n",strlen(url),url);
|
||||
# ifdef WIN32
|
||||
int *rv = win32_cr_shellexecute(url);
|
||||
// XXX TESTING
|
||||
printf("ShellExecute returned: %p\n",rv); // >32 is ok
|
||||
# else /* !WIN32 */
|
||||
const char *xargv[] = {
|
||||
CRASHREPORT,
|
||||
url,
|
||||
NULL
|
||||
};
|
||||
int pid = fork();
|
||||
extern char **environ;
|
||||
if (pid == 0) {
|
||||
char err[100];
|
||||
# ifdef CRASHREPORT_EXEC_NOSTDERR
|
||||
/* Keep the output clean - firefox spews useless errors on
|
||||
* my system. */
|
||||
(void) close(2);
|
||||
(void) open("/dev/null", O_WRONLY);
|
||||
# endif
|
||||
|
||||
(void) execve(CRASHREPORT, (char * const *) xargv, environ);
|
||||
Sprintf(err, "Can't start " CRASHREPORT ": %s", strerror(errno));
|
||||
raw_print(err);
|
||||
} else {
|
||||
int status;
|
||||
errno = 0;
|
||||
(void) waitpid(pid, &status, 0);
|
||||
if (status) { /* XXX check could be more precise */
|
||||
# ifdef BETA
|
||||
/* Not useful at the moment. XXX */
|
||||
char err[100];
|
||||
|
||||
Sprintf(err, "pid=%d e=%d status=%0x", wpid, errno, status);
|
||||
raw_print(err);
|
||||
# endif
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
/* free(info); -- Don't risk it. */
|
||||
# endif /* !WIN32 */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
int
|
||||
dobugreport(void)
|
||||
{
|
||||
if (!submit_web_report(2, NULL, "#bugreport command")) {
|
||||
pline("Unable to send bug report. Please visit %s instead.",
|
||||
(sysopt.crashreporturl && *sysopt.crashreporturl)
|
||||
? sysopt.crashreporturl
|
||||
: "https://www.nethack.org"
|
||||
);
|
||||
}
|
||||
return ECMD_OK;
|
||||
}
|
||||
|
||||
#undef SWR_ADD
|
||||
#undef SWR_ADD_URIcoded
|
||||
#undef SWR_FRAMES
|
||||
#undef SWR_HDR
|
||||
#undef SWR_LINES
|
||||
|
||||
/*ARGSUSED*/
|
||||
boolean
|
||||
NH_panictrace_libc(void)
|
||||
{
|
||||
# if 0 /* XXX how did this get left here? */
|
||||
if (submit_web_report("Panic", why))
|
||||
return TRUE;
|
||||
# endif
|
||||
|
||||
# ifdef PANICTRACE_LIBC
|
||||
void *bt[20];
|
||||
int count, x;
|
||||
char **info, buf[BUFSZ];
|
||||
|
||||
raw_print(" Generating more information you may report:\n");
|
||||
count = backtrace(bt, SIZE(bt));
|
||||
info = backtrace_symbols(bt, count);
|
||||
for (x = 0; x < count; x++) {
|
||||
copynchars(buf, info[x], (int) sizeof buf - 1);
|
||||
/* try to remove up to 16 blank spaces by removing 8 twice */
|
||||
(void) strsubst(buf, " ", "");
|
||||
(void) strsubst(buf, " ", "");
|
||||
raw_printf("[%02lu] %s", (unsigned long) x, buf);
|
||||
}
|
||||
/* free(info); -- Don't risk it. */
|
||||
return TRUE;
|
||||
# else
|
||||
return FALSE;
|
||||
# endif /* !PANICTRACE_LIBC */
|
||||
}
|
||||
|
||||
/*
|
||||
* fooPATH file system path for foo
|
||||
* fooVAR (possibly const) variable containing fooPATH
|
||||
*/
|
||||
# ifdef PANICTRACE_GDB
|
||||
# ifdef SYSCF
|
||||
# define GDBVAR sysopt.gdbpath
|
||||
# define GREPVAR sysopt.greppath
|
||||
# else /* SYSCF */
|
||||
# define GDBVAR GDBPATH
|
||||
# define GREPVAR GREPPATH
|
||||
# endif /* SYSCF */
|
||||
# endif /* PANICTRACE_GDB */
|
||||
|
||||
boolean
|
||||
NH_panictrace_gdb(void)
|
||||
{
|
||||
# ifdef PANICTRACE_GDB
|
||||
/* A (more) generic method to get a stack trace - invoke
|
||||
* gdb on ourself. */
|
||||
const char *gdbpath = GDBVAR;
|
||||
const char *greppath = GREPVAR;
|
||||
char buf[BUFSZ];
|
||||
FILE *gdb;
|
||||
|
||||
if (gdbpath == NULL || gdbpath[0] == 0)
|
||||
return FALSE;
|
||||
if (greppath == NULL || greppath[0] == 0)
|
||||
return FALSE;
|
||||
|
||||
sprintf(buf, "%s -n -q %s %d 2>&1 | %s '^#'",
|
||||
gdbpath, ARGV0, getpid(), greppath);
|
||||
gdb = popen(buf, "w");
|
||||
if (gdb) {
|
||||
raw_print(" Generating more information you may report:\n");
|
||||
fprintf(gdb, "bt\nquit\ny");
|
||||
fflush(gdb);
|
||||
sleep(4); /* ugly */
|
||||
pclose(gdb);
|
||||
return TRUE;
|
||||
} else {
|
||||
return FALSE;
|
||||
}
|
||||
# else
|
||||
return FALSE;
|
||||
# endif /* !PANICTRACE_GDB */
|
||||
}
|
||||
|
||||
/* lineno==0 gives the most recent message (e.g.
|
||||
"Do you want to call panic..." if called from #panic) */
|
||||
const char *
|
||||
get_saved_pline(int lineno)
|
||||
{
|
||||
int p;
|
||||
int limit = DUMPLOG_MSG_COUNT;
|
||||
if (lineno >= DUMPLOG_MSG_COUNT)
|
||||
return NULL;
|
||||
p = (gs.saved_pline_index - 1) % DUMPLOG_MSG_COUNT;
|
||||
|
||||
while (limit--) {
|
||||
if (gs.saved_plines[p]) { /* valid line */
|
||||
if (lineno--) {
|
||||
p = (p - 1 + DUMPLOG_MSG_COUNT) % DUMPLOG_MSG_COUNT;
|
||||
} else {
|
||||
return gs.saved_plines[p];
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif /* CRASHREPORT */
|
||||
|
||||
/*report.c*/
|
||||
@@ -227,4 +227,85 @@ rnz(int i)
|
||||
return (int) x;
|
||||
}
|
||||
|
||||
/* Sets the seed for the random number generator */
|
||||
#ifdef USE_ISAAC64
|
||||
|
||||
static void
|
||||
set_random(unsigned long seed,
|
||||
int (*fn)(int))
|
||||
{
|
||||
init_isaac64(seed, fn);
|
||||
}
|
||||
|
||||
#else /* USE_ISAAC64 */
|
||||
|
||||
/*ARGSUSED*/
|
||||
static void
|
||||
set_random(unsigned long seed,
|
||||
int (*fn)(int) UNUSED)
|
||||
{
|
||||
/*
|
||||
* The types are different enough here that sweeping the different
|
||||
* routine names into one via #defines is even more confusing.
|
||||
*/
|
||||
# ifdef RANDOM /* srandom() from sys/share/random.c */
|
||||
srandom((unsigned int) seed);
|
||||
# else
|
||||
# if defined(__APPLE__) || defined(BSD) || defined(LINUX) \
|
||||
|| defined(ULTRIX) || defined(CYGWIN32) /* system srandom() */
|
||||
# if defined(BSD) && !defined(POSIX_TYPES) && defined(SUNOS4)
|
||||
(void)
|
||||
# endif
|
||||
srandom((int) seed);
|
||||
# else
|
||||
# ifdef UNIX /* system srand48() */
|
||||
srand48((long) seed);
|
||||
# else /* poor quality system routine */
|
||||
srand((int) seed);
|
||||
# endif
|
||||
# endif
|
||||
# endif
|
||||
}
|
||||
#endif /* USE_ISAAC64 */
|
||||
|
||||
/* An appropriate version of this must always be provided in
|
||||
port-specific code somewhere. It returns a number suitable
|
||||
as seed for the random number generator */
|
||||
extern unsigned long sys_random_seed(void);
|
||||
|
||||
/*
|
||||
* Initializes the random number generator.
|
||||
* Only call once.
|
||||
*/
|
||||
void
|
||||
init_random(int (*fn)(int))
|
||||
{
|
||||
set_random(sys_random_seed(), fn);
|
||||
}
|
||||
|
||||
/* Reshuffles the random number generator. */
|
||||
void
|
||||
reseed_random(int (*fn)(int))
|
||||
{
|
||||
/* only reseed if we are certain that the seed generation is unguessable
|
||||
* by the players. */
|
||||
if (has_strong_rngseed)
|
||||
init_random(fn);
|
||||
}
|
||||
|
||||
/* randomize the given list of numbers 0 <= i < count */
|
||||
void
|
||||
shuffle_int_array(int *indices, int count)
|
||||
{
|
||||
int i, iswap, temp;
|
||||
|
||||
for (i = count - 1; i > 0; i--) {
|
||||
if ((iswap = rn2(i + 1)) == i)
|
||||
continue;
|
||||
temp = indices[i];
|
||||
indices[i] = indices[iswap];
|
||||
indices[iswap] = temp;
|
||||
}
|
||||
}
|
||||
|
||||
/*rnd.c*/
|
||||
|
||||
+802
@@ -0,0 +1,802 @@
|
||||
/* NetHack 3.7 selvar.c $NHDT-Date: 1709677544 2024/03/05 22:25:44 $ $NHDT-Branch: keni-mdlib-followup $:$NHDT-Revision: 1.360 $ */
|
||||
/* Copyright (c) 2024 by Pasi Kallinen */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
|
||||
#include "hack.h"
|
||||
#include "selvar.h"
|
||||
#include "sp_lev.h"
|
||||
|
||||
static boolean sel_flood_havepoint(coordxy, coordxy, coordxy *, coordxy *, int);
|
||||
static long line_dist_coord(long, long, long, long, long, long);
|
||||
|
||||
/* selection */
|
||||
struct selectionvar *
|
||||
selection_new(void)
|
||||
{
|
||||
struct selectionvar *tmps = (struct selectionvar *) alloc(sizeof *tmps);
|
||||
|
||||
tmps->wid = COLNO;
|
||||
tmps->hei = ROWNO;
|
||||
tmps->bounds_dirty = FALSE;
|
||||
tmps->bounds.lx = COLNO;
|
||||
tmps->bounds.ly = ROWNO;
|
||||
tmps->bounds.hx = tmps->bounds.hy = 0;
|
||||
tmps->map = (char *) alloc((COLNO * ROWNO) + 1);
|
||||
(void) memset(tmps->map, 1, (COLNO * ROWNO));
|
||||
tmps->map[(COLNO * ROWNO)] = '\0';
|
||||
|
||||
return tmps;
|
||||
}
|
||||
|
||||
void
|
||||
selection_free(struct selectionvar *sel, boolean freesel)
|
||||
{
|
||||
if (sel) {
|
||||
if (sel->map)
|
||||
free(sel->map);
|
||||
sel->map = NULL;
|
||||
if (freesel)
|
||||
free((genericptr_t) sel);
|
||||
else
|
||||
(void) memset((genericptr_t) sel, 0, sizeof *sel);
|
||||
}
|
||||
}
|
||||
|
||||
/* clear selection, setting all locations to value val */
|
||||
void
|
||||
selection_clear(struct selectionvar *sel, int val)
|
||||
{
|
||||
(void) memset(sel->map, 1 + val, (COLNO * ROWNO));
|
||||
if (val) {
|
||||
sel->bounds.lx = 0;
|
||||
sel->bounds.ly = 0;
|
||||
sel->bounds.hx = COLNO - 1;
|
||||
sel->bounds.hy = ROWNO - 1;
|
||||
} else {
|
||||
sel->bounds.lx = COLNO;
|
||||
sel->bounds.ly = ROWNO;
|
||||
sel->bounds.hx = sel->bounds.hy = 0;
|
||||
}
|
||||
sel->bounds_dirty = FALSE;
|
||||
}
|
||||
|
||||
struct selectionvar *
|
||||
selection_clone(struct selectionvar *sel)
|
||||
{
|
||||
struct selectionvar *tmps = (struct selectionvar *) alloc(sizeof *tmps);
|
||||
|
||||
*tmps = *sel;
|
||||
tmps->map = dupstr(sel->map);
|
||||
|
||||
return tmps;
|
||||
}
|
||||
|
||||
/* get boundary rect of selection sel into b */
|
||||
void
|
||||
selection_getbounds(struct selectionvar *sel, NhRect *b)
|
||||
{
|
||||
if (!sel || !b)
|
||||
return;
|
||||
|
||||
selection_recalc_bounds(sel);
|
||||
|
||||
if (sel->bounds.lx >= sel->wid) {
|
||||
b->lx = 0;
|
||||
b->ly = 0;
|
||||
b->hx = COLNO - 1;
|
||||
b->hy = ROWNO - 1;
|
||||
} else {
|
||||
b->lx = sel->bounds.lx;
|
||||
b->ly = sel->bounds.ly;
|
||||
b->hx = sel->bounds.hx;
|
||||
b->hy = sel->bounds.hy;
|
||||
}
|
||||
}
|
||||
|
||||
/* recalc the boundary of selection, if necessary */
|
||||
void
|
||||
selection_recalc_bounds(struct selectionvar *sel)
|
||||
{
|
||||
coordxy x, y;
|
||||
NhRect r;
|
||||
|
||||
if (!sel->bounds_dirty)
|
||||
return;
|
||||
|
||||
sel->bounds.lx = COLNO;
|
||||
sel->bounds.ly = ROWNO;
|
||||
sel->bounds.hx = sel->bounds.hy = 0;
|
||||
|
||||
r.lx = r.ly = r.hx = r.hy = -1;
|
||||
|
||||
/* left */
|
||||
for (x = 0; x < sel->wid; x++) {
|
||||
for (y = 0; y < sel->hei; y++) {
|
||||
if (selection_getpoint(x, y, sel)) {
|
||||
r.lx = x;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (r.lx > -1)
|
||||
break;
|
||||
}
|
||||
|
||||
if (r.lx > -1) {
|
||||
/* right */
|
||||
for (x = sel->wid-1; x >= r.lx; x--) {
|
||||
for (y = 0; y < sel->hei; y++) {
|
||||
if (selection_getpoint(x, y, sel)) {
|
||||
r.hx = x;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (r.hx > -1)
|
||||
break;
|
||||
}
|
||||
|
||||
/* top */
|
||||
for (y = 0; y < sel->hei; y++) {
|
||||
for (x = r.lx; x <= r.hx; x++) {
|
||||
if (selection_getpoint(x, y, sel)) {
|
||||
r.ly = y;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (r.ly > -1)
|
||||
break;
|
||||
}
|
||||
|
||||
/* bottom */
|
||||
for (y = sel->hei-1; y >= r.ly; y--) {
|
||||
for (x = r.lx; x <= r.hx; x++) {
|
||||
if (selection_getpoint(x, y, sel)) {
|
||||
r.hy = y;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (r.hy > -1)
|
||||
break;
|
||||
}
|
||||
sel->bounds = r;
|
||||
}
|
||||
|
||||
sel->bounds_dirty = FALSE;
|
||||
}
|
||||
|
||||
coordxy
|
||||
selection_getpoint(
|
||||
coordxy x, coordxy y,
|
||||
struct selectionvar *sel)
|
||||
{
|
||||
if (!sel || !sel->map)
|
||||
return 0;
|
||||
if (x < 0 || y < 0 || x >= sel->wid || y >= sel->hei)
|
||||
return 0;
|
||||
|
||||
return (sel->map[sel->wid * y + x] - 1);
|
||||
}
|
||||
|
||||
void
|
||||
selection_setpoint(
|
||||
coordxy x, coordxy y,
|
||||
struct selectionvar *sel,
|
||||
int c)
|
||||
{
|
||||
if (!sel || !sel->map)
|
||||
return;
|
||||
if (x < 0 || y < 0 || x >= sel->wid || y >= sel->hei)
|
||||
return;
|
||||
|
||||
if (c && !sel->bounds_dirty) {
|
||||
if (sel->bounds.lx > x) sel->bounds.lx = x;
|
||||
if (sel->bounds.ly > y) sel->bounds.ly = y;
|
||||
if (sel->bounds.hx < x) sel->bounds.hx = x;
|
||||
if (sel->bounds.hy < y) sel->bounds.hy = y;
|
||||
} else {
|
||||
sel->bounds_dirty = TRUE;
|
||||
}
|
||||
|
||||
sel->map[sel->wid * y + x] = (char) (c + 1);
|
||||
}
|
||||
|
||||
struct selectionvar *
|
||||
selection_not(struct selectionvar *s)
|
||||
{
|
||||
int x, y;
|
||||
NhRect tmprect = cg.zeroNhRect;
|
||||
|
||||
for (x = 0; x < s->wid; x++)
|
||||
for (y = 0; y < s->hei; y++)
|
||||
selection_setpoint(x, y, s, selection_getpoint(x, y, s) ? 0 : 1);
|
||||
selection_getbounds(s, &tmprect);
|
||||
return s;
|
||||
}
|
||||
|
||||
struct selectionvar *
|
||||
selection_filter_percent(
|
||||
struct selectionvar *ov,
|
||||
int percent)
|
||||
{
|
||||
int x, y;
|
||||
struct selectionvar *ret;
|
||||
NhRect rect = cg.zeroNhRect;
|
||||
|
||||
if (!ov)
|
||||
return NULL;
|
||||
|
||||
ret = selection_new();
|
||||
|
||||
selection_getbounds(ov, &rect);
|
||||
|
||||
for (x = rect.lx; x <= rect.hx; x++)
|
||||
for (y = rect.ly; y <= rect.hy; y++)
|
||||
if (selection_getpoint(x, y, ov) && (rn2(100) < percent))
|
||||
selection_setpoint(x, y, ret, 1);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
struct selectionvar *
|
||||
selection_filter_mapchar(struct selectionvar *ov, xint16 typ, int lit)
|
||||
{
|
||||
int x, y;
|
||||
struct selectionvar *ret;
|
||||
NhRect rect = cg.zeroNhRect;
|
||||
|
||||
if (!ov)
|
||||
return NULL;
|
||||
|
||||
ret = selection_new();
|
||||
|
||||
selection_getbounds(ov, &rect);
|
||||
|
||||
for (x = rect.lx; x <= rect.hx; x++)
|
||||
for (y = rect.ly; y <= rect.hy; y++)
|
||||
if (selection_getpoint(x, y, ov)
|
||||
&& match_maptyps(typ, levl[x][y].typ)) {
|
||||
switch (lit) {
|
||||
default:
|
||||
case -2:
|
||||
selection_setpoint(x, y, ret, 1);
|
||||
break;
|
||||
case -1:
|
||||
selection_setpoint(x, y, ret, rn2(2));
|
||||
break;
|
||||
case 0:
|
||||
case 1:
|
||||
if (levl[x][y].lit == (unsigned int) lit)
|
||||
selection_setpoint(x, y, ret, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
selection_rndcoord(
|
||||
struct selectionvar *ov,
|
||||
coordxy *x, coordxy *y,
|
||||
boolean removeit)
|
||||
{
|
||||
int idx = 0;
|
||||
int c;
|
||||
int dx, dy;
|
||||
NhRect rect = cg.zeroNhRect;
|
||||
|
||||
selection_getbounds(ov, &rect);
|
||||
|
||||
for (dx = rect.lx; dx <= rect.hx; dx++)
|
||||
for (dy = rect.ly; dy <= rect.hy; dy++)
|
||||
if (selection_getpoint(dx, dy, ov))
|
||||
idx++;
|
||||
|
||||
if (idx) {
|
||||
c = rn2(idx);
|
||||
for (dx = rect.lx; dx <= rect.hx; dx++)
|
||||
for (dy = rect.ly; dy <= rect.hy; dy++)
|
||||
if (selection_getpoint(dx, dy, ov)) {
|
||||
if (!c) {
|
||||
*x = dx;
|
||||
*y = dy;
|
||||
if (removeit)
|
||||
selection_setpoint(dx, dy, ov, 0);
|
||||
return 1;
|
||||
}
|
||||
c--;
|
||||
}
|
||||
}
|
||||
*x = *y = -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
selection_do_grow(struct selectionvar *ov, int dir)
|
||||
{
|
||||
coordxy x, y;
|
||||
struct selectionvar *tmp;
|
||||
NhRect rect = cg.zeroNhRect;
|
||||
|
||||
if (!ov)
|
||||
return;
|
||||
|
||||
tmp = selection_new();
|
||||
|
||||
if (dir == W_RANDOM)
|
||||
dir = random_wdir();
|
||||
|
||||
selection_getbounds(ov, &rect);
|
||||
|
||||
for (x = max(0, rect.lx-1); x <= min(COLNO-1, rect.hx+1); x++)
|
||||
for (y = max(0, rect.ly-1); y <= min(ROWNO-1, rect.hy+1); y++) {
|
||||
/* note: dir is a mask of multiple directions, but the only
|
||||
way to specify diagonals is by including the two adjacent
|
||||
orthogonal directions, which effectively specifies three-
|
||||
way growth [WEST|NORTH => WEST plus WEST|NORTH plus NORTH] */
|
||||
if (((dir & W_WEST) && selection_getpoint(x + 1, y, ov))
|
||||
|| (((dir & (W_WEST | W_NORTH)) == (W_WEST | W_NORTH))
|
||||
&& selection_getpoint(x + 1, y + 1, ov))
|
||||
|| ((dir & W_NORTH) && selection_getpoint(x, y + 1, ov))
|
||||
|| (((dir & (W_NORTH | W_EAST)) == (W_NORTH | W_EAST))
|
||||
&& selection_getpoint(x - 1, y + 1, ov))
|
||||
|| ((dir & W_EAST) && selection_getpoint(x - 1, y, ov))
|
||||
|| (((dir & (W_EAST | W_SOUTH)) == (W_EAST | W_SOUTH))
|
||||
&& selection_getpoint(x - 1, y - 1, ov))
|
||||
|| ((dir & W_SOUTH) && selection_getpoint(x, y - 1, ov))
|
||||
|| (((dir & (W_SOUTH | W_WEST)) == (W_SOUTH | W_WEST))
|
||||
&& selection_getpoint(x + 1, y - 1, ov))) {
|
||||
selection_setpoint(x, y, tmp, 1);
|
||||
}
|
||||
}
|
||||
|
||||
selection_getbounds(tmp, &rect);
|
||||
|
||||
for (x = rect.lx; x <= rect.hx; x++)
|
||||
for (y = rect.ly; y <= rect.hy; y++)
|
||||
if (selection_getpoint(x, y, tmp))
|
||||
selection_setpoint(x, y, ov, 1);
|
||||
|
||||
selection_free(tmp, TRUE);
|
||||
}
|
||||
|
||||
static int (*selection_flood_check_func)(coordxy, coordxy);
|
||||
|
||||
void
|
||||
set_selection_floodfillchk(int (*f)(coordxy, coordxy))
|
||||
{
|
||||
selection_flood_check_func = f;
|
||||
}
|
||||
|
||||
/* check whethere <x,y> is already in xs[],ys[] */
|
||||
static boolean
|
||||
sel_flood_havepoint(
|
||||
coordxy x, coordxy y,
|
||||
coordxy xs[], coordxy ys[],
|
||||
int n)
|
||||
{
|
||||
coordxy xx = x, yy = y;
|
||||
|
||||
while (n > 0) {
|
||||
--n;
|
||||
if (xs[n] == xx && ys[n] == yy)
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
selection_floodfill(
|
||||
struct selectionvar *ov,
|
||||
coordxy x, coordxy y,
|
||||
boolean diagonals)
|
||||
{
|
||||
struct selectionvar *tmp = selection_new();
|
||||
#define SEL_FLOOD_STACK (COLNO * ROWNO)
|
||||
#define SEL_FLOOD(nx, ny) \
|
||||
do { \
|
||||
if (idx < SEL_FLOOD_STACK) { \
|
||||
dx[idx] = (nx); \
|
||||
dy[idx] = (ny); \
|
||||
idx++; \
|
||||
} else \
|
||||
panic(floodfill_stack_overrun); \
|
||||
} while (0)
|
||||
#define SEL_FLOOD_CHKDIR(mx, my, sel) \
|
||||
do { \
|
||||
if (isok((mx), (my)) \
|
||||
&& (*selection_flood_check_func)((mx), (my)) \
|
||||
&& !selection_getpoint((mx), (my), (sel)) \
|
||||
&& !sel_flood_havepoint((mx), (my), dx, dy, idx)) \
|
||||
SEL_FLOOD((mx), (my)); \
|
||||
} while (0)
|
||||
static const char floodfill_stack_overrun[] = "floodfill stack overrun";
|
||||
int idx = 0;
|
||||
coordxy dx[SEL_FLOOD_STACK];
|
||||
coordxy dy[SEL_FLOOD_STACK];
|
||||
|
||||
if (selection_flood_check_func == (int (*)(coordxy, coordxy)) 0) {
|
||||
selection_free(tmp, TRUE);
|
||||
return;
|
||||
}
|
||||
SEL_FLOOD(x, y);
|
||||
do {
|
||||
idx--;
|
||||
x = dx[idx];
|
||||
y = dy[idx];
|
||||
if (isok(x, y)) {
|
||||
selection_setpoint(x, y, ov, 1);
|
||||
selection_setpoint(x, y, tmp, 1);
|
||||
}
|
||||
SEL_FLOOD_CHKDIR((x + 1), y, tmp);
|
||||
SEL_FLOOD_CHKDIR((x - 1), y, tmp);
|
||||
SEL_FLOOD_CHKDIR(x, (y + 1), tmp);
|
||||
SEL_FLOOD_CHKDIR(x, (y - 1), tmp);
|
||||
if (diagonals) {
|
||||
SEL_FLOOD_CHKDIR((x + 1), (y + 1), tmp);
|
||||
SEL_FLOOD_CHKDIR((x - 1), (y - 1), tmp);
|
||||
SEL_FLOOD_CHKDIR((x - 1), (y + 1), tmp);
|
||||
SEL_FLOOD_CHKDIR((x + 1), (y - 1), tmp);
|
||||
}
|
||||
} while (idx > 0);
|
||||
#undef SEL_FLOOD
|
||||
#undef SEL_FLOOD_STACK
|
||||
#undef SEL_FLOOD_CHKDIR
|
||||
selection_free(tmp, TRUE);
|
||||
}
|
||||
|
||||
/* McIlroy's Ellipse Algorithm */
|
||||
void
|
||||
selection_do_ellipse(
|
||||
struct selectionvar *ov,
|
||||
int xc, int yc,
|
||||
int a, int b,
|
||||
int filled)
|
||||
{ /* e(x,y) = b^2*x^2 + a^2*y^2 - a^2*b^2 */
|
||||
int x = 0, y = b;
|
||||
long a2 = (long) a * a, b2 = (long) b * b;
|
||||
long crit1 = -(a2 / 4 + a % 2 + b2);
|
||||
long crit2 = -(b2 / 4 + b % 2 + a2);
|
||||
long crit3 = -(b2 / 4 + b % 2);
|
||||
long t = -a2 * y; /* e(x+1/2,y-1/2) - (a^2+b^2)/4 */
|
||||
long dxt = 2 * b2 * x, dyt = -2 * a2 * y;
|
||||
long d2xt = 2 * b2, d2yt = 2 * a2;
|
||||
long width = 1;
|
||||
long i;
|
||||
|
||||
if (!ov)
|
||||
return;
|
||||
|
||||
filled = !filled;
|
||||
|
||||
if (!filled) {
|
||||
while (y >= 0 && x <= a) {
|
||||
selection_setpoint(xc + x, yc + y, ov, 1);
|
||||
if (x != 0 || y != 0)
|
||||
selection_setpoint(xc - x, yc - y, ov, 1);
|
||||
if (x != 0 && y != 0) {
|
||||
selection_setpoint(xc + x, yc - y, ov, 1);
|
||||
selection_setpoint(xc - x, yc + y, ov, 1);
|
||||
}
|
||||
if (t + b2 * x <= crit1 /* e(x+1,y-1/2) <= 0 */
|
||||
|| t + a2 * y <= crit3) { /* e(x+1/2,y) <= 0 */
|
||||
x++;
|
||||
dxt += d2xt;
|
||||
t += dxt;
|
||||
} else if (t - a2 * y > crit2) { /* e(x+1/2,y-1) > 0 */
|
||||
y--;
|
||||
dyt += d2yt;
|
||||
t += dyt;
|
||||
} else {
|
||||
x++;
|
||||
dxt += d2xt;
|
||||
t += dxt;
|
||||
y--;
|
||||
dyt += d2yt;
|
||||
t += dyt;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
while (y >= 0 && x <= a) {
|
||||
if (t + b2 * x <= crit1 /* e(x+1,y-1/2) <= 0 */
|
||||
|| t + a2 * y <= crit3) { /* e(x+1/2,y) <= 0 */
|
||||
x++;
|
||||
dxt += d2xt;
|
||||
t += dxt;
|
||||
width += 2;
|
||||
} else if (t - a2 * y > crit2) { /* e(x+1/2,y-1) > 0 */
|
||||
for (i = 0; i < width; i++)
|
||||
selection_setpoint(xc - x + i, yc - y, ov, 1);
|
||||
if (y != 0)
|
||||
for (i = 0; i < width; i++)
|
||||
selection_setpoint(xc - x + i, yc + y, ov, 1);
|
||||
y--;
|
||||
dyt += d2yt;
|
||||
t += dyt;
|
||||
} else {
|
||||
for (i = 0; i < width; i++)
|
||||
selection_setpoint(xc - x + i, yc - y, ov, 1);
|
||||
if (y != 0)
|
||||
for (i = 0; i < width; i++)
|
||||
selection_setpoint(xc - x + i, yc + y, ov, 1);
|
||||
x++;
|
||||
dxt += d2xt;
|
||||
t += dxt;
|
||||
y--;
|
||||
dyt += d2yt;
|
||||
t += dyt;
|
||||
width += 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* square of distance from line segment (x1,y1, x2,y2) to point (x3,y3) */
|
||||
static long
|
||||
line_dist_coord(long x1, long y1, long x2, long y2, long x3, long y3)
|
||||
{
|
||||
long px = x2 - x1;
|
||||
long py = y2 - y1;
|
||||
long s = px * px + py * py;
|
||||
long x, y, dx, dy, distsq = 0;
|
||||
float lu = 0;
|
||||
|
||||
if (x1 == x2 && y1 == y2)
|
||||
return dist2(x1, y1, x3, y3);
|
||||
|
||||
lu = ((x3 - x1) * px + (y3 - y1) * py) / (float) s;
|
||||
if (lu > 1)
|
||||
lu = 1;
|
||||
else if (lu < 0)
|
||||
lu = 0;
|
||||
|
||||
x = x1 + lu * px;
|
||||
y = y1 + lu * py;
|
||||
dx = x - x3;
|
||||
dy = y - y3;
|
||||
distsq = dx * dx + dy * dy;
|
||||
|
||||
return distsq;
|
||||
}
|
||||
|
||||
/* guts of l_selection_gradient */
|
||||
void
|
||||
selection_do_gradient(
|
||||
struct selectionvar *ov,
|
||||
long x, long y,
|
||||
long x2,long y2,
|
||||
long gtyp,
|
||||
long mind, long maxd)
|
||||
{
|
||||
long dx, dy, dofs;
|
||||
|
||||
if (mind > maxd) {
|
||||
long tmp = mind;
|
||||
mind = maxd;
|
||||
maxd = tmp;
|
||||
}
|
||||
|
||||
dofs = maxd * maxd - mind * mind;
|
||||
if (dofs < 1)
|
||||
dofs = 1;
|
||||
|
||||
switch (gtyp) {
|
||||
default:
|
||||
impossible("Unrecognized gradient type! Defaulting to radial...");
|
||||
/* FALLTHRU */
|
||||
case SEL_GRADIENT_RADIAL: {
|
||||
for (dx = 0; dx < COLNO; dx++)
|
||||
for (dy = 0; dy < ROWNO; dy++) {
|
||||
long d0 = line_dist_coord(x, y, x2, y2, dx, dy);
|
||||
|
||||
if (d0 <= mind * mind
|
||||
|| (d0 <= maxd * maxd && d0 - mind * mind < rn2(dofs)))
|
||||
selection_setpoint(dx, dy, ov, 1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SEL_GRADIENT_SQUARE: {
|
||||
for (dx = 0; dx < COLNO; dx++)
|
||||
for (dy = 0; dy < ROWNO; dy++) {
|
||||
long d1 = line_dist_coord(x, y, x2, y2, x, dy);
|
||||
long d2 = line_dist_coord(x, y, x2, y2, dx, y);
|
||||
long d3 = line_dist_coord(x, y, x2, y2, x2, dy);
|
||||
long d4 = line_dist_coord(x, y, x2, y2, dx, y2);
|
||||
long d5 = line_dist_coord(x, y, x2, y2, dx, dy);
|
||||
long d0 = min(d5, min(max(d1, d2), max(d3, d4)));
|
||||
|
||||
if (d0 <= mind * mind
|
||||
|| (d0 <= maxd * maxd && d0 - mind * mind < rn2(dofs)))
|
||||
selection_setpoint(dx, dy, ov, 1);
|
||||
}
|
||||
break;
|
||||
} /*case*/
|
||||
} /*switch*/
|
||||
}
|
||||
|
||||
/* bresenham line algo */
|
||||
void
|
||||
selection_do_line(
|
||||
coordxy x1, coordxy y1,
|
||||
coordxy x2, coordxy y2,
|
||||
struct selectionvar *ov)
|
||||
{
|
||||
int d0, dx, dy, ai, bi, xi, yi;
|
||||
|
||||
if (x1 < x2) {
|
||||
xi = 1;
|
||||
dx = x2 - x1;
|
||||
} else {
|
||||
xi = -1;
|
||||
dx = x1 - x2;
|
||||
}
|
||||
if (y1 < y2) {
|
||||
yi = 1;
|
||||
dy = y2 - y1;
|
||||
} else {
|
||||
yi = -1;
|
||||
dy = y1 - y2;
|
||||
}
|
||||
|
||||
selection_setpoint(x1, y1, ov, 1);
|
||||
|
||||
if (!dx && !dy) {
|
||||
/* single point - already all done */
|
||||
;
|
||||
} else if (dx > dy) {
|
||||
ai = (dy - dx) * 2;
|
||||
bi = dy * 2;
|
||||
d0 = bi - dx;
|
||||
do {
|
||||
if (d0 >= 0) {
|
||||
y1 += yi;
|
||||
d0 += ai;
|
||||
} else
|
||||
d0 += bi;
|
||||
x1 += xi;
|
||||
selection_setpoint(x1, y1, ov, 1);
|
||||
} while (x1 != x2);
|
||||
} else {
|
||||
ai = (dx - dy) * 2;
|
||||
bi = dx * 2;
|
||||
d0 = bi - dy;
|
||||
do {
|
||||
if (d0 >= 0) {
|
||||
x1 += xi;
|
||||
d0 += ai;
|
||||
} else
|
||||
d0 += bi;
|
||||
y1 += yi;
|
||||
selection_setpoint(x1, y1, ov, 1);
|
||||
} while (y1 != y2);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
selection_do_randline(
|
||||
coordxy x1, coordxy y1,
|
||||
coordxy x2, coordxy y2,
|
||||
schar rough,
|
||||
schar rec,
|
||||
struct selectionvar *ov)
|
||||
{
|
||||
int mx, my;
|
||||
int dx, dy;
|
||||
|
||||
if (rec < 1 || (x2 == x1 && y2 == y1))
|
||||
return;
|
||||
|
||||
if (rough > max(abs(x2 - x1), abs(y2 - y1)))
|
||||
rough = max(abs(x2 - x1), abs(y2 - y1));
|
||||
|
||||
if (rough < 2) {
|
||||
mx = ((x1 + x2) / 2);
|
||||
my = ((y1 + y2) / 2);
|
||||
} else {
|
||||
do {
|
||||
dx = rn2(rough) - (rough / 2);
|
||||
dy = rn2(rough) - (rough / 2);
|
||||
mx = ((x1 + x2) / 2) + dx;
|
||||
my = ((y1 + y2) / 2) + dy;
|
||||
} while ((mx > COLNO - 1 || mx < 0 || my < 0 || my > ROWNO - 1));
|
||||
}
|
||||
|
||||
if (!selection_getpoint(mx, my, ov)) {
|
||||
selection_setpoint(mx, my, ov, 1);
|
||||
}
|
||||
|
||||
rough = (rough * 2) / 3;
|
||||
|
||||
rec--;
|
||||
|
||||
selection_do_randline(x1, y1, mx, my, rough, rec, ov);
|
||||
selection_do_randline(mx, my, x2, y2, rough, rec, ov);
|
||||
|
||||
selection_setpoint(x2, y2, ov, 1);
|
||||
}
|
||||
|
||||
void
|
||||
selection_iterate(
|
||||
struct selectionvar *ov,
|
||||
select_iter_func func,
|
||||
genericptr_t arg)
|
||||
{
|
||||
coordxy x, y;
|
||||
NhRect rect = cg.zeroNhRect;
|
||||
|
||||
if (!ov)
|
||||
return;
|
||||
|
||||
selection_getbounds(ov, &rect);
|
||||
|
||||
for (x = rect.lx; x <= rect.hx; x++)
|
||||
for (y = rect.ly; y <= rect.hy; y++)
|
||||
if (isok(x,y) && selection_getpoint(x, y, ov))
|
||||
(*func)(x, y, arg);
|
||||
}
|
||||
|
||||
/* selection is not rectangular, or has holes in it */
|
||||
boolean
|
||||
selection_is_irregular(struct selectionvar *sel)
|
||||
{
|
||||
coordxy x, y;
|
||||
NhRect rect = cg.zeroNhRect;
|
||||
|
||||
selection_getbounds(sel, &rect);
|
||||
|
||||
for (x = rect.lx; x <= rect.hx; x++)
|
||||
for (y = rect.ly; y <= rect.hy; y++)
|
||||
if (isok(x,y) && !selection_getpoint(x, y, sel))
|
||||
return TRUE;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* return a description of the selection size */
|
||||
char *
|
||||
selection_size_description(struct selectionvar *sel, char *buf)
|
||||
{
|
||||
NhRect rect = cg.zeroNhRect;
|
||||
coordxy dx, dy;
|
||||
|
||||
selection_getbounds(sel, &rect);
|
||||
dx = rect.hx - rect.lx + 1;
|
||||
dy = rect.hy - rect.ly + 1;
|
||||
Sprintf(buf, "%s %i by %i", selection_is_irregular(sel) ? "irregularly shaped"
|
||||
: (dx == dy) ? "square"
|
||||
: "rectangular",
|
||||
dx, dy);
|
||||
return buf;
|
||||
}
|
||||
|
||||
struct selectionvar *
|
||||
selection_from_mkroom(struct mkroom *croom)
|
||||
{
|
||||
struct selectionvar *sel = selection_new();
|
||||
coordxy x, y;
|
||||
unsigned rmno;
|
||||
|
||||
if (!croom && gc.coder && gc.coder->croom)
|
||||
croom = gc.coder->croom;
|
||||
if (!croom)
|
||||
return sel;
|
||||
|
||||
rmno = (unsigned)((croom - gr.rooms) + ROOMOFFSET);
|
||||
for (y = croom->ly; y <= croom->hy; y++)
|
||||
for (x = croom->lx; x <= croom->hx; x++)
|
||||
if (isok(x, y) && !levl[x][y].edge
|
||||
&& levl[x][y].roomno == rmno)
|
||||
selection_setpoint(x, y, sel, 1);
|
||||
return sel;
|
||||
}
|
||||
|
||||
void
|
||||
selection_force_newsyms(struct selectionvar *sel)
|
||||
{
|
||||
coordxy x, y;
|
||||
|
||||
for (x = 1; x < sel->wid; x++)
|
||||
for (y = 0; y < sel->hei; y++)
|
||||
if (selection_getpoint(x, y, sel))
|
||||
newsym_force(x, y);
|
||||
}
|
||||
|
||||
/*selvar.c*/
|
||||
+2
-753
@@ -14,11 +14,8 @@
|
||||
#include "hack.h"
|
||||
#include "sp_lev.h"
|
||||
|
||||
typedef void (*select_iter_func)(coordxy, coordxy, genericptr);
|
||||
|
||||
extern void mkmap(lev_init *);
|
||||
|
||||
static boolean match_maptyps(xint16, xint16);
|
||||
static void solidify_map(void);
|
||||
static void map_cleanup(void);
|
||||
static void lvlfill_maze_grid(int, int, int, int, schar);
|
||||
@@ -101,8 +98,6 @@ static void sel_set_lit(coordxy, coordxy, genericptr_t);
|
||||
static void add_doors_to_room(struct mkroom *);
|
||||
static void get_table_coords_or_region(lua_State *,
|
||||
coordxy *, coordxy *, coordxy *, coordxy *);
|
||||
static void selection_iterate(struct selectionvar *, select_iter_func,
|
||||
genericptr_t);
|
||||
static void sel_set_ter(coordxy, coordxy, genericptr_t);
|
||||
static void sel_set_door(coordxy, coordxy, genericptr_t);
|
||||
static void sel_set_feature(coordxy, coordxy, genericptr_t);
|
||||
@@ -111,11 +106,8 @@ static void get_table_xy_or_coord(lua_State *, lua_Integer *, lua_Integer *);
|
||||
static int get_table_region(lua_State *, const char *, lua_Integer *,
|
||||
lua_Integer *, lua_Integer *, lua_Integer *, boolean);
|
||||
static void set_wallprop_in_selection(lua_State *, int);
|
||||
static coordxy random_wdir(void);
|
||||
static int floodfillchk_match_under(coordxy, coordxy);
|
||||
static int floodfillchk_match_accessible(coordxy, coordxy);
|
||||
static boolean sel_flood_havepoint(coordxy, coordxy, coordxy *, coordxy *, int);
|
||||
static long line_dist_coord(long, long, long, long, long, long);
|
||||
static void l_push_mkroom_table(lua_State *, struct mkroom *);
|
||||
static int get_table_align(lua_State *);
|
||||
static int get_table_monclass(lua_State *);
|
||||
@@ -221,7 +213,7 @@ reset_xystart_size(void)
|
||||
|
||||
/* Does typ match with levl[][].typ, considering special types
|
||||
MATCH_WALL and MAX_TYPE (aka transparency)? */
|
||||
static boolean
|
||||
boolean
|
||||
match_maptyps(xint16 typ, xint16 levltyp)
|
||||
{
|
||||
if ((typ == MATCH_WALL) && !IS_STWALL(levltyp))
|
||||
@@ -4484,371 +4476,16 @@ lspo_random_corridors(lua_State *L UNUSED)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* selection */
|
||||
struct selectionvar *
|
||||
selection_new(void)
|
||||
{
|
||||
struct selectionvar *tmps = (struct selectionvar *) alloc(sizeof *tmps);
|
||||
|
||||
tmps->wid = COLNO;
|
||||
tmps->hei = ROWNO;
|
||||
tmps->bounds_dirty = FALSE;
|
||||
tmps->bounds.lx = COLNO;
|
||||
tmps->bounds.ly = ROWNO;
|
||||
tmps->bounds.hx = tmps->bounds.hy = 0;
|
||||
tmps->map = (char *) alloc((COLNO * ROWNO) + 1);
|
||||
(void) memset(tmps->map, 1, (COLNO * ROWNO));
|
||||
tmps->map[(COLNO * ROWNO)] = '\0';
|
||||
|
||||
return tmps;
|
||||
}
|
||||
|
||||
void
|
||||
selection_free(struct selectionvar *sel, boolean freesel)
|
||||
{
|
||||
if (sel) {
|
||||
Free(sel->map);
|
||||
sel->map = NULL;
|
||||
if (freesel)
|
||||
free((genericptr_t) sel);
|
||||
else
|
||||
(void) memset((genericptr_t) sel, 0, sizeof *sel);
|
||||
}
|
||||
}
|
||||
|
||||
/* clear selection, setting all locations to value val */
|
||||
void
|
||||
selection_clear(struct selectionvar *sel, int val)
|
||||
{
|
||||
(void) memset(sel->map, 1 + val, (COLNO * ROWNO));
|
||||
if (val) {
|
||||
sel->bounds.lx = 0;
|
||||
sel->bounds.ly = 0;
|
||||
sel->bounds.hx = COLNO - 1;
|
||||
sel->bounds.hy = ROWNO - 1;
|
||||
} else {
|
||||
sel->bounds.lx = COLNO;
|
||||
sel->bounds.ly = ROWNO;
|
||||
sel->bounds.hx = sel->bounds.hy = 0;
|
||||
}
|
||||
sel->bounds_dirty = FALSE;
|
||||
}
|
||||
|
||||
struct selectionvar *
|
||||
selection_clone(struct selectionvar *sel)
|
||||
{
|
||||
struct selectionvar *tmps = (struct selectionvar *) alloc(sizeof *tmps);
|
||||
|
||||
*tmps = *sel;
|
||||
tmps->map = dupstr(sel->map);
|
||||
|
||||
return tmps;
|
||||
}
|
||||
|
||||
/* get boundary rect of selection sel into b */
|
||||
void
|
||||
selection_getbounds(struct selectionvar *sel, NhRect *b)
|
||||
{
|
||||
if (!sel || !b)
|
||||
return;
|
||||
|
||||
selection_recalc_bounds(sel);
|
||||
|
||||
if (sel->bounds.lx >= sel->wid) {
|
||||
b->lx = 0;
|
||||
b->ly = 0;
|
||||
b->hx = COLNO - 1;
|
||||
b->hy = ROWNO - 1;
|
||||
} else {
|
||||
b->lx = sel->bounds.lx;
|
||||
b->ly = sel->bounds.ly;
|
||||
b->hx = sel->bounds.hx;
|
||||
b->hy = sel->bounds.hy;
|
||||
}
|
||||
}
|
||||
|
||||
/* recalc the boundary of selection, if necessary */
|
||||
void
|
||||
selection_recalc_bounds(struct selectionvar *sel)
|
||||
{
|
||||
coordxy x, y;
|
||||
NhRect r;
|
||||
|
||||
if (!sel->bounds_dirty)
|
||||
return;
|
||||
|
||||
sel->bounds.lx = COLNO;
|
||||
sel->bounds.ly = ROWNO;
|
||||
sel->bounds.hx = sel->bounds.hy = 0;
|
||||
|
||||
r.lx = r.ly = r.hx = r.hy = -1;
|
||||
|
||||
/* left */
|
||||
for (x = 0; x < sel->wid; x++) {
|
||||
for (y = 0; y < sel->hei; y++) {
|
||||
if (selection_getpoint(x, y, sel)) {
|
||||
r.lx = x;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (r.lx > -1)
|
||||
break;
|
||||
}
|
||||
|
||||
if (r.lx > -1) {
|
||||
/* right */
|
||||
for (x = sel->wid-1; x >= r.lx; x--) {
|
||||
for (y = 0; y < sel->hei; y++) {
|
||||
if (selection_getpoint(x, y, sel)) {
|
||||
r.hx = x;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (r.hx > -1)
|
||||
break;
|
||||
}
|
||||
|
||||
/* top */
|
||||
for (y = 0; y < sel->hei; y++) {
|
||||
for (x = r.lx; x <= r.hx; x++) {
|
||||
if (selection_getpoint(x, y, sel)) {
|
||||
r.ly = y;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (r.ly > -1)
|
||||
break;
|
||||
}
|
||||
|
||||
/* bottom */
|
||||
for (y = sel->hei-1; y >= r.ly; y--) {
|
||||
for (x = r.lx; x <= r.hx; x++) {
|
||||
if (selection_getpoint(x, y, sel)) {
|
||||
r.hy = y;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (r.hy > -1)
|
||||
break;
|
||||
}
|
||||
sel->bounds = r;
|
||||
}
|
||||
|
||||
sel->bounds_dirty = FALSE;
|
||||
}
|
||||
|
||||
coordxy
|
||||
selection_getpoint(
|
||||
coordxy x, coordxy y,
|
||||
struct selectionvar *sel)
|
||||
{
|
||||
if (!sel || !sel->map)
|
||||
return 0;
|
||||
if (x < 0 || y < 0 || x >= sel->wid || y >= sel->hei)
|
||||
return 0;
|
||||
|
||||
return (sel->map[sel->wid * y + x] - 1);
|
||||
}
|
||||
|
||||
void
|
||||
selection_setpoint(
|
||||
coordxy x, coordxy y,
|
||||
struct selectionvar *sel,
|
||||
int c)
|
||||
{
|
||||
if (!sel || !sel->map)
|
||||
return;
|
||||
if (x < 0 || y < 0 || x >= sel->wid || y >= sel->hei)
|
||||
return;
|
||||
|
||||
if (c && !sel->bounds_dirty) {
|
||||
if (sel->bounds.lx > x) sel->bounds.lx = x;
|
||||
if (sel->bounds.ly > y) sel->bounds.ly = y;
|
||||
if (sel->bounds.hx < x) sel->bounds.hx = x;
|
||||
if (sel->bounds.hy < y) sel->bounds.hy = y;
|
||||
} else {
|
||||
sel->bounds_dirty = TRUE;
|
||||
}
|
||||
|
||||
sel->map[sel->wid * y + x] = (char) (c + 1);
|
||||
}
|
||||
|
||||
struct selectionvar *
|
||||
selection_not(struct selectionvar *s)
|
||||
{
|
||||
int x, y;
|
||||
NhRect tmprect = cg.zeroNhRect;
|
||||
|
||||
for (x = 0; x < s->wid; x++)
|
||||
for (y = 0; y < s->hei; y++)
|
||||
selection_setpoint(x, y, s, selection_getpoint(x, y, s) ? 0 : 1);
|
||||
selection_getbounds(s, &tmprect);
|
||||
return s;
|
||||
}
|
||||
|
||||
struct selectionvar *
|
||||
selection_filter_mapchar(struct selectionvar *ov, xint16 typ, int lit)
|
||||
{
|
||||
int x, y;
|
||||
struct selectionvar *ret;
|
||||
NhRect rect = cg.zeroNhRect;
|
||||
|
||||
if (!ov)
|
||||
return NULL;
|
||||
|
||||
ret = selection_new();
|
||||
|
||||
selection_getbounds(ov, &rect);
|
||||
|
||||
for (x = rect.lx; x <= rect.hx; x++)
|
||||
for (y = rect.ly; y <= rect.hy; y++)
|
||||
if (selection_getpoint(x, y, ov)
|
||||
&& match_maptyps(typ, levl[x][y].typ)) {
|
||||
switch (lit) {
|
||||
default:
|
||||
case -2:
|
||||
selection_setpoint(x, y, ret, 1);
|
||||
break;
|
||||
case -1:
|
||||
selection_setpoint(x, y, ret, rn2(2));
|
||||
break;
|
||||
case 0:
|
||||
case 1:
|
||||
if (levl[x][y].lit == (unsigned int) lit)
|
||||
selection_setpoint(x, y, ret, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
struct selectionvar *
|
||||
selection_filter_percent(
|
||||
struct selectionvar *ov,
|
||||
int percent)
|
||||
{
|
||||
int x, y;
|
||||
struct selectionvar *ret;
|
||||
NhRect rect = cg.zeroNhRect;
|
||||
|
||||
if (!ov)
|
||||
return NULL;
|
||||
|
||||
ret = selection_new();
|
||||
|
||||
selection_getbounds(ov, &rect);
|
||||
|
||||
for (x = rect.lx; x <= rect.hx; x++)
|
||||
for (y = rect.ly; y <= rect.hy; y++)
|
||||
if (selection_getpoint(x, y, ov) && (rn2(100) < percent))
|
||||
selection_setpoint(x, y, ret, 1);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
selection_rndcoord(
|
||||
struct selectionvar *ov,
|
||||
coordxy *x, coordxy *y,
|
||||
boolean removeit)
|
||||
{
|
||||
int idx = 0;
|
||||
int c;
|
||||
int dx, dy;
|
||||
NhRect rect = cg.zeroNhRect;
|
||||
|
||||
selection_getbounds(ov, &rect);
|
||||
|
||||
for (dx = rect.lx; dx <= rect.hx; dx++)
|
||||
for (dy = rect.ly; dy <= rect.hy; dy++)
|
||||
if (selection_getpoint(dx, dy, ov))
|
||||
idx++;
|
||||
|
||||
if (idx) {
|
||||
c = rn2(idx);
|
||||
for (dx = rect.lx; dx <= rect.hx; dx++)
|
||||
for (dy = rect.ly; dy <= rect.hy; dy++)
|
||||
if (selection_getpoint(dx, dy, ov)) {
|
||||
if (!c) {
|
||||
*x = dx;
|
||||
*y = dy;
|
||||
if (removeit)
|
||||
selection_setpoint(dx, dy, ov, 0);
|
||||
return 1;
|
||||
}
|
||||
c--;
|
||||
}
|
||||
}
|
||||
*x = *y = -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Choose a single random W_* direction. */
|
||||
static coordxy
|
||||
coordxy
|
||||
random_wdir(void)
|
||||
{
|
||||
static const coordxy wdirs[4] = { W_NORTH, W_SOUTH, W_EAST, W_WEST };
|
||||
return wdirs[rn2(4)];
|
||||
}
|
||||
|
||||
void
|
||||
selection_do_grow(struct selectionvar *ov, int dir)
|
||||
{
|
||||
coordxy x, y;
|
||||
struct selectionvar *tmp;
|
||||
NhRect rect = cg.zeroNhRect;
|
||||
|
||||
if (!ov)
|
||||
return;
|
||||
|
||||
tmp = selection_new();
|
||||
|
||||
if (dir == W_RANDOM)
|
||||
dir = random_wdir();
|
||||
|
||||
selection_getbounds(ov, &rect);
|
||||
|
||||
for (x = max(0, rect.lx-1); x <= min(COLNO-1, rect.hx+1); x++)
|
||||
for (y = max(0, rect.ly-1); y <= min(ROWNO-1, rect.hy+1); y++) {
|
||||
/* note: dir is a mask of multiple directions, but the only
|
||||
way to specify diagonals is by including the two adjacent
|
||||
orthogonal directions, which effectively specifies three-
|
||||
way growth [WEST|NORTH => WEST plus WEST|NORTH plus NORTH] */
|
||||
if (((dir & W_WEST) && selection_getpoint(x + 1, y, ov))
|
||||
|| (((dir & (W_WEST | W_NORTH)) == (W_WEST | W_NORTH))
|
||||
&& selection_getpoint(x + 1, y + 1, ov))
|
||||
|| ((dir & W_NORTH) && selection_getpoint(x, y + 1, ov))
|
||||
|| (((dir & (W_NORTH | W_EAST)) == (W_NORTH | W_EAST))
|
||||
&& selection_getpoint(x - 1, y + 1, ov))
|
||||
|| ((dir & W_EAST) && selection_getpoint(x - 1, y, ov))
|
||||
|| (((dir & (W_EAST | W_SOUTH)) == (W_EAST | W_SOUTH))
|
||||
&& selection_getpoint(x - 1, y - 1, ov))
|
||||
|| ((dir & W_SOUTH) && selection_getpoint(x, y - 1, ov))
|
||||
|| (((dir & (W_SOUTH | W_WEST)) == (W_SOUTH | W_WEST))
|
||||
&& selection_getpoint(x + 1, y - 1, ov))) {
|
||||
selection_setpoint(x, y, tmp, 1);
|
||||
}
|
||||
}
|
||||
|
||||
selection_getbounds(tmp, &rect);
|
||||
|
||||
for (x = rect.lx; x <= rect.hx; x++)
|
||||
for (y = rect.ly; y <= rect.hy; y++)
|
||||
if (selection_getpoint(x, y, tmp))
|
||||
selection_setpoint(x, y, ov, 1);
|
||||
|
||||
selection_free(tmp, TRUE);
|
||||
}
|
||||
|
||||
static int (*selection_flood_check_func)(coordxy, coordxy);
|
||||
static schar floodfillchk_match_under_typ;
|
||||
|
||||
void
|
||||
set_selection_floodfillchk(int (*f)(coordxy, coordxy))
|
||||
{
|
||||
selection_flood_check_func = f;
|
||||
}
|
||||
|
||||
static int
|
||||
floodfillchk_match_under(coordxy x, coordxy y)
|
||||
{
|
||||
@@ -4870,373 +4507,6 @@ floodfillchk_match_accessible(coordxy x, coordxy y)
|
||||
|| levl[x][y].typ == SCORR);
|
||||
}
|
||||
|
||||
/* check whethere <x,y> is already in xs[],ys[] */
|
||||
static boolean
|
||||
sel_flood_havepoint(
|
||||
coordxy x, coordxy y,
|
||||
coordxy xs[], coordxy ys[],
|
||||
int n)
|
||||
{
|
||||
coordxy xx = x, yy = y;
|
||||
|
||||
while (n > 0) {
|
||||
--n;
|
||||
if (xs[n] == xx && ys[n] == yy)
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
selection_floodfill(
|
||||
struct selectionvar *ov,
|
||||
coordxy x, coordxy y,
|
||||
boolean diagonals)
|
||||
{
|
||||
struct selectionvar *tmp = selection_new();
|
||||
#define SEL_FLOOD_STACK (COLNO * ROWNO)
|
||||
#define SEL_FLOOD(nx, ny) \
|
||||
do { \
|
||||
if (idx < SEL_FLOOD_STACK) { \
|
||||
dx[idx] = (nx); \
|
||||
dy[idx] = (ny); \
|
||||
idx++; \
|
||||
} else \
|
||||
panic(floodfill_stack_overrun); \
|
||||
} while (0)
|
||||
#define SEL_FLOOD_CHKDIR(mx, my, sel) \
|
||||
do { \
|
||||
if (isok((mx), (my)) \
|
||||
&& (*selection_flood_check_func)((mx), (my)) \
|
||||
&& !selection_getpoint((mx), (my), (sel)) \
|
||||
&& !sel_flood_havepoint((mx), (my), dx, dy, idx)) \
|
||||
SEL_FLOOD((mx), (my)); \
|
||||
} while (0)
|
||||
static const char floodfill_stack_overrun[] = "floodfill stack overrun";
|
||||
int idx = 0;
|
||||
coordxy dx[SEL_FLOOD_STACK];
|
||||
coordxy dy[SEL_FLOOD_STACK];
|
||||
|
||||
if (selection_flood_check_func == (int (*)(coordxy, coordxy)) 0) {
|
||||
selection_free(tmp, TRUE);
|
||||
return;
|
||||
}
|
||||
SEL_FLOOD(x, y);
|
||||
do {
|
||||
idx--;
|
||||
x = dx[idx];
|
||||
y = dy[idx];
|
||||
if (isok(x, y)) {
|
||||
selection_setpoint(x, y, ov, 1);
|
||||
selection_setpoint(x, y, tmp, 1);
|
||||
}
|
||||
SEL_FLOOD_CHKDIR((x + 1), y, tmp);
|
||||
SEL_FLOOD_CHKDIR((x - 1), y, tmp);
|
||||
SEL_FLOOD_CHKDIR(x, (y + 1), tmp);
|
||||
SEL_FLOOD_CHKDIR(x, (y - 1), tmp);
|
||||
if (diagonals) {
|
||||
SEL_FLOOD_CHKDIR((x + 1), (y + 1), tmp);
|
||||
SEL_FLOOD_CHKDIR((x - 1), (y - 1), tmp);
|
||||
SEL_FLOOD_CHKDIR((x - 1), (y + 1), tmp);
|
||||
SEL_FLOOD_CHKDIR((x + 1), (y - 1), tmp);
|
||||
}
|
||||
} while (idx > 0);
|
||||
#undef SEL_FLOOD
|
||||
#undef SEL_FLOOD_STACK
|
||||
#undef SEL_FLOOD_CHKDIR
|
||||
selection_free(tmp, TRUE);
|
||||
}
|
||||
|
||||
/* McIlroy's Ellipse Algorithm */
|
||||
void
|
||||
selection_do_ellipse(
|
||||
struct selectionvar *ov,
|
||||
int xc, int yc,
|
||||
int a, int b,
|
||||
int filled)
|
||||
{ /* e(x,y) = b^2*x^2 + a^2*y^2 - a^2*b^2 */
|
||||
int x = 0, y = b;
|
||||
long a2 = (long) a * a, b2 = (long) b * b;
|
||||
long crit1 = -(a2 / 4 + a % 2 + b2);
|
||||
long crit2 = -(b2 / 4 + b % 2 + a2);
|
||||
long crit3 = -(b2 / 4 + b % 2);
|
||||
long t = -a2 * y; /* e(x+1/2,y-1/2) - (a^2+b^2)/4 */
|
||||
long dxt = 2 * b2 * x, dyt = -2 * a2 * y;
|
||||
long d2xt = 2 * b2, d2yt = 2 * a2;
|
||||
long width = 1;
|
||||
long i;
|
||||
|
||||
if (!ov)
|
||||
return;
|
||||
|
||||
filled = !filled;
|
||||
|
||||
if (!filled) {
|
||||
while (y >= 0 && x <= a) {
|
||||
selection_setpoint(xc + x, yc + y, ov, 1);
|
||||
if (x != 0 || y != 0)
|
||||
selection_setpoint(xc - x, yc - y, ov, 1);
|
||||
if (x != 0 && y != 0) {
|
||||
selection_setpoint(xc + x, yc - y, ov, 1);
|
||||
selection_setpoint(xc - x, yc + y, ov, 1);
|
||||
}
|
||||
if (t + b2 * x <= crit1 /* e(x+1,y-1/2) <= 0 */
|
||||
|| t + a2 * y <= crit3) { /* e(x+1/2,y) <= 0 */
|
||||
x++;
|
||||
dxt += d2xt;
|
||||
t += dxt;
|
||||
} else if (t - a2 * y > crit2) { /* e(x+1/2,y-1) > 0 */
|
||||
y--;
|
||||
dyt += d2yt;
|
||||
t += dyt;
|
||||
} else {
|
||||
x++;
|
||||
dxt += d2xt;
|
||||
t += dxt;
|
||||
y--;
|
||||
dyt += d2yt;
|
||||
t += dyt;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
while (y >= 0 && x <= a) {
|
||||
if (t + b2 * x <= crit1 /* e(x+1,y-1/2) <= 0 */
|
||||
|| t + a2 * y <= crit3) { /* e(x+1/2,y) <= 0 */
|
||||
x++;
|
||||
dxt += d2xt;
|
||||
t += dxt;
|
||||
width += 2;
|
||||
} else if (t - a2 * y > crit2) { /* e(x+1/2,y-1) > 0 */
|
||||
for (i = 0; i < width; i++)
|
||||
selection_setpoint(xc - x + i, yc - y, ov, 1);
|
||||
if (y != 0)
|
||||
for (i = 0; i < width; i++)
|
||||
selection_setpoint(xc - x + i, yc + y, ov, 1);
|
||||
y--;
|
||||
dyt += d2yt;
|
||||
t += dyt;
|
||||
} else {
|
||||
for (i = 0; i < width; i++)
|
||||
selection_setpoint(xc - x + i, yc - y, ov, 1);
|
||||
if (y != 0)
|
||||
for (i = 0; i < width; i++)
|
||||
selection_setpoint(xc - x + i, yc + y, ov, 1);
|
||||
x++;
|
||||
dxt += d2xt;
|
||||
t += dxt;
|
||||
y--;
|
||||
dyt += d2yt;
|
||||
t += dyt;
|
||||
width += 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* square of distance from line segment (x1,y1, x2,y2) to point (x3,y3) */
|
||||
static long
|
||||
line_dist_coord(long x1, long y1, long x2, long y2, long x3, long y3)
|
||||
{
|
||||
long px = x2 - x1;
|
||||
long py = y2 - y1;
|
||||
long s = px * px + py * py;
|
||||
long x, y, dx, dy, distsq = 0;
|
||||
float lu = 0;
|
||||
|
||||
if (x1 == x2 && y1 == y2)
|
||||
return dist2(x1, y1, x3, y3);
|
||||
|
||||
lu = ((x3 - x1) * px + (y3 - y1) * py) / (float) s;
|
||||
if (lu > 1)
|
||||
lu = 1;
|
||||
else if (lu < 0)
|
||||
lu = 0;
|
||||
|
||||
x = x1 + lu * px;
|
||||
y = y1 + lu * py;
|
||||
dx = x - x3;
|
||||
dy = y - y3;
|
||||
distsq = dx * dx + dy * dy;
|
||||
|
||||
return distsq;
|
||||
}
|
||||
|
||||
/* guts of l_selection_gradient */
|
||||
void
|
||||
selection_do_gradient(
|
||||
struct selectionvar *ov,
|
||||
long x, long y,
|
||||
long x2,long y2,
|
||||
long gtyp,
|
||||
long mind, long maxd)
|
||||
{
|
||||
long dx, dy, dofs;
|
||||
|
||||
if (mind > maxd) {
|
||||
long tmp = mind;
|
||||
mind = maxd;
|
||||
maxd = tmp;
|
||||
}
|
||||
|
||||
dofs = maxd * maxd - mind * mind;
|
||||
if (dofs < 1)
|
||||
dofs = 1;
|
||||
|
||||
switch (gtyp) {
|
||||
default:
|
||||
impossible("Unrecognized gradient type! Defaulting to radial...");
|
||||
/* FALLTHRU */
|
||||
case SEL_GRADIENT_RADIAL: {
|
||||
for (dx = 0; dx < COLNO; dx++)
|
||||
for (dy = 0; dy < ROWNO; dy++) {
|
||||
long d0 = line_dist_coord(x, y, x2, y2, dx, dy);
|
||||
|
||||
if (d0 <= mind * mind
|
||||
|| (d0 <= maxd * maxd && d0 - mind * mind < rn2(dofs)))
|
||||
selection_setpoint(dx, dy, ov, 1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SEL_GRADIENT_SQUARE: {
|
||||
for (dx = 0; dx < COLNO; dx++)
|
||||
for (dy = 0; dy < ROWNO; dy++) {
|
||||
long d1 = line_dist_coord(x, y, x2, y2, x, dy);
|
||||
long d2 = line_dist_coord(x, y, x2, y2, dx, y);
|
||||
long d3 = line_dist_coord(x, y, x2, y2, x2, dy);
|
||||
long d4 = line_dist_coord(x, y, x2, y2, dx, y2);
|
||||
long d5 = line_dist_coord(x, y, x2, y2, dx, dy);
|
||||
long d0 = min(d5, min(max(d1, d2), max(d3, d4)));
|
||||
|
||||
if (d0 <= mind * mind
|
||||
|| (d0 <= maxd * maxd && d0 - mind * mind < rn2(dofs)))
|
||||
selection_setpoint(dx, dy, ov, 1);
|
||||
}
|
||||
break;
|
||||
} /*case*/
|
||||
} /*switch*/
|
||||
}
|
||||
|
||||
/* bresenham line algo */
|
||||
void
|
||||
selection_do_line(
|
||||
coordxy x1, coordxy y1,
|
||||
coordxy x2, coordxy y2,
|
||||
struct selectionvar *ov)
|
||||
{
|
||||
int d0, dx, dy, ai, bi, xi, yi;
|
||||
|
||||
if (x1 < x2) {
|
||||
xi = 1;
|
||||
dx = x2 - x1;
|
||||
} else {
|
||||
xi = -1;
|
||||
dx = x1 - x2;
|
||||
}
|
||||
if (y1 < y2) {
|
||||
yi = 1;
|
||||
dy = y2 - y1;
|
||||
} else {
|
||||
yi = -1;
|
||||
dy = y1 - y2;
|
||||
}
|
||||
|
||||
selection_setpoint(x1, y1, ov, 1);
|
||||
|
||||
if (!dx && !dy) {
|
||||
/* single point - already all done */
|
||||
;
|
||||
} else if (dx > dy) {
|
||||
ai = (dy - dx) * 2;
|
||||
bi = dy * 2;
|
||||
d0 = bi - dx;
|
||||
do {
|
||||
if (d0 >= 0) {
|
||||
y1 += yi;
|
||||
d0 += ai;
|
||||
} else
|
||||
d0 += bi;
|
||||
x1 += xi;
|
||||
selection_setpoint(x1, y1, ov, 1);
|
||||
} while (x1 != x2);
|
||||
} else {
|
||||
ai = (dx - dy) * 2;
|
||||
bi = dx * 2;
|
||||
d0 = bi - dy;
|
||||
do {
|
||||
if (d0 >= 0) {
|
||||
x1 += xi;
|
||||
d0 += ai;
|
||||
} else
|
||||
d0 += bi;
|
||||
y1 += yi;
|
||||
selection_setpoint(x1, y1, ov, 1);
|
||||
} while (y1 != y2);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
selection_do_randline(
|
||||
coordxy x1, coordxy y1,
|
||||
coordxy x2, coordxy y2,
|
||||
schar rough,
|
||||
schar rec,
|
||||
struct selectionvar *ov)
|
||||
{
|
||||
int mx, my;
|
||||
int dx, dy;
|
||||
|
||||
if (rec < 1 || (x2 == x1 && y2 == y1))
|
||||
return;
|
||||
|
||||
if (rough > max(abs(x2 - x1), abs(y2 - y1)))
|
||||
rough = max(abs(x2 - x1), abs(y2 - y1));
|
||||
|
||||
if (rough < 2) {
|
||||
mx = ((x1 + x2) / 2);
|
||||
my = ((y1 + y2) / 2);
|
||||
} else {
|
||||
do {
|
||||
dx = rn2(rough) - (rough / 2);
|
||||
dy = rn2(rough) - (rough / 2);
|
||||
mx = ((x1 + x2) / 2) + dx;
|
||||
my = ((y1 + y2) / 2) + dy;
|
||||
} while ((mx > COLNO - 1 || mx < 0 || my < 0 || my > ROWNO - 1));
|
||||
}
|
||||
|
||||
if (!selection_getpoint(mx, my, ov)) {
|
||||
selection_setpoint(mx, my, ov, 1);
|
||||
}
|
||||
|
||||
rough = (rough * 2) / 3;
|
||||
|
||||
rec--;
|
||||
|
||||
selection_do_randline(x1, y1, mx, my, rough, rec, ov);
|
||||
selection_do_randline(mx, my, x2, y2, rough, rec, ov);
|
||||
|
||||
selection_setpoint(x2, y2, ov, 1);
|
||||
}
|
||||
|
||||
static void
|
||||
selection_iterate(
|
||||
struct selectionvar *ov,
|
||||
select_iter_func func,
|
||||
genericptr_t arg)
|
||||
{
|
||||
coordxy x, y;
|
||||
NhRect rect = cg.zeroNhRect;
|
||||
|
||||
if (!ov)
|
||||
return;
|
||||
|
||||
selection_getbounds(ov, &rect);
|
||||
|
||||
for (x = rect.lx; x <= rect.hx; x++)
|
||||
for (y = rect.ly; y <= rect.hy; y++)
|
||||
if (isok(x,y) && selection_getpoint(x, y, ov))
|
||||
(*func)(x, y, arg);
|
||||
}
|
||||
|
||||
/* change map location terrain type during level creation */
|
||||
static void
|
||||
sel_set_ter(coordxy x, coordxy y, genericptr_t arg)
|
||||
@@ -6938,27 +6208,6 @@ TODO: gc.coder->croom needs to be updated
|
||||
|
||||
RESTORE_WARNING_UNREACHABLE_CODE
|
||||
|
||||
struct selectionvar *
|
||||
selection_from_mkroom(struct mkroom *croom)
|
||||
{
|
||||
struct selectionvar *sel = selection_new();
|
||||
coordxy x, y;
|
||||
unsigned rmno;
|
||||
|
||||
if (!croom && gc.coder && gc.coder->croom)
|
||||
croom = gc.coder->croom;
|
||||
if (!croom)
|
||||
return sel;
|
||||
|
||||
rmno = (unsigned)((croom - gr.rooms) + ROOMOFFSET);
|
||||
for (y = croom->ly; y <= croom->hy; y++)
|
||||
for (x = croom->lx; x <= croom->hx; x++)
|
||||
if (isok(x, y) && !levl[x][y].edge
|
||||
&& levl[x][y].roomno == rmno)
|
||||
selection_setpoint(x, y, sel, 1);
|
||||
return sel;
|
||||
}
|
||||
|
||||
void
|
||||
update_croom(void)
|
||||
{
|
||||
|
||||
+237
@@ -0,0 +1,237 @@
|
||||
/* NetHack 3.7 stairs.c $NHDT-Date: 1704043695 2023/12/31 17:28:15 $ $NHDT-Branch: keni-luabits2 $:$NHDT-Revision: 1.207 $ */
|
||||
/* Copyright (c) 2024 by Pasi Kallinen */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
|
||||
#include "hack.h"
|
||||
|
||||
void
|
||||
stairway_add(
|
||||
coordxy x, coordxy y,
|
||||
boolean up, boolean isladder,
|
||||
d_level *dest)
|
||||
{
|
||||
stairway *tmp = (stairway *) alloc(sizeof (stairway));
|
||||
|
||||
(void) memset((genericptr_t) tmp, 0, sizeof (stairway));
|
||||
tmp->sx = x;
|
||||
tmp->sy = y;
|
||||
tmp->up = up;
|
||||
tmp->isladder = isladder;
|
||||
tmp->u_traversed = FALSE;
|
||||
assign_level(&(tmp->tolev), dest);
|
||||
tmp->next = gs.stairs;
|
||||
gs.stairs = tmp;
|
||||
}
|
||||
|
||||
void
|
||||
stairway_free_all(void)
|
||||
{
|
||||
stairway *tmp = gs.stairs;
|
||||
|
||||
while (tmp) {
|
||||
stairway *tmp2 = tmp->next;
|
||||
free(tmp);
|
||||
tmp = tmp2;
|
||||
}
|
||||
gs.stairs = NULL;
|
||||
}
|
||||
|
||||
stairway *
|
||||
stairway_at(coordxy x, coordxy y)
|
||||
{
|
||||
stairway *tmp = gs.stairs;
|
||||
|
||||
while (tmp && !(tmp->sx == x && tmp->sy == y))
|
||||
tmp = tmp->next;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
stairway *
|
||||
stairway_find(d_level *fromdlev)
|
||||
{
|
||||
stairway *tmp = gs.stairs;
|
||||
|
||||
while (tmp) {
|
||||
if (tmp->tolev.dnum == fromdlev->dnum
|
||||
&& tmp->tolev.dlevel == fromdlev->dlevel)
|
||||
break; /* return */
|
||||
tmp = tmp->next;
|
||||
}
|
||||
return tmp;
|
||||
}
|
||||
|
||||
stairway *
|
||||
stairway_find_from(d_level *fromdlev, boolean isladder)
|
||||
{
|
||||
stairway *tmp = gs.stairs;
|
||||
|
||||
while (tmp) {
|
||||
if (tmp->tolev.dnum == fromdlev->dnum
|
||||
&& tmp->tolev.dlevel == fromdlev->dlevel
|
||||
&& tmp->isladder == isladder)
|
||||
break; /* return */
|
||||
tmp = tmp->next;
|
||||
}
|
||||
return tmp;
|
||||
}
|
||||
|
||||
stairway *
|
||||
stairway_find_dir(boolean up)
|
||||
{
|
||||
stairway *tmp = gs.stairs;
|
||||
|
||||
while (tmp && !(tmp->up == up))
|
||||
tmp = tmp->next;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
stairway *
|
||||
stairway_find_type_dir(boolean isladder, boolean up)
|
||||
{
|
||||
stairway *tmp = gs.stairs;
|
||||
|
||||
while (tmp && !(tmp->isladder == isladder && tmp->up == up))
|
||||
tmp = tmp->next;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
stairway *
|
||||
stairway_find_special_dir(boolean up)
|
||||
{
|
||||
stairway *tmp = gs.stairs;
|
||||
|
||||
while (tmp) {
|
||||
if (tmp->tolev.dnum != u.uz.dnum && tmp->up != up)
|
||||
return tmp;
|
||||
tmp = tmp->next;
|
||||
}
|
||||
return tmp;
|
||||
}
|
||||
|
||||
/* place you on the special staircase */
|
||||
void
|
||||
u_on_sstairs(int upflag)
|
||||
{
|
||||
stairway *stway = stairway_find_special_dir(upflag);
|
||||
|
||||
if (stway)
|
||||
u_on_newpos(stway->sx, stway->sy);
|
||||
else
|
||||
u_on_rndspot(upflag);
|
||||
}
|
||||
|
||||
/* place you on upstairs (or special equivalent) */
|
||||
void
|
||||
u_on_upstairs(void)
|
||||
{
|
||||
stairway *stway = stairway_find_dir(TRUE);
|
||||
|
||||
if (stway)
|
||||
u_on_newpos(stway->sx, stway->sy);
|
||||
else
|
||||
u_on_sstairs(0); /* destination upstairs implies moving down */
|
||||
}
|
||||
|
||||
/* place you on dnstairs (or special equivalent) */
|
||||
void
|
||||
u_on_dnstairs(void)
|
||||
{
|
||||
stairway *stway = stairway_find_dir(FALSE);
|
||||
|
||||
if (stway)
|
||||
u_on_newpos(stway->sx, stway->sy);
|
||||
else
|
||||
u_on_sstairs(1); /* destination dnstairs implies moving up */
|
||||
}
|
||||
|
||||
boolean
|
||||
On_stairs(coordxy x, coordxy y)
|
||||
{
|
||||
return (stairway_at(x, y) != NULL);
|
||||
}
|
||||
|
||||
boolean
|
||||
On_ladder(coordxy x, coordxy y)
|
||||
{
|
||||
stairway *stway = stairway_at(x, y);
|
||||
|
||||
return (boolean) (stway && stway->isladder);
|
||||
}
|
||||
|
||||
boolean
|
||||
On_stairs_up(coordxy x, coordxy y)
|
||||
{
|
||||
stairway *stway = stairway_at(x, y);
|
||||
|
||||
return (boolean) (stway && stway->up);
|
||||
}
|
||||
|
||||
boolean
|
||||
On_stairs_dn(coordxy x, coordxy y)
|
||||
{
|
||||
stairway *stway = stairway_at(x, y);
|
||||
|
||||
return (boolean) (stway && !stway->up);
|
||||
}
|
||||
|
||||
/* return True if 'sway' is a branch staircase and hero has used these stairs
|
||||
to visit the branch */
|
||||
boolean
|
||||
known_branch_stairs(stairway *sway)
|
||||
{
|
||||
return (sway && sway->tolev.dnum != u.uz.dnum && sway->u_traversed);
|
||||
}
|
||||
|
||||
/* describe staircase 'sway' based on whether hero knows the destination */
|
||||
char *
|
||||
stairs_description(
|
||||
stairway *sway, /* stairs/ladder to describe */
|
||||
char *outbuf, /* result buffer */
|
||||
boolean stcase) /* True: "staircase" or "ladder", always singular;
|
||||
* False: "stairs" or "ladder"; caller needs to deal
|
||||
* with singular vs plural when forming a sentence */
|
||||
{
|
||||
d_level tolev;
|
||||
const char *stairs, *updown;
|
||||
|
||||
tolev = sway->tolev;
|
||||
stairs = sway->isladder ? "ladder" : stcase ? "staircase" : "stairs";
|
||||
updown = sway->up ? "up" : "down";
|
||||
|
||||
if (!known_branch_stairs(sway)) {
|
||||
/* ordinary stairs or branch stairs to not-yet-visited branch */
|
||||
Sprintf(outbuf, "%s %s", stairs, updown);
|
||||
if (sway->u_traversed) {
|
||||
boolean specialdepth = (tolev.dnum == quest_dnum
|
||||
|| single_level_branch(&tolev)); /* knox */
|
||||
int to_dlev = specialdepth ? dunlev(&tolev) : depth(&tolev);
|
||||
|
||||
Sprintf(eos(outbuf), " to level %d", to_dlev);
|
||||
}
|
||||
} else if (u.uz.dnum == 0 && u.uz.dlevel == 1 && sway->up) {
|
||||
/* stairs up from level one are a special case; they are marked
|
||||
as having been traversed because the hero obviously started
|
||||
the game by coming down them, but the remote side varies
|
||||
depending on whether the Amulet is being carried */
|
||||
Sprintf(outbuf, "%s%s %s %s",
|
||||
!u.uhave.amulet ? "" : "branch ",
|
||||
stairs, updown,
|
||||
!u.uhave.amulet ? "out of the dungeon"
|
||||
/* minimize our expectations about what comes next */
|
||||
: (on_level(&tolev, &earth_level)
|
||||
|| on_level(&tolev, &air_level)
|
||||
|| on_level(&tolev, &fire_level)
|
||||
|| on_level(&tolev, &water_level))
|
||||
? "to the Elemental Planes"
|
||||
: "to the end game");
|
||||
} else {
|
||||
/* known branch stairs; tacking on destination level is too verbose */
|
||||
Sprintf(outbuf, "branch %s %s to %s",
|
||||
stairs, updown, gd.dungeons[tolev.dnum].dname);
|
||||
/* dungeons[].dname is capitalized; undo that for "The <Branch>" */
|
||||
(void) strsubst(outbuf, "The ", "the ");
|
||||
}
|
||||
return outbuf;
|
||||
}
|
||||
|
||||
/*stairs.c*/
|
||||
+158
@@ -0,0 +1,158 @@
|
||||
/* NetHack 3.7 strutil.c $NHDT-Date: 1709571807 2024/03/04 17:03:27 $ $NHDT-Branch: keni-mdlib-followup $:$NHDT-Revision: 1.0 $ */
|
||||
/* Copyright (c) Robert Patrick Rankin, 1991 */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
|
||||
#include "hack.h" /* for config.h+extern.h */
|
||||
|
||||
/* strbuf_init() initializes strbuf state for use */
|
||||
void
|
||||
strbuf_init(strbuf_t *strbuf)
|
||||
{
|
||||
strbuf->str = NULL;
|
||||
strbuf->len = 0;
|
||||
}
|
||||
|
||||
/* strbuf_append() appends given str to strbuf->str */
|
||||
void
|
||||
strbuf_append(strbuf_t *strbuf, const char *str)
|
||||
{
|
||||
int len = (int) strlen(str) + 1;
|
||||
|
||||
strbuf_reserve(strbuf,
|
||||
len + (strbuf->str ? (int) strlen(strbuf->str) : 0));
|
||||
Strcat(strbuf->str, str);
|
||||
}
|
||||
|
||||
/* strbuf_reserve() ensure strbuf->str has storage for len characters */
|
||||
void
|
||||
strbuf_reserve(strbuf_t *strbuf, int len)
|
||||
{
|
||||
if (strbuf->str == NULL) {
|
||||
strbuf->str = strbuf->buf;
|
||||
strbuf->str[0] = '\0';
|
||||
strbuf->len = (int) sizeof strbuf->buf;
|
||||
}
|
||||
|
||||
if (len > strbuf->len) {
|
||||
char *oldbuf = strbuf->str;
|
||||
|
||||
strbuf->len = len + (int) sizeof strbuf->buf;
|
||||
strbuf->str = (char *) alloc(strbuf->len);
|
||||
Strcpy(strbuf->str, oldbuf);
|
||||
if (oldbuf != strbuf->buf)
|
||||
free((genericptr_t) oldbuf);
|
||||
}
|
||||
}
|
||||
|
||||
/* strbuf_empty() frees allocated memory and set strbuf to initial state */
|
||||
void
|
||||
strbuf_empty(strbuf_t *strbuf)
|
||||
{
|
||||
if (strbuf->str != NULL && strbuf->str != strbuf->buf)
|
||||
free((genericptr_t) strbuf->str);
|
||||
strbuf_init(strbuf);
|
||||
}
|
||||
|
||||
/* strbuf_nl_to_crlf() converts all occurences of \n to \r\n */
|
||||
void
|
||||
strbuf_nl_to_crlf(strbuf_t *strbuf)
|
||||
{
|
||||
if (strbuf->str) {
|
||||
int len = (int) strlen(strbuf->str);
|
||||
int count = 0;
|
||||
char *cp = strbuf->str;
|
||||
|
||||
while (*cp)
|
||||
if (*cp++ == '\n')
|
||||
count++;
|
||||
if (count) {
|
||||
strbuf_reserve(strbuf, len + count + 1);
|
||||
for (cp = strbuf->str + len + count; count; --cp)
|
||||
if ((*cp = cp[-count]) == '\n') {
|
||||
*--cp = '\r';
|
||||
--count;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* strlen() but returns unsigned and panics if string is unreasonably long;
|
||||
used by dlb as well as by nethack */
|
||||
unsigned
|
||||
Strlen_(
|
||||
const char *str,
|
||||
const char *file,
|
||||
int line)
|
||||
{
|
||||
const char *p;
|
||||
size_t len;
|
||||
|
||||
/* strnlen(str, LARGEST_INT) w/o requiring posix.1 headers or libraries */
|
||||
for (p = str, len = 0; len < LARGEST_INT; ++len)
|
||||
if (*p++ == '\0')
|
||||
break;
|
||||
|
||||
if (len == LARGEST_INT)
|
||||
panic("%s:%d string too long", file, line);
|
||||
return (unsigned) len;
|
||||
}
|
||||
|
||||
static boolean pmatch_internal(const char *, const char *, boolean,
|
||||
const char *);
|
||||
/* guts of pmatch(), pmatchi(), and pmatchz();
|
||||
match a string against a pattern */
|
||||
static boolean
|
||||
pmatch_internal(const char *patrn, const char *strng,
|
||||
boolean ci, /* True => case-insensitive,
|
||||
False => case-sensitive */
|
||||
const char *sk) /* set of characters to skip */
|
||||
{
|
||||
char s, p;
|
||||
/*
|
||||
* Simple pattern matcher: '*' matches 0 or more characters, '?' matches
|
||||
* any single character. Returns TRUE if 'strng' matches 'patrn'.
|
||||
*/
|
||||
pmatch_top:
|
||||
if (!sk) {
|
||||
s = *strng++;
|
||||
p = *patrn++; /* get next chars and pre-advance */
|
||||
} else {
|
||||
/* fuzzy match variant of pmatch; particular characters are ignored */
|
||||
do {
|
||||
s = *strng++;
|
||||
} while (strchr(sk, s));
|
||||
do {
|
||||
p = *patrn++;
|
||||
} while (strchr(sk, p));
|
||||
}
|
||||
if (!p) /* end of pattern */
|
||||
return (boolean) (s == '\0'); /* matches iff end of string too */
|
||||
else if (p == '*') /* wildcard reached */
|
||||
return (boolean) ((!*patrn
|
||||
|| pmatch_internal(patrn, strng - 1, ci, sk))
|
||||
? TRUE
|
||||
: s ? pmatch_internal(patrn - 1, strng, ci, sk)
|
||||
: FALSE);
|
||||
else if ((ci ? lowc(p) != lowc(s) : p != s) /* check single character */
|
||||
&& (p != '?' || !s)) /* & single-char wildcard */
|
||||
return FALSE; /* doesn't match */
|
||||
else /* return pmatch_internal(patrn, strng, ci, sk); */
|
||||
goto pmatch_top; /* optimize tail recursion */
|
||||
}
|
||||
|
||||
/* case-sensitive wildcard match */
|
||||
boolean
|
||||
pmatch(const char *patrn, const char *strng)
|
||||
{
|
||||
return pmatch_internal(patrn, strng, FALSE, (const char *) 0);
|
||||
}
|
||||
|
||||
/* case-insensitive wildcard match */
|
||||
boolean
|
||||
pmatchi(const char *patrn, const char *strng)
|
||||
{
|
||||
return pmatch_internal(patrn, strng, TRUE, (const char *) 0);
|
||||
}
|
||||
|
||||
|
||||
/*strutil.c*/
|
||||
+1821
File diff suppressed because it is too large
Load Diff
+59
-40
@@ -1,5 +1,5 @@
|
||||
# NetHack 3.7 Makefile.GCC $NHDT-Date: 1596498268 2020/08/03 23:44:28 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.53 $
|
||||
# Copyright (c) NetHack PC Development Team 1996-2022.
|
||||
# Copyright (c) NetHack PC Development Team 1996-2024.
|
||||
# PC NetHack 3.7 Makefile for djgpp V2
|
||||
#
|
||||
# Gnu gcc compiler for msdos (djgpp)
|
||||
@@ -163,6 +163,9 @@ else
|
||||
DLBFLG =
|
||||
endif
|
||||
|
||||
#
|
||||
HACKLIB = $(O)hacklib.a
|
||||
|
||||
TERMLIB =
|
||||
# Build NetHack suitable for blind players
|
||||
|
||||
@@ -269,29 +272,31 @@ DLBOBJ = $(O)dlb.o
|
||||
|
||||
|
||||
VOBJ01 = $(O)allmain.o $(O)alloc.o $(O)apply.o $(O)artifact.o $(O)attrib.o
|
||||
VOBJ02 = $(O)ball.o $(O)bones.o $(O)botl.o $(O)cmd.o $(O)date.o $(O)dbridge.o
|
||||
VOBJ03 = $(O)decl.o $(O)detect.o $(O)dig.o $(O)display.o $(O)do.o
|
||||
VOBJ04 = $(O)do_name.o $(O)do_wear.o $(O)dog.o $(O)dogmove.o $(O)dokick.o
|
||||
VOBJ05 = $(O)dothrow.o $(O)drawing.o $(O)dungeon.o $(O)eat.o $(O)end.o
|
||||
VOBJ06 = $(O)engrave.o $(O)exper.o $(O)explode.o $(O)extralev.o $(O)files.o
|
||||
VOBJ07 = $(O)fountain.o $(O)getline.o $(O)hack.o $(O)hacklib.o $(O)insight.o $(O)invent.o
|
||||
VOBJ08 = $(O)isaac64.o $(O)lock.o $(O)mail.o $(O)main.o $(O)makemon.o
|
||||
VOBJ09 = $(O)mcastu.o $(O)mdlib.o $(O)mhitm.o $(O)mhitu.o $(O)minion.o $(O)mkmap.o
|
||||
VOBJ10 = $(O)mklev.o $(O)mkmaze.o $(O)mkobj.o $(O)mkroom.o $(O)mon.o
|
||||
VOBJ11 = $(O)mondata.o $(O)monmove.o $(O)monst.o $(O)mplayer.o $(O)mthrowu.o
|
||||
VOBJ12 = $(O)muse.o $(O)music.o $(O)o_init.o $(O)objects.o $(O)objnam.o
|
||||
VOBJ13 = $(O)options.o $(O)pickup.o $(O)pline.o $(O)polyself.o $(O)potion.o
|
||||
VOBJ14 = $(O)quest.o $(O)questpgr.o $(O)pager.o $(O)pray.o $(O)priest.o
|
||||
VOBJ15 = $(O)read.o $(O)rect.o $(O)region.o $(O)restore.o $(O)rip.o
|
||||
VOBJ16 = $(O)rnd.o $(O)role.o $(O)rumors.o $(O)save.o $(O)sfstruct.o
|
||||
VOBJ17 = $(O)shk.o $(O)shknam.o $(O)sit.o $(O)sounds.o $(O)sp_lev.o
|
||||
VOBJ18 = $(O)spell.o $(O)steal.o $(O)steed.o $(O)symbols.o $(O)sys.o
|
||||
VOBJ19 = $(O)teleport.o $(O)termcap.o $(O)timeout.o $(O)topl.o $(O)topten.o
|
||||
VOBJ20 = $(O)track.o $(O)trap.o $(O)u_init.o $(O)uhitm.o $(O)utf8map.o $(O)vault.o
|
||||
VOBJ21 = $(O)vision.o $(O)weapon.o $(O)were.o $(O)wield.o $(O)windows.o
|
||||
VOBJ22 = $(O)wintty.o $(O)wizard.o $(O)worm.o $(O)worn.o $(O)write.o
|
||||
VOBJ23 = $(O)zap.o $(O)light.o $(O)dlb.o
|
||||
VOBJ24 = $(REGEX)
|
||||
VOBJ02 = $(O)ball.o $(O)bones.o $(O)botl.o $(O)calendar.o $(O)cmd.o
|
||||
VOBJ03 = $(O)coloratt.o $(O)date.o $(O)dbridge.o $(O)decl.o $(O)detect.o
|
||||
VOBJ04 = $(O)dig.o $(O)display.o $(O)do.o $(O)do_name.o $(O)do_wear.o
|
||||
VOBJ05 = $(O)dog.o $(O)dogmove.o $(O)dokick.o $(O)dothrow.o $(O)drawing.o
|
||||
VOBJ06 = $(O)dungeon.o $(O)eat.o $(O)end.o $(O)engrave.o $(O)exper.o
|
||||
VOBJ07 = $(O)explode.o $(O)extralev.o $(O)files.o $(O)fountain.o $(O)getpos.o
|
||||
VOBJ08 = $(O)getline.o $(O)hack.o $(O)hacklib.o $(O)insight.o $(O)invent.o
|
||||
VOBJ09 = $(O)isaac64.o $(O)lock.o $(O)mail.o $(O)main.o $(O)makemon.o
|
||||
VOBJ10 = $(O)mcastu.o $(O)mdlib.o $(O)mhitm.o $(O)mhitu.o $(O)minion.o
|
||||
VOBJ11 = $(O)mkmap.o $(O)mklev.o $(O)mkmaze.o $(O)mkobj.o $(O)mkroom.o
|
||||
VOBJ12 = $(O)mon.o $(O)mondata.o $(O)monmove.o $(O)monst.o $(O)mplayer.o
|
||||
VOBJ13 = $(O)mthrowu.o $(O)muse.o $(O)music.o $(O)o_init.o $(O)objects.o
|
||||
VOBJ14 = $(O)objnam.o $(O)options.o $(O)pickup.o $(O)pline.o $(O)polyself.o
|
||||
VOBJ15 = $(O)potion.o $(O)quest.o $(O)questpgr.o $(O)pager.o $(O)pray.o
|
||||
VOBJ16 = $(O)priest.o $(O)read.o $(O)rect.o $(O)region.o $(O)report.o
|
||||
VOBJ17 = $(O)restore.o $(O)rip.o $(O)rnd.o $(O)role.o $(O)rumors.o
|
||||
VOBJ18 = $(O)save.o $(O)selvar.o $(O)sfstruct.o $(O)shk.o $(O)shknam.o
|
||||
VOBJ19 = $(O)sit.o $(O)sounds.o $(O)sp_lev.o $(O)spell.o $(O)stairs.o
|
||||
VOBJ20 = $(O)steal.o $(O)steed.o $(O)symbols.o $(O)sys.o $(O)teleport.o
|
||||
VOBJ21 = $(O)strutil.o $(O)termcap.o $(O)timeout.o $(O)topl.o $(O)topten.o
|
||||
VOBJ22 = $(O)trap.o $(O)u_init.o $(O)uhitm.o $(O)utf8map.o $(O)vault.o
|
||||
VOBJ23 = $(O)track.o $(O)vision.o $(O)weapon.o $(O)were.o $(O)wield.o
|
||||
VOBJ24 = $(O)windows.o $(O)wintty.o $(O)wizard.o $(O)wizcmds.o $(O)worm.o
|
||||
VOBJ25 = $(O)worn.o $(O)write.o $(O)zap.o $(O)light.o $(O)dlb.o
|
||||
VOBJ26 = $(REGEX)
|
||||
|
||||
SOBJ = $(O)msdos.o $(O)pcsys.o $(O)tty.o $(O)unix.o \
|
||||
$(O)video.o $(O)vidtxt.o $(O)pckeys.o
|
||||
@@ -313,7 +318,7 @@ VOBJ = $(VOBJ01) $(VOBJ02) $(VOBJ03) $(VOBJ04) $(VOBJ05) \
|
||||
$(VOBJ11) $(VOBJ12) $(VOBJ13) $(VOBJ14) $(VOBJ15) \
|
||||
$(VOBJ16) $(VOBJ17) $(VOBJ18) $(VOBJ19) $(VOBJ20) \
|
||||
$(VOBJ21) $(VOBJ22) $(VOBJ23) $(VOBJ24) $(VOBJ25) \
|
||||
$(CURSESOBJ) $(LUAOBJ)
|
||||
$(VOBJ26) $(CURSESOBJ) $(LUAOBJ)
|
||||
|
||||
ALLOBJ = $(VOBJ) $(SOBJ) $(TILOBJ) $(TILOBJ2) $(VVOBJ)
|
||||
|
||||
@@ -609,7 +614,7 @@ endif
|
||||
#==========================================
|
||||
|
||||
$(GAMEFILE): $(O)obj.tag $(PATCHLEV_H) $(PDCLIB) $(LUATARGETS) \
|
||||
$(O)utility.tag $(ALLOBJ)
|
||||
$(O)utility.tag $(ALLOBJ) $(O)hacklib.a
|
||||
@if exist temp.a del temp.a
|
||||
@ar ruS temp.a $(VOBJ01)
|
||||
@ar ruS temp.a $(VOBJ02)
|
||||
@@ -636,6 +641,7 @@ $(GAMEFILE): $(O)obj.tag $(PATCHLEV_H) $(PDCLIB) $(LUATARGETS) \
|
||||
@ar ruS temp.a $(VOBJ23)
|
||||
@ar ruS temp.a $(VOBJ24)
|
||||
@ar ruS temp.a $(VOBJ25)
|
||||
@ar ruS temp.a $(VOBJ26)
|
||||
@ar ruS temp.a $(SOBJ)
|
||||
@ar ruS temp.a $(TILOBJ)
|
||||
@ar ruS temp.a $(TILOBJ2)
|
||||
@@ -674,12 +680,24 @@ $(INCL)/pm.h: $(U)makedefs.exe
|
||||
# Makedefs Stuff
|
||||
#==========================================
|
||||
|
||||
$(U)makedefs.exe: $(MAKEDEFSOBJS)
|
||||
$(LINK) $(LFLAGS) -o$@ $(MAKEDEFSOBJS)
|
||||
$(U)makedefs.exe: $(MAKEDEFSOBJS) $(HACKLIB)
|
||||
$(LINK) $(LFLAGS) -o$@ $(MAKEDEFSOBJS) $(HACKLIB)
|
||||
|
||||
$(O)makedefs.o: $(CONFIG_H) $(PERMONST_H) $(INCL)/objclass.h \
|
||||
$(INCL)/sym.h $(INCL)/defsym.h $(U)makedefs.c
|
||||
|
||||
#==========================================
|
||||
# hacklib.a static library
|
||||
#==========================================
|
||||
|
||||
$(O)hacklib.a: $(O)hacklibu.o
|
||||
@ar rcs $@ $(O)hacklibu.o
|
||||
# @ranlib $@
|
||||
|
||||
$(O)hacklibu.o: $(CONFIG_H) $(SRC)/hacklib.c
|
||||
$(CC) $(cflags) -I$(SRC) -I$(MSYS) \
|
||||
-o$@ $(SRC)/hacklib.c
|
||||
|
||||
#==========================================
|
||||
# Recover Utility
|
||||
#==========================================
|
||||
@@ -707,8 +725,8 @@ $(SRC)/tile.c: $(U)tilemap.exe
|
||||
|
||||
TILEMAPOBJS = $(O)tilemap.o $(O)monst.o $(O)objects.o $(O)drawing.o
|
||||
|
||||
$(U)tilemap.exe: $(TILEMAPOBJS)
|
||||
$(LINK) $(LFLAGS) -o$@ $(TILEMAPOBJS)
|
||||
$(U)tilemap.exe: $(TILEMAPOBJS) $(HACKLIB)
|
||||
$(LINK) $(LFLAGS) -o$@ $(TILEMAPOBJS) $(HACKLIB)
|
||||
|
||||
$(O)tilemap.o: $(WSHR)/tilemap.c $(HACK_H) $(TILE_H)
|
||||
$(CC) $(cflags) -I$(WSHR) -I$(MSYS) -o$@ $(WSHR)/tilemap.c
|
||||
@@ -726,23 +744,23 @@ $(DAT)/nhtiles.bmp: $(TILEFILES) $(U)tile2bmp.exe
|
||||
@$(subst /,\,$(U)tile2bmp.exe $@)
|
||||
@$(subst /,\,chdir $(SRC))
|
||||
|
||||
$(U)tile2bmp.exe: $(O)tile2bmp.o $(TEXTIO)
|
||||
$(U)tile2bmp.exe: $(O)tile2bmp.o $(TEXTIO) $(HACKLIB)
|
||||
-rm -f temp.a
|
||||
@ar ru temp.a $(TEXTIO)
|
||||
$(LINK) $(LFLAGS) -o$@ $(O)tile2bmp.o temp.a
|
||||
$(LINK) $(LFLAGS) -o$@ $(O)tile2bmp.o temp.a $(HACKLIB)
|
||||
|
||||
$(U)tile2bin.exe: $(O)tile2bin.o $(TEXTIO)
|
||||
$(U)tile2bin.exe: $(O)tile2bin.o $(TEXTIO) $(HACKLIB)
|
||||
-rm -f temp.a
|
||||
@ar ru temp.a $(TEXTIO)
|
||||
$(LINK) $(LFLAGS) -o$@ $(O)tile2bin.o temp.a
|
||||
$(LINK) $(LFLAGS) -o$@ $(O)tile2bin.o temp.a $(HACKLIB)
|
||||
|
||||
$(U)til2bin2.exe: $(O)til2bin2.o $(TEXTIO2)
|
||||
$(U)til2bin2.exe: $(O)til2bin2.o $(TEXTIO2) $(HACKLIB)
|
||||
-rm -f temp.a
|
||||
@ar ru temp.a $(TEXTIO2)
|
||||
$(LINK) $(LFLAGS) -o$@ $(O)til2bin2.o temp.a
|
||||
$(LINK) $(LFLAGS) -o$@ $(O)til2bin2.o temp.a $(HACKLIB)
|
||||
|
||||
$(U)thintile.exe: $(O)thintile.o
|
||||
$(LINK) $(LFLAGS) -o$@ $(O)thintile.o
|
||||
$(U)thintile.exe: $(O)thintile.o $(HACKLIB)
|
||||
$(LINK) $(LFLAGS) -o$@ $(O)thintile.o $(HACKLIB)
|
||||
|
||||
$(O)thintile.o: $(HACK_H) $(WSHR)/tile.h $(WSHR)/thintile.c
|
||||
$(CC) $(cflags) -o$@ $(WSHR)/thintile.c
|
||||
@@ -895,8 +913,8 @@ $(DAT)/nhdat: $(U)dlb_main.exe $(DAT)/data $(DAT)/rumors \
|
||||
@$(subst /,\,$(U)dlb_main cvIf dlb.lst nhdat)
|
||||
@$(subst /,\,cd $(SRC))
|
||||
|
||||
$(U)dlb_main.exe: $(DLBOBJS)
|
||||
$(LINK) $(LFLAGS) -o$@ $(DLBOBJS)
|
||||
$(U)dlb_main.exe: $(DLBOBJS) $(HACKLIB)
|
||||
$(LINK) $(LFLAGS) -o$@ $(DLBOBJS) $(HACKLIB)
|
||||
|
||||
$(O)dlb_main.o: $(U)dlb_main.c $(INCL)/config.h $(DLB_H)
|
||||
$(CC) $(cflags) -o$@ $(U)dlb_main.c
|
||||
@@ -981,6 +999,7 @@ endif
|
||||
$(subst /,\,if exist $(WSHR)/monthin.txt del $(WSHR)/monthin.txt)
|
||||
$(subst /,\,if exist $(WSHR)/objthin.txt del $(WSHR)/objthin.txt)
|
||||
$(subst /,\,if exist $(WSHR)/oththin.txt del $(WSHR)/oththin.txt)
|
||||
$(subst /,\,if exist $(O)hacklib.a del $(O)hacklib.a)
|
||||
|
||||
#==========================================
|
||||
# Create directory for holding object files
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
extern "C" {
|
||||
#include "config.h"
|
||||
#define CPPREGEX_C
|
||||
#include "extern.h"
|
||||
//#include "extern.h"
|
||||
} // extern "C"
|
||||
|
||||
|
||||
|
||||
+61
-41
@@ -188,6 +188,9 @@ SYSOBJ = $(TARGETPFX)ioctl.o $(TARGETPFX)unixmain.o $(TARGETPFX)unixtty.o \
|
||||
#CFLAGS = -O -I../include
|
||||
#LFLAGS =
|
||||
|
||||
AR = ar
|
||||
ARFLAGS = rcs
|
||||
|
||||
# The Qt and Be window systems are written in C++, while the rest of
|
||||
# NetHack is standard C. If using Qt, uncomment the LINK line here to get
|
||||
# the C++ libraries linked in.
|
||||
@@ -210,6 +213,8 @@ TARGET_LFLAGS = $(LFLAGS)
|
||||
TARGET_CXX = $(CXX)
|
||||
TARGET_CXXFLAGS = $(CXXFLAGS)
|
||||
TARGET_LIBS = $(LIBS)
|
||||
TARGET_AR = $(AR)
|
||||
TARGET_ARFLAGS = $(ARFLAGS)
|
||||
|
||||
# we specify C preprocessor flags via CFLAGS; files built with default rules
|
||||
# might include $(CPPFLAGS) which could get a value from user's environment;
|
||||
@@ -478,6 +483,10 @@ AT = $(AT_V$(QUIETCC))
|
||||
PREGAME=@true
|
||||
PACKAGE=@true
|
||||
|
||||
HACKLIBSRC = hacklib.c
|
||||
HACKLIBOBJS = hacklib.o
|
||||
HACKLIB = hacklib.a
|
||||
|
||||
MAKEDEFS = ../util/makedefs
|
||||
|
||||
# -lm required by lua
|
||||
@@ -493,24 +502,23 @@ HACK_H = ../src/hack.h-t
|
||||
# all .c that are part of the main NetHack program and are not operating- or
|
||||
# windowing-system specific. Do not include date.c in this list.
|
||||
HACKCSRC = allmain.c alloc.c apply.c artifact.c attrib.c ball.c bones.c \
|
||||
botl.c coloratt.c cmd.c dbridge.c decl.c detect.c dig.c display.c \
|
||||
dlb.c do.c \
|
||||
do_name.c do_wear.c dog.c dogmove.c dokick.c dothrow.c drawing.c \
|
||||
dungeon.c eat.c end.c engrave.c exper.c explode.c extralev.c \
|
||||
files.c fountain.c hack.c hacklib.c \
|
||||
insight.c invent.c isaac64.c light.c \
|
||||
botl.c calendar.c cmd.c coloratt.c dbridge.c decl.c detect.c dig.c display.c \
|
||||
dlb.c do.c do_name.c do_wear.c dog.c dogmove.c dokick.c dothrow.c \
|
||||
drawing.c dungeon.c eat.c end.c engrave.c exper.c explode.c \
|
||||
extralev.c files.c fountain.c hack.c hacklib.c \
|
||||
getpos.c insight.c invent.c isaac64.c light.c \
|
||||
lock.c mail.c makemon.c mcastu.c mdlib.c mhitm.c \
|
||||
mhitu.c minion.c mklev.c mkmap.c mkmaze.c mkobj.c mkroom.c mon.c \
|
||||
mondata.c monmove.c monst.c mplayer.c mthrowu.c muse.c music.c \
|
||||
nhlua.c nhlsel.c nhlobj.c nhmd4.c o_init.c objects.c objnam.c \
|
||||
options.c pager.c pickup.c pline.c polyself.c potion.c pray.c \
|
||||
priest.c quest.c questpgr.c read.c rect.c region.c restore.c \
|
||||
rip.c rnd.c role.c rumors.c save.c sfstruct.c \
|
||||
shk.c shknam.c sit.c sounds.c \
|
||||
sp_lev.c spell.c steal.c steed.c symbols.c sys.c teleport.c \
|
||||
priest.c quest.c questpgr.c read.c rect.c region.c report.c restore.c \
|
||||
rip.c rnd.c role.c rumors.c save.c selvar.c sfstruct.c \
|
||||
shk.c shknam.c sit.c sounds.c sp_lev.c spell.c stairs.c steal.c steed.c \
|
||||
strutil.c symbols.c sys.c teleport.c \
|
||||
timeout.c topten.c track.c trap.c u_init.c utf8map.c \
|
||||
uhitm.c vault.c version.c vision.c weapon.c were.c wield.c \
|
||||
windows.c wizard.c worm.c worn.c write.c zap.c
|
||||
windows.c wizard.c wizcmds.c worm.c worn.c write.c zap.c
|
||||
|
||||
# all operating-system-dependent .c (for dependencies and such)
|
||||
SYSCSRC = ../sys/share/pcmain.c ../sys/share/pcsys.c \
|
||||
@@ -536,10 +544,10 @@ CHAINOBJ = $(TARGETPFX)wc_chainin.o $(TARGETPFX)wc_chainout.o \
|
||||
$(TARGETPFX)wc_trace.o
|
||||
|
||||
# .c files for this version (for date.h)
|
||||
VERSOURCES = $(HACKCSRC) $(SYSSRC) $(WINSRC) $(CHAINSRC) $(GENCSRC)
|
||||
VERSOURCES = $(HACKCSRC) $(HACKLIBSRC) $(SYSSRC) $(WINSRC) $(CHAINSRC) $(GENCSRC)
|
||||
|
||||
# .c files for all versions using this Makefile (for lint and tags)
|
||||
CSOURCES = $(HACKCSRC) $(SYSCSRC) $(WINCSRC) $(CHAINSRC) $(GENCSRC)
|
||||
CSOURCES = $(HACKCSRC) $(HACKLIBSRC) $(SYSCSRC) $(WINCSRC) $(CHAINSRC) $(GENCSRC)
|
||||
|
||||
|
||||
# all .h files except date.h, which would
|
||||
@@ -552,8 +560,8 @@ HACKINCL = align.h artifact.h artilist.h attrib.h botl.h \
|
||||
func_tab.h global.h warnings.h hack.h lint.h mextra.h mfndpos.h \
|
||||
micro.h mkroom.h monattk.h mondata.h monflag.h monst.h monsters.h \
|
||||
nhmd4.h obj.h objects.h objclass.h optlist.h patchlevel.h pcconf.h \
|
||||
permonst.h prop.h rect.h region.h sym.h defsym.h rm.h sp_lev.h \
|
||||
spell.h sndprocs.h seffects.h sys.h tcap.h timeout.h \
|
||||
permonst.h prop.h rect.h region.h selvar.h sym.h defsym.h rm.h sp_lev.h \
|
||||
spell.h sndprocs.h seffects.h stairs.h sys.h tcap.h timeout.h \
|
||||
tradstdc.h trap.h unixconf.h vision.h vmsconf.h wintty.h wincurs.h \
|
||||
winX.h winprocs.h wintype.h you.h youprop.h cstd.h
|
||||
|
||||
@@ -569,8 +577,8 @@ HOSTOBJ = $(FIRSTOBJ) alloc.o drawing.o
|
||||
HOBJ = $(TARGETPFX)allmain.o $(TARGETPFX)alloc.o \
|
||||
$(TARGETPFX)apply.o $(TARGETPFX)artifact.o $(TARGETPFX)attrib.o \
|
||||
$(TARGETPFX)ball.o $(TARGETPFX)bones.o $(TARGETPFX)botl.o \
|
||||
$(TARGETPFX)coloratt.o \
|
||||
$(TARGETPFX)cmd.o $(TARGETPFX)dbridge.o $(TARGETPFX)decl.o \
|
||||
$(TARGETPFX)calendar.o \
|
||||
$(TARGETPFX)cmd.o $(TARGETPFX)coloratt.o $(TARGETPFX)dbridge.o $(TARGETPFX)decl.o \
|
||||
$(TARGETPFX)detect.o $(TARGETPFX)dig.o $(TARGETPFX)display.o \
|
||||
$(TARGETPFX)dlb.o $(TARGETPFX)do.o $(TARGETPFX)do_name.o \
|
||||
$(TARGETPFX)do_wear.o $(TARGETPFX)dog.o $(TARGETPFX)dogmove.o \
|
||||
@@ -578,7 +586,7 @@ HOBJ = $(TARGETPFX)allmain.o $(TARGETPFX)alloc.o \
|
||||
$(TARGETPFX)dungeon.o $(TARGETPFX)eat.o $(TARGETPFX)end.o \
|
||||
$(TARGETPFX)engrave.o $(TARGETPFX)exper.o $(TARGETPFX)explode.o \
|
||||
$(TARGETPFX)extralev.o $(TARGETPFX)files.o $(TARGETPFX)fountain.o \
|
||||
$(TARGETPFX)hack.o $(TARGETPFX)hacklib.o $(TARGETPFX)insight.o \
|
||||
$(TARGETPFX)getpos.o $(TARGETPFX)hack.o $(TARGETPFX)insight.o \
|
||||
$(TARGETPFX)invent.o $(TARGETPFX)isaac64.o $(TARGETPFX)light.o \
|
||||
$(TARGETPFX)lock.o $(TARGETPFX)mail.o $(TARGETPFX)makemon.o \
|
||||
$(TARGETPFX)mcastu.o $(TARGETPFX)mdlib.o \
|
||||
@@ -594,22 +602,23 @@ HOBJ = $(TARGETPFX)allmain.o $(TARGETPFX)alloc.o \
|
||||
$(TARGETPFX)pickup.o $(TARGETPFX)pline.o $(TARGETPFX)polyself.o \
|
||||
$(TARGETPFX)potion.o $(TARGETPFX)pray.o $(TARGETPFX)priest.o \
|
||||
$(TARGETPFX)quest.o $(TARGETPFX)questpgr.o $(TARGETPFX)read.o \
|
||||
$(TARGETPFX)rect.o $(TARGETPFX)region.o $(TARGETPFX)restore.o \
|
||||
$(TARGETPFX)rip.o $(TARGETPFX)rnd.o $(TARGETPFX)role.o \
|
||||
$(TARGETPFX)rumors.o $(TARGETPFX)save.o $(TARGETPFX)sfstruct.o \
|
||||
$(TARGETPFX)rect.o $(TARGETPFX)region.o $(TARGETPFX)report.o \
|
||||
$(TARGETPFX)restore.o $(TARGETPFX)rip.o $(TARGETPFX)rnd.o \
|
||||
$(TARGETPFX)role.o $(TARGETPFX)rumors.o $(TARGETPFX)save.o \
|
||||
$(TARGETPFX)selvar.o $(TARGETPFX)sfstruct.o \
|
||||
$(TARGETPFX)shk.o $(TARGETPFX)shknam.o $(TARGETPFX)sit.o \
|
||||
$(TARGETPFX)sounds.o $(TARGETPFX)sp_lev.o $(TARGETPFX)spell.o \
|
||||
$(TARGETPFX)sounds.o $(TARGETPFX)sp_lev.o $(TARGETPFX)spell.o $(TARGETPFX)stairs.o \
|
||||
$(TARGETPFX)symbols.o $(TARGETPFX)sys.o $(TARGETPFX)steal.o \
|
||||
$(TARGETPFX)steed.o $(TARGETPFX)teleport.o $(TARGETPFX)timeout.o \
|
||||
$(TARGETPFX)topten.o $(TARGETPFX)track.o $(TARGETPFX)trap.o \
|
||||
$(TARGETPFX)steed.o $(TARGETPFX)strutil.o $(TARGETPFX)teleport.o \
|
||||
$(TARGETPFX)timeout.o $(TARGETPFX)topten.o $(TARGETPFX)track.o $(TARGETPFX)trap.o \
|
||||
$(TARGETPFX)u_init.o $(TARGETPFX)uhitm.o $(TARGETPFX)utf8map.o \
|
||||
$(TARGETPFX)vault.o $(TARGETPFX)vision.o $(TARGETPFX)weapon.o \
|
||||
$(TARGETPFX)were.o $(TARGETPFX)wield.o $(TARGETPFX)windows.o \
|
||||
$(TARGETPFX)wizard.o $(TARGETPFX)worm.o $(TARGETPFX)worn.o \
|
||||
$(TARGETPFX)wizard.o $(TARGETPFX)wizcmds.o $(TARGETPFX)worm.o $(TARGETPFX)worn.o \
|
||||
$(TARGETPFX)write.o $(TARGETPFX)zap.o \
|
||||
$(REGEXOBJ) $(RANDOBJ) $(SYSOBJ) $(WINOBJ) $(HINTOBJ) $(SNDLIBOBJ) \
|
||||
$(TARGETPFX)version.o
|
||||
#
|
||||
|
||||
DATE_O = $(TARGETPFX)date.o
|
||||
|
||||
# the .o files from the HACKCSRC, SYSSRC, and WINSRC lists
|
||||
@@ -624,41 +633,46 @@ pregame:
|
||||
$(GAME): pregame $(MAKEDEFS) $(LUALIB) $(WAVS) $(SYSTEM)
|
||||
@echo "$(GAME) is up to date."
|
||||
|
||||
Sysunix: $(HOSTOBJ) $(HOBJ) $(DATE_O) $(BUILDMORE) Makefile
|
||||
Sysunix: $(HOSTOBJ) $(HOBJ) $(TARGETPFX)$(HACKLIB) $(DATE_O) $(BUILDMORE) Makefile
|
||||
@echo "Linking $(GAME)."
|
||||
$(AT)$(TARGET_LINK) $(TARGET_LFLAGS) -o $(GAMEBIN) \
|
||||
$(HOBJ) $(DATE_O) $(WINLIB) $(TARGET_LIBS) $(LUALIBS) \
|
||||
$(AUTOLIBS)
|
||||
$(HOBJ) $(DATE_O) $(TARGETPFX)$(HACKLIB) $(WINLIB) \
|
||||
$(TARGET_LIBS) $(LUALIBS) $(AUTOLIBS)
|
||||
@touch Sysunix
|
||||
|
||||
Sys3B2: $(HOSTOBJ) $(HOBJ) $(DATE_O) $(BUILDMORE) Makefile
|
||||
Sys3B2: $(HOSTOBJ) $(HOBJ) $(TARGETPFX)$(HACKLIB) $(DATE_O) $(BUILDMORE) Makefile
|
||||
@echo "Linking $(GAME)."
|
||||
$(AT)$(TARGET_LINK) $(TARGET_LFLAGS) -o $(GAMEBIN) \
|
||||
$(HOBJ) $(DATE_O) $(WINLIB) $(LUALIBS) -lmalloc
|
||||
$(HOBJ) $(DATE_O) $(TARGETPFX)$(HACKLIB) $(WINLIB) \
|
||||
$(LUALIBS) -lmalloc
|
||||
@touch Sys3B2
|
||||
|
||||
Sysatt: $(HOSTOBJ) $(HOBJ) $(DATE_O) $(BUILDMORE) Makefile
|
||||
Sysatt: $(HOSTOBJ) $(HOBJ) $(TARGETPFX)$(HACKLIB) $(DATE_O) $(BUILDMORE) Makefile
|
||||
@echo "Loading $(GAME)."
|
||||
$(AT)$(LD) $(TARGET_LFLAGS) /lib/crt0s.o /lib/shlib.ifile \
|
||||
-o $(GAMEBIN) $(HOSTOBJ) $(HOBJ) $(DATE_O) $(LUALIBS)
|
||||
-o $(GAMEBIN) $(HOSTOBJ) $(HOBJ) $(DATE_O) $(TARGETPFX)$(HACKLIB) \
|
||||
$(LUALIBS)
|
||||
@touch Sysatt
|
||||
|
||||
Systos: $(HOSTOBJ) $(HOBJ) $(DATE_O) $(BUILDMORE) Makefile
|
||||
Systos: $(HOSTOBJ) $(HOBJ) $(TARGETPFX)$(HACKLIB) $(DATE_O) $(BUILDMORE) Makefile
|
||||
@echo "Linking $(GAME)."
|
||||
$(AT)$(TARGET_LINK) $(TARGET_LFLAGS) -o $(GAMEBIN) \
|
||||
$(HOBJ) $(DATE_O) $(WINLIB) $(LUALIBS)
|
||||
$(HOBJ) $(DATE_O) $(TARGETPFX)$(HACKLIB) \
|
||||
$(WINLIB) $(LUALIBS)
|
||||
@touch Systos
|
||||
|
||||
SysV-AT: DUMB.Setup $(HOSTOBJ) $(HOBJ) $(DATE_O) $(BUILDMORE) Makefile
|
||||
SysV-AT: DUMB.Setup $(HOSTOBJ) $(HOBJ) $(TARGETPFX)$(HACKLIB) $(DATE_O) $(BUILDMORE) Makefile
|
||||
@echo "Linking $(GAME)."
|
||||
$(AT)$(TARGET_LINK) $(TARGET_LFLAGS) -o $(GAMEBIN) \
|
||||
$(HOBJ) $(DATE_O) $(WINLIB) $(LUALIBS)
|
||||
$(HOBJ) $(DATE_O) $(TARGETPFX)$(HACKLIB) \
|
||||
$(WINLIB) $(LUALIBS)
|
||||
@touch SysV-AT
|
||||
|
||||
SysBe: $(HOSTOBJ) $(HOBJ) $(DATE_O) $(BUILDMORE) Makefile
|
||||
SysBe: $(HOSTOBJ) $(HOBJ) $(TARGETPFX)$(HACKLIB) $(DATE_O) $(BUILDMORE) Makefile
|
||||
@echo "Linking $(GAME)."
|
||||
$(AT)$(TARGET_LINK) $(TARGET_LFLAGS) -o $(GAME) \
|
||||
$(HOBJ) $(DATE_O) $(WINLIB) $(TARGET_LIBS) $(LUALIBS)
|
||||
$(HOBJ) $(DATE_O) $(TARGETPFX)$(HACKLIB) \
|
||||
$(WINLIB) $(TARGET_LIBS) $(LUALIBS)
|
||||
@xres -o $(GAME) ../win/BeOS/nethack.rsrc
|
||||
@mimeset -f $(GAME)
|
||||
@touch SysBe
|
||||
@@ -730,6 +744,12 @@ $(MAKEDEFS): $(FIRSTOBJ) \
|
||||
tile.c: ../win/share/tilemap.c $(HACK_H)
|
||||
@( cd ../util ; $(MAKE) ../src/tile.c )
|
||||
|
||||
#
|
||||
# hacklib (a library of utility routines)
|
||||
#
|
||||
|
||||
hacklib.a: hacklib.o
|
||||
$(AR) $(ARFLAGS) $@ hacklib.o
|
||||
|
||||
../win/gnome/gn_rip.h: ../win/X11/rip.xpm
|
||||
cp ../win/X11/rip.xpm ../win/gnome/gn_rip.h
|
||||
@@ -738,7 +758,7 @@ $(TARGETPFX)sfstruct.o: sfstruct.c $(HACK_H)
|
||||
|
||||
# date.c should be recompiled any time any of the source or include code
|
||||
# is modified.
|
||||
$(TARGETPFX)date.o: date.c $(HACK_H) $(HACKCSRC) $(HOBJ)
|
||||
$(TARGETPFX)date.o: date.c $(HACK_H) $(HACKCSRC) $(HOBJ) $(TARGETPFX)$(HACKLIB)
|
||||
$(TARGET_CC) $(TARGET_CFLAGS) $(GITHASH) $(GITBRANCH) -c -o $@ date.c
|
||||
|
||||
# date.h should be remade any time any of the source or include code
|
||||
@@ -774,7 +794,7 @@ clean:
|
||||
true; $(CLEANMORE)
|
||||
|
||||
spotless: clean
|
||||
-rm -f a.out core $(GAMEBIN) Sys*
|
||||
-rm -f a.out core $(HACKLIB) $(GAMEBIN) Sys*
|
||||
-rm -f ../include/nhlua.h
|
||||
-rm -f ../include/date.h #created but no longer used, at least by core
|
||||
-rm -f ../include/onames.h ../include/pm.h #obsolete generated files
|
||||
|
||||
+28
-13
@@ -191,6 +191,11 @@ OALLOC = $(OBJDIR)/alloc.o panic.o
|
||||
CDATE = ../src/date.c
|
||||
ODATE = $(OBJDIR)/date.o
|
||||
|
||||
# hacklib utility routines
|
||||
HACKLIB = $(OBJDIR)/hacklib.a
|
||||
HACKLIBSRC = ../src/hacklib.c
|
||||
HACKLIBOBJ = $(OBJDIR)/hacklib.o panic.o
|
||||
|
||||
# object files for makedefs
|
||||
MAKEOBJS = makedefs.o $(OMONOBJ) $(ODATE) $(OALLOC)
|
||||
|
||||
@@ -213,11 +218,12 @@ TARGET_CLINK = $(CLINK)
|
||||
TARGET_LFLAGS = $(LFLAGS)
|
||||
TARGET_CXX = $(CXX)
|
||||
TARGET_CXXFLAGS = $(CXXFLAGS)
|
||||
TARGET_AR = $(AR)
|
||||
|
||||
# dependencies for makedefs
|
||||
#
|
||||
makedefs: $(MAKEOBJS) mdgrep.h
|
||||
$(CLINK) $(LFLAGS) -o makedefs $(MAKEOBJS)
|
||||
makedefs: $(HACKLIB) $(MAKEOBJS) mdgrep.h
|
||||
$(CLINK) $(LFLAGS) -o makedefs $(MAKEOBJS) $(HACKLIB)
|
||||
|
||||
|
||||
# note: the headers listed here are maintained manually rather than via
|
||||
@@ -233,6 +239,8 @@ makedefs.o: makedefs.c ../src/mdlib.c $(CONFIG_H) \
|
||||
../include/dlb.h ../include/patchlevel.h mdgrep.h
|
||||
$(CC) $(CFLAGS) $(CSTD) -c makedefs.c -o $@
|
||||
|
||||
$(OBJDIR)/hacklib.o: $(HACKLIBSRC)
|
||||
|
||||
# Don't require perl to build; that is why mdgrep.h is spelled wrong below.
|
||||
mdgreph: mdgrep.pl
|
||||
perl mdgrep.pl
|
||||
@@ -252,6 +260,9 @@ lintdefs:
|
||||
../include/date.h::
|
||||
@( cd ../src ; $(MAKE) ../include/date.h )
|
||||
|
||||
$(HACKLIB): $(CONFIG_H) $(HACKLIBSRC) panic.o
|
||||
@( cd ../src ; $(MAKE) hacklib.a )
|
||||
|
||||
# support code used by several of the utility programs (but not makedefs)
|
||||
panic.o: panic.c $(CONFIG_H)
|
||||
$(CC) $(CFLAGS) $(CSTD) -c panic.c -o $@
|
||||
@@ -275,8 +286,8 @@ $(TARGETPFX)recover.o: recover.c $(CONFIG_H)
|
||||
|
||||
# dependencies for dlb
|
||||
#
|
||||
dlb: $(DLBOBJS)
|
||||
$(CLINK) $(LFLAGS) -o dlb $(DLBOBJS) $(LIBS)
|
||||
dlb: $(DLBOBJS) $(HACKLIB)
|
||||
$(CLINK) $(LFLAGS) -o dlb $(DLBOBJS) $(HACKLIB) $(LIBS)
|
||||
|
||||
dlb_main.o: dlb_main.c $(CONFIG_H) ../include/dlb.h
|
||||
$(CC) $(CFLAGS) $(CSTD) -c dlb_main.c -o $@
|
||||
@@ -295,30 +306,34 @@ gif2txt: $(GIFREADERS) $(TEXT_IO)
|
||||
txt2ppm: $(PPMWRITERS) $(TEXT_IO)
|
||||
$(CLINK) $(LFLAGS) -o txt2ppm $(PPMWRITERS) $(TEXT_IO) $(LIBS)
|
||||
|
||||
tile2x11: tile2x11.o $(TEXT_IO)
|
||||
$(CLINK) $(LFLAGS) -o tile2x11 tile2x11.o $(TEXT_IO) $(LIBS)
|
||||
tile2x11: tile2x11.o $(TEXT_IO) $(HACKLIB)
|
||||
$(CLINK) $(LFLAGS) -o tile2x11 tile2x11.o $(TEXT_IO) \
|
||||
$(HACKLIB) $(LIBS)
|
||||
|
||||
tile2img.ttp: tile2img.o bitmfile.o $(TEXT_IO)
|
||||
$(CLINK) $(LFLAGS) -o tile2img.ttp tile2img.o bitmfile.o \
|
||||
$(TEXT_IO) $(LIBS)
|
||||
|
||||
tile2bmp: tile2bmp.o $(TEXT_IO)
|
||||
$(CLINK) $(LFLAGS) -o tile2bmp tile2bmp.o $(TEXT_IO)
|
||||
tile2bmp: tile2bmp.o $(TEXT_IO) $(HACKLIB)
|
||||
$(CLINK) $(LFLAGS) -o tile2bmp tile2bmp.o $(TEXT_IO) $(HACKLIB)
|
||||
|
||||
xpm2img.ttp: xpm2img.o bitmfile.o
|
||||
$(CLINK) $(LFLAGS) -o xpm2img.ttp xpm2img.o bitmfile.o $(LIBS)
|
||||
|
||||
tile2beos: tile2beos.o $(TEXT_IO)
|
||||
$(CXXLINK) $(LFLAGS) -o tile2beos tile2beos.o $(TEXT_IO) -lbe
|
||||
tile2beos: tile2beos.o $(TEXT_IO) $(HACKLIB)
|
||||
$(CXXLINK) $(LFLAGS) -o tile2beos tile2beos.o \
|
||||
$(TEXT_IO) $(HACKLIB) -lbe
|
||||
|
||||
#--compiling and linking in one step leaves extra debugging files (in their
|
||||
# own subdirectories!) on OSX; compile and link separately to suppress
|
||||
# that without mucking about with extra OS-specific CFLAGS and/or LFLAGS
|
||||
#tilemap: ../win/share/tilemap.c $(HACK_H)
|
||||
# $(CC) $(CFLAGS) $(LFLAGS) -o tilemap ../win/share/tilemap.c $(LIBS)
|
||||
tilemap: tilemap.o $(OBJDIR)/objects.o $(OBJDIR)/monst.o $(OBJDIR)/drawing.o
|
||||
tilemap: tilemap.o $(OBJDIR)/objects.o $(OBJDIR)/monst.o $(OBJDIR)/drawing.o \
|
||||
$(HACKLIB)
|
||||
$(CLINK) $(LFLAGS) -o tilemap tilemap.o $(OBJDIR)/objects.o \
|
||||
$(OBJDIR)/monst.o $(OBJDIR)/drawing.o $(LIBS)
|
||||
$(OBJDIR)/monst.o $(OBJDIR)/drawing.o $(HACKLIB) \
|
||||
$(LIBS)
|
||||
../src/tile.c: tilemap
|
||||
./tilemap
|
||||
|
||||
@@ -426,6 +441,6 @@ clean: clean-fixup
|
||||
-rm -f *.o
|
||||
|
||||
spotless: clean
|
||||
-rm -f makedefs recover dlb
|
||||
-rm -f makedefs recover dlb $(HACKLIB)
|
||||
-rm -f gif2txt txt2ppm tile2x11 tile2img.ttp xpm2img.ttp \
|
||||
tilemap tileedit tile2bmp uudecode
|
||||
|
||||
@@ -22,9 +22,9 @@ $(TARGETPFX)tile.o : tile.c
|
||||
$(TARGETPFX)exceptn.o : ../lib/djgpp/djgpp-patch/src/libc/go32/exceptn.S
|
||||
$(TARGET_CC) -c -o $@ ../lib/djgpp/djgpp-patch/src/libc/go32/exceptn.S
|
||||
$(TARGET_AR) ru ../lib/djgpp/i586-pc-msdosdjgpp/lib/libc.a $(TARGETPFX)exceptn.o
|
||||
$(GAMEBIN) : $(HOBJ) $(LUACROSSLIB)
|
||||
$(GAMEBIN) : $(HOBJ) $(HACKLIB) $(LUACROSSLIB)
|
||||
$(TARGET_LINK) $(TARGET_LFLAGS) -o $(GAMEBIN) \
|
||||
$(HOBJ) $(WINLIB) $(TARGET_LIBS)
|
||||
$(HOBJ) $(HACKLIB) $(WINLIB) $(TARGET_LIBS)
|
||||
$(DOSFONT)/ter-u16b.psf: $(FONTTOP)/ter-u16b.bdf $(DOSFONT)/nh-u16b.bdf $(DOSFONT)/makefont.lua $(LUABIN)
|
||||
$(LUABIN) $(DOSFONT)/makefont.lua $(FONTTOP)/ter-u16b.bdf $(DOSFONT)/nh-u16b.bdf $@
|
||||
$(DOSFONT)/ter-u16v.psf: $(FONTTOP)/ter-u16v.bdf $(DOSFONT)/nh-u16v.bdf $(DOSFONT)/makefont.lua $(LUABIN)
|
||||
@@ -41,6 +41,8 @@ $(DOSFONT)/ter-u28b.psf: $(FONTTOP)/ter-u28b.bdf $(DOSFONT)/nh-u28b.bdf $(DOSFON
|
||||
$(LUABIN) $(DOSFONT)/makefont.lua $(FONTTOP)/ter-u28b.bdf $(DOSFONT)/nh-u28b.bdf $@
|
||||
$(DOSFONT)/ter-u32b.psf: $(FONTTOP)/ter-u32b.bdf $(DOSFONT)/nh-u32b.bdf $(DOSFONT)/makefont.lua $(LUABIN)
|
||||
$(LUABIN) $(DOSFONT)/makefont.lua $(FONTTOP)/ter-u32b.bdf $(DOSFONT)/nh-u32b.bdf $@
|
||||
$(TARGETPFX)hacklib.a: $(TARGETPFX)hacklib.o
|
||||
$(TARGET_AR) $(TARGET_ARFLAGS) $@ $(TARGETPFX)hacklib.o
|
||||
#
|
||||
.PHONY: dodata dospkg dosfonts
|
||||
dosfonts: $(FONTTARGETS)
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
#===============-=================================================
|
||||
# NetHack 3.7 include/cross-pre1. $NHDT-Date: 1597332785 2020/08/13 15:33:05 $ $NHDT-Branch: NetHack-3.7 $
|
||||
#
|
||||
# Cross-compiling -PRE section 1
|
||||
#
|
||||
|
||||
ifdef CROSS_TO_MSDOS
|
||||
CROSS=1
|
||||
BUILD_TARGET_LUA=1
|
||||
BUILD_PDCURSES=1
|
||||
CROSS_SHARED=1
|
||||
override TARGET = msdos
|
||||
override TARGETDIR=../targets/$(TARGET)
|
||||
override TARGETPFX = $(TARGETDIR)/
|
||||
override TARGET_LIBS=
|
||||
endif
|
||||
|
||||
ifdef CROSS_TO_WASM
|
||||
CROSS=1
|
||||
BUILD_TARGET_LUA=1
|
||||
HACKDIR=/
|
||||
PREFIX=
|
||||
override TARGET = wasm
|
||||
override TARGETDIR=../targets/$(TARGET)
|
||||
override TARGETPFX = $(TARGETDIR)/
|
||||
override TARGET_LIBS=
|
||||
endif
|
||||
|
||||
ifdef CROSS_TO_MIPS
|
||||
CROSS=1
|
||||
BUILD_TARGET_LUA=1
|
||||
BUILD_TARGET_NCURSES=1
|
||||
HACKDIR=/
|
||||
PREFIX=
|
||||
override TARGET = mips
|
||||
override TARGETDIR=../targets/$(TARGET)
|
||||
override TARGETPFX = $(TARGETDIR)/
|
||||
override TARGET_LIBS=
|
||||
endif
|
||||
|
||||
ifdef CROSS
|
||||
override PREGAME=
|
||||
override BUILDMORE=
|
||||
override CLEANMORE=
|
||||
override PACKAGE=
|
||||
endif
|
||||
# End of cross-compiling -PRE section 1
|
||||
#===============-=================================================
|
||||
|
||||
@@ -1,50 +1,9 @@
|
||||
#===============-=================================================
|
||||
# NetHack 3.7 include/cross-pre $NHDT-Date: 1597332785 2020/08/13 15:33:05 $ $NHDT-Branch: NetHack-3.7 $
|
||||
# NetHack 3.7 include/cross-pre2 $NHDT-Date: 1597332785 2020/08/13 15:33:05 $ $NHDT-Branch: NetHack-3.7 $
|
||||
#
|
||||
# Cross-compiling -PRE section
|
||||
# Cross-compiling -PRE section 2
|
||||
#
|
||||
|
||||
ifdef CROSS_TO_MSDOS
|
||||
CROSS=1
|
||||
BUILD_TARGET_LUA=1
|
||||
BUILD_PDCURSES=1
|
||||
CROSS_SHARED=1
|
||||
override TARGET = msdos
|
||||
override TARGETDIR=../targets/$(TARGET)
|
||||
override TARGETPFX = $(TARGETDIR)/
|
||||
override TARGET_LIBS=
|
||||
endif
|
||||
|
||||
ifdef CROSS_TO_WASM
|
||||
CROSS=1
|
||||
BUILD_TARGET_LUA=1
|
||||
HACKDIR=/
|
||||
PREFIX=
|
||||
override TARGET = wasm
|
||||
override TARGETDIR=../targets/$(TARGET)
|
||||
override TARGETPFX = $(TARGETDIR)/
|
||||
override TARGET_LIBS=
|
||||
endif
|
||||
|
||||
ifdef CROSS_TO_MIPS
|
||||
CROSS=1
|
||||
BUILD_TARGET_LUA=1
|
||||
BUILD_TARGET_NCURSES=1
|
||||
HACKDIR=/
|
||||
PREFIX=
|
||||
override TARGET = mips
|
||||
override TARGETDIR=../targets/$(TARGET)
|
||||
override TARGETPFX = $(TARGETDIR)/
|
||||
override TARGET_LIBS=
|
||||
endif
|
||||
|
||||
ifdef CROSS
|
||||
override PREGAME=
|
||||
override BUILDMORE=
|
||||
override CLEANMORE=
|
||||
override PACKAGE=
|
||||
endif
|
||||
|
||||
ifdef BUILD_TARGET_LUA
|
||||
#===============-=================================================
|
||||
# LUA library
|
||||
@@ -27,7 +27,7 @@ ifeq ($(MAKELEVEL),0)
|
||||
PRECHECK+=checkmakefiles
|
||||
# all files included from this hints file get listed
|
||||
# in HINTSINCLNAMES (without suffix and without a path)
|
||||
HINTSINCLNAMES := compiler cross-pre cross-post \
|
||||
HINTSINCLNAMES := compiler cross-pre1 cross-pre2 cross-post \
|
||||
gbdates-pre gbdates-post \
|
||||
multiw-1 multiw-2 misc \
|
||||
multisnd1-pre multisnd2-pre multisnd-post
|
||||
@@ -43,6 +43,10 @@ endif
|
||||
GAMEUID = $(USER)
|
||||
GAMEGRP = games
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
#-INCLUDE cross-pre1.370
|
||||
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# You shouldn't need to change anything below here (in the hints file; if
|
||||
# you're reading this in Makefile augmented by hints, that may not be true).
|
||||
@@ -366,7 +370,7 @@ CHGRP=true
|
||||
# manpages directory
|
||||
MANDIR=/usr/share/man/man6
|
||||
#
|
||||
#-INCLUDE cross-pre.370
|
||||
#-INCLUDE cross-pre2.370
|
||||
#
|
||||
|
||||
#
|
||||
|
||||
@@ -27,7 +27,7 @@ ifeq ($(MAKELEVEL),0)
|
||||
PRECHECK+=checkmakefiles
|
||||
# all files included from this hints file get listed
|
||||
# in HINTSINCLNAMES (without suffix and without a path)
|
||||
HINTSINCLNAMES := compiler cross-pre cross-post \
|
||||
HINTSINCLNAMES := compiler cross-pre1 cross-pre2 cross-post \
|
||||
gbdates-pre gbdates-post \
|
||||
multiw-1 multiw-2 misc \
|
||||
multisnd1-pre multisnd2-pre multisnd-post
|
||||
@@ -55,6 +55,8 @@ endif
|
||||
# you're reading this in Makefile augmented by hints, that may not be true).
|
||||
#
|
||||
|
||||
#-INCLUDE cross-pre1.370
|
||||
|
||||
#-INCLUDE multiw-2.370
|
||||
|
||||
# compiler.370 contains compiler detection and adjustments common
|
||||
@@ -427,7 +429,7 @@ SYSCONFENSURE = (if ! test -f $(INSTDIR)/sysconf ; then \
|
||||
# Install.Qt mentions a patch for macos - it's not there (it seems to be in the Qt binary
|
||||
# package under the docs directory).
|
||||
#
|
||||
#-INCLUDE cross-pre.370
|
||||
#-INCLUDE cross-pre2.370
|
||||
#
|
||||
#
|
||||
#-INCLUDE gbdates-pre.370
|
||||
|
||||
+23
-23
@@ -147,23 +147,22 @@ HACK_H = $(SRC)hack.h-t
|
||||
# all .c that are part of the main NetHack program and are not operating- or
|
||||
# windowing-system specific
|
||||
HACKCSRC = allmain.c alloc.c apply.c artifact.c attrib.c ball.c bones.c \
|
||||
botl.c cmd.c dbridge.c decl.c detect.c dig.c display.c dlb.c do.c \
|
||||
do_name.c do_wear.c dog.c dogmove.c dokick.c dothrow.c drawing.c \
|
||||
dungeon.c eat.c end.c engrave.c exper.c explode.c extralev.c \
|
||||
files.c fountain.c hack.c hacklib.c \
|
||||
botl.c calendar.c cmd.c coloratt.c dbridge.c decl.c detect.c dig.c \
|
||||
display.c dlb.c do.c do_name.c do_wear.c dog.c dogmove.c dokick.c \
|
||||
dothrow.c drawing.c dungeon.c eat.c end.c engrave.c exper.c \
|
||||
explode.c extralev.c files.c fountain.c getpos.c hack.c hacklib.c \
|
||||
insight.c invent.c light.c lock.c \
|
||||
mail.c makemon.c mcastu.c mhitm.c mhitu.c minion.c \
|
||||
mklev.c mkmap.c \
|
||||
mkmaze.c mkobj.c mkroom.c mon.c mondata.c monmove.c monst.c \
|
||||
mplayer.c mthrowu.c muse.c music.c o_init.c objects.c objnam.c \
|
||||
options.c pager.c pickup.c pline.c polyself.c potion.c pray.c \
|
||||
priest.c quest.c questpgr.c read.c rect.c region.c restore.c \
|
||||
rip.c rnd.c role.c \
|
||||
rumors.c save.c shk.c shknam.c sit.c sounds.c sp_lev.c spell.c \
|
||||
steal.c steed.c sys.c teleport.c timeout.c topten.c track.c \
|
||||
trap.c u_init.c \
|
||||
uhitm.c vault.c version.c vision.c weapon.c were.c wield.c \
|
||||
windows.c wizard.c worm.c worn.c write.c zap.c
|
||||
mklev.c mkmap.c mkmaze.c mkobj.c mkroom.c mon.c mondata.c \
|
||||
monmove.c monst.c mplayer.c mthrowu.c muse.c music.c o_init.c \
|
||||
objects.c objnam.c options.c pager.c pickup.c pline.c polyself.c \
|
||||
potion.c pray.c priest.c quest.c questpgr.c read.c rect.c \
|
||||
region.c report.c restore.c rip.c rnd.c role.c rumors.c save.c \
|
||||
selvar.c sfstruct.c shk.c shknam.c sit.c sounds.c sp_lev.c \
|
||||
spell.c stairs.c steal.c steed.c strutil.c sys.c teleport.c \
|
||||
timeout.c topten.c track.c trap.c u_init.c uhitm.c vault.c \
|
||||
version.c vision.c weapon.c were.c wield.c windows.c wizard.c \
|
||||
wizcmds.c worm.c worn.c write.c zap.c
|
||||
|
||||
#-# generated source files (vis_tab.c is gone; tile.c is handled separately
|
||||
#-# via WINxxxSRC)
|
||||
@@ -178,7 +177,7 @@ VERSOURCES = $(HACKCSRC) $(SYSSRC) $(WINSRC) $(RANDSRC) $(GENCSRC)
|
||||
HACKINCL = align.h artifact.h artilist.h attrib.h color.h \
|
||||
config.h config1.h context.h coord.h decl.h defsym.h display.h \
|
||||
dlb.h dungeon.h engrave.h extern.h flag.h func_tab.h global.h \
|
||||
hack.h mextra.h mfndpos.h micro.h mkroom.h \
|
||||
hack.h hacklib.h mextra.h mfndpos.h micro.h mkroom.h \
|
||||
monattk.h mondata.h monflag.h monst.h sym.h obj.h objclass.h \
|
||||
patchlevel.h pcconf.h permonst.h prop.h rect.h \
|
||||
region.h sym.h defsym.h rm.h sp_lev.h spell.h sys.h system.h \
|
||||
@@ -192,11 +191,12 @@ FIRSTOBJ = vmsmisc.obj,vmsfiles.obj,monst.obj,objects.obj
|
||||
|
||||
# split up long list so that we can write pieces of it into nethack.opt
|
||||
HOBJ1 = allmain.obj,alloc.obj,apply.obj,artifact.obj,attrib.obj, \
|
||||
ball.obj,bones.obj,botl.obj,cmd.obj,dbridge.obj,decl.obj, \
|
||||
detect.obj,dig.obj,display.obj,dlb.obj,do.obj,do_name.obj,do_wear.obj
|
||||
ball.obj,bones.obj,botl.obj,calendar.obj,cmd.obj,coloratt.obj, \
|
||||
dbridge.obj,decl.obj,detect.obj,dig.obj,display.obj,dlb.obj, \
|
||||
do.obj,do_name.obj,do_wear.obj
|
||||
HOBJ2 = dog.obj,dogmove.obj,dokick.obj,dothrow.obj,drawing.obj, \
|
||||
dungeon.obj,eat.obj,end.obj,engrave.obj,exper.obj,explode.obj, \
|
||||
extralev.obj,files.obj,fountain.obj,hack.obj,hacklib.obj, \
|
||||
extralev.obj,files.obj,fountain.obj,getpos.obj,hack.obj,hacklib.obj, \
|
||||
insight.obj,invent.obj
|
||||
HOBJ3 = light.obj,lock.obj,mail.obj,makemon.obj,mcastu.obj, \
|
||||
mhitm.obj,mhitu.obj,minion.obj,mklev.obj,mkmap.obj,mkmaze.obj, \
|
||||
@@ -205,11 +205,11 @@ HOBJ4 = mplayer.obj,mthrowu.obj,muse.obj,music.obj,o_init.obj,objnam.obj, \
|
||||
options.obj,pager.obj,pickup.obj,pline.obj,polyself.obj, \
|
||||
potion.obj,pray.obj,priest.obj,quest.obj,questpgr.obj,read.obj
|
||||
HOBJ5 = rect.obj,region.obj,restore.obj,rip.obj,rnd.obj,role.obj, \
|
||||
rumors.obj,save.obj,sfstruct.obj,shk.obj,shknam.obj,sit.obj, \
|
||||
sounds.obj,sp_lev.obj,spell.obj,steal.obj,steed.obj,sys.obj, \
|
||||
rumors.obj,save.obj,selvar.obj,sfstruct.obj,shk.obj,shknam.obj,sit.obj, \
|
||||
sounds.obj,sp_lev.obj,spell.obj,stairs.obj,steal.obj,steed.obj,sys.obj, \
|
||||
teleport.obj,timeout.obj,topten.obj, track.obj,trap.obj
|
||||
HOBJ6 = u_init.obj,uhitm.obj,vault.obj,vision.obj,weapon.obj, \
|
||||
were.obj,wield.obj,windows.obj,wizard.obj,worm.obj,worn.obj, \
|
||||
HOBJ6 = u_init.obj,uhitm.obj,utf8map.obj,vault.obj,vision.obj,weapon.obj, \
|
||||
were.obj,wield.obj,windows.obj,wizard.obj,wizcmds.obj,worm.obj,worn.obj, \
|
||||
write.obj,zap.obj,version.obj
|
||||
HOBJ = $(FIRSTOBJ) $(SYSOBJ) $(WINOBJ) $(RANDOBJ) \
|
||||
$(HOBJ1) $(HOBJ2) $(HOBJ3) $(HOBJ4) $(HOBJ5) $(HOBJ6)
|
||||
|
||||
@@ -420,10 +420,10 @@ $ c_list = "decl,version,[-.sys.vms]vmsunix" -
|
||||
$ gosub compile_list
|
||||
$ c_list = interface !ttysrc or cursessrc or both
|
||||
$ gosub compile_list
|
||||
$ c_list = "allmain,apply,artifact,attrib,ball,bones,botl,cmd,dbridge" -
|
||||
+ ",dothrow,drawing,detect,dig,display,do,do_name,do_wear,dog" -
|
||||
+ ",dogmove,dokick,dungeon,eat,end,engrave,exper,explode" -
|
||||
+ ",extralev,files,fountain"
|
||||
$ c_list = "allmain,apply,artifact,attrib,ball,bones,botl,calendar,cmd" -
|
||||
+ ",coloratt,dbridge,dothrow,drawing,detect,dig,display,do,do_name" -
|
||||
+ ",do_wear,dog,dogmove,dokick,dungeon,eat,end,engrave,exper,explode" -
|
||||
+ ",extralev,files,fountain,getpos"
|
||||
$ gosub compile_list
|
||||
$ c_list = "hack,hacklib,insight,invent,light,lock,mail,makemon" -
|
||||
+ ",mcastu,mdlib,mhitm,mhitu,minion,mklev,mkmap,mkmaze" -
|
||||
@@ -437,12 +437,13 @@ $ c_list = "nhlua,nhlobj,nhlsel"
|
||||
$ gosub compile_list
|
||||
$ c_list = "o_init,objnam,options,pager,pickup" -
|
||||
+ ",pline,polyself,potion,pray,priest,quest,questpgr,read" -
|
||||
+ ",rect,region,restore,rip,rnd,role,rumors,save,sfstruct,shk" -
|
||||
+ ",shknam,sit,sounds,sp_lev,spell,steal,steed,symbols" -
|
||||
+ ",sys,teleport,timeout,topten,track,trap,utf8map,u_init"
|
||||
+ ",rect,region,report,restore,rip,rnd,role,rumors,save,selvar" -
|
||||
+ ",sfstruct,shk,shknam,sit,sounds,sp_lev,spell,stairs,steal" -
|
||||
+ ",steed,strutil,symbols,sys,teleport,timeout,topten,track" -
|
||||
+ ",trap,u_init,utf8map"
|
||||
$ gosub compile_list
|
||||
$ c_list = "uhitm,vault,vision,weapon,were,wield,windows" -
|
||||
+ ",wizard,worm,worn,write,zap"
|
||||
+ ",wizard,wizcmds,worm,worn,write,zap"
|
||||
$ gosub compile_list
|
||||
$!
|
||||
$link:
|
||||
|
||||
@@ -458,6 +458,29 @@ LUALIST = air Arc-fila Arc-filb Arc-goal Arc-loca Arc-strt \
|
||||
|
||||
LUAFILES = $(addprefix $(DAT)/, $(addsuffix .lua, $(LUALIST)))
|
||||
|
||||
#==========================================
|
||||
# Hacklib
|
||||
#==========================================
|
||||
HACKLIBLIST = hacklib
|
||||
HACKLIBSRC = $(addprefix ../src/,$(addsuffix .c, $(HACKLIBLIST)))
|
||||
HL = $(O)hacklib
|
||||
HLHACKLIB = $(HL)/hacklib.a
|
||||
HLHACKLIBOBJS = $(addprefix $(HL)/, $(addsuffix .o, $(HACKLIBLIST)))
|
||||
HLTARGETS = $(HLHACKLIB) $(HLHACKLIBOBJS)
|
||||
|
||||
$(HL)/hacklib.a: $(HLHACKLIBOBJS)
|
||||
ar rcs $@ $^
|
||||
|
||||
$(HL)/hacklib.o: $(HACKLIBSRC) | $(HL)
|
||||
|
||||
$(HL)/%.o: $(SRC)/%.c | $(HL)
|
||||
$(cc) $(CFLAGSU) $< -o$@
|
||||
$(HL):
|
||||
@mkdir -p $@
|
||||
|
||||
CLEAN_DIR += $(HL)
|
||||
CLEAN_FILE += $(HLTARGETS)
|
||||
|
||||
#==========================================
|
||||
# Makedefs
|
||||
#==========================================
|
||||
@@ -467,7 +490,7 @@ MTARGETS = $(U)makedefs.exe
|
||||
|
||||
makedefs: $(MTARGETS)
|
||||
|
||||
$(U)makedefs.exe: $(MOBJS)
|
||||
$(U)makedefs.exe: $(MOBJS) $(HLHACKLIB)
|
||||
$(ld) $(LDFLAGS) $^ -o$@
|
||||
|
||||
$(OM)/%.o: $(SRC)/%.c $(NHLUAH) | $(OM)
|
||||
@@ -579,8 +602,8 @@ TTARGETS = $(U)tile2bmp.exe
|
||||
|
||||
tile2bmp: $(TTARGETS)
|
||||
|
||||
$(U)tile2bmp.exe: $(TOBJS)
|
||||
$(ld) $(LDFLAGS) $^ -o$@
|
||||
$(U)tile2bmp.exe: $(TOBJS) $(HLHACKLIB)
|
||||
$(ld) $(LDFLAGS) $(HLHACKLIB) $^ -o$@
|
||||
|
||||
$(OT)/tiletxt.o: $(WSHR)/tilemap.c $(NHLUAH) | $(OT)
|
||||
$(cc) $(CFLAGSU) -DTILETEXT $< -o$@
|
||||
@@ -662,8 +685,8 @@ tilemap: $(SRC)/tile.c
|
||||
$(SRC)/tile.c: $(U)tilemap.exe
|
||||
$<
|
||||
|
||||
$(U)tilemap.exe: $(TMOBJS)
|
||||
$(ld) $(LDFLAGS) $^ -o$@
|
||||
$(U)tilemap.exe: $(TMOBJS) $(HLHACKLIB)
|
||||
$(ld) $(LDFLAGS) $(HLHACKLIB) $^ -o$@
|
||||
|
||||
$(OTM)/tilemap.o: $(WSHR)/tilemap.c $(NHLUAH) | $(OTM)
|
||||
$(cc) $(CFLAGSU) $< -o$@
|
||||
@@ -716,8 +739,8 @@ DTARGETS = $(U)dlb.exe $(DAT_CLEAN) $(DLBLST) $(DLB)
|
||||
|
||||
dlb: $(DTARGETS)
|
||||
|
||||
$(U)dlb.exe: $(DLBOBJS)
|
||||
$(ld) $(LDFLAGS) $^ -o$@
|
||||
$(U)dlb.exe: $(DLBOBJS) $(HLHACKLIB)
|
||||
$(ld) $(LDFLAGS) $(HLHACKLIB) $^ -o$@
|
||||
|
||||
$(ODLB)/%.o: $(SRC)/%.c $(NHLUAH) | $(ODLB)
|
||||
$(cc) $(CFLAGSU) $< -o$@
|
||||
@@ -961,17 +984,18 @@ endif # HAVE_SOUNDLIB
|
||||
# nethackw
|
||||
#==========================================
|
||||
COREOBJS = $(addsuffix .o, allmain alloc apply artifact attrib ball bones botl \
|
||||
coloratt cmd cppregex \
|
||||
calendar coloratt cmd cppregex \
|
||||
dbridge decl detect dig display dlb do do_name do_wear \
|
||||
dog dogmove dokick dothrow drawing dungeon \
|
||||
eat end engrave exper explode extralev files fountain \
|
||||
hack hacklib insight invent isaac64 light lock \
|
||||
getpos hack insight invent isaac64 light lock \
|
||||
mail makemon mcastu mdlib mhitm mhitu minion mklev mkmap mkmaze mkobj mkroom \
|
||||
mon mondata monmove monst mplayer mthrowu muse music \
|
||||
nhlobj nhlsel nhlua windsound o_init objects objnam options \
|
||||
pager pickup pline polyself potion pray priest quest questpgr \
|
||||
random read rect region restore rip rnd role rumors \
|
||||
safeproc save sfstruct shk shknam sit sounds sp_lev spell steal steed \
|
||||
random read rect region report restore rip rnd role rumors \
|
||||
safeproc save sfstruct shk shknam sit selvar sounds sp_lev \
|
||||
spell stairs steal steed strutil \
|
||||
symbols sys teleport timeout topten track trap u_init uhitm utf8map \
|
||||
vault version vision weapon were wield windmain windows windsys wizard \
|
||||
worm worn write zap $(SOUNDLIBOBJS))
|
||||
@@ -1006,7 +1030,8 @@ endif
|
||||
nethackw: $(NHWTARGETS)
|
||||
|
||||
$(GAMEDIR)/NetHackW.exe: $(NHWOBJS) $(NHWRES) $(DATEW_O) $(LUALIB) $(PDCWLIB) | $(GAMEDIR)
|
||||
$(ld) $(LDFLAGS) -mwindows $^ $(LIBS) -static -lstdc++ $(SOUNDLIBLIBS) -o$@
|
||||
$(ld) $(LDFLAGS) -mwindows $^ $(HLHACKLIB) $(LIBS) -static -lstdc++ \
|
||||
$(SOUNDLIBLIBS) -o$@
|
||||
|
||||
$(ONHW)/%.o: $(SRC)/%.c $(NHLUAH) | $(ONHW)
|
||||
$(cc) $(CFLAGSW) $< -o$@
|
||||
@@ -1096,8 +1121,9 @@ NHTARGET = $(GAMEDIR)/NetHack.exe
|
||||
|
||||
nethack: $(NHTARGET)
|
||||
|
||||
$(GAMEDIR)/NetHack.exe: $(NHOBJS) $(NHRES) $(DATE_O) $(LUALIB) $(PDCLIB) $(SOUNDLIBLIBS) | $(GAMEDIR)
|
||||
$(ld) $(LDFLAGS) -mconsole $^ $(LIBS) -static -lstdc++ -o$@
|
||||
$(GAMEDIR)/NetHack.exe: $(NHOBJS) $(NHRES) $(DATE_O) $(LUALIB) $(PDCLIB) \
|
||||
$(SOUNDLIBLIBS) | $(GAMEDIR)
|
||||
$(ld) $(LDFLAGS) -mconsole $^ $(HLHACKLIB) $(LIBS) -static -lstdc++ -o$@
|
||||
|
||||
$(ONH)/%.o: $(SRC)/%.c $(NHLUAH) | $(ONH)
|
||||
$(cc) $(CFLAGSNH) $< -o$@
|
||||
|
||||
@@ -9,6 +9,9 @@ cce = gcc -E -MM -MT "$(@:d=o) $@"
|
||||
# Run
|
||||
# mingw32-make depend
|
||||
|
||||
$(HL)/%.d: $(SRC)/%.c | $(HL)
|
||||
$(cce) $(CFLAGSU) $< -o$@
|
||||
|
||||
$(OM)/%.d: $(SRC)/%.c $(NHLUAH) | $(OM)
|
||||
$(cce) $(CFLAGSU) -DENUM_PM $< -o$@
|
||||
|
||||
@@ -108,7 +111,7 @@ $(ONH)/%.d: $(TTY)/%.c $(NHLUAH) | $(ONH)
|
||||
$(ONH)/%.d: $(WCURSES)/%.c $(NHLUAH) | $(ONH)
|
||||
$(cce) $(CFLAGSNH) $(PDCINCL) $< -o$@
|
||||
|
||||
OBJS4DEP = $(MOBJS) $(ROBJS) \
|
||||
OBJS4DEP = $(MOBJS) $(ROBJS) $(HLHACKLIBOBJS) \
|
||||
$(TOBJS) $(GIFOBJ) $(GIF32OBJ) $(PPMOBJ) $(BMP32OBJ) $(T32OBJS) $(TUCOMMON) \
|
||||
$(TMOBJS) $(UOBJS) $(DLBOBJS) $(NHWOBJS) $(NHOBJS)
|
||||
DEP_TARGETS = $(OBJS4DEP:o=d)
|
||||
|
||||
+92
-65
@@ -495,8 +495,8 @@ HACKINCL = $(INCL)\align.h $(INCL)\artifact.h $(INCL)\artilist.h \
|
||||
$(INCL)\monsters.h $(INCL)\obj.h $(INCL)\objects.h $(INCL)\objclass.h \
|
||||
$(INCL)\optlist.h $(INCL)\patchlevel.h $(INCL)\pcconf.h \
|
||||
$(INCL)\permonst.h $(INCL)\prop.h $(INCL)\rect.h $(INCL)\region.h \
|
||||
$(INCL)\sym.h $(INCL)\defsym.h $(INCL)\rm.h $(INCL)\sp_lev.h \
|
||||
$(INCL)\spell.h $(INCL)\sys.h $(INCL)\cstd.h $(INCL)\tcap.h \
|
||||
$(INCL)\sym.h $(INCL)\defsym.h $(INCL)\rm.h $(INCL)\selvar.h $(INCL)\sp_lev.h \
|
||||
$(INCL)\spell.h $(INCL)\stairs.h $(INCL)\sys.h $(INCL)\cstd.h $(INCL)\tcap.h \
|
||||
$(INCL)\timeout.h $(INCL)\tradstdc.h $(INCL)\trap.h \
|
||||
$(INCL)\unixconf.h $(INCL)\vision.h $(INCL)\vmsconf.h \
|
||||
$(INCL)\wintty.h $(INCL)\wincurs.h $(INCL)\winX.h \
|
||||
@@ -506,10 +506,10 @@ HACKINCL = $(INCL)\align.h $(INCL)\artifact.h $(INCL)\artilist.h \
|
||||
# all .c that are part of the main NetHack program and are not operating- or
|
||||
# windowing-system specific
|
||||
HACKCSRC = allmain.c alloc.c apply.c artifact.c attrib.c ball.c bones.c \
|
||||
botl.c coloratt.c cmd.c dbridge.c decl.c detect.c dig.c display.c \
|
||||
botl.c calendar.c cmd.c coloratt.c dbridge.c decl.c detect.c dig.c display.c \
|
||||
dlb.c do.c do_name.c do_wear.c dog.c dogmove.c dokick.c dothrow.c \
|
||||
drawing.c dungeon.c eat.c end.c engrave.c exper.c explode.c \
|
||||
extralev.c files.c fountain.c hack.c hacklib.c \
|
||||
files.c fountain.c hack.c \
|
||||
insight.c invent.c isaac64.c light.c \
|
||||
lock.c mail.c makemon.c mcastu.c mdlib.c mhitm.c \
|
||||
mhitu.c minion.c mklev.c mkmap.c mkmaze.c mkobj.c mkroom.c mon.c \
|
||||
@@ -630,6 +630,14 @@ CURSESDEF2=-DCURSES_UNICODE $(PDCURSESFLAGS)
|
||||
!UNDEF PDCWINGUILIB
|
||||
!ENDIF
|
||||
|
||||
OUTLHACKLIBOBJS = $(OUTL)hacklib.o
|
||||
OTTYHACKLIBOBJS = $(OTTY)hacklib.o
|
||||
OGUIHACKLIBOBJS = $(OGUI)hacklib.o
|
||||
OUTLHACKLIB = $(OUTL)hacklib-$(TARGET_CPU)-static.lib
|
||||
OTTYHACKLIB = $(OTTY)hacklib-$(TARGET_CPU)-static.lib
|
||||
OGUIHACKLIB = $(OGUI)hacklib-$(TARGET_CPU)-static.lib
|
||||
|
||||
|
||||
#
|
||||
# - TTY
|
||||
#
|
||||
@@ -650,32 +658,33 @@ TTYOBJ = $(OTTY)topl.o $(OTTY)getline.o $(OTTY)wintty.o
|
||||
|
||||
VTTYOBJ01 = $(OTTY)allmain.o $(OTTY)alloc.o $(OTTY)apply.o $(OTTY)artifact.o
|
||||
VTTYOBJ02 = $(OTTY)attrib.o $(OTTY)ball.o $(OTTY)bones.o $(OTTY)botl.o
|
||||
VTTYOBJ03 = $(OTTY)coloratt.o $(OTTY)cmd.o $(OTTY)dbridge.o $(OTTY)decl.o $(OTTY)detect.o
|
||||
VTTYOBJ04 = $(OTTY)dig.o $(OTTY)display.o $(OTTY)do.o $(OTTY)do_name.o
|
||||
VTTYOBJ05 = $(OTTY)do_wear.o $(OTTY)dog.o $(OTTY)dogmove.o $(OTTY)dokick.o
|
||||
VTTYOBJ03 = $(OTTY)calendar.o $(OTTY)cmd.o $(OTTY)coloratt.o $(OTTY)dbridge.o
|
||||
VTTYOBJ04 = $(OTTY)decl.o $(OTTY)detect.o $(OTTY)dig.o $(OTTY)display.o $(OTTY)do.o
|
||||
VTTYOBJ05 = $(OTTY)do_name.o $(OTTY)do_wear.o $(OTTY)dog.o $(OTTY)dogmove.o $(OTTY)dokick.o
|
||||
VTTYOBJ06 = $(OTTY)dothrow.o $(OTTY)drawing.o $(OTTY)dungeon.o $(OTTY)eat.o
|
||||
VTTYOBJ07 = $(OTTY)end.o $(OTTY)engrave.o $(OTTY)exper.o $(OTTY)explode.o
|
||||
VTTYOBJ08 = $(OTTY)extralev.o $(OTTY)files.o $(OTTY)fountain.o $(OTTY)hack.o
|
||||
VTTYOBJ09 = $(OTTY)hacklib.o $(OTTY)insight.o $(OTTY)invent.o $(OTTY)isaac64.o
|
||||
VTTYOBJ10 = $(OTTY)light.o $(OTTY)lock.o $(OTTY)mail.o $(OTTY)makemon.o
|
||||
VTTYOBJ11 = $(OTTY)mcastu.o $(OTTY)mhitm.o $(OTTY)mhitu.o $(OTTY)minion.o
|
||||
VTTYOBJ12 = $(OTTY)mklev.o $(OTTY)mkmap.o $(OTTY)mkmaze.o $(OTTY)mkobj.o
|
||||
VTTYOBJ13 = $(OTTY)mkroom.o $(OTTY)mon.o $(OTTY)mondata.o $(OTTY)monmove.o
|
||||
VTTYOBJ14 = $(OTTY)monst.o $(OTTY)mplayer.o $(OTTY)mthrowu.o $(OTTY)muse.o
|
||||
VTTYOBJ15 = $(OTTY)music.o $(OTTY)o_init.o $(OTTY)objects.o $(OTTY)objnam.o
|
||||
VTTYOBJ16 = $(OTTY)options.o $(OTTY)pager.o $(OTTY)pickup.o $(OTTY)pline.o
|
||||
VTTYOBJ17 = $(OTTY)polyself.o $(OTTY)potion.o $(OTTY)pray.o $(OTTY)priest.o
|
||||
VTTYOBJ18 = $(OTTY)quest.o $(OTTY)questpgr.o $(RANDOM) $(OTTY)read.o
|
||||
VTTYOBJ19 = $(OTTY)rect.o $(OTTY)region.o $(OTTY)restore.o $(OTTY)rip.o
|
||||
VTTYOBJ20 = $(OTTY)rnd.o $(OTTY)role.o $(OTTY)rumors.o $(OTTY)save.o
|
||||
VTTYOBJ21 = $(OTTY)sfstruct.o $(OTTY)shk.o $(OTTY)shknam.o $(OTTY)sit.o
|
||||
VTTYOBJ22 = $(OTTY)sounds.o $(OTTY)sp_lev.o $(OTTY)spell.o $(OTTY)steal.o
|
||||
VTTYOBJ23 = $(OTTY)steed.o $(OTTY)symbols.o $(OTTY)sys.o $(OTTY)teleport.o
|
||||
VTTYOBJ24 = $(OTTY)timeout.o $(OTTY)topten.o $(OTTY)track.o $(OTTY)trap.o
|
||||
VTTYOBJ25 = $(OTTY)u_init.o $(OTTY)uhitm.o $(OTTY)utf8map.o $(OTTY)vault.o
|
||||
VTTYOBJ26 = $(OTTY)vision.o $(OTTY)weapon.o $(OTTY)were.o $(OTTY)wield.o
|
||||
VTTYOBJ27 = $(OTTY)windows.o $(OTTY)wizard.o $(OTTY)worm.o $(OTTY)worn.o
|
||||
VTTYOBJ28 = $(OTTY)write.o $(OTTY)zap.o
|
||||
VTTYOBJ08 = $(OTTY)extralev.o $(OTTY)files.o $(OTTY)fountain.o $(OTTY)getpos.o
|
||||
VTTYOBJ09 = $(OTTY)hack.o $(OTTY)insight.o $(OTTY)invent.o
|
||||
VTTYOBJ10 = $(OTTY)isaac64.o $(OTTY)light.o $(OTTY)lock.o $(OTTY)mail.o
|
||||
VTTYOBJ11 = $(OTTY)makemon.o $(OTTY)mcastu.o $(OTTY)mhitm.o $(OTTY)mhitu.o
|
||||
VTTYOBJ12 = $(OTTY)minion.o $(OTTY)mklev.o $(OTTY)mkmap.o $(OTTY)mkmaze.o
|
||||
VTTYOBJ13 = $(OTTY)mkobj.o $(OTTY)mkroom.o $(OTTY)mon.o $(OTTY)mondata.o
|
||||
VTTYOBJ14 = $(OTTY)monmove.o $(OTTY)monst.o $(OTTY)mplayer.o $(OTTY)mthrowu.o
|
||||
VTTYOBJ15 = $(OTTY)muse.o $(OTTY)music.o $(OTTY)o_init.o $(OTTY)objects.o
|
||||
VTTYOBJ16 = $(OTTY)objnam.o $(OTTY)options.o $(OTTY)pager.o $(OTTY)pickup.o
|
||||
VTTYOBJ17 = $(OTTY)pline.o $(OTTY)polyself.o $(OTTY)potion.o $(OTTY)pray.o
|
||||
VTTYOBJ18 = $(OTTY)priest.o $(OTTY)quest.o $(OTTY)questpgr.o $(RANDOM)
|
||||
VTTYOBJ19 = $(OTTY)read.o $(OTTY)rect.o $(OTTY)region.o $(OTTY)report.o $(OTTY)restore.o
|
||||
VTTYOBJ20 = $(OTTY)rip.o $(OTTY)rnd.o $(OTTY)role.o $(OTTY)rumors.o
|
||||
VTTYOBJ21 = $(OTTY)save.o $(OTTY)selvar.o $(OTTY)sfstruct.o $(OTTY)shk.o
|
||||
VTTYOBJ22 = $(OTTY)shknam.o $(OTTY)sit.o $(OTTY)sounds.o $(OTTY)sp_lev.o
|
||||
VTTYOBJ23 = $(OTTY)spell.o $(OTTY)stairs.o $(OTTY)steal.o $(OTTY)steed.o
|
||||
VTTYOBJ24 = $(OTTY)strutil.o $(OTTY)symbols.o $(OTTY)sys.o $(OTTY)teleport.o $(OTTY)timeout.o
|
||||
VTTYOBJ25 = $(OTTY)topten.o $(OTTY)track.o $(OTTY)trap.o $(OTTY)u_init.o
|
||||
VTTYOBJ26 = $(OTTY)uhitm.o $(OTTY)utf8map.o $(OTTY)vault.o $(OTTY)vision.o
|
||||
VTTYOBJ27 = $(OTTY)weapon.o $(OTTY)were.o $(OTTY)wield.o $(OTTY)windows.o
|
||||
VTTYOBJ28 = $(OTTY)wizard.o $(OTTY)wizcmds.o $(OTTY)worm.o $(OTTY)worn.o
|
||||
VTTYOBJ29 = $(OTTY)write.o $(OTTY)zap.o
|
||||
|
||||
OBJSTTY = $(MDLIBTTY) \
|
||||
$(VTTYOBJ01) $(VTTYOBJ02) $(VTTYOBJ03) $(VTTYOBJ04) $(VTTYOBJ05) \
|
||||
@@ -717,32 +726,33 @@ GUIOBJ = $(OGUI)mhaskyn.o $(OGUI)mhdlg.o \
|
||||
|
||||
VGUIOBJ01 = $(OGUI)allmain.o $(OGUI)alloc.o $(OGUI)apply.o $(OGUI)artifact.o
|
||||
VGUIOBJ02 = $(OGUI)attrib.o $(OGUI)ball.o $(OGUI)bones.o $(OGUI)botl.o
|
||||
VGUIOBJ03 = $(OGUI)coloratt.o $(OGUI)cmd.o $(OGUI)dbridge.o $(OGUI)decl.o $(OGUI)detect.o
|
||||
VGUIOBJ04 = $(OGUI)dig.o $(OGUI)display.o $(OGUI)do.o $(OGUI)do_name.o
|
||||
VGUIOBJ03 = $(OGUI)calendar.o $(OGUI)cmd.o $(OGUI)coloratt.o $(OGUI)dbridge.o $(OGUI)decl.o
|
||||
VGUIOBJ04 = $(OGUI)detect.o $(OGUI)dig.o $(OGUI)display.o $(OGUI)do.o $(OGUI)do_name.o
|
||||
VGUIOBJ05 = $(OGUI)do_wear.o $(OGUI)dog.o $(OGUI)dogmove.o $(OGUI)dokick.o
|
||||
VGUIOBJ06 = $(OGUI)dothrow.o $(OGUI)drawing.o $(OGUI)dungeon.o $(OGUI)eat.o
|
||||
VGUIOBJ07 = $(OGUI)end.o $(OGUI)engrave.o $(OGUI)exper.o $(OGUI)explode.o
|
||||
VGUIOBJ08 = $(OGUI)extralev.o $(OGUI)files.o $(OGUI)fountain.o $(OGUI)hack.o
|
||||
VGUIOBJ09 = $(OGUI)hacklib.o $(OGUI)insight.o $(OGUI)invent.o $(OGUI)isaac64.o
|
||||
VGUIOBJ10 = $(OGUI)light.o $(OGUI)lock.o $(OGUI)mail.o $(OGUI)makemon.o
|
||||
VGUIOBJ11 = $(OGUI)mcastu.o $(OGUI)mhitm.o $(OGUI)mhitu.o $(OGUI)minion.o
|
||||
VGUIOBJ12 = $(OGUI)mklev.o $(OGUI)mkmap.o $(OGUI)mkmaze.o $(OGUI)mkobj.o
|
||||
VGUIOBJ13 = $(OGUI)mkroom.o $(OGUI)mon.o $(OGUI)mondata.o $(OGUI)monmove.o
|
||||
VGUIOBJ14 = $(OGUI)monst.o $(OGUI)mplayer.o $(OGUI)mthrowu.o $(OGUI)muse.o
|
||||
VGUIOBJ15 = $(OGUI)music.o $(OGUI)o_init.o $(OGUI)objects.o $(OGUI)objnam.o
|
||||
VGUIOBJ16 = $(OGUI)options.o $(OGUI)pager.o $(OGUI)pickup.o $(OGUI)pline.o
|
||||
VGUIOBJ17 = $(OGUI)polyself.o $(OGUI)potion.o $(OGUI)pray.o $(OGUI)priest.o
|
||||
VGUIOBJ18 = $(OGUI)quest.o $(OGUI)questpgr.o $(RANDOMGUI) $(OGUI)read.o
|
||||
VGUIOBJ19 = $(OGUI)rect.o $(OGUI)region.o $(OGUI)restore.o $(OGUI)rip.o
|
||||
VGUIOBJ20 = $(OGUI)rnd.o $(OGUI)role.o $(OGUI)rumors.o $(OGUI)save.o
|
||||
VGUIOBJ21 = $(OGUI)sfstruct.o $(OGUI)shk.o $(OGUI)shknam.o $(OGUI)sit.o
|
||||
VGUIOBJ22 = $(OGUI)sounds.o $(OGUI)sp_lev.o $(OGUI)spell.o $(OGUI)steal.o
|
||||
VGUIOBJ23 = $(OGUI)steed.o $(OGUI)symbols.o $(OGUI)sys.o $(OGUI)teleport.o
|
||||
VGUIOBJ24 = $(OGUI)timeout.o $(OGUI)topten.o $(OGUI)track.o $(OGUI)trap.o
|
||||
VGUIOBJ25 = $(OGUI)u_init.o $(OGUI)uhitm.o $(OGUI)utf8map.o $(OGUI)vault.o
|
||||
VGUIOBJ26 = $(OGUI)vision.o $(OGUI)weapon.o $(OGUI)were.o $(OGUI)wield.o
|
||||
VGUIOBJ27 = $(OGUI)windows.o $(OGUI)wizard.o $(OGUI)worm.o $(OGUI)worn.o
|
||||
VGUIOBJ28 = $(OGUI)write.o $(OGUI)zap.o
|
||||
VGUIOBJ08 = $(OGUI)extralev.o $(OGUI)files.o $(OGUI)fountain.o $(OGUI)getpos.o
|
||||
VGUIOBJ09 = $(OGUI)hack.o $(OGUI)insight.o $(OGUI)invent.o
|
||||
VGUIOBJ10 = $(OGUI)isaac64.o $(OGUI)light.o $(OGUI)lock.o $(OGUI)mail.o
|
||||
VGUIOBJ11 = $(OGUI)makemon.o $(OGUI)mcastu.o $(OGUI)mhitm.o $(OGUI)mhitu.o
|
||||
VGUIOBJ12 = $(OGUI)minion.o $(OGUI)mklev.o $(OGUI)mkmap.o $(OGUI)mkmaze.o
|
||||
VGUIOBJ13 = $(OGUI)mkobj.o $(OGUI)mkroom.o $(OGUI)mon.o $(OGUI)mondata.o
|
||||
VGUIOBJ14 = $(OGUI)monmove.o $(OGUI)monst.o $(OGUI)mplayer.o $(OGUI)mthrowu.o
|
||||
VGUIOBJ15 = $(OGUI)muse.o $(OGUI)music.o $(OGUI)o_init.o $(OGUI)objects.o
|
||||
VGUIOBJ16 = $(OGUI)objnam.o $(OGUI)options.o $(OGUI)pager.o $(OGUI)pickup.o
|
||||
VGUIOBJ17 = $(OGUI)pline.o $(OGUI)polyself.o $(OGUI)potion.o $(OGUI)pray.o
|
||||
VGUIOBJ18 = $(OGUI)priest.o $(OGUI)quest.o $(OGUI)questpgr.o $(RANDOMGUI)
|
||||
VGUIOBJ19 = $(OGUI)read.o $(OGUI)rect.o $(OGUI)region.o $(OGUI)report.o $(OGUI)restore.o
|
||||
VGUIOBJ20 = $(OGUI)rip.o $(OGUI)rnd.o $(OGUI)role.o $(OGUI)rumors.o
|
||||
VGUIOBJ21 = $(OGUI)save.o $(OGUI)selvar.o $(OGUI)sfstruct.o $(OGUI)shk.o
|
||||
VGUIOBJ22 = $(OGUI)shknam.o $(OGUI)sit.o $(OGUI)sounds.o $(OGUI)sp_lev.o
|
||||
VGUIOBJ23 = $(OGUI)spell.o $(OGUI)stairs.o $(OGUI)steal.o $(OGUI)steed.o
|
||||
VGUIOBJ24 = $(OGUI)strutil.o $(OGUI)symbols.o $(OGUI)sys.o $(OGUI)teleport.o $(OGUI)timeout.o
|
||||
VGUIOBJ25 = $(OGUI)topten.o $(OGUI)track.o $(OGUI)trap.o $(OGUI)u_init.o
|
||||
VGUIOBJ26 = $(OGUI)uhitm.o $(OGUI)utf8map.o $(OGUI)vault.o $(OGUI)vision.o
|
||||
VGUIOBJ27 = $(OGUI)weapon.o $(OGUI)were.o $(OGUI)wield.o $(OGUI)windows.o
|
||||
VGUIOBJ28 = $(OGUI)wizard.o $(OGUI)wizcmds.o $(OGUI)worm.o $(OGUI)worn.o
|
||||
VGUIOBJ29 = $(OGUI)write.o $(OGUI)zap.o
|
||||
|
||||
OBJSGUI = $(MDLIBGUI) \
|
||||
$(VGUIOBJ01) $(VGUIOBJ02) $(VGUIOBJ03) $(VGUIOBJ04) $(VGUIOBJ05) \
|
||||
@@ -1456,11 +1466,11 @@ GAMEOBJ=$(GAMEOBJ:^ =^
|
||||
$(GAMEDIR)\NetHack.exe : gamedir.tag $(OTTY)consoletty.o \
|
||||
$(ALLOBJTTY) $(CURSESWINCONOBJS) \
|
||||
$(TTYSOUNDOBJS) $(OTTY)date.o $(OTTY)console.res \
|
||||
$(LUALIB) $(TTYOBJ) $(PDCWINCONLIB) $(PDCWINCONOBJS)
|
||||
$(LUALIB) $(TTYOBJ) $(PDCWINCONLIB) $(PDCWINCONOBJS) $(OTTYHACKLIB)
|
||||
@if not exist $(GAMEDIR)\*.* mkdir $(GAMEDIR)
|
||||
@echo Linking $(@:\=/)
|
||||
$(link) $(LFLAGS) $(conlflags) /STACK:2048 /PDB:$(GAMEDIR)\$(@B).PDB /MAP:$(OTTY)$(@B).MAP \
|
||||
$(LIBS) $(PDCWINCONLIB) $(LUALIB) $(TTYSOUNDLIBS) \
|
||||
$(LIBS) $(PDCWINCONLIB) $(LUALIB) $(TTYSOUNDLIBS) $(OTTYHACKLIB) \
|
||||
$(conlibs) $(BCRYPT) -out:$@ @<<$(@B).lnk
|
||||
$(GAMEOBJTTY)
|
||||
$(ALLOBJTTY)
|
||||
@@ -1480,12 +1490,12 @@ $(GAMEDIR)\NetHackW.exe : gamedir.tag $(OGUI)tile.o \
|
||||
$(ALLOBJGUI) $(GAMEOBJGUI) $(GUIOBJ) $(GUISOUNDOBJS) \
|
||||
$(CURSESWINGUIOBJS) $(OGUI)date.o \
|
||||
$(OGUI)NetHackW.res \
|
||||
$(LUALIB) $(PDCWINGUILIB) $(PDCWINGUIOBJS)
|
||||
$(LUALIB) $(PDCWINGUILIB) $(PDCWINGUIOBJS) $(OGUIHACKLIB)
|
||||
@if not exist $(GAMEDIR)\*.* mkdir $(GAMEDIR)
|
||||
@echo Linking $(@:\=/)
|
||||
$(link) $(LFLAGS) $(guilflags) /STACK:2048 /PDB:$(GAMEDIR)\$(@B).PDB \
|
||||
/MAP:$(OGUI)$(@B).MAP $(LIBS) $(PDCWINGUILIB) $(LUALIB) \
|
||||
$(GUISOUNDLIBS) \
|
||||
$(GUISOUNDLIBS) $(OGUIHACKLIB) \
|
||||
$(guilibs) $(COMCTRL) $(BCRYPT) -out:$@ @<<$(@B).lnk
|
||||
$(GAMEOBJGUI)
|
||||
$(ALLOBJGUI)
|
||||
@@ -1547,7 +1557,7 @@ recover: $(U)recover.exe
|
||||
if exist $(U)recover.exe copy $(U)recover.exe $(GAMEDIR)
|
||||
if exist $(DOC)\recover.txt copy $(DOC)\recover.txt $(GAMEDIR)\recover.txt
|
||||
|
||||
$(OUTL)utility.tag: $(INCL)\nhlua.h outldir$(TARGET_CPU).tag $(U)tile2bmp.exe $(U)makedefs.exe
|
||||
$(OUTL)utility.tag: $(INCL)\nhlua.h outldir$(TARGET_CPU).tag $(OUTLHACKLIB) $(U)tile2bmp.exe $(U)makedefs.exe
|
||||
@echo utilities made >$@
|
||||
@echo utilities made.
|
||||
|
||||
@@ -1587,9 +1597,9 @@ $(U)nhsizes3.exe: $(OUTL)nhsizes3.o
|
||||
$(OUTL)nhsizes3.o: $(CONFIG_H) nhsizes3.c
|
||||
$(Q)$(CC) $(CFLAGS) $(CROSSCOMPILE) -Fo$@ nhsizes3.c
|
||||
|
||||
$(U)makedefs.exe: $(MAKEDEFSOBJS)
|
||||
$(U)makedefs.exe: $(OUTLHACKLIB) $(MAKEDEFSOBJS)
|
||||
@echo Linking $(@:\=/)
|
||||
@$(link) $(LFLAGS) /PDB:"$(OUTL)$(@B).PDB" /MAP:"$(OUTL)$(@B).MAP" -out:$@ $(MAKEDEFSOBJS)
|
||||
@$(link) $(LFLAGS) /PDB:"$(OUTL)$(@B).PDB" /MAP:"$(OUTL)$(@B).MAP" -out:$@ $(MAKEDEFSOBJS) $(OUTLHACKLIB)
|
||||
|
||||
$(OUTL)makedefs.o: $(U)makedefs.c $(SRC)\mdlib.c $(CONFIG_H) $(INCL)\permonst.h \
|
||||
$(INCL)\objclass.h $(INCL)\sym.h $(INCL)\defsym.h \
|
||||
@@ -1663,6 +1673,23 @@ $(INCL)\onames.h : $(U)makedefs.exe
|
||||
$(INCL)\pm.h : $(U)makedefs.exe
|
||||
$(U)makedefs -p
|
||||
|
||||
|
||||
#==========================================
|
||||
# HACKLIB
|
||||
#==========================================
|
||||
|
||||
$(OUTLHACKLIB): $(OUTLHACKLIBOBJS)
|
||||
@echo Building library $@ from $**
|
||||
@$(librarian) /OUT:$@ $(OUTLHACKLIBOBJS)
|
||||
|
||||
$(OTTYHACKLIB): $(OTTYHACKLIBOBJS)
|
||||
@echo Building library $@ from $**
|
||||
@$(librarian) /OUT:$@ $(OTTYHACKLIBOBJS)
|
||||
|
||||
$(OGUIHACKLIB): $(OGUIHACKLIBOBJS)
|
||||
@echo Building library $@ from $**
|
||||
@$(librarian) /OUT:$@ $(OGUIHACKLIBOBJS)
|
||||
|
||||
#==========================================
|
||||
# uudecode utility and uuencoded targets
|
||||
#==========================================
|
||||
@@ -1802,9 +1829,9 @@ fetch-pdcurses:
|
||||
# DLB utility and nhdatNNN file creation
|
||||
#==========================================
|
||||
|
||||
$(U)dlb.exe: $(DLBOBJ_HOST) $(OUTL)dlb$(HOST).o
|
||||
$(U)dlb.exe: $(DLBOBJ_HOST) $(OUTL)dlb$(HOST).o $(OUTLHACKLIB)
|
||||
@echo Linking $(@:\=/)
|
||||
@$(link) $(LFLAGS) /PDB:"$(OUTL)$(@B).PDB" /MAP:"$(OUTL)$(@B).MAP" -out:$@ @<<$(@B).lnk
|
||||
@$(link) $(LFLAGS) /PDB:"$(OUTL)$(@B).PDB" /MAP:"$(OUTL)$(@B).MAP" $(OUTLHACKLIB) -out:$@ @<<$(@B).lnk
|
||||
$(OUTL)dlb_main$(HOST).o
|
||||
$(OUTL)dlb$(HOST).o
|
||||
$(OUTL)alloc$(HOST).o
|
||||
@@ -1886,10 +1913,10 @@ tile.c: $(U)tilemap.exe
|
||||
@$(U)tilemap
|
||||
@echo A new $(@:\=/) has been created
|
||||
|
||||
$(U)tilemap.exe: $(OUTL)tilemap.o $(OUTL)monst.o $(OUTL)objects.o $(OUTL)drawing.o
|
||||
$(U)tilemap.exe: $(OUTL)tilemap.o $(OUTL)monst.o $(OUTL)objects.o $(OUTL)drawing.o $(OUTLHACKLIB)
|
||||
@echo Linking $(@:\=/)
|
||||
@$(link) $(LFLAGS) /PDB:"$(OUTL)$(@B).PDB" /MAP:"$(OUTL)$(@B).MAP" -out:$@ \
|
||||
$(OUTL)tilemap.o $(OUTL)monst.o $(OUTL)objects.o $(OUTL)drawing.o
|
||||
@$(link) $(LFLAGS) /PDB:"$(OUTL)$(@B).PDB" /MAP:"$(OUTL)$(@B).MAP" $(HACKLIB) -out:$@ \
|
||||
$(OUTL)tilemap.o $(OUTL)monst.o $(OUTL)objects.o $(OUTL)drawing.o $(OUTLHACKLIB)
|
||||
|
||||
$(OUTL)tilemap.o: $(WSHR)\tilemap.c $(HACK_H)
|
||||
$(Q)$(CC) $(CFLAGS) $(CROSSCOMPILE) -Fo$@ $(WSHR)\tilemap.c
|
||||
@@ -1952,7 +1979,7 @@ $(SRC)\tiles.bmp: $(U)tile2bmp.exe $(TILEFILES)
|
||||
|
||||
$(U)tile2bmp.exe: $(OUTL)tile2bmp.o $(TEXT_IO)
|
||||
@echo Linking $(@:\=/)
|
||||
@$(link) $(LFLAGS) /PDB:"$(OUTL)$(@B).PDB" /MAP:"$(OUTL)$(@B).MAP" -out:$@ @<<$(@B).lnk
|
||||
@$(link) $(LFLAGS) /PDB:"$(OUTL)$(@B).PDB" /MAP:"$(OUTL)$(@B).MAP" $(OUTLHACKLIB) -out:$@ @<<$(@B).lnk
|
||||
$(OUTL)tile2bmp.o
|
||||
$(TEXT_IO:^ =^
|
||||
)
|
||||
@@ -1960,7 +1987,7 @@ $(U)tile2bmp.exe: $(OUTL)tile2bmp.o $(TEXT_IO)
|
||||
|
||||
$(U)til2bm32.exe: $(OUTL)til2bm32.o $(TEXT_IO32)
|
||||
@echo Linking $(@:\=/)
|
||||
@$(link) $(LFLAGS) /PDB:"$(OUTL)$(@B).PDB" /MAP:"$(OUTL)$(@B).MAP" -out:$@ @<<$(@B).lnk
|
||||
@$(link) $(LFLAGS) /PDB:"$(OUTL)$(@B).PDB" /MAP:"$(OUTL)$(@B).MAP" $(OUTLHACKLIB) -out:$@ @<<$(@B).lnk
|
||||
$(OUTL)til2bm32.o
|
||||
$(TEXT_IO32:^ =^
|
||||
)
|
||||
|
||||
+2
-9
@@ -7,6 +7,8 @@
|
||||
|
||||
#include "config.h"
|
||||
#include "dlb.h"
|
||||
#include "hacklib.h"
|
||||
|
||||
#if !defined(O_WRONLY) && !defined(MAC) && !defined(AZTEC_C)
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
@@ -16,7 +18,6 @@
|
||||
|
||||
ATTRNORETURN static void xexit(int) NORETURN;
|
||||
ATTRNORETURN extern void panic(const char *, ...) NORETURN;
|
||||
char *eos(char *); /* also used by dlb.c */
|
||||
FILE *fopen_datafile(const char *, const char *);
|
||||
|
||||
#ifdef DLB
|
||||
@@ -138,14 +139,6 @@ fopen_datafile(const char *filename, const char *mode)
|
||||
return fopen(filename, mode);
|
||||
}
|
||||
|
||||
char *
|
||||
eos(char *s)
|
||||
{
|
||||
while (*s)
|
||||
s++;
|
||||
return s;
|
||||
}
|
||||
|
||||
#ifdef DLB
|
||||
#define UNUSED_if_no_DLB /*empty*/
|
||||
#else
|
||||
|
||||
+14
-9
@@ -21,6 +21,7 @@
|
||||
#include "context.h"
|
||||
#include "flag.h"
|
||||
#include "dlb.h"
|
||||
#include "hacklib.h"
|
||||
|
||||
#include <ctype.h>
|
||||
#ifdef MAC
|
||||
@@ -166,7 +167,9 @@ extern void objects_globals_init(void); /* objects.c */
|
||||
static char *name_file(const char *, const char *);
|
||||
static FILE *getfp(const char *, const char *, const char *, int);
|
||||
static void do_ext_makedefs(int, char **);
|
||||
#if 0
|
||||
static char *xcrypt(const char *);
|
||||
#endif
|
||||
static char *padline(char *, unsigned);
|
||||
static unsigned long read_rumors_file(const char *, int *,
|
||||
long *, unsigned long, unsigned);
|
||||
@@ -974,10 +977,11 @@ grep0(FILE *inputfp0, FILE* outputfp0, int flg)
|
||||
return;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* trivial text encryption routine which can't be broken with `tr' */
|
||||
static char *
|
||||
xcrypt(const char *str)
|
||||
{ /* duplicated in src/hacklib.c */
|
||||
{ /* slightly different version in src/hacklib.c */
|
||||
static char buf[BUFSZ];
|
||||
const char *p;
|
||||
char *q;
|
||||
@@ -993,6 +997,7 @@ xcrypt(const char *str)
|
||||
*q = '\0';
|
||||
return buf;
|
||||
}
|
||||
#endif
|
||||
|
||||
static char *
|
||||
padline(char *line, unsigned padlength)
|
||||
@@ -1038,7 +1043,7 @@ read_rumors_file(
|
||||
unsigned long old_rumor_offset,
|
||||
unsigned padlength)
|
||||
{
|
||||
char infile[MAXFNAMELEN];
|
||||
char infile[MAXFNAMELEN], xbuf[BUFSZ];
|
||||
char *line;
|
||||
unsigned long rumor_offset;
|
||||
|
||||
@@ -1059,7 +1064,7 @@ read_rumors_file(
|
||||
/*[if we forced binary output, this would be sufficient]*/
|
||||
*rumor_size += strlen(line); /* includes newline */
|
||||
#endif
|
||||
(void) fputs(xcrypt(line), tfp);
|
||||
(void) fputs(xcrypt(line, xbuf), tfp);
|
||||
free((genericptr_t) line);
|
||||
}
|
||||
/* record the current position; next rumors section will start here */
|
||||
@@ -1081,7 +1086,7 @@ do_rnd_access_file(
|
||||
const char *deflt_content,
|
||||
unsigned padlength)
|
||||
{
|
||||
char *line, buf[BUFSZ];
|
||||
char *line, buf[BUFSZ], xbuf[BUFSZ];
|
||||
|
||||
Sprintf(filename, DATA_IN_TEMPLATE, fname);
|
||||
Strcat(filename, ".txt");
|
||||
@@ -1108,7 +1113,7 @@ do_rnd_access_file(
|
||||
Strcpy(buf, deflt_content);
|
||||
if (!strchr(buf, '\n')) /* lines from the file include trailing newline +*/
|
||||
Strcat(buf, "\n"); /* so make sure that the default one does too */
|
||||
(void) fputs(xcrypt(padline(buf, padlength)), ofp);
|
||||
(void) fputs(xcrypt(padline(buf, padlength), xbuf), ofp);
|
||||
|
||||
tfp = getfp(DATA_TEMPLATE, "grep.tmp", WRTMODE, FLG_TEMPFILE);
|
||||
grep0(ifp, tfp, FLG_TEMPFILE);
|
||||
@@ -1122,7 +1127,7 @@ do_rnd_access_file(
|
||||
while ((line = fgetline(ifp)) != 0) {
|
||||
if (line[0] != '#' && line[0] != '\n') {
|
||||
(void) padline(line, padlength);
|
||||
(void) fputs(xcrypt(line), ofp);
|
||||
(void) fputs(xcrypt(line, xbuf), ofp);
|
||||
}
|
||||
free((genericptr_t) line);
|
||||
}
|
||||
@@ -1413,7 +1418,7 @@ static const char *special_oracle[] = {
|
||||
void
|
||||
do_oracles(void)
|
||||
{
|
||||
char infile[60], tempfile[60];
|
||||
char infile[60], tempfile[60], xbuf[BUFSZ];
|
||||
boolean in_oracle, ok;
|
||||
long fpos;
|
||||
unsigned long txt_offset, offset;
|
||||
@@ -1457,7 +1462,7 @@ do_oracles(void)
|
||||
offset = (unsigned long) ftell(tfp);
|
||||
Fprintf(ofp, "%05lx\n", offset); /* start pos of special oracle */
|
||||
for (i = 0; i < SIZE(special_oracle); i++) {
|
||||
(void) fputs(xcrypt(special_oracle[i]), tfp);
|
||||
(void) fputs(xcrypt(special_oracle[i], xbuf), tfp);
|
||||
(void) fputc('\n', tfp);
|
||||
}
|
||||
SpinCursor(3);
|
||||
@@ -1488,7 +1493,7 @@ do_oracles(void)
|
||||
Fprintf(ofp, "%05lx\n", offset); /* start pos of this oracle */
|
||||
} else {
|
||||
in_oracle = TRUE;
|
||||
(void) fputs(xcrypt(line), tfp);
|
||||
(void) fputs(xcrypt(line, xbuf), tfp);
|
||||
}
|
||||
free((genericptr_t) line);
|
||||
}
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
#endif
|
||||
|
||||
#include "config.h"
|
||||
#include "hacklib.h"
|
||||
|
||||
#include "tile.h"
|
||||
extern void monst_globals_init(void);
|
||||
extern void objects_globals_init(void);
|
||||
|
||||
+10
-33
@@ -18,10 +18,14 @@
|
||||
#include "rm.h"
|
||||
#else
|
||||
#include "hack.h"
|
||||
#include "display.h"
|
||||
#include <stdarg.h>
|
||||
#endif
|
||||
|
||||
#ifdef Snprintf
|
||||
#undef Snprintf
|
||||
#endif
|
||||
#define Snprintf(str, size, ...) \
|
||||
nh_snprintf(__func__, __LINE__, str, size, __VA_ARGS__)
|
||||
|
||||
#ifdef MONITOR_HEAP
|
||||
/* with heap monitoring enabled, free(ptr) is a macro which expands to
|
||||
nhfree(ptr,__FILE__,__LINE__); since tilemap doesn't link with
|
||||
@@ -30,10 +34,6 @@
|
||||
#endif
|
||||
|
||||
#define Fprintf (void) fprintf
|
||||
#define Snprintf(str, size, ...) \
|
||||
nh_snprintf(__func__, __LINE__, str, size, __VA_ARGS__)
|
||||
void nh_snprintf(const char *func, int line, char *str, size_t size,
|
||||
const char *fmt, ...);
|
||||
|
||||
/*
|
||||
* Defining OBTAIN_TILEMAP to get a listing of the tile-mappings
|
||||
@@ -118,14 +118,14 @@ struct tilemap_t {
|
||||
#endif
|
||||
} tilemap[MAX_GLYPH];
|
||||
|
||||
#define MAX_TILENAM 30
|
||||
#define MAX_TILENAM 256
|
||||
/* List of tiles encountered and their usage */
|
||||
struct tiles_used {
|
||||
int tilenum;
|
||||
enum tilesrc src;
|
||||
int file_entry;
|
||||
char tilenam[MAX_TILENAM];
|
||||
char references[120];
|
||||
char references[1024];
|
||||
};
|
||||
struct tiles_used *tilelist[2500] = { 0 };
|
||||
|
||||
@@ -1484,7 +1484,8 @@ precheck(int offset, const char *glyphtype)
|
||||
glyphtype);
|
||||
}
|
||||
|
||||
void add_tileref(
|
||||
void
|
||||
add_tileref(
|
||||
int n,
|
||||
int glyphref,
|
||||
enum tilesrc src,
|
||||
@@ -1548,28 +1549,4 @@ free_tilerefs(void)
|
||||
|
||||
#endif
|
||||
|
||||
DISABLE_WARNING_FORMAT_NONLITERAL
|
||||
|
||||
void
|
||||
nh_snprintf(
|
||||
const char *func UNUSED,
|
||||
int line UNUSED,
|
||||
char *str, size_t size,
|
||||
const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
int n;
|
||||
|
||||
va_start(ap, fmt);
|
||||
n = vsnprintf(str, size, fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
if (n < 0 || (size_t) n >= size) { /* is there a problem? */
|
||||
str[size - 1] = 0; /* make sure it is nul terminated */
|
||||
}
|
||||
}
|
||||
|
||||
RESTORE_WARNING_FORMAT_NONLITERAL
|
||||
|
||||
|
||||
/*tilemap.c*/
|
||||
|
||||
Reference in New Issue
Block a user