NetHack Community Patches (or Variation) Included
-------------------------------------------------
Malcolm Ryan's improved tin opener
+Ray Chason's keyboard may stop responding after locking or unlocking a door when
+ using altkeyhandler=nhraykey.dll
+Ray Chason's fix: window interfaces that support transparency may give away unseen
+ parts of the map
+Ray Chason's xprname should honor iflags.menu_tab_sep
+Ray Chason's punctuation for "That foo is really a mimic."
+Ray Chason's proper background tiles for lava and water
+Ray Chason's MS-DOS port restored to functionality with credit to Reddit user
+ b_helyer for the fix to sys/share/pcmain.c
+Ray Chason's MSDOS port support for some VESA modes
Code Cleanup and Reorganization
-/* NetHack 3.6 flag.h $NHDT-Date: 1451683047 2016/01/01 21:17:27 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.93 $ */
+/* NetHack 3.6 flag.h $NHDT-Date: 1457207000 2016/03/05 19:43:20 $ $NHDT-Branch: chasonr $:$NHDT-Revision: 1.101 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
#ifdef MSDOS
boolean hasvga; /* has a vga adapter */
boolean usevga; /* use the vga adapter */
+ boolean hasvesa; /* has a VESA-capable VGA adapter */
+ boolean usevesa; /* use the VESA-capable VGA adapter */
boolean grmode; /* currently in graphics mode */
#endif
#ifdef LAN_FEATURES
-/* NetHack 3.6 pcconf.h $NHDT-Date: 1432512776 2015/05/25 00:12:56 $ $NHDT-Branch: master $:$NHDT-Revision: 1.17 $ */
+/* NetHack 3.6 pcconf.h $NHDT-Date: 1457207019 2016/03/05 19:43:39 $ $NHDT-Branch: chasonr $:$NHDT-Revision: 1.19 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
#if (defined(SCREEN_BIOS) || defined(SCREEN_DJGPPFAST)) && !defined(PC9800)
#ifdef USE_TILES
#define SCREEN_VGA /* Include VGA graphics routines in the build */
+#define SCREEN_VESA
#endif
#endif
#else
#undef SCREEN_BIOS
#undef SCREEN_DJGPPFAST
#undef SCREEN_VGA
+#undef SCREEN_VESA
#undef TERMLIB
#define ANSI_DEFAULT
#endif
#endif
/* SCREEN_8514, SCREEN_VESA are only placeholders presently - sub VGA instead
*/
-#if defined(SCREEN_8514) || defined(SCREEN_VESA)
+#if defined(SCREEN_8514)
#undef SCREEN_8514
-#undef SCREEN_VESA
#define SCREEN_VGA
#endif
/* Graphical tile sanity checks */
--- /dev/null
+/* NetHack 3.6 tileset.h $NHDT-Date: 1457207052 2016/03/05 19:44:12 $ $NHDT-Branch: chasonr $:$NHDT-Revision: 1.0 $ */
+/* Copyright (c) Ray Chason, 2016. */
+/* NetHack may be freely redistributed. See license for details. */
+
+#ifndef TILESET_H
+#define TILESET_H
+
+struct Pixel {
+ unsigned char r, g, b, a;
+};
+
+struct TileImage {
+ /* Image data */
+ unsigned width, height;
+ struct Pixel *pixels; /* for direct color */
+ unsigned char *indexes; /* for paletted images */
+};
+
+boolean FDECL(read_tiles, (const char *filename, BOOLEAN_P true_color));
+const struct Pixel *NDECL(get_palette);
+void NDECL(free_tiles);
+const struct TileImage *FDECL(get_tile, (unsigned tile_index));
+
+/* Used internally by the tile set code */
+struct TileSetImage {
+ /* Image data */
+ unsigned width, height;
+ struct Pixel *pixels; /* for direct color */
+ unsigned char *indexes; /* for paletted images */
+ struct Pixel palette[256];
+
+ /* Image description from the file */
+ char *image_desc;
+
+ /* Tile dimensions */
+ unsigned tile_width, tile_height;
+};
+
+boolean FDECL(read_bmp_tiles, (const char *filename, struct TileSetImage *image));
+boolean FDECL(read_gif_tiles, (const char *filename, struct TileSetImage *image));
+boolean FDECL(read_png_tiles, (const char *filename, struct TileSetImage *image));
+
+#endif
-/* NetHack 3.6 apply.c $NHDT-Date: 1456528594 2016/02/26 23:16:34 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.222 $ */
+/* NetHack 3.6 apply.c $NHDT-Date: 1457207021 2016/03/05 19:43:41 $ $NHDT-Branch: chasonr $:$NHDT-Revision: 1.223 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
break;
}
seemimic(mtmp);
- pline("That %s is really %s", what, mnm);
+ pline("That %s is really %s.", what, mnm);
} else if (flags.verbose && !canspotmon(mtmp)) {
There("is %s there.", mnm);
}
-/* NetHack 3.6 cmd.c $NHDT-Date: 1452660189 2016/01/13 04:43:09 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.219 $ */
+/* NetHack 3.6 cmd.c $NHDT-Date: 1457207033 2016/03/05 19:43:53 $ $NHDT-Branch: chasonr $:$NHDT-Revision: 1.220 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
return 0;
}
-#ifdef TTY_GRAPHICS
+#if defined(TTY_GRAPHICS) || defined(CURSES_GRAPHICS)
#define MAX_EXT_CMD 50 /* Change if we ever have > 50 ext cmds */
/*
-/* NetHack 3.6 display.c $NHDT-Date: 1446808439 2015/11/06 11:13:59 $ $NHDT-Branch: master $:$NHDT-Revision: 1.77 $ */
+/* NetHack 3.6 display.c $NHDT-Date: 1457207034 2016/03/05 19:43:54 $ $NHDT-Branch: chasonr $:$NHDT-Revision: 1.82 $ */
/* Copyright (c) Dean Luick, with acknowledgements to Kevin Darcy */
/* and Dave Cohrs, 1990. */
/* NetHack may be freely redistributed. See license for details. */
int idx, bkglyph = NO_GLYPH;
struct rm *lev = &levl[x][y];
- if (iflags.use_background_glyph) {
+ if (iflags.use_background_glyph && lev->seenv != 0
+ && gbuf[y][x].glyph != cmap_to_glyph(S_stone)) {
switch (lev->typ) {
case SCORR:
case STONE:
case CLOUD:
idx = S_cloud;
break;
+ case POOL:
+ case MOAT:
+ idx = S_pool;
+ break;
case WATER:
idx = S_water;
break;
+ case LAVAPOOL:
+ idx = S_lava;
+ break;
default:
idx = S_room;
break;
-/* NetHack 3.6 invent.c $NHDT-Date: 1456907837 2016/03/02 08:37:17 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.196 $ */
+/* NetHack 3.6 invent.c $NHDT-Date: 1457207035 2016/03/05 19:43:55 $ $NHDT-Branch: chasonr $:$NHDT-Revision: 1.197 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
*/
if (cost != 0 || let == '*') {
/* if dot is true, we're doing Iu, otherwise Ix */
- Sprintf(li, "%c - %-45s %6ld %s",
+ Sprintf(li,
+ iflags.menu_tab_sep ? "%c - %s\t%6ld %s"
+ : "%c - %-45s %6ld %s",
(dot && use_invlet ? obj->invlet : let),
(txt ? txt : doname(obj)), cost, currency(cost));
} else {
-# NetHack 3.6 Makefile.GCC $NHDT-Date: 1432512792 2015/05/25 00:13:12 $ $NHDT-Branch: master $:$NHDT-Revision: 1.28 $
+# NetHack 3.6 Makefile.GCC $NHDT-Date: 1457207036 2016/03/05 19:43:56 $ $NHDT-Branch: chasonr $:$NHDT-Revision: 1.29 $
# Copyright (c) NetHack PC Development Team 1996-2006.
# PC NetHack 3.6 Makefile for djgpp V2
#
#
# If you have yacc/lex or a work-alike set YACC_LEX to Y
#
-YACC_LEX = Y
+YACC_LEX = N
ifeq ($(YACC_LEX),Y)
DO_YACC = YACC_ACT
DO_LEX = LEX_ACT
else
# Debugging
-#cflags = -pg -c -I../include $(DLBFLG) -DUSE_TILES
-#LFLAGS = -pg
+#cflags = -g -c -I../include $(DLBFLG) -DUSE_TILES
+#LFLAGS = -g
# Normal
cflags = -c -O -I../include $(DLBFLG) -DUSE_TILES
#================ RULES ==================
#==========================================
-.SUFFIXES: .exe .o .tib .til .uu .c .y .l
+.SUFFIXES: .exe .o .til .uu .c .y .l
#==========================================
# Rules for files in src
# Utility Objects.
#==========================================
-VGAOBJ = $(O)vidvga.o
+VGAOBJ = $(O)vidvga.o $(O)vidvesa.o
MAKESRC = makedefs.c
ifeq ($(SUPPRESS_GRAPHICS),Y)
TILOBJ =
+TILOBJ2 =
TEXTIO =
TEXTIO2 =
-PLANAR_TIB =
-OVERVIEW_TIB =
+TILE_BMP =
TILEUTIL =
TILEFILES =
TILEFILES2 =
else
-TILOBJ = $(O)tile.o $(O)pctiles.o $(VGAOBJ)
+TILOBJ = $(O)tile.o $(VGAOBJ)
+
+TILOBJ2 = $(O)tileset.o $(O)bmptiles.o $(O)giftiles.o
TEXTIO = $(O)tiletext.o $(O)tiletxt.o $(O)drawing.o $(O)decl.o $(O)monst.o \
$(O)objects.o $(O)stubvid.o
TEXTIO2 = $(O)tiletex2.o $(O)tiletxt2.o $(O)drawing.o $(O)decl.o $(O)monst.o \
$(O)objects.o $(O)stubvid.o
-PLANAR_TIB = $(DAT)/NetHack1.tib
-
-OVERVIEW_TIB = $(DAT)/NetHacko.tib
+TILE_BMP = $(DAT)/nhtiles.bmp
-TILEUTIL = $(TILOBJ) $(U)tile2bin.exe $(U)til2bin2.exe $(PLANAR_TIB) $(OVERVIEW_TIB)
+TILEUTIL = $(TILOBJ) $(U)tile2bin.exe $(U)til2bin2.exe $(TILE_BMP)
TILEFILES = $(WSHR)/monsters.txt $(WSHR)/objects.txt $(WSHR)/other.txt
VOBJ20 = $(O)vis_tab.o $(O)weapon.o $(O)were.o $(O)wield.o $(O)windows.o
VOBJ21 = $(O)wintty.o $(O)wizard.o $(O)worm.o $(O)worn.o $(O)write.o
VOBJ22 = $(O)zap.o $(O)light.o $(O)dlb.o $(O)dig.o $(O)teleport.o
-VOBJ23 = $(O)region.o $(O)sys.o
+VOBJ23 = $(O)region.o $(O)sys.o $(O)pmatchre.o $(O)string.o $(O)unicode.o
SOBJ = $(O)msdos.o $(O)sound.o $(O)pcsys.o $(O)tty.o $(O)unix.o \
$(O)video.o $(O)vidtxt.o $(O)pckeys.o
$(VOBJ16) $(VOBJ17) $(VOBJ18) $(VOBJ19) $(VOBJ20) \
$(VOBJ21) $(VOBJ22) $(VOBJ23)
-ALLOBJ = $(VOBJ) $(SOBJ) $(TILOBJ) $(VVOBJ)
+ALLOBJ = $(VOBJ) $(SOBJ) $(TILOBJ) $(TILOBJ2) $(VVOBJ)
#==========================================
# Header file macros
ifeq ($(SUPPRESS_GRAPHICS),Y)
TILE_H =
else
-TILE_H = $(WSHR)/tile.h $(MSYS)/pctiles.h
+TILE_H = $(WSHR)/tile.h $(INCL)/tileset.h
endif
ifeq ($(USE_DLB),Y)
ifdef TERMLIB
@$(subst /,\,copy $(SSHR)/termcap $(GAMEDIR))
endif
- @$(subst /,\,if exist $(DAT)/*.tib copy $(DAT)/*.tib $(GAMEDIR))
+ @$(subst /,\,if exist $(TILE_BMP) copy $(TILE_BMP) $(GAMEDIR))
@$(subst /,\,if exist $(DAT)/symbols copy $(DAT)/symbols $(GAMEDIR))
@$(subst /,\,copy $(SSHR)/NetHack.cnf $(GAMEDIR)/defaults.nh)
- @$(subst /,\,copy $(MSYS)/NHAccess.nh $(GAMEDIR))
+ -@$(subst /,\,touch $(GAMEDIR)/record)
@$(subst /,\,copy $(DOC)/guidebo*.txt $(GAMEDIR))
+ @$(subst /,\,copy ../sys/winnt/sysconf $(GAMEDIR))
@$(subst /,\,if exist $(DOC)/nethack.txt copy $(DOC)/nethack.txt $(GAMEDIR))
ifdef CWSDPMI
@$(subst /,\,if exist $(CWSDPMI) copy $(CWSDPMI) $(GAMEDIR))
#==========================================
$(GAMEFILE): $(O)obj.tag $(PATCHLEV_H) $(O)utility.tag $(ALLOBJ) $(O)$(GAME).lnk
- $(LINK) $(LFLAGS) -o$(GAME).exe @$(O)$(GAME).lnk $(LIBRARIES) $(ZLIB)
+ @if exist temp.a del temp.a
+ @ar ru temp.a $(VOBJ01)
+ @ar ru temp.a $(VOBJ02)
+ @ar ru temp.a $(VOBJ03)
+ @ar ru temp.a $(VOBJ04)
+ @ar ru temp.a $(VOBJ05)
+ @ar ru temp.a $(VOBJ06)
+ @ar ru temp.a $(VOBJ07)
+ @ar ru temp.a $(VOBJ08)
+ @ar ru temp.a $(VOBJ09)
+ @ar ru temp.a $(VOBJ10)
+ @ar ru temp.a $(VOBJ11)
+ @ar ru temp.a $(VOBJ12)
+ @ar ru temp.a $(VOBJ13)
+ @ar ru temp.a $(VOBJ14)
+ @ar ru temp.a $(VOBJ15)
+ @ar ru temp.a $(VOBJ16)
+ @ar ru temp.a $(VOBJ17)
+ @ar ru temp.a $(VOBJ18)
+ @ar ru temp.a $(VOBJ19)
+ @ar ru temp.a $(VOBJ20)
+ @ar ru temp.a $(VOBJ21)
+ @ar ru temp.a $(VOBJ22)
+ @ar ru temp.a $(VOBJ23)
+ @ar ru temp.a $(SOBJ)
+ @ar ru temp.a $(TILOBJ)
+ @ar ru temp.a $(TILOBJ2)
+ @ar ru temp.a $(VVOBJ)
+ $(LINK) $(LFLAGS) -o$(GAME).exe temp.a $(LIBRARIES) $(ZLIB)
@$(subst /,\,stubedit $(GAME).exe minstack=2048K)
@$(subst /,\,copy $(GAME).exe $(GAMEFILE))
@$(subst /,\,del $(GAME).exe)
echo $(VOBJ23) >> $(subst /,\,$@)
echo $(SOBJ) >> $(subst /,\,$@)
echo $(TILOBJ) >> $(subst /,\,$@)
+ echo $(TILOBJ2) >> $(subst /,\,$@)
echo $(VVOBJ) >> $(subst /,\,$@)
$(subst /,\,if exist $(O)sp_lev.tag del $(O)sp_lev.tag)
$(subst /,\,if exist $(O)thintile.tag del $(O)thintile.tag)
$(subst /,\,if exist $(O)utility.tag del $(O)utility.tag)
+ $(subst /,\,if exist temp.a del temp.a)
spotless: clean
$(subst /,\,if exist $(U)dgn_comp.exe del $(U)dgn_comp.exe)
$(subst /,\,if exist $(U)recover.exe del $(U)recover.exe)
$(subst /,\,if exist $(U)tilemap.exe del $(U)tilemap.exe)
+ $(subst /,\,if exist $(U)tile2bmp.exe del $(U)tile2bmp.exe)
$(subst /,\,if exist $(U)tile2bin.exe del $(U)tile2bin.exe)
$(subst /,\,if exist $(U)til2bin2.exe del $(U)til2bin2.exe)
$(subst /,\,if exist $(U)thintile.exe del $(U)thintile.exe)
$(subst /,\,if exist $(DAT)/dungeon del $(DAT)/dungeon)
$(subst /,\,if exist $(DAT)/oracles del $(DAT)/oracles)
$(subst /,\,if exist $(DAT)/quest.dat del $(DAT)/quest.dat)
+ $(subst /,\,if exist $(DAT)/bogusmon del $(DAT)/bogusmon)
+ $(subst /,\,if exist $(DAT)/engrave del $(DAT)/engrave)
+ $(subst /,\,if exist $(DAT)/epitaph del $(DAT)/epitaph)
$(subst /,\,if exist $(DAT)/dlb.lst del $(DAT)/dlb.lst)
$(subst /,\,if exist $(DAT)/nhdat del $(DAT)/nhdat)
$(subst /,\,if exist $(DAT)/*.lev del $(DAT)/*.lev)
- $(subst /,\,if exist $(PLANAR_TIB) del $(PLANAR_TIB))
- $(subst /,\,if exist $(OVERVIEW_TIB) del $(OVERVIEW_TIB))
+ $(subst /,\,if exist $(TILE_BMP) del $(TILE_BMP))
$(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)
#==========================================
$(U)lev_comp.exe: $(SPLEVOBJS)
- $(LINK) $(LFLAGS) -o$@ $(SPLEVOBJS)
+ @rm -f temp.a
+ @ar ru temp.a $(SPLEVOBJS)
+ $(LINK) $(LFLAGS) -o$@ temp.a
ifeq ($(YACC_LEX),Y)
# Required for tile support
#==========================================
-$(DAT)/NetHack1.tib: $(TILEFILES) $(U)tile2bin.exe
+$(DAT)/nhtiles.bmp: $(TILEFILES) $(U)tile2bmp.exe
@echo Creating binary tile files (this may take some time)
@$(subst /,\,chdir $(DAT))
- @$(subst /,\,$(U)tile2bin.exe)
+ @$(subst /,\,$(U)tile2bmp.exe $@)
@$(subst /,\,chdir $(SRC))
-$(DAT)/NetHacko.tib: $(O)thintile.tag $(TILEFILES2) $(U)til2bin2.exe
- @echo Creating overview binary tile files (this may take some time)
- @$(subst /,\,chdir $(DAT))
- @$(subst /,\,$(U)til2bin2.exe)
- @$(subst /,\,chdir $(SRC))
+$(U)tile2bmp.exe: $(O)tile2bmp.o $(TEXTIO)
+ @rm -f temp.a
+ @ar ru temp.a $(TEXTIO)
+ $(LINK) $(LFLAGS) -o$@ $(O)tile2bmp.o temp.a
$(U)tile2bin.exe: $(O)tile2bin.o $(TEXTIO)
- $(LINK) $(LFLAGS) -o$@ $(O)tile2bin.o $(TEXTIO)
+ @rm -f temp.a
+ @ar ru temp.a $(TEXTIO)
+ $(LINK) $(LFLAGS) -o$@ $(O)tile2bin.o temp.a
$(U)til2bin2.exe: $(O)til2bin2.o $(TEXTIO2)
- $(LINK) $(LFLAGS) -o$@ $(O)til2bin2.o $(TEXTIO2)
+ @rm -f temp.a
+ @ar ru temp.a $(TEXTIO2)
+ $(LINK) $(LFLAGS) -o$@ $(O)til2bin2.o temp.a
$(U)thintile.exe: $(O)thintile.o
$(LINK) $(LFLAGS) -o$@ $(O)thintile.o
@$(subst /,\,$(U)thintile.exe)
@$(subst /,\,echo thintiles created >$@)
+$(O)tile2bmp.o: $(HACK_H) $(TILE_H) $(WSHR)/tile2bmp.c
+ $(CC) $(cflags) -I$(MSYS) -I$(WSHR) -o$@ $(WSHR)/tile2bmp.c
+
$(O)tile2bin.o: $(HACK_H) $(TILE_H) $(MSYS)/pctiles.h $(MSYS)/pcvideo.h $(MSYS)/tile2bin.c
$(CC) $(cflags) -I$(MSYS) -I$(WSHR) -o$@ $(MSYS)/tile2bin.c
$(DAT)/oracles: $(O)utility.tag $(DAT)/oracles.txt
@$(subst /,\,$(U)makedefs.exe -h)
+$(DAT)/bogusmon: $(O)utility.tag $(DAT)/bogusmon.txt
+ @$(subst /,\,$(U)makedefs.exe -s)
+
+$(DAT)/engrave: $(O)utility.tag $(DAT)/engrave.txt
+ @$(subst /,\,$(U)makedefs.exe -s)
+
+$(DAT)/epitaph: $(O)utility.tag $(DAT)/epitaph.txt
+ @$(subst /,\,$(U)makedefs.exe -s)
+
$(O)sp_lev.tag: $(O)utility.tag $(DAT)/bigroom.des $(DAT)/castle.des \
$(DAT)/endgame.des $(DAT)/gehennom.des $(DAT)/knox.des \
$(DAT)/medusa.des $(DAT)/oracle.des $(DAT)/tower.des \
#note that dir below assumes bin/dir.exe from djgpp distribution
#
$(DAT)/nhdat: $(U)dlb_main.exe $(DAT)/data $(DAT)/rumors $(DAT)/dungeon \
- $(DAT)/oracles $(DAT)/quest.dat $(O)sp_lev.tag
+ $(DAT)/oracles $(DAT)/quest.dat $(O)sp_lev.tag \
+ $(DAT)/bogusmon $(DAT)/engrave $(DAT)/epitaph $(DAT)/tribute
@$(subst /,\,echo dat done >$(O)dat.tag)
@$(subst /,\,cd $(DAT))
@$(subst /,\,copy $(MSYS)/msdoshlp.txt .)
- @$(subst /,\,echo data >dlb.lst)
- @$(subst /,\,echo dungeon >>dlb.lst)
- @$(subst /,\,echo oracles >>dlb.lst)
- @$(subst /,\,echo options >>dlb.lst)
- @$(subst /,\,echo quest.dat >>dlb.lst)
- @$(subst /,\,echo rumors >>dlb.lst)
- @$(subst /,\,echo help >>dlb.lst)
- @$(subst /,\,echo hh >>dlb.lst)
- @$(subst /,\,echo cmdhelp >>dlb.lst)
- @$(subst /,\,echo history >>dlb.lst)
- @$(subst /,\,echo opthelp >>dlb.lst)
- @$(subst /,\,echo wizhelp >>dlb.lst)
- @$(subst /,\,echo license >>dlb.lst)
- @$(subst /,\,echo msdoshlp.txt >>dlb.lst)
+ @$(LS) data dungeon oracles options quest.dat rumors help hh >dlb.lst
+ @$(LS) cmdhelp history opthelp wizhelp license msdoshlp.txt >>dlb.lst
+ @$(LS) bogusmon engrave epitaph tribute >>dlb.lst
$(LS) $(subst /,\,*.lev) >>dlb.lst
@$(subst /,\,$(U)dlb_main cvIf dlb.lst nhdat)
@$(subst /,\,cd $(SRC))
$(O)vidvga.o : $(HACK_H) $(MSYS)/pcvideo.h $(MSYS)/portio.h $(TILE_H) $(MSYS)/vidvga.c
$(CC) $(cflags) -I$(MSYS) -I$(WSHR) -o$@ $(MSYS)/vidvga.c
+$(O)vidvesa.o : $(HACK_H) $(MSYS)/pcvideo.h $(MSYS)/portio.h $(TILE_H) $(MSYS)/vidvesa.c
+ $(CC) $(cflags) -I$(MSYS) -I$(WSHR) -o$@ $(MSYS)/vidvesa.c
+
$(O)vidtxt.o : $(HACK_H) $(MSYS)/pcvideo.h $(MSYS)/portio.h $(TILE_H) $(MSYS)/vidtxt.c
# $(CC) $(cflags) -o$@ -I$(MSYS) $(MSYS)/vidtxt.c
$(O)worn.o: worn.c $(HACK_H)
$(O)write.o: write.c $(HACK_H)
$(O)zap.o: zap.c $(HACK_H)
+$(O)pmatchre.o: $(SSHR)/pmatchre.c $(HACK_H)
+$(O)tileset.o: $(WSHR)/tileset.c $(HACK_H)
+$(O)bmptiles.o: $(WSHR)/bmptiles.c $(INCL)/config.h $(INCL)/tileset.h $(INCL)/integer.h
+$(O)giftiles.o: $(WSHR)/giftiles.c $(INCL)/config.h $(INCL)/tileset.h $(INCL)/integer.h
# end of file
-/* NetHack 3.6 pckeys.c $NHDT-Date: 1432512792 2015/05/25 00:13:12 $ $NHDT-Branch: master $:$NHDT-Revision: 1.10 $ */
+/* NetHack 3.6 pckeys.c $NHDT-Date: 1457207039 2016/03/05 19:43:59 $ $NHDT-Branch: chasonr $:$NHDT-Revision: 1.11 $ */
/* Copyright (c) NetHack PC Development Team 1996 */
/* NetHack may be freely redistributed. See license for details. */
#include "pcvideo.h"
boolean FDECL(pckeys, (unsigned char, unsigned char));
+static void FDECL(userpan, (BOOLEAN_P));
+static void FDECL(overview, (BOOLEAN_P));
+static void FDECL(traditional, (BOOLEAN_P));
+static void NDECL(refresh);
extern struct WinDesc *wins[MAXWIN]; /* from wintty.c */
extern boolean inmap; /* from video.c */
#endif
case 0x74: /* Control-right_arrow = scroll horizontal to right */
if ((shift & CTRL) && iflags.tile_view && !opening_dialog)
- vga_userpan(1);
+ userpan(1);
break;
case 0x73: /* Control-left_arrow = scroll horizontal to left */
if ((shift & CTRL) && iflags.tile_view && !opening_dialog)
- vga_userpan(0);
+ userpan(0);
break;
case 0x3E: /* F4 = toggle overview mode */
if (iflags.tile_view && !opening_dialog && !Is_rogue_level(&u.uz)) {
iflags.traditional_view = FALSE;
- vga_overview(iflags.over_view ? FALSE : TRUE);
- vga_refresh();
+ overview(iflags.over_view ? FALSE : TRUE);
+ refresh();
}
break;
case 0x3F: /* F5 = toggle traditional mode */
if (iflags.tile_view && !opening_dialog && !Is_rogue_level(&u.uz)) {
iflags.over_view = FALSE;
- vga_traditional(iflags.traditional_view ? FALSE : TRUE);
- vga_refresh();
+ traditional(iflags.traditional_view ? FALSE : TRUE);
+ refresh();
}
break;
default:
}
return TRUE;
}
+
+static void
+userpan(on)
+boolean on;
+{
+#ifdef SCREEN_VGA
+ if (iflags.usevga)
+ vga_userpan(on);
+#endif
+#ifdef SCREEN_VESA
+ if (iflags.usevesa)
+ vesa_userpan(on);
+#endif
+}
+
+static void
+overview(on)
+boolean on;
+{
+#ifdef SCREEN_VGA
+ if (iflags.usevga)
+ vga_overview(on);
+#endif
+#ifdef SCREEN_VESA
+ if (iflags.usevesa)
+ vesa_overview(on);
+#endif
+}
+
+static void
+traditional(on)
+boolean on;
+{
+#ifdef SCREEN_VGA
+ if (iflags.usevga)
+ vga_traditional(on);
+#endif
+#ifdef SCREEN_VESA
+ if (iflags.usevesa)
+ vesa_traditional(on);
+#endif
+}
+
+static void
+refresh()
+{
+#ifdef SCREEN_VGA
+ if (iflags.usevga)
+ vga_refresh();
+#endif
+#ifdef SCREEN_VESA
+ if (iflags.usevesa)
+ vesa_refresh();
+#endif
+}
#endif /* USE_TILES */
#endif /* MSDOS */
-/* NetHack 3.6 pctiles.h $NHDT-Date: 1432512791 2015/05/25 00:13:11 $ $NHDT-Branch: master $:$NHDT-Revision: 1.8 $ */
+/* NetHack 3.6 pctiles.h $NHDT-Date: 1457207040 2016/03/05 19:44:00 $ $NHDT-Branch: chasonr $:$NHDT-Revision: 1.9 $ */
/* Copyright (c) NetHack PC Development Team 1993, 1994 */
/* NetHack may be freely redistributed. See license for details. */
/* */
*/
#ifdef USE_TILES
+#ifndef TILE_X
+#define TILE_X 16
+#endif
+
#define NETHACK_PLANAR_TILEFILE "NetHack1.tib" /* Planar style tiles */
#define NETHACK_PACKED_TILEFILE "NetHack2.tib" /* Packed style tiles */
#define NETHACK_OVERVIEW_TILEFILE "NetHacko.tib" /* thin overview tiles */
-/* NetHack 3.6 pcvideo.h $NHDT-Date: 1432512792 2015/05/25 00:13:12 $ $NHDT-Branch: master $:$NHDT-Revision: 1.8 $ */
+/* NetHack 3.6 pcvideo.h $NHDT-Date: 1457207040 2016/03/05 19:44:00 $ $NHDT-Branch: chasonr $:$NHDT-Revision: 1.9 $ */
/* Copyright (c) NetHack PC Development Team 1993, 1994 */
/* NetHack may be freely redistributed. See license for details. */
/* */
#define M_BRIGHTCYAN 11
#define M_TEXT M_GRAY
-#define BACKGROUND_COLOR 0
+#define BACKGROUND_COLOR 1
#define ATTRIB_NORMAL M_TEXT /* Normal attribute */
#define ATTRIB_INTENSE M_WHITE /* Intense White */
#define ATTRIB_MONO_NORMAL 0x01 /* Underlined,white */
#endif /*SCREEN_BIOS || SCREEN_DJGPPFAST */
#if defined(SCREEN_VGA) || defined(SCREEN_8514)
-#define BACKGROUND_VGA_COLOR 0
+#define BACKGROUND_VGA_COLOR 1
#define ATTRIB_VGA_NORMAL CLR_GRAY /* Normal attribute */
-#define ATTRIB_VGA_INTENSE 13 /* Intense White 94/06/07 palette chg*/
+#define ATTRIB_VGA_INTENSE 14 /* Intense White 94/06/07 palette chg*/
#endif /*SCREEN_VGA || SCREEN_8514*/
#if defined(PC9800)
#ifdef SIMULATE_CURSOR
E void NDECL(vga_DrawCursor);
#endif
-E void FDECL(vga_DisplayCell, (struct planar_cell_struct *, int, int));
-E void FDECL(vga_DisplayCell_O,
- (struct overview_planar_cell_struct *, int, int));
E void NDECL(vga_Finish);
E char __far *NDECL(vga_FontPtrs);
E void NDECL(vga_get_scr_size);
E void NDECL(vga_HideCursor);
#endif
E void NDECL(vga_Init);
-E void FDECL(vga_SwitchMode, (unsigned int));
-E void FDECL(vga_SetPalette, (char *));
E void NDECL(vga_tty_end_screen);
E void FDECL(vga_tty_startup, (int *, int *));
-E void FDECL(vga_WriteChar, (int, int, int, int));
-E void FDECL(vga_WriteStr, (char *, int, int, int, int));
E void FDECL(vga_xputs, (const char *, int, int));
E void FDECL(vga_xputc, (CHAR_P, int));
E void FDECL(vga_xputg, (int, int, unsigned));
E void FDECL(vga_traditional, (BOOLEAN_P));
E void NDECL(vga_refresh);
#endif /* SCREEN_VGA */
+#ifdef SCREEN_VESA
+E void NDECL(vesa_backsp);
+E void FDECL(vesa_clear_screen, (int));
+E void FDECL(vesa_cl_end, (int, int));
+E void FDECL(vesa_cl_eos, (int));
+E int NDECL(vesa_detect);
+#ifdef SIMULATE_CURSOR
+E void NDECL(vesa_DrawCursor);
+#endif
+E void NDECL(vesa_Finish);
+E void NDECL(vesa_get_scr_size);
+E void FDECL(vesa_gotoloc, (int, int));
+#ifdef POSITIONBAR
+E void FDECL(vesa_update_positionbar, (char *));
+#endif
+#ifdef SIMULATE_CURSOR
+E void NDECL(vesa_HideCursor);
+#endif
+E void NDECL(vesa_Init);
+E void NDECL(vesa_tty_end_screen);
+E void FDECL(vesa_tty_startup, (int *, int *));
+E void FDECL(vesa_xputs, (const char *, int, int));
+E void FDECL(vesa_xputc, (CHAR_P, int));
+E void FDECL(vesa_xputg, (int, int, unsigned));
+E void FDECL(vesa_userpan, (BOOLEAN_P));
+E void FDECL(vesa_overview, (BOOLEAN_P));
+E void FDECL(vesa_traditional, (BOOLEAN_P));
+E void NDECL(vesa_refresh);
+#endif /* SCREEN_VESA */
#endif /* NO_TERMS */
#undef E
-/* NetHack 3.6 tile2bin.c $NHDT-Date: 1432512792 2015/05/25 00:13:12 $ $NHDT-Branch: master $:$NHDT-Revision: 1.8 $ */
+/* NetHack 3.6 tile2bin.c $NHDT-Date: 1457207041 2016/03/05 19:44:01 $ $NHDT-Branch: chasonr $:$NHDT-Revision: 1.9 $ */
/* Copyright (c) NetHack PC Development Team 1993, 1994, 1995 */
/* NetHack may be freely redistributed. See license for details. */
extern unsigned _stklen = STKSIZ;
#endif
+/* Produce only a planar file if building the overview file; with packed
+ files, we can make overview-size tiles on the fly */
+#if defined(OVERVIEW_FILE) && defined(PACKED_FILE)
+#undef PACKED_FILE
+#endif
+
extern char *FDECL(tilename, (int, int));
#ifdef PLANAR_FILE
static void FDECL(write_tibtile, (int));
static void FDECL(write_tibheader, (FILE *, struct tibhdr_struct *));
-static void FDECL(build_tibtile, (pixel(*) [TILE_X]));
+static void FDECL(build_tibtile, (pixel(*) [TILE_X], BOOLEAN_P));
+static void NDECL(remap_colors);
#ifndef OVERVIEW_FILE
char *tilefiles[] = { "../win/share/monsters.txt", "../win/share/objects.txt",
struct tm *newtime;
time_t aclock;
char *paletteptr;
+ unsigned num_monsters = 0;
if (argc != 1) {
Fprintf(stderr, "usage: tile2bin (from the util directory)\n");
}
if (!paletteflag) {
+ remap_colors();
paletteptr = tibheader.palette;
for (i = 0; i < num_colors; i++) {
*paletteptr++ = ColorMap[CM_RED][i],
}
while (read_text_tile(pixels)) {
- build_tibtile(pixels);
+ build_tibtile(pixels, FALSE);
write_tibtile(tilecount);
tilecount++;
}
(void) fclose_text_file();
+ if (filenum == 0) {
+ num_monsters = tilecount;
+ }
++filenum;
}
+ /* Build the statue glyphs */
+ if (!fopen_text_file(tilefiles[0], RDTMODE)) {
+ Fprintf(stderr,
+ "usage: tile2bin (from the util or src directory)\n");
+ exit(EXIT_FAILURE);
+ }
+
+ while (read_text_tile(pixels)) {
+ build_tibtile(pixels, TRUE);
+ write_tibtile(tilecount);
+ tilecount++;
+ }
+
+ (void) fclose_text_file();
+
#if defined(_MSC_VER)
tibheader.compiler = MSC_COMP;
#elif defined(__BORLANDC__)
}
static void
-build_tibtile(pixels)
+build_tibtile(pixels, statues)
pixel (*pixels)[TILE_X];
+boolean statues;
{
+ static int graymappings[] = {
+ /* . A B C D E F G H I J K L M N O P */
+ 0, 1, 17, 18, 19, 20, 27, 22, 23, 24, 25, 26, 21, 15, 13, 14, 14
+ };
int i, j, k, co_off;
unsigned char co_mask, tmp;
+#ifdef PLANAR_FILE
#ifndef OVERVIEW_FILE
memset((void *) &planetile, 0, sizeof(struct planar_cell_struct));
#else
memset((void *) &planetile, 0,
sizeof(struct overview_planar_cell_struct));
+#endif
#endif
for (j = 0; j < TILE_Y; j++) {
for (i = 0; i < TILE_X; i++) {
}
if (k >= num_colors)
Fprintf(stderr, "color not in colormap!\n");
+ if (statues) {
+ k = graymappings[k];
+ } else {
+ if (k == 16) {
+ k = 13;
+ } else if (k == 13) {
+ k = 16;
+ }
+ }
#ifdef PACKED_FILE
packtile[j][i] = k;
#endif
co_mask = masktable[i];
}
+ if (!statues) {
+ if (k == 28) {
+ k = 0;
+ }
+ if (k >= 16) {
+ fprintf(stderr, "Warning: pixel value %d in 16 color bitmap\n", k);
+ }
+ }
tmp = planetile.plane[0].image[j][co_off];
planetile.plane[0].image[j][co_off] =
(k & 0x0008) ? (tmp | co_mask) : (tmp & ~co_mask);
fwrite(&packtile, sizeof(packtile), 1, tibfile2);
#endif
}
+
+static void
+remap_colors()
+{
+ char swap;
+
+ swap = ColorMap[CM_RED][13];
+ ColorMap[CM_RED][13] = ColorMap[CM_RED][16];
+ ColorMap[CM_RED][16] = swap;
+ swap = ColorMap[CM_GREEN][13];
+ ColorMap[CM_GREEN][13] = ColorMap[CM_GREEN][16];
+ ColorMap[CM_GREEN][16] = swap;
+ swap = ColorMap[CM_BLUE][13];
+ ColorMap[CM_BLUE][13] = ColorMap[CM_BLUE][16];
+ ColorMap[CM_BLUE][16] = swap;
+}
-/* NetHack 3.6 video.c $NHDT-Date: 1432512791 2015/05/25 00:13:11 $ $NHDT-Branch: master $:$NHDT-Revision: 1.10 $ */
+/* NetHack 3.6 video.c $NHDT-Date: 1457207042 2016/03/05 19:44:02 $ $NHDT-Branch: chasonr $:$NHDT-Revision: 1.11 $ */
/* Copyright (c) NetHack PC Development Team 1993, 1994, 2001 */
/* NetHack may be freely redistributed. See license for details. */
/* */
if (iflags.usevga) {
vga_get_scr_size();
} else
+#endif
+#ifdef SCREEN_VESA
+ if (iflags.usevesa) {
+ vesa_get_scr_size();
+ } else
#endif
txt_get_scr_size();
}
#ifdef SCREEN_VGA
} else if (iflags.usevga) {
vga_backsp();
+#endif
+#ifdef SCREEN_VESA
+ } else if (iflags.usevesa) {
+ vesa_backsp();
#endif
}
}
#ifdef SCREEN_VGA
} else if (iflags.usevga) {
vga_clear_screen(BACKGROUND_VGA_COLOR);
+#endif
+#ifdef SCREEN_VESA
+ } else if (iflags.usevesa) {
+ vesa_clear_screen(BACKGROUND_VGA_COLOR);
#endif
}
}
#ifdef SCREEN_VGA
} else if (iflags.usevga) {
vga_cl_end(col, row);
+#endif
+#ifdef SCREEN_VESA
+ } else if (iflags.usevesa) {
+ vesa_cl_end(col, row);
#endif
}
tty_curs(BASE_WINDOW, (int) ttyDisplay->curx + 1, (int) ttyDisplay->cury);
#ifdef SCREEN_VGA
} else if (iflags.usevga) {
vga_cl_eos(cy);
+#endif
+#ifdef SCREEN_VESA
+ } else if (iflags.usevesa) {
+ vesa_cl_eos(cy);
#endif
}
tty_curs(BASE_WINDOW, (int) ttyDisplay->curx + 1, (int) ttyDisplay->cury);
#ifdef SCREEN_VGA
} else if (iflags.usevga) {
vga_gotoloc(col, row);
+#endif
+#ifdef SCREEN_VESA
+ } else if (iflags.usevesa) {
+ vesa_gotoloc(col, row);
#endif
}
}
#ifdef SCREEN_VGA
} else if (iflags.usevga) {
vga_gotoloc(0, 0);
+#endif
+#ifdef SCREEN_VESA
+ } else if (iflags.usevesa) {
+ vesa_gotoloc(0, 0);
#endif
}
}
#ifdef SCREEN_VGA
} else if (iflags.usevga) {
vga_gotoloc(col, row);
+#endif
+#ifdef SCREEN_VESA
+ } else if (iflags.usevesa) {
+ vesa_gotoloc(col, row);
#endif
}
}
#ifdef SCREEN_VGA
} else if (iflags.usevga) {
vga_tty_end_screen();
+#endif
+#ifdef SCREEN_VESA
+ } else if (iflags.usevesa) {
+ vesa_tty_end_screen();
#endif
}
}
if (iflags.usevga) {
vga_tty_startup(wid, hgt);
} else
+#endif
+#ifdef SCREEN_VESA
+ if (iflags.usevesa) {
+ vesa_tty_startup(wid, hgt);
+ } else
#endif
txt_startup(wid, hgt);
void
gr_init()
{
- if (iflags.usevga) {
#ifdef SCREEN_VGA
+ if (iflags.usevga) {
vga_Init();
+ } else
#endif
#ifdef SCREEN_VESA
- } else if (iflags.usevesa) {
+ if (iflags.usevesa) {
vesa_Init();
-
+ } else
#endif
#ifdef SCREEN_8514
- } else if (iflags.use8514) {
+ if (iflags.use8514) {
v8514_Init();
+ } else
#endif
- }
+ {}
}
void
gr_finish()
{
if (iflags.grmode) {
- if (iflags.usevga) {
#ifdef SCREEN_VGA
+ if (iflags.usevga) {
vga_Finish();
+ } else
#endif
#ifdef SCREEN_VESA
- } else if (iflags.usevesa) {
+ if (iflags.usevesa) {
vesa_Finish();
+ } else
#endif
#ifdef SCREEN_8514
- } else if (iflags.use8514) {
+ if (iflags.use8514) {
v8514_Finish();
+ } else
#endif
- }
+ {}
}
}
#ifdef SCREEN_VGA
} else if (iflags.usevga) {
vga_xputs(s, col, row);
+#endif
+#ifdef SCREEN_VESA
+ } else if (iflags.usevesa) {
+ vesa_xputs(s, col, row);
#endif
}
}
} else if (iflags.usevga) {
vga_xputc(ch, attribute);
#endif /*SCREEN_VGA*/
+#ifdef SCREEN_VESA
+ } else if (iflags.usevesa) {
+ vesa_xputc(ch, attribute);
+#endif /*SCREEN_VESA*/
}
}
if (!iflags.grmode || !iflags.tile_view) {
xputc((char) ch);
#ifdef SCREEN_VGA
- } else {
+ } else if (iflags.grmode && iflags.usevga) {
vga_xputg(glyphnum, ch, special);
+#endif
+#ifdef SCREEN_VESA
+ } else if (iflags.grmode && iflags.usevesa) {
+ vesa_xputg(glyphnum, ch, special);
#endif
}
}
if (!iflags.grmode)
return;
#ifdef SCREEN_VGA
- else
+ else if (iflags.usevga)
vga_update_positionbar(posbar);
#endif
+#ifdef SCREEN_VESA
+ else if (iflags.usevesa)
+ vesa_update_positionbar(posbar);
+#endif
}
#endif
DrawCursor()
{
#ifdef SCREEN_VGA
- vga_DrawCursor();
+ if (iflags.usevga)
+ vga_DrawCursor();
+#endif
+#ifdef SCREEN_VESA
+ if (iflags.usevesa)
+ vesa_DrawCursor();
#endif
}
HideCursor()
{
#ifdef SCREEN_VGA
- vga_HideCursor();
+ if (iflags.usevga)
+ vga_HideCursor();
+#endif
+#ifdef SCREEN_VESA
+ if (iflags.usevesa)
+ vesa_HideCursor();
#endif
}
* getch();
*/
iflags.grmode = 0;
+ iflags.hasvesa = 0;
iflags.hasvga = 0;
+ iflags.usevesa = 0;
iflags.usevga = 0;
if (strncmpi(sopt, "def", 3) == 0) { /* default */
#endif
/*
* Auto-detect Priorities (arbitrary for now):
- * VGA
+ * VESA, VGA
*/
- if (iflags.hasvga) {
+ if (iflags.hasvesa) iflags.usevesa = 1;
+ else if (iflags.hasvga) {
iflags.usevga = 1;
/* VGA depends on BIOS to enable function keys*/
iflags.BIOS = 1;
boolean enable;
{
#ifdef SCREEN_VGA
- if (iflags.grmode)
+ if (iflags.grmode && iflags.usevga)
vga_traditional(enable ? FALSE : TRUE);
#endif
+#ifdef SCREEN_VESA
+ if (iflags.grmode && iflags.usevesa)
+ vesa_traditional(enable ? FALSE : TRUE);
+#endif
}
#endif /* NO_TERMS */
-/* NetHack 3.6 vidtxt.c $NHDT-Date: 1432512791 2015/05/25 00:13:11 $ $NHDT-Branch: master $:$NHDT-Revision: 1.10 $ */
+/* NetHack 3.6 vidtxt.c $NHDT-Date: 1457207043 2016/03/05 19:44:03 $ $NHDT-Branch: chasonr $:$NHDT-Revision: 1.11 $ */
/* Copyright (c) NetHack PC Development Team 1993 */
/* NetHack may be freely redistributed. See license for details. */
/* */
#else
txt_get_cursor(&col, &row);
txt_cl_end(col, row); /* clear to end of line */
- txt_gotoxy(0, (row < (LI - 1) ? row + 1 : (LI - 1)));
- regs.h.dl = (char) (CO - 1); /* X of lower right */
- regs.h.dh = (char) (LI - 1); /* Y of lower right */
- regs.h.cl = 0; /* X of upper left */
- /* Y (row) of upper left */
- regs.h.ch = (char) (row < (LI - 1) ? row + 1 : (LI - 1));
- regs.x.cx = 0;
- regs.x.ax = 0;
- regs.x.bx = 0;
- regs.h.bh = (char) attrib_text_normal;
- regs.h.ah = SCROLL;
- (void) int86(VIDEO_BIOS, ®s, ®s); /* Scroll or initialize window */
+ if (row < LI - 1) {
+ txt_gotoxy(0, (row < (LI - 1) ? row + 1 : (LI - 1)));
+ regs.h.dl = (char) (CO - 1); /* X of lower right */
+ regs.h.dh = (char) (LI - 1); /* Y of lower right */
+ regs.h.cl = 0; /* X of upper left */
+ /* Y (row) of upper left */
+ regs.h.ch = (char) (row < (LI - 1) ? row + 1 : (LI - 1));
+ regs.x.ax = 0;
+ regs.x.bx = 0;
+ regs.h.bh = (char) attrib_text_normal;
+ regs.h.ah = SCROLL;
+ (void) int86(VIDEO_BIOS, ®s, ®s); /* Scroll or initialize window */
+ }
#endif
}
-/* NetHack 3.6 vidvga.c $NHDT-Date: 1432512791 2015/05/25 00:13:11 $ $NHDT-Branch: master $:$NHDT-Revision: 1.17 $ */
+/* NetHack 3.6 vidvga.c $NHDT-Date: 1457207044 2016/03/05 19:44:04 $ $NHDT-Branch: chasonr $:$NHDT-Revision: 1.18 $ */
/* Copyright (c) NetHack PC Development Team 1995 */
/* NetHack may be freely redistributed. See license for details. */
/*
#ifdef SCREEN_VGA /* this file is for SCREEN_VGA only */
#include "pcvideo.h"
#include "tile.h"
-#include "pctiles.h"
+#include "tileset.h"
#include <dos.h>
#include <ctype.h>
#include <conio.h>
#endif
+extern short glyph2tile[];
+
/* STATIC_DCL void FDECL(vga_NoBorder, (int)); */
void FDECL(vga_gotoloc, (int, int)); /* This should be made a macro */
void NDECL(vga_backsp);
STATIC_DCL void FDECL(vga_scrollmap, (BOOLEAN_P));
#endif
STATIC_DCL void FDECL(vga_redrawmap, (BOOLEAN_P));
-void FDECL(vga_cliparound, (int, int));
+static void FDECL(vga_cliparound, (int, int));
STATIC_OVL void FDECL(decal_planar, (struct planar_cell_struct *, unsigned));
#ifdef POSITIONBAR
static void FDECL(vga_special, (int, int, int));
#endif
+static void FDECL(vga_DisplayCell, (struct planar_cell_struct *, int, int));
+static void FDECL(vga_DisplayCell_O,
+ (struct overview_planar_cell_struct *, int, int));
+static void FDECL(vga_SwitchMode, (unsigned int));
+static void FDECL(vga_SetPalette, (const struct Pixel *));
+static void FDECL(vga_WriteChar, (int, int, int, int));
+static void FDECL(vga_WriteStr, (char *, int, int, int, int));
+
+static void FDECL(read_planar_tile, (unsigned, struct planar_cell_struct *));
+static void FDECL(read_planar_tile_O,
+ (unsigned, struct overview_planar_cell_struct *));
+static void FDECL(read_tile_indexes, (unsigned, unsigned char (*)[TILE_X]));
+
extern int clipx, clipxmax; /* current clipping column from wintty.c */
extern boolean clipping; /* clipping on? from wintty.c */
extern int savevmode; /* store the original video mode */
STATIC_VAR unsigned char __far *font;
STATIC_VAR char *screentable[SCREENHEIGHT];
-STATIC_VAR char *paletteptr;
+STATIC_VAR const struct Pixel *paletteptr;
STATIC_VAR struct map_struct {
int glyph;
int ch;
}
#define TOP_MAP_ROW 1
-STATIC_VAR int vgacmap[CLR_MAX] = { 0, 3, 5, 9, 4, 8, 12, 14,
- 11, 2, 6, 7, 1, 8, 12, 13 };
+STATIC_VAR int vgacmap[CLR_MAX] = { 1, 4, 6, 10, 5, 9, 0, 15,
+ 12, 3, 7, 8, 2, 9, 0, 14 };
STATIC_VAR int viewport_size = 40;
/* STATIC_VAR char masktable[8]={0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01}; */
/* STATIC_VAR char bittable[8]= {0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80}; */
#endif
int vp2[SCREENPLANES] = { 1, 2, 4, 8 };
-STATIC_VAR struct planar_cell_struct *planecell;
-STATIC_VAR struct overview_planar_cell_struct *planecell_O;
-
-#if defined(USE_TILES)
-STATIC_VAR struct tibhdr_struct tibheader;
-/* extern FILE *tilefile; */ /* Not needed in here most likely */
-#endif
+STATIC_VAR struct planar_cell_struct planecell;
+STATIC_VAR struct overview_planar_cell_struct planecell_O;
/* STATIC_VAR int g_attribute; */ /* Current attribute to use */
int attr;
int ry;
+ /* If statue glyph, map to the generic statue */
+ if (GLYPH_STATUE_OFF <= glyphnum && glyphnum < GLYPH_STATUE_OFF + NUMMONS) {
+ glyphnum = objnum_to_glyph(STATUE);
+ }
+
row = currow;
col = curcol;
if ((col < 0 || col >= COLNO)
vga_WriteChar((unsigned char) ch, col, row, attr);
} else if (!iflags.over_view) {
if ((col >= clipx) && (col <= clipxmax)) {
- if (!ReadPlanarTileFile(glyph2tile[glyphnum], &planecell)) {
- if (map[ry][col].special)
- decal_planar(planecell, special);
- vga_DisplayCell(planecell, col - clipx, row);
- } else
- pline("vga_xputg: Error reading tile (%d,%d) from file",
- glyphnum, glyph2tile[glyphnum]);
+ read_planar_tile(glyphnum, &planecell);
+ if (map[ry][col].special)
+ decal_planar(&planecell, special);
+ vga_DisplayCell(&planecell, col - clipx, row);
}
} else {
- if (!ReadPlanarTileFile_O(glyph2tile[glyphnum], &planecell_O))
- vga_DisplayCell_O(planecell_O, col, row);
- else
- pline("vga_xputg: Error reading tile (%d,%d) from file", glyphnum,
- glyph2tile[glyphnum]);
+ read_planar_tile_O(glyphnum, &planecell_O);
+ vga_DisplayCell_O(&planecell_O, col, row);
}
if (col < (CO - 1))
++col;
}
#if defined(USE_TILES) && defined(CLIPPING)
-void
+static void
vga_cliparound(x, y)
int x, y;
{
t = map[y][x].glyph;
if (!(clearfirst && t == cmap_to_glyph(S_stone))) {
if (!iflags.over_view) {
- if (!ReadPlanarTileFile(glyph2tile[t], &planecell)) {
- if (map[y][x].special)
- decal_planar(planecell, map[y][x].special);
- vga_DisplayCell(planecell, x - clipx,
- y + TOP_MAP_ROW);
- } else
- pline("vga_redrawmap: Error reading tile (%d,%d)",
- t, glyph2tile[t]);
+ read_planar_tile(t, &planecell);
+ if (map[y][x].special)
+ decal_planar(&planecell, map[y][x].special);
+ vga_DisplayCell(&planecell, x - clipx, y + TOP_MAP_ROW);
} else {
- if (!ReadPlanarTileFile_O(glyph2tile[t],
- &planecell_O)) {
- vga_DisplayCell_O(planecell_O, x,
- y + TOP_MAP_ROW);
- } else
- pline("vga_redrawmap: Error reading tile (%d,%d)",
- t, glyph2tile[t]);
+ read_planar_tile_O(t, &planecell_O);
+ vga_DisplayCell_O(&planecell_O, x, y + TOP_MAP_ROW);
}
}
}
for (y = 0; y < ROWNO; ++y) {
for (x = i; x < j; x += 2) {
t = map[y][x].glyph;
- if (!ReadPlanarTileFile(glyph2tile[t], &planecell)) {
- if (map[y][x].special)
- decal_planar(planecell, map[y][x].special);
- vga_DisplayCell(planecell, x - clipx, y + TOP_MAP_ROW);
- } else {
- pline("vga_shiftmap: Error reading tile (%d,%d)", t,
- glyph2tile[t]);
- }
+ read_planar_tile(t, &planecell);
+ if (map[y][x].special)
+ decal_planar(&planecell, map[y][x].special);
+ vga_DisplayCell(&planecell, x - clipx, y + TOP_MAP_ROW);
}
}
}
#endif /* SCROLLMAP */
+static void
+read_planar_tile(glyph, cell)
+unsigned glyph;
+struct planar_cell_struct *cell;
+{
+ unsigned char indexes[TILE_Y][TILE_X];
+ unsigned plane, y, byte, bit;
+
+ read_tile_indexes(glyph, indexes);
+ /* cell->plane[0..3].image[0..15][0..1] */
+ for (plane = 0; plane < SCREENPLANES; ++plane) {
+ for (y = 0; y < TILE_Y; ++y) {
+ for (byte = 0; byte < MAX_BYTES_PER_CELL; ++byte) {
+ unsigned char b = 0;
+ for (bit = 0; bit < 8; ++bit) {
+ unsigned char x = byte * 8 + bit;
+ unsigned char i = indexes[y][x];
+ b <<= 1;
+ if (i & (0x8 >> plane)) b |= 1;
+ }
+ cell->plane[plane].image[y][byte] = b;
+ }
+ }
+ }
+}
+
+static void
+read_planar_tile_O(glyph, cell)
+unsigned glyph;
+struct overview_planar_cell_struct *cell;
+{
+ unsigned char indexes[TILE_Y][TILE_X];
+ unsigned plane, y, bit;
+
+ read_tile_indexes(glyph, indexes);
+ /* cell->plane[0..3].image[0..15][0..0] */
+ for (plane = 0; plane < SCREENPLANES; ++plane) {
+ for (y = 0; y < TILE_Y; ++y) {
+ unsigned char b = 0;
+ for (bit = 0; bit < 8; ++bit) {
+ unsigned char x = bit * 2;
+ unsigned char i = indexes[y][x];
+ b <<= 1;
+ if (i & (0x8 >> plane)) b |= 1;
+ }
+ cell->plane[plane].image[y][0] = b;
+ }
+ }
+}
+
+static void
+read_tile_indexes(glyph, indexes)
+unsigned glyph;
+unsigned char (*indexes)[TILE_X];
+{
+ const struct TileImage *tile;
+ unsigned x, y;
+
+ /* We don't have enough colors to show the statues */
+ if (glyph >= GLYPH_STATUE_OFF) {
+ glyph = GLYPH_OBJ_OFF + STATUE;
+ }
+
+ /* Get the tile from the image */
+ tile = get_tile(glyph2tile[glyph]);
+
+ /* Map to a 16 bit palette; assume colors laid out as in default tileset */
+ memset(indexes, 0, sizeof(indexes));
+ for (y = 0; y < TILE_Y && y < tile->height; ++y) {
+ for (x = 0; x < TILE_X && x < tile->width; ++x) {
+ unsigned i = tile->indexes[y * tile->width + x];
+ if (i == 28) {
+ i = 0;
+ } else if (i == 16) {
+ i = 13;
+ } else if (i > 15) {
+ i = 15;
+ }
+ indexes[y][x] = i;
+ }
+ }
+}
+
STATIC_OVL void
decal_planar(gp, special)
struct planar_cell_struct *gp;
int i;
#ifdef USE_TILES
+ const char *tile_file;
int tilefailure = 0;
/*
* Attempt to open the required tile files. If we can't
* don't perform the video mode switch, use TTY code instead.
*
*/
- if (OpenTileFile(NETHACK_PLANAR_TILEFILE, FALSE))
+ tile_file = iflags.wc_tile_file;
+ if (tile_file == NULL || tile_file == '\0') {
+ tile_file = "nhtiles.bmp";
+ }
+ if (!read_tiles(tile_file, FALSE))
tilefailure |= 1;
- if (OpenTileFile(NETHACK_OVERVIEW_TILEFILE, TRUE))
- tilefailure |= 2;
- if (ReadTileFileHeader(&tibheader, FALSE))
+ if (get_palette() == NULL)
tilefailure |= 4;
if (tilefailure) {
/* vga_NoBorder(BACKGROUND_VGA_COLOR); */ /* Not needed after palette
mod */
#ifdef USE_TILES
- paletteptr = tibheader.palette;
+ paletteptr = get_palette();
iflags.tile_view = TRUE;
iflags.over_view = FALSE;
#else
* mode (video mode 0x12). No other modes are currently supported.
*
*/
-void
+static void
vga_SwitchMode(unsigned int mode)
{
union REGS regs;
void
vga_Finish(void)
{
- CloseTileFile(0);
- CloseTileFile(1);
+ free_tiles();
vga_SwitchMode(MODETEXT);
windowprocs.win_cliparound = tty_cliparound;
g_attribute = attrib_text_normal;
* do it using the colour 'colour'.
*
*/
-void
+static void
vga_WriteChar(chr, col, row, colour)
int chr, col, row, colour;
{
* not the x,y pixel location.
*
*/
-void
+static void
vga_DisplayCell(gp, col, row)
struct planar_cell_struct *gp;
int col, row;
egawriteplane(15);
}
-void
+static void
vga_DisplayCell_O(gp, col, row)
struct overview_planar_cell_struct *gp;
int col, row;
* is 'len' at location (x,y) using the 'colour' colour.
*
*/
-void
+static void
vga_WriteStr(s, len, col, row, colour)
char *s;
int len, col, row, colour;
* 16 colour mode at 640 x 480.
*
*/
-void
+static void
vga_SetPalette(p)
-char *p;
+const struct Pixel *p;
{
union REGS regs;
int i;
outportb(0x3c6, 0xff);
for (i = 0; i < COLORDEPTH; ++i) {
+ struct Pixel color = (i == 13) ? p[16] : p[i];
outportb(0x3c8, i);
- outportb(0x3c9, (*p++) >> 2);
- outportb(0x3c9, (*p++) >> 2);
- outportb(0x3c9, (*p++) >> 2);
+ outportb(0x3c9, color.r >> 2);
+ outportb(0x3c9, color.g >> 2);
+ outportb(0x3c9, color.b >> 2);
}
regs.x.bx = 0x0000;
for (i = 0; i < COLORDEPTH; ++i) {
#ifdef POSITIONBAR
#define PBAR_ROW (LI - 4)
-#define PBAR_COLOR_ON 15 /* slate grey background colour of tiles */
-#define PBAR_COLOR_OFF 12 /* bluish grey, used in old style only */
-#define PBAR_COLOR_STAIRS 9 /* brown */
-#define PBAR_COLOR_HERO 14 /* creamy white */
+#define PBAR_COLOR_ON 13 /* slate grey background colour of tiles */
+#define PBAR_COLOR_OFF 0 /* bluish grey, used in old style only */
+#define PBAR_COLOR_STAIRS 10 /* brown */
+#define PBAR_COLOR_HERO 15 /* creamy white */
static unsigned char pbar[COLNO];
pixy = PBAR_ROW * MAX_ROWS_PER_CELL;
for (vplane = 0; vplane < SCREENPLANES; ++vplane) {
- egareadplane(vplane);
+ egareadplane(SCREENPLANES - 1 - vplane);
y = pixy;
for (i = 0; i < ROWS_PER_CELL; ++i) {
tmp_d = screentable[y++] + col;
-/* NetHack 3.6 pcmain.c $NHDT-Date: 1451697809 2016/01/02 01:23:29 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.68 $ */
+/* NetHack 3.6 pcmain.c $NHDT-Date: 1457207045 2016/03/05 19:44:05 $ $NHDT-Branch: chasonr $:$NHDT-Revision: 1.69 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
{
register int fd;
register char *dir;
-#if defined(WIN32)
+#if defined(WIN32) || defined(MSDOS)
char *envp = NULL;
char *sptr = NULL;
+#endif
+#if defined(WIN32)
char fnamebuf[BUFSZ], encodedfnamebuf[BUFSZ];
boolean save_getreturn_status = getreturn_enabled;
#endif
-/* NetHack 3.6 nhraykey.c $NHDT-Date: 1432512794 2015/05/25 00:13:14 $ $NHDT-Branch: master $:$NHDT-Revision: 1.15 $ */
+/* NetHack 3.6 nhraykey.c $NHDT-Date: 1457207047 2016/03/05 19:44:07 $ $NHDT-Branch: chasonr $:$NHDT-Revision: 1.16 $ */
/* Copyright (c) NetHack PC Development Team 2003 */
/* NetHack may be freely redistributed. See license for details. */
scan = ir->Event.KeyEvent.wVirtualScanCode;
shiftstate = ir->Event.KeyEvent.dwControlKeyState;
vk = ir->Event.KeyEvent.wVirtualKeyCode;
- keycode = MapVirtualKey(vk, 2);
- if (is_altseq(shiftstate)) {
- if (ch || inmap(keycode, vk))
- altseq = 1;
- else
- altseq = -1; /* invalid altseq */
- }
- if (ch || iskeypad(scan) || altseq) {
- done = 1; /* Stop looking */
- retval = 1; /* Found what we sought */
+ if (scan == 0 && vk == 0) {
+ /* It's the bogus_key. Discard it */
+ ReadConsoleInput(hConIn,ir,1,&count);
} else {
- /* Strange Key event; let's purge it to avoid trouble */
- ReadConsoleInput(hConIn, ir, 1, &count);
+ keycode = MapVirtualKey(vk, 2);
+ if (is_altseq(shiftstate)) {
+ if (ch || inmap(keycode, vk))
+ altseq = 1;
+ else
+ altseq = -1; /* invalid altseq */
+ }
+ if (ch || iskeypad(scan) || altseq) {
+ done = 1; /* Stop looking */
+ retval = 1; /* Found what we sought */
+ } else {
+ /* Strange Key event; let's purge it to avoid trouble */
+ ReadConsoleInput(hConIn, ir, 1, &count);
+ }
}
} else if ((ir->EventType == MOUSE_EVENT
--- /dev/null
+/* NetHack 3.6 bmptiles.c $NHDT-Date: 1457207054 2016/03/05 19:44:14 $ $NHDT-Branch: chasonr $:$NHDT-Revision: 1.0 $ */
+/* Copyright (c) Ray Chason, 2016. */
+/* NetHack may be freely redistributed. See license for details. */
+
+#include "config.h"
+#include "integer.h"
+#include "tileset.h"
+
+/* First BMP file header */
+struct BitmapHeader {
+ char magic[2];
+ uint32 bmp_size;
+ uint32 img_offset;
+};
+
+/* Color model information for larger BMP headers */
+struct CIE_XYZ {
+ uint32 ciexyzX;
+ uint32 ciexyzY;
+ uint32 ciexyzZ;
+};
+
+struct CIE_XYZTriple {
+ struct CIE_XYZ ciexyzRed;
+ struct CIE_XYZ ciexyzGreen;
+ struct CIE_XYZ ciexyzBlue;
+};
+
+/* Second BMP file header */
+/* This one can vary in size; contents can vary according to the size */
+struct BitmapInfoHeader {
+ uint32 Size; /* 12 40 52 56 108 124 64 */
+ int32 Width; /* 12 40 52 56 108 124 64 */
+ int32 Height; /* 12 40 52 56 108 124 64 */
+ uint16 NumPlanes; /* 12 40 52 56 108 124 64 */
+ uint16 BitsPerPixel; /* 12 40 52 56 108 124 64 */
+ uint32 Compression; /* 40 52 56 108 124 64 */
+ uint32 ImageDataSize; /* 40 52 56 108 124 64 */
+ int32 XResolution; /* 40 52 56 108 124 64 */
+ int32 YResolution; /* 40 52 56 108 124 64 */
+ uint32 ColorsUsed; /* 40 52 56 108 124 64 */
+ uint32 ColorsImportant; /* 40 52 56 108 124 64 */
+ uint32 RedMask; /* 52 56 108 124 */
+ uint32 GreenMask; /* 52 56 108 124 */
+ uint32 BlueMask; /* 52 56 108 124 */
+ uint32 AlphaMask; /* 56 108 124 */
+ uint32 CSType; /* 108 124 */
+ struct CIE_XYZTriple Endpoints; /* 108 124 */
+ uint32 GammaRed; /* 108 124 */
+ uint32 GammaGreen; /* 108 124 */
+ uint32 GammaBlue; /* 108 124 */
+ uint32 Intent; /* 124 */
+ uint32 ProfileData; /* 124 */
+ uint32 ProfileSize; /* 124 */
+};
+/* Compression */
+#define BI_RGB 0
+#define BI_RLE8 1
+#define BI_RLE4 2
+#define BI_BITFIELDS 3
+#define BI_JPEG 4
+#define BI_PNG 5
+
+static uint16 FDECL(read_u16, (const unsigned char buf[2]));
+static uint32 FDECL(read_u32, (const unsigned char buf[4]));
+static int32 FDECL(read_s32, (const unsigned char buf[4]));
+static struct Pixel FDECL(build_pixel, (const struct BitmapInfoHeader *, uint32));
+static unsigned char FDECL(pixel_element, (uint32, uint32));
+static boolean FDECL(read_header, (FILE *, struct BitmapHeader *));
+static boolean FDECL(read_info_header, (FILE *, struct BitmapInfoHeader *));
+static boolean FDECL(check_info_header, (const struct BitmapInfoHeader *));
+static unsigned FDECL(get_palette_size, (const struct BitmapInfoHeader *));
+static boolean FDECL(read_palette, (FILE *, struct Pixel *, unsigned));
+
+/* Read a .BMP file into the image structure */
+/* Return TRUE if successful, FALSE on any error */
+boolean
+read_bmp_tiles(filename, image)
+const char *filename;
+struct TileSetImage *image;
+{
+ struct BitmapHeader header1;
+ struct BitmapInfoHeader header2;
+ unsigned palette_size;
+ size_t num_pixels, size;
+ unsigned x, y, y_start, y_end, y_inc;
+ unsigned bytes_per_row;
+
+ FILE *fp = NULL; /* custodial */
+ unsigned char *row_bytes = NULL; /* custodial */
+
+ image->width = 0;
+ image->height = 0;
+ image->pixels = NULL; /* custodial, returned */
+ image->indexes = NULL; /* custodial, returned */
+ image->image_desc = NULL; /* custodial, returned */
+ image->tile_width = 0;
+ image->tile_height = 0;
+
+ fp = fopen(filename, "rb");
+ if (fp == NULL) goto error;
+
+ /* Read the headers */
+ if (!read_header(fp, &header1)) goto error;
+ if (memcmp(header1.magic, "BM", 2) != 0) goto error;
+
+ if (!read_info_header(fp, &header2)) goto error;
+ if (!check_info_header(&header2)) goto error;
+
+#if 0 /* TODO */
+ if (header2.Compression == BI_PNG) {
+ /* Image data is an embedded PNG bit stream */
+ boolean ok = do_read_png_tiles(fp, image));
+ fclose(fp);
+ return ok;
+ }
+#endif
+
+ /* header2.Height < 0 means the Y coordinate is reversed; the origin is
+ * top left rather than bottom left */
+ image->width = header2.Width;
+ image->height = labs(header2.Height);
+
+ /* Allocate pixel area; watch out for overflow */
+ num_pixels = (size_t) image->width * (size_t) image->height;
+ if (num_pixels / image->width != image->height) goto error; /* overflow */
+ size = num_pixels * sizeof(image->pixels[0]);
+ if (size / sizeof(image->pixels[0]) != num_pixels) goto error; /* overflow */
+ image->pixels = (struct Pixel *) alloc(size);
+ if (header2.BitsPerPixel <= 8) {
+ image->indexes = (unsigned char *) alloc(num_pixels);
+ }
+
+ /* Read the palette */
+ palette_size = get_palette_size(&header2);
+ if (!read_palette(fp, image->palette, palette_size)) goto error;
+
+ /* Read the pixels */
+ fseek(fp, header1.img_offset, SEEK_SET);
+ if (header2.Height < 0) {
+ y_start = 0;
+ y_end = image->height;
+ y_inc = 1;
+ } else {
+ y_start = image->height - 1;
+ y_end = (unsigned) -1;
+ y_inc = -1;
+ }
+ if (header2.Compression == BI_RLE4 || header2.Compression == BI_RLE8) {
+ unsigned char *p;
+ p = image->indexes;
+ memset(p, 0, num_pixels);
+ x = 0;
+ y = image->height - 1;
+ while (TRUE) {
+ int b1, b2;
+ b1 = fgetc(fp);
+ if (b1 == EOF) goto error;
+ b2 = fgetc(fp);
+ if (b2 == EOF) goto error;
+ /*
+ * b1 b2
+ * 0 0 end of line
+ * 0 1 end of bitmap
+ * 0 2 next two bytes are x and y offset
+ * 0 >2 b2 is a count of bytes
+ * >0 any repeat b2, b1 times
+ */
+ if (b1 == 0) {
+ if (b2 == 0) {
+ /* end of line */
+ --y;
+ x = 0;
+ } else if (b2 == 1) {
+ /* end of bitmap */
+ break;
+ } else if (b2 == 2) {
+ /* next two bytes are x and y offset */
+ b1 = fgetc(fp);
+ if (b1 == EOF) break;
+ b2 = fgetc(fp);
+ if (b2 == EOF) break;
+ x += b1;
+ y += b2;
+ } else {
+ /* get bytes */
+ int i;
+ if (y < image->height) {
+ p = image->indexes + y * image->width;
+ for (i = 0; i < b2; ++i) {
+ b1 = fgetc(fp);
+ if (b1 == EOF) break;
+ if (header2.BitsPerPixel == 8) {
+ if (x < image->width) {
+ p[x] = b1;
+ }
+ ++x;
+ } else {
+ if (x < image->width) {
+ p[x] = b1 >> 4;
+ }
+ ++x;
+ if (x < image->width) {
+ p[x] = b1 & 0xF;
+ }
+ ++x;
+ }
+ }
+ if (b2 & 1) {
+ b1 = fgetc(fp);
+ if (b1 == EOF) break;
+ }
+ }
+ }
+ } else {
+ /* repeat b2, b1 times */
+ int i;
+ if (y < image->height) {
+ p = image->indexes + y * image->width;
+ for (i = 0; i < b1; ++i) {
+ if (header2.BitsPerPixel == 8) {
+ if (x < image->width) {
+ p[x] = b2;
+ }
+ ++x;
+ } else {
+ if (x < image->width) {
+ p[x] = b2 >> 4;
+ }
+ ++x;
+ if (x < image->width) {
+ p[x] = b2 & 0xF;
+ }
+ ++x;
+ }
+ }
+ }
+ }
+ }
+ } else {
+ bytes_per_row = (image->width * header2.BitsPerPixel + 31) / 32 * 4;
+ row_bytes = (unsigned char *) alloc(bytes_per_row);
+ if (header2.Compression == BI_RGB) {
+ switch (header2.BitsPerPixel) {
+ case 16:
+ header2.RedMask = 0x001F;
+ header2.GreenMask = 0x07E0;
+ header2.BlueMask = 0xF800;
+ header2.AlphaMask = 0x0000;
+ break;
+
+ case 32:
+ header2.RedMask = 0x000000FF;
+ header2.GreenMask = 0x0000FF00;
+ header2.BlueMask = 0x00FF0000;
+ header2.AlphaMask = 0xFF000000;
+ break;
+ }
+ }
+ for (y = y_start; y != y_end; y += y_inc) {
+ struct Pixel *row = image->pixels + y * image->width;
+ unsigned char *ind = image->indexes + y * image->width;
+ size = fread(row_bytes, 1, bytes_per_row, fp);
+ if (size < bytes_per_row) goto error;
+ switch (header2.BitsPerPixel) {
+ case 1:
+ for (x = 0; x < image->width; ++x) {
+ unsigned byte = x / 8;
+ unsigned shift = x % 8;
+ unsigned color = (row_bytes[byte] >> shift) & 1;
+ ind[x] = color;
+ }
+ break;
+ case 4:
+ for (x = 0; x < image->width; ++x) {
+ unsigned byte = x / 2;
+ unsigned shift = (x % 2) * 4;
+ unsigned color = (row_bytes[byte] >> shift) & 1;
+ ind[x] = color;
+ }
+ break;
+ case 8:
+ for (x = 0; x < image->width; ++x) {
+ ind[x] = row_bytes[x];
+ }
+ break;
+ case 16:
+ for (x = 0; x < image->width; ++x) {
+ uint16 color = read_u16(row_bytes + x * 2);
+ row[x] = build_pixel(&header2, color);
+ }
+ break;
+ case 24:
+ for (x = 0; x < image->width; ++x) {
+ row[x].r = row_bytes[x * 3 + 2];
+ row[x].g = row_bytes[x * 3 + 1];
+ row[x].b = row_bytes[x * 3 + 0];
+ row[x].a = 255;
+ }
+ break;
+ case 32:
+ for (x = 0; x < image->width; ++x) {
+ uint32 color = read_u32(row_bytes + x * 2);
+ row[x] = build_pixel(&header2, color);
+ }
+ break;
+ }
+ }
+ free(row_bytes);
+ row_bytes = NULL;
+ }
+
+ if (image->indexes != NULL) {
+ size_t i;
+ for (i = 0; i < num_pixels; ++i) {
+ image->pixels[i] = image->palette[image->indexes[i]];
+ }
+ }
+
+ fclose(fp);
+ return TRUE;
+
+error:
+ if (fp) fclose(fp);
+ free(row_bytes);
+ free(image->pixels);
+ image->pixels = NULL;
+ free(image->indexes);
+ image->indexes = NULL;
+ free(image->image_desc);
+ image->image_desc = NULL;
+ return FALSE;
+}
+
+/* Read and decode the first header */
+static boolean
+read_header(fp, header)
+FILE *fp;
+struct BitmapHeader *header;
+{
+ unsigned char buf[14];
+ size_t size;
+
+ size = fread(buf, 1, sizeof(buf), fp);
+ if (size < sizeof(buf)) return FALSE;
+
+ memcpy(header->magic, buf + 0, 2);
+ header->bmp_size = read_u32(buf + 2);
+ /* 6 and 8 are 16 bit integers giving the hotspot of a cursor */
+ header->img_offset = read_u32(buf + 10);
+ return TRUE;
+}
+
+/* Read and decode the second header */
+static boolean
+read_info_header(fp, header)
+FILE *fp;
+struct BitmapInfoHeader *header;
+{
+ unsigned char buf[124]; /* maximum size */
+ size_t size;
+ boolean have_color_mask;
+
+ memset(header, 0, sizeof(*header));
+
+ /* Get the header size */
+ size = fread(buf, 1, 4, fp);
+ if (size < 4) return FALSE;
+ header->Size = read_u32(buf + 0);
+ if (header->Size > sizeof(buf)) return FALSE;
+
+ /* Get the rest of the header */
+ size = fread(buf + 4, 1, header->Size - 4, fp);
+ if (size < header->Size - 4) return FALSE;
+
+ have_color_mask = FALSE;
+ switch (header->Size) {
+ case 124: /* BITMAPV5INFOHEADER */
+ /* 120 is reserved */
+ header->ProfileSize = read_u32(buf + 116);
+ header->ProfileData = read_u32(buf + 112);
+ header->Intent = read_u32(buf + 108);
+ /* fall through */
+
+ case 108: /* BITMAPV4INFOHEADER */
+ header->GammaBlue = read_u32(buf + 104);
+ header->GammaGreen = read_u32(buf + 100);
+ header->GammaRed = read_u32(buf + 96);
+ header->Endpoints.ciexyzBlue.ciexyzZ = read_u32(buf + 92);
+ header->Endpoints.ciexyzBlue.ciexyzY = read_u32(buf + 88);
+ header->Endpoints.ciexyzBlue.ciexyzX = read_u32(buf + 84);
+ header->Endpoints.ciexyzGreen.ciexyzZ = read_u32(buf + 80);
+ header->Endpoints.ciexyzGreen.ciexyzY = read_u32(buf + 76);
+ header->Endpoints.ciexyzGreen.ciexyzX = read_u32(buf + 72);
+ header->Endpoints.ciexyzRed.ciexyzZ = read_u32(buf + 68);
+ header->Endpoints.ciexyzRed.ciexyzY = read_u32(buf + 64);
+ header->Endpoints.ciexyzRed.ciexyzX = read_u32(buf + 60);
+ header->CSType = read_u32(buf + 56);
+ /* fall through */
+
+ case 56: /* BITMAPV3INFOHEADER */
+ header->AlphaMask = read_u32(buf + 52);
+ /* fall through */
+
+ case 52: /* BITMAPV2INFOHEADER */
+ header->BlueMask = read_u32(buf + 48);
+ header->GreenMask = read_u32(buf + 44);
+ header->RedMask = read_u32(buf + 40);
+ have_color_mask = TRUE;
+ /* fall through */
+
+ case 40: /* BITMAPINFOHEADER */
+ case 64: /* OS22XBITMAPHEADER */
+ /* The last 24 bytes in OS22XBITMAPHEADER are incompatible with the
+ * later Microsoft versions of the header */
+ header->ColorsImportant = read_u32(buf + 36);
+ header->ColorsUsed = read_u32(buf + 32);
+ header->YResolution = read_s32(buf + 28);
+ header->XResolution = read_s32(buf + 24);
+ header->ImageDataSize = read_u32(buf + 20);
+ header->Compression = read_u32(buf + 16);
+ header->BitsPerPixel = read_u16(buf + 14);
+ header->NumPlanes = read_u16(buf + 12);
+ header->Height = read_s32(buf + 8);
+ header->Width = read_s32(buf + 4);
+ break;
+
+ case 12: /* BITMAPCOREHEADER */
+ header->BitsPerPixel = read_u16(buf + 10);
+ header->NumPlanes = read_u16(buf + 8);
+ header->Height = read_u16(buf + 6);
+ header->Width = read_u16(buf + 4);
+ break;
+
+ default:
+ return FALSE;
+ }
+
+ /* For BI_BITFIELDS, the next three 32 bit words are the color masks */
+ if (header->Compression == BI_BITFIELDS && !have_color_mask) {
+ size = fread(buf, 1, 12, fp);
+ if (size < 12) return FALSE;
+ header->RedMask = read_u32(buf + 0);
+ header->GreenMask = read_u32(buf + 4);
+ header->BlueMask = read_u32(buf + 8);
+ }
+
+ return TRUE;
+}
+
+/* Check the second header for consistency and unsupported features */
+static boolean
+check_info_header(header)
+const struct BitmapInfoHeader *header;
+{
+ if (header->NumPlanes != 1) return FALSE;
+ switch (header->BitsPerPixel) {
+#if 0 /* TODO */
+ case 0:
+ if (header->Compression != BI_PNG) return FALSE;
+ /* JPEG not supported */
+ break;
+#endif
+
+ case 1:
+ case 24:
+ if (header->Compression != BI_RGB) return FALSE;
+ break;
+
+ case 4:
+ if (header->Compression != BI_RGB
+ && header->Compression != BI_RLE4) return FALSE;
+ break;
+
+ case 8:
+ if (header->Compression != BI_RGB
+ && header->Compression != BI_RLE8) return FALSE;
+ break;
+
+ case 16:
+ case 32:
+ if (header->Compression != BI_RGB
+ && header->Compression != BI_BITFIELDS) return FALSE;
+ /* Any of the color masks could conceivably be zero; the bitmap, though
+ * limited, would still be meaningful */
+ if (header->Compression == BI_BITFIELDS
+ && header->RedMask == 0
+ && header->GreenMask == 0
+ && header->BlueMask == 0) return FALSE;
+ break;
+
+ default:
+ return FALSE;
+ }
+
+ if (header->Height < 0 && header->Compression != BI_RGB
+ && header->Compression != BI_BITFIELDS) return FALSE;
+
+ return TRUE;
+}
+
+/* Return the number of palette entries to read from the file */
+static unsigned
+get_palette_size(header)
+const struct BitmapInfoHeader *header;
+{
+ switch (header->BitsPerPixel) {
+ case 1:
+ return 2;
+
+ case 4:
+ return header->ColorsUsed ? header->ColorsUsed : 16;
+
+ case 8:
+ return header->ColorsUsed ? header->ColorsUsed : 256;
+
+ default:
+ return 0;
+ }
+}
+
+/*
+ * Read the palette from the file
+ * palette_size is the number of entries to read, but no more than 256 will
+ * be written into the palette array
+ * Return TRUE if successful, FALSE on any error
+ */
+static boolean
+read_palette(fp, palette, palette_size)
+FILE *fp;
+struct Pixel *palette;
+unsigned palette_size;
+{
+ unsigned i;
+ unsigned char buf[4];
+ unsigned read_size;
+
+ read_size = (palette_size < 256) ? palette_size : 256;
+ for (i = 0; i < read_size; ++i) {
+ size_t size = fread(buf, 1, sizeof(buf), fp);
+ if (size < sizeof(buf)) return FALSE;
+ palette[i].b = buf[0];
+ palette[i].g = buf[1];
+ palette[i].r = buf[2];
+ palette[i].a = 255;
+ }
+ for (; i < 256; ++i) {
+ palette[i].b = 0;
+ palette[i].g = 0;
+ palette[i].r = 0;
+ palette[i].a = 255;
+ }
+ fseek(fp, 4 * (palette_size - read_size), SEEK_CUR);
+ return TRUE;
+}
+
+/* Decode an unsigned 16 bit quantity */
+static uint16
+read_u16(buf)
+const unsigned char buf[2];
+{
+ return ((uint16)buf[0] << 0)
+ | ((uint16)buf[1] << 8);
+}
+
+/* Decode an unsigned 32 bit quantity */
+static uint32
+read_u32(buf)
+const unsigned char buf[4];
+{
+ return ((uint32)buf[0] << 0)
+ | ((uint32)buf[1] << 8)
+ | ((uint32)buf[2] << 16)
+ | ((uint32)buf[3] << 24);
+}
+
+/* Decode a signed 32 bit quantity */
+static int32
+read_s32(buf)
+const unsigned char buf[4];
+{
+ return (int32)((read_u32(buf) ^ 0x80000000) - 0x80000000);
+}
+
+/* Build a pixel structure, given the mask words in the second header and
+ * a packed 16 or 32 bit pixel */
+static struct Pixel
+build_pixel(header, color)
+const struct BitmapInfoHeader *header;
+uint32 color;
+{
+ struct Pixel pixel;
+
+ pixel.r = pixel_element(header->RedMask, color);
+ pixel.g = pixel_element(header->GreenMask, color);
+ pixel.b = pixel_element(header->BlueMask, color);
+ pixel.a = header->AlphaMask ? pixel_element(header->AlphaMask, color) : 255;
+ return pixel;
+}
+
+/* Extract one element (red, green, blue or alpha) from a pixel */
+static unsigned char
+pixel_element(mask, color)
+uint32 mask;
+uint32 color;
+{
+ uint32 bits, shift;
+
+ if (mask == 0) return 0;
+ bits = 0xFFFF; /* 0xFF, 0xF, 0x3, 0x1 */
+ shift = 16; /* 8, 4, 2, 1 */
+ while (bits != 0) {
+ if ((mask & bits) == 0) {
+ mask >>= shift;
+ color >>= shift;
+ }
+ shift /= 2;
+ bits >>= shift;
+ }
+ color &= mask;
+ return color * 255 / mask;
+}
-/* NetHack 3.6 thintile.c $NHDT-Date: 1432512803 2015/05/25 00:13:23 $ $NHDT-Branch: master $:$NHDT-Revision: 1.9 $ */
+/* NetHack 3.6 thintile.c $NHDT-Date: 1457207049 2016/03/05 19:44:09 $ $NHDT-Branch: chasonr $:$NHDT-Revision: 1.10 $ */
/* Copyright (c) NetHack Development Team 1995 */
/* NetHack may be freely redistributed. See license for details. */
int r, g, b;
char c[2];
- while (fscanf(infile, "%[A-Za-z0-9] = (%d, %d, %d) ", c, &r, &g, &b)
+ while (fscanf(infile, "%[A-Za-z0-9.] = (%d, %d, %d) ", c, &r, &g, &b)
== 4) {
Fprintf(outfile, "%c = (%d, %d, %d)\n", c[0], r, g, b);
}
-/* NetHack 3.6 tilemap.c $NHDT-Date: 1454502429 2016/02/03 12:27:09 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.28 $ */
+/* NetHack 3.6 tilemap.c $NHDT-Date: 1457207051 2016/03/05 19:44:11 $ $NHDT-Branch: chasonr $:$NHDT-Revision: 1.29 $ */
/* NetHack may be freely redistributed. See license for details. */
/*
#endif
#endif
-#if defined(WIN32)
+#if defined(MSDOS) || defined(WIN32)
#define STATUES_LOOK_LIKE_MONSTERS
#endif
--- /dev/null
+/* NetHack 3.6 tileset.c $NHDT-Date: 1457207053 2016/03/05 19:44:13 $ $NHDT-Branch: chasonr $:$NHDT-Revision: 1.0 $ */
+/* Copyright (c) Ray Chason, 2016. */
+/* NetHack may be freely redistributed. See license for details. */
+
+#include "hack.h"
+#include "tileset.h"
+
+static void FDECL(get_tile_map, (const char *));
+static void FDECL(split_tiles, (const struct TileSetImage *));
+static void FDECL(free_image, (struct TileSetImage *));
+
+static struct TileImage *tiles;
+static unsigned num_tiles;
+static struct TileImage blank_tile; /* for graceful undefined tile handling */
+
+static boolean have_palette;
+static struct Pixel palette[256];
+
+boolean
+read_tiles(filename, true_color)
+const char *filename;
+boolean true_color;
+{
+ static const unsigned char png_sig[] = {
+ 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A
+ };
+ struct TileSetImage image;
+ FILE *fp = NULL; /* custodial */
+ char header[16];
+ boolean ok;
+
+ /* Fill the image structure with known values */
+ image.width = 0;
+ image.height = 0;
+ image.pixels = NULL; /* custodial */
+ image.indexes = NULL; /* custodial */
+ image.image_desc = NULL; /* custodial */
+ image.tile_width = 0;
+ image.tile_height = 0;
+
+ /* Identify the image type */
+ fp = fopen(filename, "rb");
+ if (fp == NULL) goto error;
+ memset(header, 0, sizeof(header));
+ fread(header, 1, sizeof(header), fp);
+ fclose(fp);
+
+ /* Call the loader appropriate for the image */
+ if (memcmp(header, "BM", 2) == 0) {
+ ok = read_bmp_tiles(filename, &image);
+ } else if (memcmp(header, "GIF87a", 6) == 0
+ || memcmp(header, "GIF89a", 6) == 0) {
+ ok = read_gif_tiles(filename, &image);
+ } else if (memcmp(header, png_sig, sizeof(png_sig)) == 0) {
+ ok = read_png_tiles(filename, &image);
+ } else {
+ ok = FALSE;
+ }
+ if (!ok) goto error;
+
+ /* Reject if the interface cannot handle direct color and the image does
+ not use a palette */
+ if (!true_color && image.indexes == NULL) goto error;
+
+ /* Save the palette if present */
+ have_palette = image.indexes != NULL;
+ memcpy(palette, image.palette, sizeof(palette));
+
+ /* Set defaults for tile metadata */
+ if (image.tile_width == 0) {
+ image.tile_width = image.width / 40;
+ }
+ if (image.tile_height == 0) {
+ image.tile_height = image.tile_width;
+ }
+ /* Set the tile dimensions if the user has not done so */
+ if (iflags.wc_tile_width == 0) {
+ iflags.wc_tile_width = image.tile_width;
+ }
+ if (iflags.wc_tile_height == 0) {
+ iflags.wc_tile_height = image.tile_height;
+ }
+
+ /* Parse the tile map */
+ get_tile_map(image.image_desc);
+
+ /* Split the image into tiles */
+ split_tiles(&image);
+
+ fclose(fp);
+ free_image(&image);
+ return TRUE;
+
+error:
+ if (fp) fclose(fp);
+ free_image(&image);
+ return FALSE;
+}
+
+const struct Pixel *
+get_palette()
+{
+ return have_palette ? palette : NULL;
+}
+
+/* TODO: derive tile_map from image_desc */
+static void
+get_tile_map(image_desc)
+const char *image_desc;
+{
+}
+
+void
+free_tiles()
+{
+ unsigned i;
+
+ if (tiles != NULL) {
+ for (i = 0; i < num_tiles; ++i) {
+ free(tiles[i].pixels);
+ free(tiles[i].indexes);
+ }
+ }
+ free(tiles);
+ tiles = NULL;
+ num_tiles = 0;
+
+ free(blank_tile.pixels);
+ blank_tile.pixels = NULL;
+ free(blank_tile.indexes);
+ blank_tile.indexes = NULL;
+}
+
+static void
+free_image(image)
+struct TileSetImage *image;
+{
+ free(image->pixels);
+ image->pixels = NULL;
+ free(image->indexes);
+ image->indexes = NULL;
+ free(image->image_desc);
+ image->image_desc = NULL;
+}
+
+const struct TileImage *
+get_tile(tile_index)
+unsigned tile_index;
+{
+ if (tile_index >= num_tiles) {
+ return &blank_tile;
+ } else {
+ return &tiles[tile_index];
+ }
+}
+
+static void
+split_tiles(image)
+const struct TileSetImage *image;
+{
+ unsigned tile_rows, tile_cols;
+ size_t tile_size, i, j;
+ unsigned x1, y1, x2, y2;
+
+ /* Get the number of tiles */
+ tile_rows = image->height / iflags.wc_tile_height;
+ tile_cols = image->width / iflags.wc_tile_width;
+ num_tiles = tile_rows * tile_cols;
+ tile_size = (size_t) iflags.wc_tile_height * (size_t) iflags.wc_tile_width;
+
+ /* Allocate the tile array */
+ tiles = (struct TileImage *) alloc(num_tiles * sizeof(tiles[0]));
+ memset(tiles, 0, num_tiles * sizeof(tiles[0]));
+
+ /* Copy the pixels into the tile structures */
+ for (y1 = 0; y1 < tile_rows; ++y1) {
+ for (x1 = 0; x1 < tile_cols; ++x1) {
+ struct TileImage *tile = &tiles[y1 * tile_cols + x1];
+ tile->width = iflags.wc_tile_width;
+ tile->height = iflags.wc_tile_height;
+ tile->pixels = (struct Pixel *)
+ alloc(tile_size * sizeof(struct Pixel));
+ if (image->indexes != NULL) {
+ tile->indexes = (unsigned char *) alloc(tile_size);
+ }
+ for (y2 = 0; y2 < iflags.wc_tile_height; ++y2) {
+ for (x2 = 0; x2 < iflags.wc_tile_width; ++x2) {
+ unsigned x = x1 * iflags.wc_tile_width + x2;
+ unsigned y = y1 * iflags.wc_tile_height + y2;
+ i = y * image->width + x;
+ j = y2 * tile->width + x2;
+ tile->pixels[j] = image->pixels[i];
+ if (image->indexes != NULL) {
+ tile->indexes[j] = image->indexes[i];
+ }
+ }
+ }
+ }
+ }
+
+ /* Create a blank tile for use when the tile index is invalid */
+ blank_tile.width = iflags.wc_tile_width;
+ blank_tile.height = iflags.wc_tile_height;
+ blank_tile.pixels = (struct Pixel *)
+ alloc(tile_size * sizeof(struct Pixel));
+ for (i = 0; i < tile_size; ++i) {
+ blank_tile.pixels[i].r = 0;
+ blank_tile.pixels[i].g = 0;
+ blank_tile.pixels[i].b = 0;
+ blank_tile.pixels[i].a = 255;
+ }
+ if (image->indexes) {
+ blank_tile.indexes = (unsigned char *) alloc(tile_size);
+ memset(blank_tile.indexes, 0, tile_size);
+ }
+}
+
+boolean
+read_png_tiles(filename, image)
+const char *filename;
+struct TileSetImage *image;
+{
+ /* stub */
+ return FALSE;
+}