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:
nhmall
2024-03-07 11:01:04 -05:00
parent c22900fb63
commit 50811037f3
43 changed files with 5913 additions and 5677 deletions
+1
View File
@@ -55,6 +55,7 @@
#include <string.h>
#include <signal.h>
#include <assert.h>
#include <stdarg.h>
#endif /* !__cplusplus */
#endif /* CSTD_H */
-9
View File
@@ -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
View File
@@ -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
View File
@@ -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"
+83
View File
@@ -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 */
+11
View File
@@ -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 */
+18
View File
@@ -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
View File
@@ -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
View File
@@ -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 */
+4 -1867
View File
File diff suppressed because it is too large Load Diff
+6 -5
View File
@@ -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
View File
File diff suppressed because it is too large Load Diff
-230
View File
@@ -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)
+82 -695
View File
@@ -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
View File
File diff suppressed because it is too large Load Diff
+28
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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*/
+81
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
File diff suppressed because it is too large Load Diff
+59 -40
View File
@@ -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
+1 -1
View File
@@ -10,7 +10,7 @@
extern "C" {
#include "config.h"
#define CPPREGEX_C
#include "extern.h"
//#include "extern.h"
} // extern "C"
+61 -41
View File
@@ -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
View File
@@ -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
+4 -2
View File
@@ -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)
+49
View File
@@ -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
+6 -2
View File
@@ -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
#
#
+4 -2
View File
@@ -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
View File
@@ -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)
+9 -8
View File
@@ -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:
+40 -14
View File
@@ -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$@
+4 -1
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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);
}
+2
View File
@@ -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
View File
@@ -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*/