From: nhmall Date: Sat, 5 Mar 2016 19:44:50 +0000 (-0500) Subject: some of Ray Chason's MSDOS and other fixes X-Git-Tag: NetHack-3.6.1_RC01~888 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=78857961d2b40f01516ec3ecdafd348c79142bbc;p=nethack some of Ray Chason's MSDOS and other fixes --- diff --git a/doc/fixes36.1 b/doc/fixes36.1 index f1f03b2cc..daf41c182 100644 --- a/doc/fixes36.1 +++ b/doc/fixes36.1 @@ -261,6 +261,16 @@ X11: status display split into three columns to accomodate Stone/Deaf/Lev/&c; 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 diff --git a/include/flag.h b/include/flag.h index af3b59b65..26009e26a 100644 --- a/include/flag.h +++ b/include/flag.h @@ -1,4 +1,4 @@ -/* 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. */ @@ -261,6 +261,8 @@ struct instance_flags { #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 diff --git a/include/pcconf.h b/include/pcconf.h index a8806cfe5..01ae261b6 100644 --- a/include/pcconf.h +++ b/include/pcconf.h @@ -1,4 +1,4 @@ -/* 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. */ @@ -79,6 +79,7 @@ #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 @@ -86,6 +87,7 @@ #undef SCREEN_BIOS #undef SCREEN_DJGPPFAST #undef SCREEN_VGA +#undef SCREEN_VESA #undef TERMLIB #define ANSI_DEFAULT #endif @@ -310,9 +312,8 @@ #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 */ diff --git a/include/tileset.h b/include/tileset.h new file mode 100644 index 000000000..2ab145e66 --- /dev/null +++ b/include/tileset.h @@ -0,0 +1,43 @@ +/* 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 diff --git a/src/apply.c b/src/apply.c index 28bb61fc4..e30542dd2 100644 --- a/src/apply.c +++ b/src/apply.c @@ -1,4 +1,4 @@ -/* 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. */ @@ -395,7 +395,7 @@ register struct obj *obj; 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); } diff --git a/src/cmd.c b/src/cmd.c index 47cdf8a2e..40c711bd0 100644 --- a/src/cmd.c +++ b/src/cmd.c @@ -1,4 +1,4 @@ -/* 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. */ @@ -355,7 +355,7 @@ doextlist(VOID_ARGS) 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 */ /* diff --git a/src/display.c b/src/display.c index b4970378f..48101d432 100644 --- a/src/display.c +++ b/src/display.c @@ -1,4 +1,4 @@ -/* 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. */ @@ -1748,7 +1748,8 @@ xchar x, y; 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: @@ -1769,9 +1770,16 @@ xchar x, y; 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; diff --git a/src/invent.c b/src/invent.c index 4ca6b8a07..103ee9580 100644 --- a/src/invent.c +++ b/src/invent.c @@ -1,4 +1,4 @@ -/* 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. */ @@ -1935,7 +1935,9 @@ long quan; /* if non-0, print this quantity, not obj->quan */ */ 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 { diff --git a/sys/msdos/Makefile.GCC b/sys/msdos/Makefile.GCC index 7258fd47a..68265b6c2 100644 --- a/sys/msdos/Makefile.GCC +++ b/sys/msdos/Makefile.GCC @@ -1,4 +1,4 @@ -# 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 # @@ -66,7 +66,7 @@ LIBRARIES = $(LIBS) $(TERMLIB) # # 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 @@ -161,8 +161,8 @@ LFLAGS = 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 @@ -173,7 +173,7 @@ endif #================ RULES ================== #========================================== -.SUFFIXES: .exe .o .tib .til .uu .c .y .l +.SUFFIXES: .exe .o .til .uu .c .y .l #========================================== # Rules for files in src @@ -241,7 +241,7 @@ U = $(UTIL)/ # Utility Objects. #========================================== -VGAOBJ = $(O)vidvga.o +VGAOBJ = $(O)vidvga.o $(O)vidvesa.o MAKESRC = makedefs.c @@ -267,10 +267,10 @@ RECOVOBJS = $(O)recover.o ifeq ($(SUPPRESS_GRAPHICS),Y) TILOBJ = +TILOBJ2 = TEXTIO = TEXTIO2 = -PLANAR_TIB = -OVERVIEW_TIB = +TILE_BMP = TILEUTIL = TILEFILES = TILEFILES2 = @@ -281,7 +281,9 @@ PPMWRIT2 = 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 @@ -289,11 +291,9 @@ TEXTIO = $(O)tiletext.o $(O)tiletxt.o $(O)drawing.o $(O)decl.o $(O)monst.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 @@ -336,7 +336,7 @@ VOBJ19 = $(O)trap.o $(O)u_init.o $(O)uhitm.o $(O)vault.o $(O)vision.o 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 @@ -349,7 +349,7 @@ VOBJ = $(VOBJ01) $(VOBJ02) $(VOBJ03) $(VOBJ04) $(VOBJ05) \ $(VOBJ16) $(VOBJ17) $(VOBJ18) $(VOBJ19) $(VOBJ20) \ $(VOBJ21) $(VOBJ22) $(VOBJ23) -ALLOBJ = $(VOBJ) $(SOBJ) $(TILOBJ) $(VVOBJ) +ALLOBJ = $(VOBJ) $(SOBJ) $(TILOBJ) $(TILOBJ2) $(VVOBJ) #========================================== # Header file macros @@ -391,7 +391,7 @@ DLB_H = $(INCL)/dlb.h 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) @@ -448,11 +448,12 @@ endif 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)) @@ -466,7 +467,35 @@ endif #========================================== $(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) @@ -497,6 +526,7 @@ $(O)$(GAME).lnk: $(ALLOBJ) echo $(VOBJ23) >> $(subst /,\,$@) echo $(SOBJ) >> $(subst /,\,$@) echo $(TILOBJ) >> $(subst /,\,$@) + echo $(TILOBJ2) >> $(subst /,\,$@) echo $(VVOBJ) >> $(subst /,\,$@) @@ -513,6 +543,7 @@ clean: $(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 @@ -527,6 +558,7 @@ 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) @@ -547,11 +579,13 @@ spotless: clean $(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) @@ -614,7 +648,9 @@ $(O)makedefs.o: $(CONFIG_H) $(PERMONST_H) $(INCL)/objclass.h \ #========================================== $(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) @@ -770,23 +806,26 @@ $(O)tilemap.o: $(WSHR)/tilemap.c $(HACK_H) $(TILE_H) # 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 @@ -798,6 +837,9 @@ $(O)thintile.tag: $(U)thintile.exe $(TILEFILES) @$(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 @@ -900,6 +942,15 @@ $(DAT)/quest.dat: $(O)utility.tag $(DAT)/quest.txt $(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 \ @@ -949,24 +1000,14 @@ $(DAT)/dungeon: $(O)utility.tag $(DAT)/dungeon.def #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)) @@ -1013,6 +1054,9 @@ $(O)video.o : $(HACK_H) $(MSYS)/pcvideo.h $(MSYS)/portio.h $(MSYS)/video.c $(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 @@ -1270,6 +1314,10 @@ $(O)worm.o: worm.c $(HACK_H) $(INCL)/lev.h $(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 diff --git a/sys/msdos/pckeys.c b/sys/msdos/pckeys.c index 567b8ee4d..352c916e8 100644 --- a/sys/msdos/pckeys.c +++ b/sys/msdos/pckeys.c @@ -1,4 +1,4 @@ -/* 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. */ @@ -14,6 +14,10 @@ #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 */ @@ -47,25 +51,25 @@ unsigned char shift; #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: @@ -73,6 +77,61 @@ unsigned char shift; } 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 */ diff --git a/sys/msdos/pctiles.h b/sys/msdos/pctiles.h index 58f29a390..e56812371 100644 --- a/sys/msdos/pctiles.h +++ b/sys/msdos/pctiles.h @@ -1,4 +1,4 @@ -/* 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. */ /* */ @@ -11,6 +11,10 @@ */ #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 */ diff --git a/sys/msdos/pcvideo.h b/sys/msdos/pcvideo.h index e62bd7be1..bc2f876fd 100644 --- a/sys/msdos/pcvideo.h +++ b/sys/msdos/pcvideo.h @@ -1,4 +1,4 @@ -/* 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. */ /* */ @@ -166,7 +166,7 @@ struct overview_planar_cell_struct { #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 */ @@ -176,9 +176,9 @@ struct overview_planar_cell_struct { #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) @@ -258,9 +258,6 @@ E int NDECL(vga_detect); #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); @@ -272,12 +269,8 @@ E void FDECL(vga_update_positionbar, (char *)); 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)); @@ -286,6 +279,35 @@ E void FDECL(vga_overview, (BOOLEAN_P)); 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 diff --git a/sys/msdos/tile2bin.c b/sys/msdos/tile2bin.c index 8ecdbfe17..4c7a3228d 100644 --- a/sys/msdos/tile2bin.c +++ b/sys/msdos/tile2bin.c @@ -1,4 +1,4 @@ -/* 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. */ @@ -38,6 +38,12 @@ 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 @@ -62,7 +68,8 @@ struct tibhdr_struct tibheader; 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", @@ -85,6 +92,7 @@ char *argv[]; struct tm *newtime; time_t aclock; char *paletteptr; + unsigned num_monsters = 0; if (argc != 1) { Fprintf(stderr, "usage: tile2bin (from the util directory)\n"); @@ -135,6 +143,7 @@ char *argv[]; } if (!paletteflag) { + remap_colors(); paletteptr = tibheader.palette; for (i = 0; i < num_colors; i++) { *paletteptr++ = ColorMap[CM_RED][i], @@ -145,15 +154,33 @@ char *argv[]; } 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__) @@ -207,17 +234,24 @@ struct tibhdr_struct *tibhdr; } 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++) { @@ -229,6 +263,15 @@ pixel (*pixels)[TILE_X]; } 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 @@ -242,6 +285,14 @@ pixel (*pixels)[TILE_X]; 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); @@ -299,3 +350,19 @@ int recnum; 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; +} diff --git a/sys/msdos/video.c b/sys/msdos/video.c index ce1de0415..cfa5e972e 100644 --- a/sys/msdos/video.c +++ b/sys/msdos/video.c @@ -1,4 +1,4 @@ -/* 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. */ /* */ @@ -79,6 +79,11 @@ get_scr_size() 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(); } @@ -141,6 +146,10 @@ backsp() #ifdef SCREEN_VGA } else if (iflags.usevga) { vga_backsp(); +#endif +#ifdef SCREEN_VESA + } else if (iflags.usevesa) { + vesa_backsp(); #endif } } @@ -153,6 +162,10 @@ clear_screen() #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 } } @@ -168,6 +181,10 @@ void cl_end() /* clear to end of line */ #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); @@ -182,6 +199,10 @@ void cl_eos() /* clear to end of screen */ #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); @@ -198,6 +219,10 @@ register int col, row; #ifdef SCREEN_VGA } else if (iflags.usevga) { vga_gotoloc(col, row); +#endif +#ifdef SCREEN_VESA + } else if (iflags.usevesa) { + vesa_gotoloc(col, row); #endif } } @@ -223,6 +248,10 @@ home() #ifdef SCREEN_VGA } else if (iflags.usevga) { vga_gotoloc(0, 0); +#endif +#ifdef SCREEN_VESA + } else if (iflags.usevesa) { + vesa_gotoloc(0, 0); #endif } } @@ -236,6 +265,10 @@ int col, row; #ifdef SCREEN_VGA } else if (iflags.usevga) { vga_gotoloc(col, row); +#endif +#ifdef SCREEN_VESA + } else if (iflags.usevesa) { + vesa_gotoloc(col, row); #endif } } @@ -360,6 +393,10 @@ tty_end_screen() #ifdef SCREEN_VGA } else if (iflags.usevga) { vga_tty_end_screen(); +#endif +#ifdef SCREEN_VESA + } else if (iflags.usevesa) { + vesa_tty_end_screen(); #endif } } @@ -395,6 +432,11 @@ int *wid, *hgt; 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); @@ -430,39 +472,44 @@ tty_start_screen() 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 - } + {} } } @@ -510,6 +557,10 @@ const char *s; #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 } } @@ -529,6 +580,10 @@ char ch; } 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*/ } } @@ -541,8 +596,12 @@ unsigned special; 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 } } @@ -555,9 +614,13 @@ char *posbar; 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 @@ -593,7 +656,12 @@ void DrawCursor() { #ifdef SCREEN_VGA - vga_DrawCursor(); + if (iflags.usevga) + vga_DrawCursor(); +#endif +#ifdef SCREEN_VESA + if (iflags.usevesa) + vesa_DrawCursor(); #endif } @@ -601,7 +669,12 @@ void HideCursor() { #ifdef SCREEN_VGA - vga_HideCursor(); + if (iflags.usevga) + vga_HideCursor(); +#endif +#ifdef SCREEN_VESA + if (iflags.usevesa) + vesa_HideCursor(); #endif } @@ -854,7 +927,9 @@ char *sopt; * getch(); */ iflags.grmode = 0; + iflags.hasvesa = 0; iflags.hasvga = 0; + iflags.usevesa = 0; iflags.usevga = 0; if (strncmpi(sopt, "def", 3) == 0) { /* default */ @@ -892,9 +967,10 @@ char *sopt; #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; @@ -911,9 +987,13 @@ tileview(enable) 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 */ diff --git a/sys/msdos/vidtxt.c b/sys/msdos/vidtxt.c index 82e18e8a3..6dd23832b 100644 --- a/sys/msdos/vidtxt.c +++ b/sys/msdos/vidtxt.c @@ -1,4 +1,4 @@ -/* 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. */ /* */ @@ -235,18 +235,19 @@ void txt_cl_eos() /* clear to end of screen */ #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 } diff --git a/sys/msdos/vidvga.c b/sys/msdos/vidvga.c index 533ce179f..888010d4b 100644 --- a/sys/msdos/vidvga.c +++ b/sys/msdos/vidvga.c @@ -1,4 +1,4 @@ -/* 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. */ /* @@ -10,7 +10,7 @@ #ifdef SCREEN_VGA /* this file is for SCREEN_VGA only */ #include "pcvideo.h" #include "tile.h" -#include "pctiles.h" +#include "tileset.h" #include #include @@ -102,6 +102,8 @@ #include #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); @@ -109,7 +111,7 @@ 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 @@ -117,6 +119,19 @@ STATIC_DCL void NDECL(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 */ @@ -135,7 +150,7 @@ extern boolean inmap; /* in the map window */ 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; @@ -156,8 +171,8 @@ STATIC_VAR struct map_struct { } #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}; */ @@ -187,13 +202,8 @@ int vp[SCREENPLANES] = { 8, 4, 2, 1 }; #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 */ @@ -365,6 +375,11 @@ unsigned special; /* special feature: corpse, invis, detected, pet, ridden - 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) @@ -380,20 +395,14 @@ unsigned special; /* special feature: corpse, invis, detected, pet, ridden - 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; @@ -422,7 +431,7 @@ int col, row; } #if defined(USE_TILES) && defined(CLIPPING) -void +static void vga_cliparound(x, y) int x, y; { @@ -489,22 +498,13 @@ boolean clearfirst; 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); } } } @@ -632,19 +632,98 @@ boolean left; 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; @@ -671,17 +750,20 @@ vga_Init(void) 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) { @@ -708,7 +790,7 @@ vga_Init(void) /* 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 @@ -730,7 +812,7 @@ vga_Init(void) * mode (video mode 0x12). No other modes are currently supported. * */ -void +static void vga_SwitchMode(unsigned int mode) { union REGS regs; @@ -760,8 +842,7 @@ vga_SwitchMode(unsigned int mode) void vga_Finish(void) { - CloseTileFile(0); - CloseTileFile(1); + free_tiles(); vga_SwitchMode(MODETEXT); windowprocs.win_cliparound = tty_cliparound; g_attribute = attrib_text_normal; @@ -853,7 +934,7 @@ vga_detect() * do it using the colour 'colour'. * */ -void +static void vga_WriteChar(chr, col, row, colour) int chr, col, row, colour; { @@ -901,7 +982,7 @@ 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; @@ -932,7 +1013,7 @@ int col, row; egawriteplane(15); } -void +static void vga_DisplayCell_O(gp, col, row) struct overview_planar_cell_struct *gp; int col, row; @@ -965,7 +1046,7 @@ 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; @@ -993,19 +1074,20 @@ 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) { @@ -1021,10 +1103,10 @@ static unsigned char colorbits[] = { 0x08, 0x04, 0x02, 0x01 }; #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]; @@ -1152,7 +1234,7 @@ int chr, col, color; 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; diff --git a/sys/share/pcmain.c b/sys/share/pcmain.c index a42c49233..df756234a 100644 --- a/sys/share/pcmain.c +++ b/sys/share/pcmain.c @@ -1,4 +1,4 @@ -/* 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. */ @@ -115,9 +115,11 @@ char *argv[]; { 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 diff --git a/sys/winnt/nhraykey.c b/sys/winnt/nhraykey.c index 95dfddf24..cae80ccd8 100644 --- a/sys/winnt/nhraykey.c +++ b/sys/winnt/nhraykey.c @@ -1,4 +1,4 @@ -/* 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. */ @@ -559,19 +559,24 @@ INPUT_RECORD *ir; 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 diff --git a/win/share/bmptiles.c b/win/share/bmptiles.c new file mode 100644 index 000000000..641415915 --- /dev/null +++ b/win/share/bmptiles.c @@ -0,0 +1,622 @@ +/* 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; +} diff --git a/win/share/thintile.c b/win/share/thintile.c index 6980623c0..4d6793c46 100644 --- a/win/share/thintile.c +++ b/win/share/thintile.c @@ -1,4 +1,4 @@ -/* 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. */ @@ -32,7 +32,7 @@ copy_colormap() 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); } diff --git a/win/share/tilemap.c b/win/share/tilemap.c index d743c549c..47a8155d1 100644 --- a/win/share/tilemap.c +++ b/win/share/tilemap.c @@ -1,4 +1,4 @@ -/* 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. */ /* @@ -21,7 +21,7 @@ extern void FDECL(exit, (int)); #endif #endif -#if defined(WIN32) +#if defined(MSDOS) || defined(WIN32) #define STATUES_LOOK_LIKE_MONSTERS #endif diff --git a/win/share/tileset.c b/win/share/tileset.c new file mode 100644 index 000000000..1b65c32b0 --- /dev/null +++ b/win/share/tileset.c @@ -0,0 +1,225 @@ +/* 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; +}