diff options
67 files changed, 6166 insertions, 9970 deletions
diff --git a/crawl-ref/source/AppHdr.h b/crawl-ref/source/AppHdr.h index 700bfc2c0c..0ad0b91951 100644 --- a/crawl-ref/source/AppHdr.h +++ b/crawl-ref/source/AppHdr.h @@ -206,10 +206,6 @@ #error Missing platform #define or unsupported compiler. #endif -#ifdef USE_TILE - #include "libgui.h" -#endif - // ========================================================================= // Defines for dgamelaunch-specific things. // ========================================================================= @@ -317,6 +313,12 @@ #endif #endif + +#ifdef USE_TILE + #include "libgui.h" + #include "tilesdl.h" +#endif + // ========================================================================= // Lua user scripts (NOTE: this may also be enabled in your makefile!) // ========================================================================= diff --git a/crawl-ref/source/abyss.cc b/crawl-ref/source/abyss.cc index 14440d8d0a..ce0fba4011 100644 --- a/crawl-ref/source/abyss.cc +++ b/crawl-ref/source/abyss.cc @@ -34,6 +34,9 @@ #include "stuff.h" #include "spells3.h" #include "terrain.h" +#ifdef USE_TILE +#include "tiledef-dngn.h" +#endif #include "tiles.h" #include "traps.h" #include "view.h" @@ -654,11 +657,6 @@ void abyss_teleport( bool new_area ) _generate_area(MAPGEN_BORDER, MAPGEN_BORDER, GXM - MAPGEN_BORDER, GYM - MAPGEN_BORDER, true); -#ifdef USE_TILE - // Update the wall colours. - TileLoadWall(true); -#endif - _xom_check_nearness(); grd[you.x_pos][you.y_pos] = DNGN_FLOOR; @@ -884,16 +882,15 @@ static void _corrupt_square(const crawl_environment &oenv, const coord_def &c) env.grid_colours(c) = oenv.floor_colour; #ifdef USE_TILE - // Modify tile flavor to use corrupted tiles. if (feat == DNGN_ROCK_WALL) { - env.tile_flavor[c.x][c.y].wall = - TILE_DNGN_WALL_CORRUPT - get_wall_tile_idx() + random2(4); + env.tile_flv[c.x][c.y].wall = tile_DNGN_start[IDX_WALL_UNDEAD] + + random2(tile_DNGN_count[IDX_WALL_UNDEAD]); } else if (feat == DNGN_FLOOR) { - env.tile_flavor[c.x][c.y].floor = - TILE_DNGN_FLOOR_CORRUPT - get_floor_tile_idx() + random2(4); + env.tile_flv[c.x][c.y].floor = tile_DNGN_start[IDX_FLOOR_NERVES] + + random2(tile_DNGN_count[IDX_FLOOR_NERVES]); } #endif } diff --git a/crawl-ref/source/acr.cc b/crawl-ref/source/acr.cc index 043182e73a..bf8fc64634 100644 --- a/crawl-ref/source/acr.cc +++ b/crawl-ref/source/acr.cc @@ -140,7 +140,10 @@ #include "stash.h" #include "xom.h" +#ifdef USE_TILE #include "tiles.h" +#include "tiledef-dngn.h" +#endif // ---------------------------------------------------------------------- // Globals whose construction/destruction order needs to be managed @@ -206,14 +209,15 @@ static void _compile_time_asserts(); // to new_game and then input. // -#ifdef WIN32TILES -int old_main( int argc, char *argv[] ) -#else -int main( int argc, char *argv[] ) +#ifdef USE_TILE +#include <SDL_main.h> #endif + +int main( int argc, char *argv[] ) { _compile_time_asserts(); // Just to quiet "unused static function" warning. + // Load in the system environment variables get_system_environment(); @@ -245,6 +249,11 @@ int main( int argc, char *argv[] ) SysEnv.scorefile.clear(); } +#ifdef USE_TILE + if (!tiles.initialise()) + return -1; +#endif + const bool game_start = _initialise(); // Override some options for tutorial. @@ -281,7 +290,7 @@ int main( int argc, char *argv[] ) // Should never reach this stage, right? #if defined(USE_TILE) - libgui_shutdown(); + tiles.shutdown(); #elif defined(UNIX) unixcurses_shutdown(); #endif @@ -420,10 +429,6 @@ static void _startup_tutorial() // Print stats and everything. _prep_input(); -#ifdef USE_TILE - tile_draw_inv(REGION_INV1); -#endif - msg::streams(MSGCH_TUTORIAL) << "Press any key to start the tutorial intro, or Escape to skip it." << std::endl; @@ -1477,7 +1482,9 @@ static void _input() handle_delay(); const coord_def cwhere = grid2view(you.pos()); +#ifndef USE_TILE cgotoxy(cwhere.x, cwhere.y); +#endif if (you_are_delayed()) { @@ -1805,33 +1812,6 @@ void process_command( command_type cmd ) switch (cmd) { #ifdef USE_TILE - case CMD_EDIT_PREFS: - edit_prefs(); - break; - - case CMD_USE_ITEM: - { - int idx; - InvAction act; - gui_get_mouse_inv(idx, act); - tile_use_item(idx, act); - } - break; - - case CMD_VIEW_ITEM: - { - int idx; - InvAction act; - gui_get_mouse_inv(idx, act); - - if (idx < 0) // item on floor - describe_item(mitm[-idx]); - else // item in inventory - describe_item(you.inv[idx], true); - redraw_screen(); - } - break; - case CMD_EDIT_PLAYER_TILE: TilePlayerEdit(); break; @@ -3082,6 +3062,11 @@ static void _world_reacts() { crawl_state.clear_god_acting(); +#ifdef USE_TILE + tiles.clear_text_tags(TAG_TUTORIAL); + tiles.place_cursor(CURSOR_TUTORIAL, Region::NO_CURSOR); +#endif + if (you.num_turns != -1) { if (you.num_turns < LONG_MAX) @@ -3426,9 +3411,7 @@ static command_type _keycode_to_command( keycode_type key ) { #ifdef USE_TILE case '-': return CMD_EDIT_PLAYER_TILE; - case CK_MOUSE_DONE: return CMD_NEXT_CMD; - case CK_MOUSE_B1ITEM: return CMD_USE_ITEM; - case CK_MOUSE_B2ITEM: return CMD_VIEW_ITEM; + case CK_MOUSE_CMD: return CMD_NEXT_CMD; #endif case KEY_MACRO_DISABLE_MORE: return CMD_DISABLE_MORE; @@ -3542,11 +3525,7 @@ static command_type _keycode_to_command( keycode_type key ) case CONTROL('R'): return CMD_REDRAW_SCREEN; case CONTROL('S'): return CMD_MARK_STASH; case CONTROL('T'): return CMD_TOGGLE_FRIENDLY_PICKUP; -#ifdef USE_TILE - case CONTROL('V'): return CMD_EDIT_PREFS; -#else case CONTROL('V'): return CMD_NO_CMD; -#endif case CONTROL('W'): return CMD_FIX_WAYPOINT; case CONTROL('X'): return CMD_SAVE_GAME_NOW; case CONTROL('Z'): return CMD_SUSPEND_GAME; @@ -3563,17 +3542,8 @@ static keycode_type _get_next_keycode() flush_input_buffer( FLUSH_BEFORE_COMMAND ); -#ifdef USE_TILE - tile_draw_inv(REGION_INV1); - #ifdef USE_X11 - update_screen(); - #endif - mouse_set_mode(MOUSE_MODE_COMMAND); + mouse_control mc(MOUSE_MODE_COMMAND); keyin = unmangle_direction_keys(getch_with_command_macros()); - mouse_set_mode(MOUSE_MODE_NORMAL); -#else // !USE_TILE - keyin = unmangle_direction_keys(getch_with_command_macros()); -#endif if (!is_synthetic_key(keyin)) mesclr(); @@ -4114,8 +4084,7 @@ static bool _initialise(void) } #ifdef USE_TILE - TilePlayerInit(); - TileInitItems(); + tiles.initialise_items(); TileNewLevel(newc); #endif diff --git a/crawl-ref/source/beam.cc b/crawl-ref/source/beam.cc index 74fdd24a67..3cd3f40501 100644 --- a/crawl-ref/source/beam.cc +++ b/crawl-ref/source/beam.cc @@ -191,6 +191,7 @@ void zap_animation(int colour, const monsters *mon, bool force) if (in_los_bounds(drawx, drawy)) { #ifdef USE_TILE + // TODO enne - fixme! TileDrawBolt(drawx-1, drawy-1, tileidx_zap(colour)); #else view_update(); diff --git a/crawl-ref/source/cio.cc b/crawl-ref/source/cio.cc index e74e6dbd3e..f12061eb25 100644 --- a/crawl-ref/source/cio.cc +++ b/crawl-ref/source/cio.cc @@ -173,7 +173,10 @@ int c_getch() void cursorxy(int x, int y) { #if defined(USE_TILE) +#if 0 + // TODO enne - handle this old use of place cursor tile_place_cursor(x-1, y-1, true); +#endif #elif defined(UNIX) if (Options.use_fake_cursor) fakecursorxy(x, y); diff --git a/crawl-ref/source/cio.h b/crawl-ref/source/cio.h index 69085ebd48..a28d601256 100644 --- a/crawl-ref/source/cio.h +++ b/crawl-ref/source/cio.h @@ -185,7 +185,7 @@ enum KEYS // Mouse codes. CK_MOUSE_MOVE = 10001, - CK_MOUSE_DONE, + CK_MOUSE_CMD, CK_MOUSE_B1, CK_MOUSE_B2, CK_MOUSE_B3, diff --git a/crawl-ref/source/dat/tiles/VeraMono.ttf b/crawl-ref/source/dat/tiles/VeraMono.ttf Binary files differnew file mode 100644 index 0000000000..139f0b4311 --- /dev/null +++ b/crawl-ref/source/dat/tiles/VeraMono.ttf diff --git a/crawl-ref/source/dat/tiles/stone_soup_icon-16x16.png b/crawl-ref/source/dat/tiles/stone_soup_icon-16x16.png Binary files differnew file mode 100644 index 0000000000..334ec2d3c7 --- /dev/null +++ b/crawl-ref/source/dat/tiles/stone_soup_icon-16x16.png diff --git a/crawl-ref/source/dat/tiles/stone_soup_icon-32x32.png b/crawl-ref/source/dat/tiles/stone_soup_icon-32x32.png Binary files differnew file mode 100644 index 0000000000..0c38c15eb9 --- /dev/null +++ b/crawl-ref/source/dat/tiles/stone_soup_icon-32x32.png diff --git a/crawl-ref/source/debug.h b/crawl-ref/source/debug.h index 27c1272eba..9e57942fed 100644 --- a/crawl-ref/source/debug.h +++ b/crawl-ref/source/debug.h @@ -16,6 +16,8 @@ #ifndef DEBUG_H #define DEBUG_H +#include <string> + // Synch with ANSI definitions. #if DEBUG && defined(NDEBUG) #error DEBUG and NDEBUG are out of sync! diff --git a/crawl-ref/source/defines.h b/crawl-ref/source/defines.h index 4ee5296b04..b61107ff13 100644 --- a/crawl-ref/source/defines.h +++ b/crawl-ref/source/defines.h @@ -248,6 +248,8 @@ const int LABYRINTH_BORDER = 4; #define DARKGREY DARKGRAY #endif +#define MAX_TERM_COLOUR 16 + // Colour options... these are used as bit flags along with the colour // value in the low byte. @@ -325,7 +327,7 @@ enum GotoRegion }; // Mouse modes (for tiles) -enum MouseMode +enum mouse_mode { MOUSE_MODE_NORMAL, MOUSE_MODE_COMMAND, diff --git a/crawl-ref/source/describe.cc b/crawl-ref/source/describe.cc index d7dd7d100d..3d65db6941 100644 --- a/crawl-ref/source/describe.cc +++ b/crawl-ref/source/describe.cc @@ -1945,9 +1945,7 @@ void describe_feature_wide(int x, int y) print_description(desc); -#ifdef USE_TILE mouse_control mc(MOUSE_MODE_MORE); -#endif if (Options.tutorial_left) tutorial_describe_pos(x, y); @@ -2212,9 +2210,7 @@ void describe_spell(spell_type spelled) print_description(description); -#ifdef USE_TILE mouse_control mc(MOUSE_MODE_MORE); -#endif if (getch() == 0) getch(); @@ -2496,9 +2492,7 @@ void describe_monsters(monsters& mons) print_description(body.str(), title, suffix, prefix); -#ifdef USE_TILE mouse_control mc(MOUSE_MODE_MORE); -#endif if (Options.tutorial_left) tutorial_describe_monster(static_cast<const monsters*>(&mons)); @@ -2915,9 +2909,7 @@ static void _detailed_god_description(god_type which_god) "Press '<w>!</w>' to toggle between the overview and the more detailed " "description.").display(); -#ifdef USE_TILE mouse_control mc(MOUSE_MODE_MORE); -#endif const int keyin = getch(); if (keyin == '!') @@ -3133,9 +3125,7 @@ void describe_god( god_type which_god, bool give_title ) "Press '<w>!</w>' to toggle between the overview and the more detailed " "description.").display(); -#ifdef USE_TILE mouse_control mc(MOUSE_MODE_MORE); -#endif const int keyin = getch(); if (keyin == '!') diff --git a/crawl-ref/source/directn.cc b/crawl-ref/source/directn.cc index 746ac18bb3..c16b552c6b 100644 --- a/crawl-ref/source/directn.cc +++ b/crawl-ref/source/directn.cc @@ -121,16 +121,45 @@ void direction_choose_compass( dist& moves, targeting_behaviour *beh) moves.isCancel = false; moves.dx = moves.dy = 0; -#ifdef USE_TILE mouse_control mc(MOUSE_MODE_TARGET_DIR); -#endif beh->compass = true; +#ifdef USE_TILE + // Force update of mouse cursor to direction-compatible location. + tiles.place_cursor(CURSOR_MOUSE, tiles.get_cursor()); +#endif + do { const command_type key_command = beh->get_command(); +#ifdef USE_TILE + if (key_command == CMD_TARGET_MOUSE_MOVE) + { + continue; + } + else if (key_command == CMD_TARGET_MOUSE_SELECT) + { + const coord_def &gc = tiles.get_cursor(); + if (gc == Region::NO_CURSOR) + continue; + + coord_def delta = gc - you.pos(); + if (delta.x < -1 || delta.x > 1 + || delta.y < -1 || delta.y > 1) + { + // This shouldn't happen. + continue; + } + + moves.dx = delta.x; + moves.dy = delta.y; + moves.isMe = (delta.x == 0) && (delta.y == 0); + break; + } +#endif + if (key_command == CMD_TARGET_SELECT) { moves.dx = moves.dy = 0; @@ -597,9 +626,7 @@ void direction(dist& moves, targeting_type restricts, } else { -#ifdef USE_TILE mouse_control mc(MOUSE_MODE_TARGET); -#endif key_command = beh->get_command(); } @@ -608,8 +635,8 @@ void direction(dist& moves, targeting_type restricts, if (key_command == CMD_TARGET_MOUSE_MOVE || key_command == CMD_TARGET_MOUSE_SELECT) { - coord_def gc; - if (gui_get_mouse_grid_pos(gc)) + const coord_def &gc = tiles.get_cursor(); + if (gc != Region::NO_CURSOR) { moves.tx = gc.x; moves.ty = gc.y; @@ -2663,9 +2690,7 @@ targeting_behaviour::~targeting_behaviour() int targeting_behaviour::get_key() { -#ifdef USE_TILE mouse_control mc(MOUSE_MODE_TARGET_DIR); -#endif if (!crawl_state.is_replaying_keys()) flush_input_buffer(FLUSH_BEFORE_COMMAND); diff --git a/crawl-ref/source/enum.h b/crawl-ref/source/enum.h index eb850c9320..b445dda5e7 100644 --- a/crawl-ref/source/enum.h +++ b/crawl-ref/source/enum.h @@ -613,10 +613,7 @@ enum command_type #ifdef USE_TILE CMD_TARGET_MOUSE_MOVE, CMD_TARGET_MOUSE_SELECT, - CMD_EDIT_PREFS, CMD_EDIT_PLAYER_TILE, - CMD_USE_ITEM, - CMD_VIEW_ITEM, #endif // Disable/enable -more- prompts. @@ -1430,6 +1427,34 @@ enum map_marker_type MAT_ANY }; +enum map_feature +{ + MF_UNSEEN, + MF_FLOOR, + MF_WALL, + MF_MAP_FLOOR, + MF_MAP_WALL, + MF_DOOR, + MF_ITEM, + MF_MONS_HOSTILE, + MF_MONS_FRIENDLY, + MF_MONS_NEUTRAL, + MF_MONS_NO_EXP, + MF_STAIR_UP, + MF_STAIR_DOWN, + MF_STAIR_BRANCH, + MF_FEATURE, + MF_WATER, + MF_LAVA, + MF_TRAP, + MF_EXCL_ROOT, + MF_EXCL, + MF_PLAYER, + MF_MAX, + + MF_SKIP +}; + enum menu_type { MT_ANY = -1, diff --git a/crawl-ref/source/externs.h b/crawl-ref/source/externs.h index 66c056c8a6..34cbf315dc 100644 --- a/crawl-ref/source/externs.h +++ b/crawl-ref/source/externs.h @@ -35,11 +35,14 @@ #include "store.h" #ifdef USE_TILE -struct TileFlavor +struct tile_flavour { - char floor; - char wall; - char special; + // The floor tile to use. + unsigned char floor; + // The wall tile to use. + unsigned char wall; + // Used as a random value or for special cases e.g. (bazaars, gates). + unsigned char special; }; #endif @@ -1423,7 +1426,7 @@ public: // indexed by grid coords FixedArray<unsigned int,GXM, GYM> tile_bk_fg; // tile fg FixedArray<unsigned int,GXM, GYM> tile_bk_bg; // tile bg - FixedArray<TileFlavor, GXM, GYM> tile_flavor; + FixedArray<tile_flavour, GXM, GYM> tile_flv; // indexed by (show-1) coords FixedArray<unsigned int,ENV_SHOW_DIAMETER-2,ENV_SHOW_DIAMETER-2> tile_fg; FixedArray<unsigned int,ENV_SHOW_DIAMETER-2,ENV_SHOW_DIAMETER-2> tile_bg; @@ -1504,6 +1507,7 @@ struct feature_def unsigned short em_colour; // Emphasised colour when in LoS. unsigned short seen_em_colour; // Emphasised colour when out of LoS unsigned flags; + map_feature minimap; // mini-map categorization bool is_notable() const { return (flags & FFT_NOTABLE); } }; @@ -1872,6 +1876,7 @@ public: char tile_lava_col; char tile_excluded_col; char tile_excl_centre_col; + char tile_window_col; #endif #ifdef WIN32TILES bool use_dos_char; diff --git a/crawl-ref/source/guic-win.cc b/crawl-ref/source/guic-win.cc deleted file mode 100644 index bc8b2a50c0..0000000000 --- a/crawl-ref/source/guic-win.cc +++ /dev/null @@ -1,996 +0,0 @@ -/* - * File: guic-win.cc - * Created by: ennewalker on Sat Jan 5 01:33:53 2008 UTC - * - * Modified for Crawl Reference by $Author: j-p-e-g $ on $Date: 2008-03-07 $ - */ - -#include "AppHdr.h" -#include "debug.h" -#include "externs.h" -#include "guic.h" - -#include <windows.h> -#include <commdlg.h> -#include <commctrl.h> - -#include <stdio.h> -#include <stdlib.h> -#include <malloc.h> -#include <memory.h> -#include <tchar.h> - -// WinClass & RegionClass definitions -static HINSTANCE hInst; -static int nCmdShow; - -// colors -static COLORREF term_pix[MAX_TERM_COL]; -BYTE pix_transparent; -BYTE pix_black; -BYTE pix_white; -BYTE pix_magenta; -BYTE pix_rimcolor; - -RGBQUAD RegionClass::std_palette[256]; - -bool GuicInit(HINSTANCE h, int nCmd) -{ - int i; - hInst = h; - nCmdShow = nCmd; - - for (i = 0; i < MAX_TERM_COL; i++) - { - int *c = (int *)&term_colors[i]; - term_pix[i] = PALETTERGB( c[0], c[1], c[2] ); - } - return (true); -} - -void GuicDeinit() -{ - -} - -void WinClass::SysInit() -{ - hWnd = NULL; -} - -void WinClass::SysDeinit() -{} - -void RegionClass::SysInit() -{ - font = NULL; -} - -void RegionClass::SysDeinit() -{ - if (font != NULL && !font_copied) DeleteObject(font); -} - -void RegionClass::sys_flush() -{} - -void TextRegionClass::SysInit(int x, int y, int cx, int cy) -{ - dos_char = false; -} - -void TextRegionClass::SysDeinit() -{} - -void TileRegionClass::SysInit(int mx0, int my0, int dx0, int dy0) -{} - -void TileRegionClass::SysDeinit() -{} - -void MapRegionClass::SysInit(int x, int y, int o_x, int o_y) -{} - -void MapRegionClass::SysDeinit() -{} - -void RegionClass::init_font(const char *name, int height) -{ - int wid, hgt; - LOGFONT lf; - HFONT ftmp; - - strcpy(lf.lfFaceName, name); - lf.lfHeight = height; - lf.lfWidth = 0; - lf.lfEscapement = 0; - lf.lfOrientation = lf.lfEscapement; - lf.lfWeight = FW_NORMAL; - lf.lfItalic = FALSE; - lf.lfUnderline = FALSE; - lf.lfStrikeOut = FALSE; - lf.lfOutPrecision = OUT_DEFAULT_PRECIS; - lf.lfClipPrecision = CLIP_DEFAULT_PRECIS; - lf.lfQuality = DEFAULT_QUALITY; -#ifdef JP - lf.lfCharSet = (dos_char) ? OEM_CHARSET:SHIFTJIS_CHARSET; - lf.lfPitchAndFamily= FF_DONTCARE|FIXED_PITCH; -#else - lf.lfCharSet = (dos_char) ? OEM_CHARSET:ANSI_CHARSET; - lf.lfPitchAndFamily= FF_MODERN|FIXED_PITCH; -#endif - ftmp = CreateFontIndirect( &lf ); - - if (!ftmp) - { - if (font) return; - exit(1); - } - font = ftmp; - - wid = lf.lfWidth; - hgt = lf.lfHeight; - /* This part is taken from angband */ - /* Hack -- Unknown size */ - if (!wid || !hgt) - { - HDC hdcDesktop; - HFONT hfOld; - TEXTMETRIC tm; - - /* all this trouble to get the cell size */ - hdcDesktop = GetDC(HWND_DESKTOP); - hfOld = (HFONT)SelectObject(hdcDesktop, font); - GetTextMetrics(hdcDesktop, &tm); - SelectObject(hdcDesktop, hfOld); - ReleaseDC(HWND_DESKTOP, hdcDesktop); - - /* Font size info */ - wid = tm.tmAveCharWidth; - hgt = tm.tmHeight; - } - - fx = dx = wid; - fy = dy = hgt; -} - -void RegionClass::change_font(const char *name, int height) -{ - if (font != NULL) DeleteObject(font); - init_font(name, height); -} - -void RegionClass::copy_font(RegionClass *r) -{ - fx = r->fx; - fy = r->fy; - dx = r->dx; - dy = r->dy; - font = r->font; -} - -void RegionClass::set_std_palette(RGBQUAD *pPal) -{ - int i; - for (i = 0; i < 256; i++) - { - std_palette[i].rgbRed = pPal[i].rgbRed ; - std_palette[i].rgbGreen = pPal[i].rgbGreen; - std_palette[i].rgbBlue = pPal[i].rgbBlue ; - - if (pPal[i].rgbRed == 0 - && pPal[i].rgbGreen == 0 - && pPal[i].rgbBlue == 0) - { - pix_black = i; - } - - if (pPal[i].rgbRed == 255 - && pPal[i].rgbGreen == 255 - && pPal[i].rgbBlue == 255) - { - pix_white = i; - } - - if (pPal[i].rgbRed == 255 - && pPal[i].rgbGreen == 0 - && pPal[i].rgbBlue == 255) - { - pix_magenta = i; - } - - if (pPal[i].rgbRed == 1 - && pPal[i].rgbGreen == 1 - && pPal[i].rgbBlue == 1) - { - pix_rimcolor = i; - } - } - - std_palette[pix_transparent].rgbRed = 0; - std_palette[pix_transparent].rgbGreen = 0; - std_palette[pix_transparent].rgbBlue = 0; -} - -void RegionClass::init_backbuf(RGBQUAD *pPal, int ncolor) -{ - int i; - - // first time - if (backbuf == NULL) - { - // alloc for misc info - backbuf = (dib_pack *)GlobalAlloc(GPTR, sizeof(dib_pack)); - - // alloc for header+palette data - backbuf->pDib = (LPBITMAPINFO)GlobalAlloc(GPTR, - (sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)) ); - - // set header data - backbuf->pDib->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); - backbuf->pDib->bmiHeader.biPlanes = 1; - backbuf->pDib->bmiHeader.biBitCount = 8; - backbuf->pDib->bmiHeader.biCompression = BI_RGB; - backbuf->pDib->bmiHeader.biSizeImage = 0; - backbuf->pDib->bmiHeader.biXPelsPerMeter = 0; - backbuf->pDib->bmiHeader.biYPelsPerMeter = 0; - backbuf->pDib->bmiHeader.biClrUsed = 0; - backbuf->pDib->bmiHeader.biClrImportant = 0; - - // set palette data - for (i = 0; i < ncolor; i++) - { - // copy palette from given palette pPal - backbuf->pDib->bmiColors[i].rgbRed = pPal[i].rgbRed ; - backbuf->pDib->bmiColors[i].rgbGreen = pPal[i].rgbGreen; - backbuf->pDib->bmiColors[i].rgbBlue = pPal[i].rgbBlue ; - } - } - // set dimension - backbuf->pDib->bmiHeader.biWidth = mx*dx; - backbuf->pDib->bmiHeader.biHeight = my*dy; - backbuf->Width = mx * dx; - backbuf->Height= my * dy; - - if (win != NULL) - { - // this routine should be called after the window is initialized - if (win->hWnd != NULL) - { - HDC hdc1 = GetDC(0); - HDC hdc2 = GetDC(win->hWnd); - // alloc a region of the window - backbuf->hDib = CreateDIBSection(hdc1, backbuf->pDib, - DIB_RGB_COLORS, (VOID **)&(backbuf->pDibBits), NULL, 0); - backbuf->hDC = CreateCompatibleDC(hdc2); - SelectObject(backbuf->hDC, backbuf->hDib); - ReleaseDC(win->hWnd, hdc2); - ReleaseDC(0, hdc1); - } - } - backbuf->pDibZero = (backbuf->pDibBits - + (backbuf->Height -1) * backbuf->Width); -} - -void RegionClass::resize_backbuf() -{ - int i; - - // discard it for resize - if (backbuf->hDC != NULL) DeleteDC(backbuf->hDC); - if (backbuf->hDib != NULL) DeleteObject(backbuf->hDib); - - // set dimension - backbuf->pDib->bmiHeader.biWidth = mx*dx; - backbuf->pDib->bmiHeader.biHeight = my*dy; - backbuf->Width = mx * dx; - backbuf->Height = my * dy; - - HDC hdc1 = GetDC(0); - HDC hdc2 = GetDC(win->hWnd); - // alloc a region of the window - backbuf->hDib = CreateDIBSection(hdc1, backbuf->pDib, - DIB_RGB_COLORS, (VOID **)&(backbuf->pDibBits), NULL, 0); - backbuf->hDC = CreateCompatibleDC(hdc2); - SelectObject(backbuf->hDC, backbuf->hDib); - ReleaseDC(win->hWnd, hdc2); - ReleaseDC(0, hdc1); - - backbuf->pDibZero = (backbuf->pDibBits - + (backbuf->Height -1) * backbuf->Width); - - for (i = 0; i< mx*dx*my*dy; i++) - *(backbuf->pDibBits + i) = pix_black; -} - -void MapRegionClass::resize_backbuf() -{ - RegionClass::resize_backbuf(); -} - -void TileRegionClass::resize_backbuf() -{ - RegionClass::resize_backbuf(); -} - -void TextRegionClass::init_backbuf() -{ - /* not used */ -} - -void TileRegionClass::init_backbuf(RGBQUAD *pPal) -{ - int i; - if (!pPal) - RegionClass::init_backbuf(std_palette, 256); - else - RegionClass::init_backbuf(pPal, 256); - - for (i = 0; i< mx*dx*my*dy; i++) - *(backbuf->pDibBits + i) = pix_black; -} - -void MapRegionClass::init_backbuf() -{ - BYTE black = 0; - RGBQUAD scol[MAX_MAP_COL]; - int i; - - for (i = 0; i < MAX_MAP_COL; i++) - { - scol[i].rgbBlue = map_colors[i][2]; - scol[i].rgbGreen = map_colors[i][1]; - scol[i].rgbRed = map_colors[i][0]; - scol[i].rgbReserved = 0; - } - - // just resize - if (backbuf != NULL) - RegionClass::init_backbuf(NULL, 0); - else - RegionClass::init_backbuf(scol, MAX_MAP_COL); - - for (i = 0; i < MAX_MAP_COL; i++) - { - if (backbuf->pDib->bmiColors[i].rgbRed == 0 - && backbuf->pDib->bmiColors[i].rgbGreen == 0 - && backbuf->pDib->bmiColors[i].rgbBlue == 0) - { - black = i; - } - } - - for (i = 0; i< mx*dx*my*dy; i++) - *(backbuf->pDibBits + i) = black; -} - -// defined to object, not to class -void TextRegionClass::draw_string(int x, int y, unsigned char *buf, - int len, int col) -{ - HDC hdc = GetDC(win->hWnd); - RECT rc; - rc.left = ox + x * dx; - rc.right = rc.left + len * dx; - rc.top = oy + y * dy; - rc.bottom = rc.top + dy; - - SelectObject(hdc, font); - SetBkColor(hdc, term_pix[col>>4]); - SetTextColor(hdc, term_pix[col&0x0f]); - ExtTextOut(hdc, rc.left, rc.top, ETO_CLIPPED, &rc, - (char *)buf, len, NULL); - ReleaseDC(win->hWnd, hdc); -} - -void TextRegionClass::draw_cursor(int x, int y) -{ - RECT rc; - HDC hdc; - - int cx = x - cx_ofs; - int cy = y - cy_ofs; - - if (!flag) - return; - - hdc = GetDC(win->hWnd); - SelectObject(hdc, font); - - rc.left = ox + cx * dx ; - rc.right = rc.left + (2 * dx); - rc.top = oy + cy * dy; - rc.bottom = rc.top + dy; - - SetBkMode(hdc, TRANSPARENT); - SetTextColor(hdc, term_pix[0x0f]); - ExtTextOut(hdc, rc.left, rc.top, ETO_CLIPPED, &rc, - "_ ", 2, NULL); - ReleaseDC(win->hWnd, hdc); -} - -void TextRegionClass::erase_cursor() -{ - int x0 = cursor_x; - int y0 = cursor_y; - int adrs = y0 * mx + x0; - int col = abuf[adrs]; - - if (!flag) - return; - - RECT rc; - HDC hdc = GetDC(win->hWnd); - SelectObject(hdc, font); - - //restore previous cursor cell - rc.left = ox + x0 * dx; - rc.right = rc.left + (2 * dx); - rc.top = oy + y0 * dy; - rc.bottom = rc.top + dy; - unsigned char rchar[3]; - - SetBkColor(hdc, term_pix[col>>4]); - SetTextColor(hdc, term_pix[col&0x0f]); - rchar[0] = cbuf[adrs]; -#ifdef JP - if ( (rchar[0]&0x80) && !dos_char /*_ismbblead( rchar[0])*/ ) - { - rchar[1] = cbuf[adrs+1]; - rchar[2] = '\0'; - ExtTextOut(hdc, rc.left, rc.top, ETO_CLIPPED, &rc, - (char *)&rchar, 2, NULL); - } - else -#endif - { - rchar[1] = '\0'; - ExtTextOut(hdc, rc.left, rc.top, ETO_CLIPPED, &rc, - (char *)&rchar, 1, NULL); - } - ReleaseDC(win->hWnd, hdc); -} - - -void WinClass::clear() -{ - fillrect(0, 0, wx-1, wy-1, PIX_BLACK); -} - -void RegionClass::clear() -{ - fillrect(0, 0, wx-1, wy-1, PIX_BLACK); -} - -void TileRegionClass::clear() -{ - RegionClass::clear(); -} - -void MapRegionClass::clear() -{ - for (int i = 0; i < mx2*my2; i++) - mbuf[i] = PIX_BLACK; - - RegionClass::clear(); -} - -void TextRegionClass::clear() -{ - int i; - - for (i = 0; i < mx*my; i++) - { - cbuf[i] = ' '; - abuf[i] = 0; - } - RegionClass::clear(); -} - -BOOL WinClass::create(const char *name) -{ - - RECT rc; - rc.left = 0; - rc.right = wx; - rc.top = 0; - rc.bottom = wy; - - //game_state = STAT_NORMAL; - - if ( GetSystemMetrics(SM_CYSCREEN) < (oy + wy) ) - oy = 0; - if ( GetSystemMetrics(SM_CXSCREEN) < (ox + wx) ) - ox = 0; - - AdjustWindowRectEx(&rc, - (WS_OVERLAPPED | WS_SYSMENU | WS_MINIMIZEBOX - | WS_CAPTION | WS_VISIBLE), - false, 0); - - if (hWnd == NULL) - { - hWnd = CreateWindowEx(0, "CrawlList",name, - (WS_OVERLAPPED | WS_SYSMENU | WS_MINIMIZEBOX - | WS_CAPTION | WS_VISIBLE), - ox, oy, //pos - rc.right - rc.left, rc.bottom - rc.top, //size - HWND_DESKTOP, NULL, hInst, NULL); - ShowWindow( hWnd, nCmdShow ); - } - if (!hWnd) - return (FALSE); - - clear(); - return (TRUE); -} - -void WinClass::move() -{ - SetWindowPos(hWnd, 0, ox, oy, wx, wy, SWP_NOSIZE); - UpdateWindow( hWnd ); -} - -void WinClass::resize() -{ - RECT rc; - rc.left = 0; - rc.right = wx; - rc.top = 0; - rc.bottom = wy; - - AdjustWindowRectEx(&rc, - (WS_OVERLAPPED | WS_SYSMENU | WS_MINIMIZEBOX - | WS_CAPTION | WS_VISIBLE), - false, 0); - - SetWindowPos(hWnd, 0, ox, oy, - rc.right - rc.left, - rc.bottom - rc.top, - SWP_NOMOVE); - - UpdateWindow( hWnd ); -} - - -void TileRegionClass::redraw(int x1, int y1, int x2, int y2) -{ - if (!flag) return; - if (!is_active()) return; - - HDC hdc = GetDC(win->hWnd); - BitBlt(hdc, ox, oy, mx*dx, my*dy, - backbuf->hDC, 0, 0, SRCCOPY); - ReleaseDC(win->hWnd, hdc); -} - -void MapRegionClass::redraw(int x1, int y1, int x2, int y2) -{ - if (!flag) return; - if (!is_active()) return; - HDC hdc = GetDC(win->hWnd); - BitBlt(hdc, ox, oy, dx*mx, dy*my, - backbuf->hDC, 0, 0, SRCCOPY); - ReleaseDC(win->hWnd, hdc); -} - -void MapRegionClass::draw_data(unsigned char *buf, bool show_mark, - int mark_x, int mark_y) -{ - if (!flag) - return; - - LPBYTE ppix ,dpix; - int inc_x, inc_y, inc_x0, inc_y0; - int bufx = mx * dx; - int bufy = my * dy; - - bufx = (bufx+3)/4; - bufx *= 4; -#define BUF_IDX(x,y, x1, y1) ((x)*dx-(y)*dy*bufx + (x1) - (y1)*bufx) - // upper left corner - LPBYTE pDibBit0 = backbuf->pDibBits + bufx*(bufy-1); - - ppix = pDibBit0; - - inc_x = dx; - inc_x0 = 1; - - inc_y = - mx2 * inc_x + BUF_IDX(0, 1, 0, 0); - inc_y0 = - dx * inc_x0 + BUF_IDX(0, 0, 0, 1); - - // erase old markers - for (int j = 0; j < dy * marker_length; j++) - *(pDibBit0 + BUF_IDX(old_mark_x, 0, dx/2 + x_margin, j)) = MAP_BLACK; - - for (int j = 0; j < dx * marker_length; j++) - *(pDibBit0 + BUF_IDX(0, old_mark_y, j, dy/2 + y_margin)) = MAP_BLACK; - - force_redraw = true; - - dpix = ppix; - for (int j = 0; j < my2; j++) - { - unsigned char *ptr = &buf[j * (mx2 - x_margin)]; - for (int i = 0; i < mx2; i++) - { - int col = (j >= my2 - y_margin || i >= mx2 - x_margin) ? - MAP_BLACK : ptr[i]; - if ( col != get_col(i,j) || force_redraw - || i < marker_length || j < marker_length) - { - dpix = ppix; - for (int y = 0; y < dy; y++) - { - for (int x = 0; x < dx; x++) - { - *dpix = col; - dpix += inc_x0; - } - dpix += inc_y0; - } - set_col(col, i, j); - } - ppix += inc_x; - } - ppix += inc_y; - } - - old_mark_x = mark_x; - old_mark_y = mark_y; - - if (show_mark) - { - // draw new markers - for (int j = 0; j < dy * marker_length; j++) - *(pDibBit0 + BUF_IDX(mark_x, 0, dx/2 + x_margin, j)) = MAP_WHITE; - - for (int j = 0; j < dx * marker_length; j++) - *(pDibBit0 + BUF_IDX(0, mark_y, j, dy/2 + y_margin)) = MAP_WHITE; - } - - redraw(); - force_redraw = false; -} - -// -// img_type related -// - -LPBYTE dib_ref_pixel(dib_pack* dib, int x, int y) -{ - int w = ((3 + dib->Width)/4)*4; - LPBYTE ref = dib->pDibBits + x + (dib->Height -1 -y) * w; - return (ref); -} - -bool ImgIsTransparentAt(img_type img, int x, int y) -{ - if (pix_transparent == *( dib_ref_pixel(img, x, y) )) - return (true); - - return (false); -} -void ImgSetTransparentPix(img_type img) -{ - pix_transparent = (BYTE)*(img->pDibZero); -} - -img_type ImgCreateSimple(int wx, int wy) -{ - if (wx == 0 || wy == 0) - return NULL; - - dib_pack *ptr = (dib_pack *)GlobalAlloc(GPTR, sizeof(dib_pack)); - - ptr->pDibBits = (LPBYTE)GlobalAlloc(GPTR, wx*wy ); - ptr->pDibZero = ptr->pDibBits + (wy -1)* wx; - ptr->Width = wx; - ptr->Height = wy; - - ptr->pDib = NULL; - ptr->hDib = NULL; - ptr->hDC = NULL; - - return (ptr); -} - -void ImgDestroy(img_type img) -{ - if (!img) - return; - - if (img->pDib) - GlobalFree(img->pDib); - - if (img->hDC) - DeleteDC(img->hDC); - - if (img->hDib) - DeleteObject(img->hDib); - - GlobalFree(img); -} - -img_type ImgLoadFile(const char *name) -{ - HANDLE fh; - DWORD dummy; - BITMAPFILEHEADER bmHead; - int BitsSize; - HDC hdc1; - dib_pack *img; - - hdc1 = GetDC(0); - - fh = CreateFile(name, GENERIC_READ, 0, NULL, OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL, NULL); - - if (fh == INVALID_HANDLE_VALUE) - return NULL; - - SetFilePointer(fh, 0, NULL, FILE_BEGIN); - - if (!ReadFile(fh,&bmHead, sizeof(BITMAPFILEHEADER), &dummy, NULL)) - return NULL; - - img = (dib_pack *) GlobalAlloc(GPTR, sizeof(dib_pack)); - if (!img) - return NULL; - - img->pDib = (LPBITMAPINFO)GlobalAlloc(GPTR, - (sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)) ); - if (img->pDib == NULL) - { - GlobalFree(img); - return NULL; - } - - SetFilePointer(fh, sizeof(BITMAPFILEHEADER), NULL, FILE_BEGIN); - if (!ReadFile(fh, img->pDib, - sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD), - &dummy, NULL)) - { - GlobalFree(img->pDib); - GlobalFree(img); - return NULL; - } - - img->hDib = CreateDIBSection(hdc1, img->pDib, DIB_RGB_COLORS, - (VOID **)&(img->pDibBits), NULL,0); - if (img->hDib == NULL) - { - GlobalFree(img->pDib); - GlobalFree(img); - return NULL; - } - - - BitsSize = bmHead.bfSize-bmHead.bfOffBits; - SetFilePointer(fh, bmHead.bfOffBits, NULL, FILE_BEGIN); - - if (!ReadFile(fh, img->pDibBits, BitsSize, &dummy, NULL)) - { - GlobalFree(img->hDib); - GlobalFree(img->pDib); - GlobalFree(img); - return NULL; - } - - CloseHandle(fh); - - img->Width = img->pDib->bmiHeader.biWidth ; - img->Height = img->pDib->bmiHeader.biHeight; - img->pDibZero = img->pDibBits + (img->Height - 1) * img->Width; - - ReleaseDC(0, hdc1); - return img; -} - -void ImgClear(img_type img) -{ - int i; - for (i = 0; i< (img->Width * img->Height); i++) - *(img->pDibBits + i) = pix_transparent; -} - -// Copy internal image to another internal image -void ImgCopy(img_type src, int sx, int sy, int wx, int wy, - img_type dest, int dx, int dy, int copy) -{ - int x, y; - BYTE pix; - - if (copy) - { - for (x = 0; x < wx; x++) - for (y = 0; y < wy; y++) - { - pix = *( dib_ref_pixel(src, sx+x, sy+y) ); - *( dib_ref_pixel(dest, dx+x, dy+y) ) = pix; - } - } - else - { - for (x = 0; x < wx; x++) - for (y = 0; y < wy; y++) - { - pix = *( dib_ref_pixel(src, sx+x, sy+y) ); - if (pix!=pix_transparent) - *( dib_ref_pixel(dest, dx+x, dy+y) ) = pix; - } - } -} - -// Copy internal image to another internal image -void ImgCopyH(img_type src, int sx, int sy, int wx, int wy, - img_type dest, int dx, int dy, int copy) -{ - int x, y; - BYTE pix; - - if (copy) - { - for (x = 0; x < wx; x++) - for (y = 0; y < wy; y++) - { - pix = *( dib_ref_pixel(src, sx+x, sy+y) ); - if (pix == pix_rimcolor) pix = pix_magenta; - *( dib_ref_pixel(dest, dx+x, dy+y) ) = pix; - } - } - else - { - for (x = 0; x < wx; x++) - for (y = 0; y < wy; y++) - { - pix = *( dib_ref_pixel(src, sx+x, sy+y) ); - - if (pix == pix_rimcolor) - pix = pix_magenta; - if (pix != pix_transparent) - *( dib_ref_pixel(dest, dx+x, dy+y) ) = pix; - } - } -} - - -// Copy internal image to another internal image -void ImgCopyMasked(img_type src, int sx, int sy, int wx, int wy, - img_type dest, int dx, int dy, char *mask) -{ - int x, y; - BYTE pix; - int count = 0; - for (y = 0; y < wy; y++) - for (x = 0; x < wx; x++) - { - pix = *( dib_ref_pixel(src, sx+x, sy+y) ); - if (mask[count] == 0 && pix != pix_transparent) - *( dib_ref_pixel(dest, dx+x, dy+y) ) = pix; - count++; - } -} - -// Copy internal image to another internal image -void ImgCopyMaskedH(img_type src, int sx, int sy, int wx, int wy, - img_type dest, int dx, int dy, char *mask) -{ - int x, y; - BYTE pix; - int count = 0; - for (y = 0; y < wy; y++) - for (x = 0; x < wx; x++) - { - pix = *( dib_ref_pixel(src, sx+x, sy+y) ); - if (pix == pix_rimcolor) - pix = pix_magenta; - if (mask[count] == 0 && pix != pix_transparent) - *( dib_ref_pixel(dest, dx+x, dy+y) ) = pix; - count++; - } -} - -void WinClass::fillrect(int left, int top, int right, int bottom, int color) -{ - HDC hdc = GetDC(hWnd); - - HBRUSH curbrush; - HDC curbrushhdc = NULL; - RECT currect; - curbrush = CreateSolidBrush(term_pix[color]); - currect.left = left; - currect.right = right; - currect.top = top; - currect.bottom = bottom; - SelectObject(curbrushhdc, curbrush); - FillRect(hdc, &currect, curbrush); - DeleteObject(curbrush); - DeleteDC(curbrushhdc); - - ReleaseDC(hWnd, hdc); -} - - -void TileRegionClass::DrawPanel(int left, int top, int width, int height) -{ - framerect(left, top , left + width, top + height, PIX_WHITE); - framerect(left + 1, top + 1, left + width, top + height, PIX_DARKGREY); - fillrect (left + 1, top + 1, left + width - 1, top + height -1, PIX_LIGHTGREY); -} - -void RegionClass::framerect(int left, int top, int right, int bottom, int color) -{ - HDC hdc = GetDC(win->hWnd); - - HBRUSH curbrush; - HDC curbrushhdc = NULL; - RECT currect; - curbrush = CreateSolidBrush(term_pix[color]); - currect.left = sx + left; - currect.right = sx + right; - currect.top = sy + top; - currect.bottom = sy + bottom; - SelectObject(curbrushhdc, curbrush); - FrameRect(hdc, &currect, curbrush); - DeleteObject(curbrush); - DeleteDC(curbrushhdc); - - ReleaseDC(win->hWnd, hdc); -} - -void TileRegionClass::framerect(int left, int top, int right, int bottom, - int color) -{ - HDC dhdc = backbuf->hDC; - HBRUSH curbrush; - HDC curbrushhdc = NULL; - RECT currect; - curbrush = CreateSolidBrush(term_pix[color]); - currect.left = left; - currect.right = right; - currect.top = top; - currect.bottom = bottom; - SelectObject(curbrushhdc, curbrush); - FrameRect(dhdc, &currect, curbrush); - DeleteObject(curbrush); - DeleteDC(curbrushhdc); -} - -void RegionClass::fillrect(int left, int top, int right, int bottom, int color) -{ - HDC hdc = GetDC(win->hWnd); - - HBRUSH curbrush; - HDC curbrushhdc = NULL; - RECT currect; - curbrush = CreateSolidBrush(term_pix[color]); - currect.left = sx + left; - currect.right = sx + right; - currect.top = sy + top; - currect.bottom = sy + bottom; - SelectObject(curbrushhdc, curbrush); - FillRect(hdc, &currect, curbrush); - DeleteObject(curbrush); - DeleteDC(curbrushhdc); - - ReleaseDC(win->hWnd, hdc); -} - -void TileRegionClass::fillrect(int left, int top, int right, int bottom, - int color) -{ - HDC dhdc = backbuf->hDC; - HBRUSH curbrush; - HDC curbrushhdc = NULL; - RECT currect; - curbrush = CreateSolidBrush(term_pix[color]); - currect.left = left; - currect.right = right; - currect.top = top; - currect.bottom = bottom; - SelectObject(curbrushhdc, curbrush); - FillRect(dhdc, &currect, curbrush); - DeleteObject(curbrush); - DeleteDC(curbrushhdc); -} diff --git a/crawl-ref/source/guic-x11.cc b/crawl-ref/source/guic-x11.cc deleted file mode 100644 index 965f3089d4..0000000000 --- a/crawl-ref/source/guic-x11.cc +++ /dev/null @@ -1,1106 +0,0 @@ -/* - * File: guic-x11.cc - * Created by: ennewalker on Sat Jan 5 01:33:53 2008 UTC - * - * Modified for Crawl Reference by $Author: j-p-e-g $ on $Date: 2008-03-07 $ - */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#include <X11/Xlib.h> -#include <X11/X.h> -#include <X11/Xutil.h> -#include <X11/Xlocale.h> -#include <X11/keysym.h> -#include <X11/keysymdef.h> -#include <X11/Xmd.h> - -#include "AppHdr.h" -#include "debug.h" -#include "externs.h" -#include "guic.h" -#include "version.h" - -static Display *display; -static int screen; -static GC term_gc[MAX_TERM_COL]; -static GC map_gc[MAX_MAP_COL]; -static unsigned long term_pix[MAX_TERM_COL]; -static unsigned long map_pix[MAX_MAP_COL]; -static unsigned long pix_transparent; -static unsigned long pix_hilite; -static unsigned long pix_black; -static unsigned long pix_rimcolor; -static int x11_byte_per_pixel_ximage(); -static unsigned long create_pixel(unsigned int red, unsigned int green, - unsigned int blue); -static XImage *read_png(const char *fname); - -/*******************************************************/ -void WinClass::SysInit() -{ - win = (Window)NULL; -} - -void WinClass::SysDeinit() -{} - -void RegionClass::SysInit() -{ - font = NULL; -} - -void RegionClass::SysDeinit() -{ - if (font != NULL && !font_copied) XFreeFont(display, font); -} - -void TextRegionClass::SysInit(int x, int y, int cx, int cy) -{} - -void TextRegionClass::SysDeinit() -{} - -void TileRegionClass::SysInit(int mx0, int my0, int dx0, int dy0) -{} - -void TileRegionClass::SysDeinit() -{} - -void MapRegionClass::SysInit(int x, int y, int o_x, int o_y) -{} - -void MapRegionClass::SysDeinit() -{} - -void RegionClass::init_font(const char *name) -{ - /*** Large part of this routine was copied from Hengband ***/ - int ascent, descent, width; - - font = XLoadQueryFont(display, name); - if (!font) - { - fprintf(stderr,"Error! Can't load font %s\n",name); - exit(1); - } - width = font->max_bounds.width; - ascent = font->ascent; - descent = font->descent; - - int i; - for (i = 0; i < MAX_TERM_COL; i++) - XSetFont(display, term_gc[i], font->fid); - - fx = dx = width; - fy = dy = ascent + descent; - asc = ascent; - font_copied = false; -} - -void RegionClass::copy_font(RegionClass *r) -{ - fx = r->fx; - fy = r->fy; - dx = r->dx; - dy = r->dy; - asc = r->asc; - font = r->font; - font_copied = true; -} - -void RegionClass::sys_flush() -{ - XFlush(display); -} - -void RegionClass::init_backbuf() -{ -} - -void TextRegionClass::init_backbuf() -{ -} - -void TileRegionClass::init_backbuf() -{ - int x, y; - - backbuf = ImgCreateSimple(mx*dx, my*dy); - for (x = 0; x < mx*dx; x++) - for (y = 0; y < my*dy; y++) - XPutPixel(backbuf, x, y, pix_black); -} - -void TileRegionClass::resize_backbuf() -{ - if (backbuf != NULL) ImgDestroy(backbuf); - init_backbuf(); -} - -void RegionClass::resize_backbuf() -{ - if (backbuf != NULL) ImgDestroy(backbuf); - init_backbuf(); -} - -void MapRegionClass::init_backbuf() -{ - int x, y; - backbuf = ImgCreateSimple(mx*dx, my*dy); - for (x = 0; x < mx*dx; x++) - for (y = 0; y < my*dy; y++) - XPutPixel(backbuf, x, y, pix_black); -} - -void MapRegionClass::resize_backbuf() -{ - if (backbuf != NULL) - ImgDestroy(backbuf); - init_backbuf(); -} - -void TextRegionClass::draw_string(int x, int y, unsigned char *buf, - int len, int col) -{ - XFillRectangle(display, win->win, term_gc[col>>4], - x*dx+ox, y*dy+oy, dx * len, dy); - XDrawString(display, win->win, term_gc[col&0x0f], x*dx+ox, y*dy+asc+oy, - (char *)&cbuf[y*mx+x], len); -} - -void TextRegionClass::draw_cursor(int x, int y) -{ - if (!flag) - return; - - XDrawString(display, win->win, term_gc[0x0f], x*dx+ox, y*dy+asc+oy, - "_", 1); - sys_flush(); -} - -void TextRegionClass::erase_cursor() -{ - WinClass *w = win; - - int x0 = cursor_x; - int y0 = cursor_y; - int width = 1; - int adrs = y0 * mx + x0; - int col = abuf[adrs]; - int x1 = x0;; - if (!flag) - return; - - XFillRectangle(display, w->win, term_gc[col>>4], - x1*dx + ox, y0*dy +oy, dx*width, dy); - - XDrawString(display, w->win, - term_gc[col&0x0f], x0*dx+ ox, y0*dy+asc+ oy, - (char *)&cbuf[adrs], width ); -} - - -void WinClass::clear() -{ - fillrect(0, 0, wx, wy, PIX_BLACK); - XFlush(display); -} - -void RegionClass::clear() -{ - fillrect(0, 0, wx, wy, PIX_BLACK); - XFlush(display); -} - -void TileRegionClass::clear() -{ - RegionClass::clear(); -} - -void MapRegionClass::clear() -{ - int i; - - for (i = 0; i < mx2*my2; i++) - mbuf[i] = PIX_BLACK; - - RegionClass::clear(); -} - -void TextRegionClass::clear() -{ - int i; - - for (i = 0; i < mx*my; i++) - { - cbuf[i] = ' '; - abuf[i] = 0; - } - - RegionClass::clear(); -} - -void WinClass::create(char *name) -{ - - if (!win) - { - win = XCreateSimpleWindow(display, RootWindow(display,screen), - 10,10, wx, wy, 0, - BlackPixel(display,screen), BlackPixel(display,screen)); - - XMapWindow(display, win); - XSelectInput(display, win, ExposureMask | KeyPressMask - | ButtonPressMask | ButtonReleaseMask | PointerMotionMask | - LeaveWindowMask | EnterWindowMask | StructureNotifyMask ); - move(ox, oy); - - XStoreName(display, win, CRAWL " " VERSION); - } - else - resize(0,0); - - clear(); -} - -void WinClass::move() -{ - XMoveWindow(display, win, ox, oy); -} - -void WinClass::resize() -{ - XResizeWindow(display, win, wx, wy); -} - -void TileRegionClass::redraw(int x1, int y1, int x2, int y2) -{ - int wwx = x2-x1+1; - int wwy = y2-y1+1; - - if (x1<0) - { - wwx += x1; - x1 = 0; - } - - if (y1<0) - { - wwy += y1; - y1 = 0; - } - - if (x2 >= mx*dx) - { - wwx -= x2-mx*dx+1; - } - - if (y2 >= my*dy) - { - wwy -= y2-my*dy+1; - } - - XPutImage(display, win->win, term_gc[0], - backbuf, x1, y1, x1+ox, y1+oy, wwx, wwy); -} - -void MapRegionClass::redraw(int x1, int y1, int x2, int y2) -{ - if (!flag) - return; - - XPutImage(display, win->win, term_gc[0], - backbuf, x1*dx, y1*dy, - x1*dx+ox, y1*dy+oy, - (x2-x1+1)*dx, (y2-y1+1)*dy); -} - -void MapRegionClass::draw_data(unsigned char *buf, bool show_mark, - int mark_x, int mark_y) -{ - if (!flag) - return; - - for (int yy = 0; yy < dy * marker_length; yy++) - { - XPutPixel(backbuf, old_mark_x*dx+dx/2 + x_margin, yy, - map_pix[MAP_BLACK]); - } - - for (int xx = 0; xx < dx * marker_length; xx++) - { - XPutPixel(backbuf, xx, old_mark_y*dy+dy/2 + y_margin, - map_pix[MAP_BLACK]); - } - - for (int y = 0; y < my - y_margin; y++) - { - unsigned char *ptr = &buf[y * (mx2 - x_margin)]; - for (int x = 0; x < mx - x_margin; x++) - { - int col = ptr[x]; - if (col != get_col(x, y) || force_redraw - || x < marker_length || y < marker_length) - { - for (int xx = 0; xx < dx; xx++) - for (int yy = 0; yy < dy; yy++) - { - XPutPixel(backbuf, x_margin + x*dx+xx, - y_margin + y*dy+yy, map_pix[col]); - } - - set_col(col, x, y); - } - } - } - - old_mark_x = mark_x; - old_mark_y = mark_y; - - if (show_mark) - { - for (int yy = 0; yy < dy * marker_length; yy++) - { - XPutPixel(backbuf, old_mark_x*dx+dx/2 + x_margin, yy, - map_pix[MAP_WHITE]); - } - - for (int xx = 0; xx < dx * marker_length; xx++) - { - XPutPixel(backbuf, xx, old_mark_y*dy+dy/2 + y_margin, - map_pix[MAP_WHITE]); - } - } - - redraw(); - XFlush(display); - force_redraw = false; -} - -/* XXXXX - * img_type related - */ - -bool ImgIsTransparentAt(img_type img, int x, int y) -{ - ASSERT(x >= 0); - ASSERT(y >= 0); - ASSERT(x < img->width); - ASSERT(y < img->height); - - return (pix_transparent == XGetPixel(img, x, y)) ? true : false; -} - -void ImgSetTransparentPix(img_type img) -{ - pix_transparent = XGetPixel(img, 0, 0); -} - -void ImgDestroy(img_type img) -{ - if (img) - XDestroyImage(img); -} - -img_type ImgCreateSimple(int wx, int wy) -{ - if (wx == 0 || wy == 0) - return NULL; - - char *buf = (char *)malloc(x11_byte_per_pixel_ximage()* wx * wy); - - img_type res = XCreateImage(display, DefaultVisual(display, screen), - DefaultDepth(display, screen), - ZPixmap, 0, buf, wx, wy, 8, 0); - return(res); -} - -img_type ImgLoadFile(const char *name) -{ - return read_png(name); -} - -void ImgClear(img_type img) -{ - int x, y; - ASSERT(img != NULL); - for (x = 0; x < img->width; x++) - for (y = 0; y < img->height; y++) - XPutPixel(img, x, y, pix_transparent); -} - -// Copy internal image to another internal image -void ImgCopy(img_type src, int sx, int sy, int wx, int wy, - img_type dest, int dx, int dy, int copy) -{ - int x, y; - int bpp = src->bytes_per_line / src->width; - int bpl_s = src->bytes_per_line; - int bpl_d = dest->bytes_per_line; - - ASSERT(sx >= 0); - ASSERT(sy >= 0); - ASSERT(sx + wx <= src->width); - ASSERT(sy + wy <= src->height); - ASSERT(dx >= 0); - ASSERT(dy >= 0); - ASSERT(dx + wx <= dest->width); - ASSERT(dy + wy <= dest->height); - - if (copy == 1) - { - char *p_src = (char *)(src->data + bpl_s * sy + sx * bpp); - char *p_dest = (char *)(dest->data + bpl_d * dy + dx * bpp); - - for (y = 0; y < wy; y++) - { - memcpy(p_dest, p_src, wx * bpp); - p_src += bpl_s; - p_dest += bpl_d; - } - } - else if (bpp <= 1) - { - CARD8 *p_src = (CARD8 *)(src->data + bpl_s * sy + sx * bpp); - CARD8 *p_dest = (CARD8 *)(dest->data + bpl_d * dy + dx * bpp); - for (y = 0; y < wy; y++) - { - for (x = 0; x < wx; x++) - { - //X11 specific - if (p_src[x] != pix_transparent) - p_dest[x] = p_src[x]; - } - p_src += bpl_s; - p_dest += bpl_d; - } - } - else if (bpp <= 2) - { - CARD16 *p_src = (CARD16 *)(src->data + bpl_s * sy + sx * bpp); - CARD16 *p_dest = (CARD16 *)(dest->data + bpl_d * dy + dx * bpp); - for (y = 0; y < wy; y++) - { - for (x = 0; x < wx; x++) - { - //X11 specific - if (p_src[x] != pix_transparent) - p_dest[x] = p_src[x]; - } - p_src += bpl_s/bpp; - p_dest += bpl_d/bpp; - } - } - else if (bpp <= 4) - { - CARD32 *p_src = (CARD32 *)(src->data + bpl_s * sy + sx * bpp); - CARD32 *p_dest = (CARD32 *)(dest->data + bpl_d * dy + dx * bpp); - for (y = 0; y < wy; y++) - { - for (x = 0; x < wx; x++) - { - //X11 specific - if (p_src[x] != pix_transparent) - p_dest[x] = p_src[x]; - } - p_src += bpl_s/bpp; - p_dest += bpl_d/bpp; - } - } - -} - -// Copy internal image to another internal image -void ImgCopyH(img_type src, int sx, int sy, int wx, int wy, - img_type dest, int dx, int dy, int copy) -{ - int x, y; - int bpp = src->bytes_per_line / src->width; - int bpl_s = src->bytes_per_line; - int bpl_d = dest->bytes_per_line; - - ASSERT(sx >= 0); - ASSERT(sy >= 0); - ASSERT(sx + wx <= src->width); - ASSERT(sy + wy <= src->height); - ASSERT(dx >= 0); - ASSERT(dy >= 0); - ASSERT(dx + wx <= dest->width); - ASSERT(dy + wy <= dest->height); - - if (copy == 1) - { - char *p_src = (char *)(src->data + bpl_s * sy + sx * bpp); - char *p_dest = (char *)(dest->data + bpl_d * dy + dx * bpp); - - for (y = 0; y < wy; y++) - { - memcpy(p_dest, p_src, wx * bpp); - p_src += bpl_s; - p_dest += bpl_d; - } - } - else if (bpp <= 1) - { - CARD8 *p_src = (CARD8 *)(src->data + bpl_s * sy + sx * bpp); - CARD8 *p_dest = (CARD8 *)(dest->data + bpl_d * dy + dx * bpp); - for (y = 0; y < wy; y++) - { - for (x = 0; x < wx; x++) - { - //X11 specific - if (p_src[x] == pix_rimcolor) - p_dest[x] = pix_hilite; - else if (p_src[x] != pix_transparent) - p_dest[x] = p_src[x]; - } - p_src += bpl_s; - p_dest += bpl_d; - } - } - else if (bpp <= 2) - { - CARD16 *p_src = (CARD16 *)(src->data + bpl_s * sy + sx * bpp); - CARD16 *p_dest = (CARD16 *)(dest->data + bpl_d * dy + dx * bpp); - for (y = 0; y < wy; y++) - { - for (x = 0; x < wx; x++) - { - //X11 specific - if (p_src[x] == pix_rimcolor) - p_dest[x] = pix_hilite; - else if (p_src[x] != pix_transparent) - p_dest[x] = p_src[x]; - } - p_src += bpl_s/bpp; - p_dest += bpl_d/bpp; - } - } - else if (bpp <= 4) - { - CARD32 *p_src = (CARD32 *)(src->data + bpl_s * sy + sx * bpp); - CARD32 *p_dest = (CARD32 *)(dest->data + bpl_d * dy + dx * bpp); - for (y = 0; y < wy; y++) - { - for (x = 0; x < wx; x++) - { - //X11 specific - if (p_src[x] == pix_rimcolor) - p_dest[x] = pix_hilite; - else if (p_src[x] != pix_transparent) - p_dest[x] = p_src[x]; - } - p_src += bpl_s/bpp; - p_dest += bpl_d/bpp; - } - } - -} - - -// Copy internal image to another internal image -void ImgCopyMasked(img_type src, int sx, int sy, int wx, int wy, - img_type dest, int dx, int dy, char *mask) -{ - int x, y, count; - int bpp = src->bytes_per_line / src->width; - int bpl_s = src->bytes_per_line; - int bpl_d = dest->bytes_per_line; - ASSERT(sx >= 0); - ASSERT(sy >= 0); - ASSERT(sx + wx <= src->width); - ASSERT(sy + wy <= src->height); - ASSERT(dx >= 0); - ASSERT(dy >= 0); - ASSERT(dx + wx <= dest->width); - ASSERT(dy + wy <= dest->height); - - count = 0; - - if (bpp <= 1) - { - CARD8 *p_src = (CARD8 *)(src->data + bpl_s * sy + sx * bpp); - CARD8 *p_dest = (CARD8 *)(dest->data + bpl_d * dy + dx * bpp); - for (y = 0; y < wy; y++) - { - for (x = 0; x < wx; x++) - { - //X11 specific - if (p_src[x] != pix_transparent && mask[count] == 0) - p_dest[x] = p_src[x]; - count++; - } - p_src += bpl_s; - p_dest += bpl_d; - } - } - else if (bpp <= 2) - { - CARD16 *p_src = (CARD16 *)(src->data + bpl_s * sy + sx * bpp); - CARD16 *p_dest = (CARD16 *)(dest->data + bpl_d * dy + dx * bpp); - for (y = 0; y < wy; y++) - { - for (x = 0; x < wx; x++) - { - //X11 specific - if (p_src[x] != pix_transparent && mask[count] == 0) - p_dest[x] = p_src[x]; - count++; - } - p_src += bpl_s/bpp; - p_dest += bpl_d/bpp; - } - } - else if (bpp <= 4) - { - CARD32 *p_src = (CARD32 *)(src->data + bpl_s * sy + sx * bpp); - CARD32 *p_dest = (CARD32 *)(dest->data + bpl_d * dy + dx * bpp); - for (y = 0; y < wy; y++) - { - for (x = 0; x < wx; x++) - { - //X11 specific - if (p_src[x] != pix_transparent && mask[count] == 0) - p_dest[x] = p_src[x]; - count++; - } - p_src += bpl_s/bpp; - p_dest += bpl_d/bpp; - } - } -} - -// Copy internal image to another internal image -void ImgCopyMaskedH(img_type src, int sx, int sy, int wx, int wy, - img_type dest, int dx, int dy, char *mask) -{ - int x, y, count; - int bpp = src->bytes_per_line / src->width; - int bpl_s = src->bytes_per_line; - int bpl_d = dest->bytes_per_line; - ASSERT(sx >= 0); - ASSERT(sy >= 0); - ASSERT(sx + wx <= src->width); - ASSERT(sy + wy <= src->height); - ASSERT(dx >= 0); - ASSERT(dy >= 0); - ASSERT(dx + wx <= dest->width); - ASSERT(dy + wy <= dest->height); - - count = 0; - - if (bpp <= 1) - { - CARD8 *p_src = (CARD8 *)(src->data + bpl_s * sy + sx * bpp); - CARD8 *p_dest = (CARD8 *)(dest->data + bpl_d * dy + dx * bpp); - for (y = 0; y < wy; y++) - { - for (x = 0; x < wx; x++) - { - //X11 specific - if (p_src[x] == pix_rimcolor) - p_dest[x] = pix_hilite; - else if (p_src[x] != pix_transparent && mask[count] == 0) - p_dest[x] = p_src[x]; - - count++; - } - p_src += bpl_s; - p_dest += bpl_d; - } - } - else if (bpp <= 2) - { - CARD16 *p_src = (CARD16 *)(src->data + bpl_s * sy + sx * bpp); - CARD16 *p_dest = (CARD16 *)(dest->data + bpl_d * dy + dx * bpp); - for (y = 0; y < wy; y++) - { - for (x = 0; x < wx; x++) - { - //X11 specific - if (p_src[x] == pix_rimcolor) - p_dest[x] = pix_hilite; - else if (p_src[x] != pix_transparent && mask[count] == 0) - p_dest[x] = p_src[x]; - count++; - } - p_src += bpl_s/bpp; - p_dest += bpl_d/bpp; - } - } - else if (bpp <= 4) - { - CARD32 *p_src = (CARD32 *)(src->data + bpl_s * sy + sx * bpp); - CARD32 *p_dest = (CARD32 *)(dest->data + bpl_d * dy + dx * bpp); - for (y = 0; y < wy; y++) - { - for (x = 0; x < wx; x++) - { - //X11 specific - if (p_src[x] == pix_rimcolor) - p_dest[x] = pix_hilite; - else if (p_src[x] != pix_transparent && mask[count] == 0) - p_dest[x] = p_src[x]; - count++; - } - p_src += bpl_s/bpp; - p_dest += bpl_d/bpp; - } - } -} - -void TileRegionClass::DrawPanel(int left, int top, int width, int height) -{ - framerect(left, top , left + width, top + height, PIX_WHITE); - framerect(left + 1, top + 1, left + width, top + height, PIX_DARKGREY); - fillrect (left + 1, top + 1, left + width - 1, top + height -1, PIX_LIGHTGREY); -} - -void RegionClass::framerect(int left, int top, int right, int bottom, - int color) -{ - XDrawRectangle(display, win->win, term_gc[color&0xf], - ox+left, oy+top, right-left, bottom-top); -} - -void TileRegionClass::framerect(int left, int top, int right, int bottom, - int color) -{ - int x,y; - int pix = term_pix[color]; - - for (x = left; x <= right; x++) - { - XPutPixel(backbuf, x, top, pix); - XPutPixel(backbuf, x, bottom, pix); - } - - for (y = top+1; y < bottom; y++) - { - XPutPixel(backbuf, left, y, pix); - XPutPixel(backbuf, right, y, pix); - } -} - -void WinClass::fillrect(int left, int top, int right, int bottom, - int color) -{ - XFillRectangle(display, win, term_gc[color&0xf], - top, left, right-left+1, bottom-top+1); -} - -void RegionClass::fillrect(int left, int top, int right, int bottom, - int color) -{ - XFillRectangle(display, win->win, term_gc[color&0xf], - ox+left, oy+top, right-left, bottom-top); -} - -void TileRegionClass::fillrect(int left, int top, int right, int bottom, - int color) -{ - int x,y; - int pix = term_pix[color]; - - ASSERT(left >= 0); - ASSERT(top >= 0); - ASSERT(right < mx*dx); - ASSERT(bottom < my*dy); - - for (x = left; x <= right; x++) - for (y = top; y <= bottom; y++) - XPutPixel(backbuf, x, y, pix); -} - -/********************************************/ - -bool GuicInit(Display **d, int *s) -{ - int i; - setlocale(LC_ALL, ""); - display = XOpenDisplay(""); - if (!display) - { - fprintf(stderr,"Cannot open display\n"); - return (false); - } - screen=DefaultScreen(display); - - *d = display; - *s = screen; - - // for text display - for (i = 0; i < MAX_TERM_COL; i++) - { - const int *c = term_colors[i]; - term_pix[i] = create_pixel(c[0], c[1], c[2]); - term_gc[i] = XCreateGC(display, RootWindow(display,screen), 0, 0); - XSetForeground(display,term_gc[i], term_pix[i]); - } - // for text display - for (i = 0; i < MAX_MAP_COL; i++) - { - const int *c = map_colors[i]; - map_pix[i] = create_pixel(c[0], c[1], c[2]); - map_gc[i] = XCreateGC(display, RootWindow(display,screen), 0, 0); - XSetForeground(display, map_gc[i], map_pix[i]); - } - - // for Image manipulation - pix_black = term_pix[PIX_BLACK] ; - pix_hilite = term_pix[PIX_LIGHTMAGENTA] ; - pix_rimcolor = create_pixel(1,1,1); - - return (true); -} - -void GuicDeinit() -{ - int i; - - for (i = 0; i < MAX_TERM_COL; i++) - XFreeGC(display,term_gc[i]); - - for (i = 0; i < MAX_MAP_COL; i++) - XFreeGC(display,map_gc[i]); - - XCloseDisplay(display); -} - -static int x11_byte_per_pixel_ximage() -{ - int i = 1; - int j = (DefaultDepth(display, screen) - 1) >> 2; - while (j >>= 1) - { - i <<= 1; - } - return i; -} - -unsigned long create_pixel(unsigned int red, unsigned int green, - unsigned int blue) -{ - Colormap cmap = DefaultColormapOfScreen(DefaultScreenOfDisplay(display)); - XColor xcolour; - - xcolour.red = red * 256; - xcolour.green = green * 256; - xcolour.blue = blue * 256; - xcolour.flags = DoRed | DoGreen | DoBlue; - - XAllocColor(display, cmap, &xcolour); - return (xcolour.pixel); -} - -/* - Copied from pngtopnm.c and modified by M.Itakura - (mostly omitted and added a few lines) - only color paletted image is handled -*/ - -/* -** pngtopnm.c - -** read a Portable Network Graphics file and produce a portable anymap -** -** Copyright (C) 1995,1998 by Alexander Lehmann <alex@hal.rhein-main.de> -** and Willem van Schaik <willem@schaik.com> -** -** Permission to use, copy, modify, and distribute this software and its -** documentation for any purpose and without fee is hereby granted, provided -** that the above copyright notice appear in all copies and that both that -** copyright notice and this permission notice appear in supporting -** documentation. This software is provided "as is" without express or -** implied warranty. -** -** modeled after giftopnm by David Koblas and -** with lots of bits pasted from libpng.txt by Guy Eric Schalnat -*/ - -#include "png.h" - -#define pm_message printf -#define pm_error(x) {fprintf(stderr,x);return NULL;} - -# define TRUE 1 -# define FALSE 0 -# define NONE 0 - -#define SIG_CHECK_SIZE 4 - -XImage *read_png (const char *fname) -{ - char sig_buf [SIG_CHECK_SIZE]; - png_struct *png_ptr; - png_info *info_ptr; - png_byte **png_image; - png_byte *png_pixel; - unsigned int x, y; - int linesize; - png_uint_16 c; - unsigned int i; - - //X11 - XImage *res; - unsigned long pix_table[256]; - - FILE *ifp = fopen(fname,"r"); - - if (!ifp) - { - fprintf(stderr, "File not found: %s", fname); - return NULL; - } - - if (fread (sig_buf, 1, SIG_CHECK_SIZE, ifp) != SIG_CHECK_SIZE) - pm_error ("input file empty or too short"); - if (png_sig_cmp ((unsigned char *)sig_buf, (png_size_t) 0, - (png_size_t) SIG_CHECK_SIZE) != 0) - { - pm_error ("input file not a PNG file"); - } - - png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); - if (png_ptr == NULL) - pm_error ("cannot allocate LIBPNG structure"); - - info_ptr = png_create_info_struct (png_ptr); - if (info_ptr == NULL) - { - png_destroy_read_struct (&png_ptr, (png_infopp)NULL, (png_infopp)NULL); - pm_error ("cannot allocate LIBPNG structures"); - } - - if (setjmp (png_ptr->jmpbuf)) - { - png_destroy_read_struct (&png_ptr, (png_infopp)NULL, (png_infopp)NULL); - free (png_ptr); - free (info_ptr); - pm_error ("setjmp returns error condition"); - } - - png_init_io (png_ptr, ifp); - png_set_sig_bytes (png_ptr, SIG_CHECK_SIZE); - png_read_info (png_ptr, info_ptr); - - png_image = (png_byte **)malloc (info_ptr->height * sizeof (png_byte*)); - if (png_image == NULL) - { - free (png_ptr); - free (info_ptr); - pm_error ("couldn't alloc space for image"); - } - - if (info_ptr->bit_depth == 16) - linesize = 2 * info_ptr->width; - else - linesize = info_ptr->width; - - if (info_ptr->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) - linesize *= 2; - else if (info_ptr->color_type == PNG_COLOR_TYPE_RGB) - linesize *= 3; - else if (info_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA) - linesize *= 4; - - for (y = 0 ; y < info_ptr->height ; y++) - { - png_image[y] = (png_byte *)malloc (linesize); - if (png_image[y] == NULL) - { - for (x = 0; x < y; x++) - free (png_image[x]); - - free (png_image); - free (png_ptr); - free (info_ptr); - pm_error ("couldn't alloc space for image"); - } - } - - if (info_ptr->bit_depth < 8) - png_set_packing (png_ptr); - - /* sBIT handling is very tricky. If we are extracting only the image, we - can use the sBIT info for greyscale and color images, if the three - values agree. If we extract the transparency/alpha mask, sBIT is - irrelevant for trans and valid for alpha. If we mix both, the - multiplication may result in values that require the normal bit depth, - so we will use the sBIT info only for transparency, if we know that only - solid and fully transparent is used */ - - if (info_ptr->valid & PNG_INFO_sBIT) - { - if ((info_ptr->color_type == PNG_COLOR_TYPE_PALETTE || - info_ptr->color_type == PNG_COLOR_TYPE_RGB || - info_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA) && - (info_ptr->sig_bit.red != info_ptr->sig_bit.green || - info_ptr->sig_bit.red != info_ptr->sig_bit.blue) ) - { - pm_message ("different bit depths for color channels not " - "supported"); - pm_message ("writing file with %d bit resolution", - info_ptr->bit_depth); - } - else if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE - && info_ptr->sig_bit.red < 255) - { - for (i = 0 ; i < info_ptr->num_palette ; i++) - { - info_ptr->palette[i].red >>= (8 - info_ptr->sig_bit.red); - info_ptr->palette[i].green >>= (8 - info_ptr->sig_bit.green); - info_ptr->palette[i].blue >>= (8 - info_ptr->sig_bit.blue); - } - } - else if ((info_ptr->color_type == PNG_COLOR_TYPE_GRAY - || info_ptr->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) - && info_ptr->sig_bit.gray < info_ptr->bit_depth) - { - png_set_shift (png_ptr, &(info_ptr->sig_bit)); - } - } - - if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) - { - //X11 - for (i = 0 ; i < info_ptr->num_palette ; i++) - pix_table[i] = create_pixel(info_ptr->palette[i].red, - - info_ptr->palette[i].green, info_ptr->palette[i].blue); - } - else if (info_ptr->color_type == PNG_COLOR_TYPE_GRAY) - { - //X11 - for (i = 0 ; i < 256 ; i++) - pix_table[i] = create_pixel(i, i, i); - } - - png_read_image (png_ptr, png_image); - png_read_end (png_ptr, info_ptr); - - res = ImgCreateSimple(info_ptr->width, info_ptr->height); - - for (y = 0; y < info_ptr->height; y++) - { - png_pixel = png_image[y]; - for (x = 0; x < info_ptr->width; x++) - { - c = *png_pixel; - png_pixel++; - XPutPixel(res, x, y, pix_table[c]); - } - } - - for (y = 0 ; y < info_ptr->height ; y++) - free (png_image[y]); - - free (png_image); - free (png_ptr); - free (info_ptr); - - fclose(ifp); - return res; -} diff --git a/crawl-ref/source/guic.cc b/crawl-ref/source/guic.cc deleted file mode 100644 index 3e0aa4e1c3..0000000000 --- a/crawl-ref/source/guic.cc +++ /dev/null @@ -1,773 +0,0 @@ -/* - * File: guic-win.cc - * Summary: 1) Image manipulation routines - * 2) WinClass and RegionClass system independent imprementaions - * see guic-*.cc for system dependent implementations - * Created by: ennewalker on Sat Jan 5 01:33:53 2008 UTC - * - * Modified for Crawl Reference by $Author: j-p-e-g $ on $Date: 2008-03-07 $ - */ - -#include "AppHdr.h" -#include "debug.h" -#include "guic.h" - -#ifdef WIN32TILES -#else -#define dos_char false; -#endif - -int TextRegionClass::print_x; -int TextRegionClass::print_y; -TextRegionClass *TextRegionClass::text_mode = NULL; -int TextRegionClass::text_col = 0; - -TextRegionClass *TextRegionClass::cursor_region= NULL; -int TextRegionClass::cursor_flag = 0; -int TextRegionClass::cursor_x; -int TextRegionClass::cursor_y; - -// more logical color naming -const int map_colors[MAX_MAP_COL][3] = -{ - { 0, 0, 0}, // BLACK - {128, 128, 128}, // DKGREY - {160, 160, 160}, // MDGREY - {192, 192, 192}, // LTGREY - {255, 255, 255}, // WHITE - - { 0, 64, 255}, // BLUE (actually cyan-blue) - {128, 128, 255}, // LTBLUE - { 0, 32, 128}, // DKBLUE (maybe too dark) - - { 0, 255, 0}, // GREEN - {128, 255, 128}, // LTGREEN - { 0, 128, 0}, // DKGREEN - - { 0, 255, 255}, // CYAN - { 64, 255, 255}, // LTCYAN (maybe too pale) - { 0, 128, 128}, // DKCYAN - - {255, 0, 0}, // RED - {255, 128, 128}, // LTRED (actually pink) - {128, 0, 0}, // DKRED - - {192, 0, 255}, // MAGENTA (actually blue-magenta) - {255, 128, 255}, // LTMAGENTA - { 96, 0, 128}, // DKMAGENTA - - {255, 255, 0}, // YELLOW - {255, 255, 64}, // LTYELLOW (maybe too pale) - {128, 128, 0}, // DKYELLOW - - {165, 91, 0}, // BROWN -}; - -const int term_colors[MAX_TERM_COL][3] = -{ - { 0, 0, 0}, // BLACK - { 0, 82, 255}, // BLUE - {100, 185, 70}, // GREEN - { 0, 180, 180}, // CYAN - {255, 48, 0}, // RED - {238, 92, 238}, // MAGENTA - {165, 91, 0}, // BROWN - {162, 162, 162}, // LIGHTGREY - { 82, 82, 82}, // DARKGREY - { 82, 102, 255}, // LIGHTBLUE - { 82, 255, 82}, // LIGHTGREEN - { 82, 255, 255}, // LIGHTCYAN - {255, 82, 82}, // LIGHTRED - {255, 82, 255}, // LIGHTMAGENTA - {255, 255, 82}, // YELLOW - {255, 255, 255} // WHITE -}; - -WinClass::WinClass() -{ - // Minimum; - wx = 10; - wy = 10; - - ox = 0; - oy = 0; - SysInit(); -} - -WinClass::~WinClass() -{ - SysDeinit(); - regions.clear(); - layers.clear(); -} - -void WinClass::placeRegion(RegionClass *r, int layer0, - int x, int y, - int margin_top, int margin_left, - int margin_bottom, int margin_right) -{ - if (r->win == NULL) - { - regions.push_back(r); - layers.push_back(layer0); - } - - r->win = this; - r->layer = layer0; - r->flag = true; - - r->sx = x; - r->sy = y; - - r->ox = r->sx + margin_left; - r->oy = r->sy + margin_top; - r->wx = r->dx * r->mx + margin_left + margin_right; - r->wy = r->dy * r->my + margin_top + margin_bottom; - r->ex = r->sx + r->wx; - r->ey = r->sy + r->wy; - if (r->ex > wx) wx = r->ex; - if (r->ey > wy) wy = r->ey; -} - -void WinClass::placeRegion(RegionClass *r, int layer0, - RegionClass *neighbor, int pflag, - int margin_top, int margin_left, - int margin_bottom, int margin_right) -{ - int sx0 = 0; - int sy0 = 0; - int ex0 = 0; - int ey0 = 0; - - int x = 0; - int y = 0; - - if (neighbor!=NULL) - { - sx0 = neighbor->sx; - sy0 = neighbor->sy; - ex0 = neighbor->ex; - ey0 = neighbor->ey; - } - - if (pflag == PLACE_RIGHT) - { - x = ex0; - y = sy0; - } - else - { - x = sx0; - y = ey0; - } - placeRegion(r, layer0, x, y, margin_top, margin_left, - margin_bottom, margin_right); - -} - -void WinClass::removeRegion(RegionClass *r) -{ - for (unsigned int i = 0; i < regions.size(); i++) - { - if (regions[i] == r) - { - for (unsigned int j = i + 1; j < regions.size(); j++) - { - regions[j-1] = regions[j]; - layers[j-1] = layers[j]; - } - - regions.pop_back(); - layers.pop_back(); - - return; - } - } -} - -void WinClass::redraw(int x1, int y1, int x2, int y2) -{ - std::vector <RegionClass *>::iterator r; - int cx1, cx2, cy1, cy2; - for (r = regions.begin();r != regions.end();r++) - { - if (!(*r)->is_active()) - continue; - - if ( (*r)->convert_redraw_rect(x1, y1, x2, y2, &cx1, &cy1, &cx2, &cy2) ) - (*r)->redraw(cx1, cy1, cx2, cy2); - } -} - -void WinClass::redraw() -{ - redraw(0, 0, wx-1, wy-1); -} - -void WinClass::move(int ox0, int oy0) -{ - ox = ox0; - oy = oy0; - move(); // system dependent -} - -void WinClass::resize(int wx0, int wy0) -{ - if (wx0>0) wx = wx0; - if (wy0>0) wy = wy0; - resize(); // system dependent -} - -RegionClass::RegionClass() -{ - flag = false; - win = NULL; - backbuf = NULL; - SysInit(); - ox = oy = 0; - dx = dy = 1; - font_copied = false; - id = 0; -} - -RegionClass::~RegionClass() -{ - SysDeinit(); - if (backbuf != NULL) - ImgDestroy(backbuf); -} - -void TextRegionClass::resize(int x, int y) -{ - int i; - free(cbuf); - free(abuf); - cbuf = (unsigned char *)malloc(x*y); - abuf = (unsigned char *)malloc(x*y); - for (i = 0; i < x*y; i++) - { - cbuf[i] = ' '; - abuf[i] = 0; - } - mx = x; - my = y; -} - -TextRegionClass::TextRegionClass(int x, int y, int cx, int cy) -{ - cbuf = NULL; - abuf = NULL; - resize(x, y); - - // Cursor Offset - cx_ofs = cx; - cy_ofs = cy; - - SysInit(x, y, cx, cy); -} - -TextRegionClass::~TextRegionClass() -{ - SysDeinit(); - free(cbuf); - free(abuf); -} - -TileRegionClass::TileRegionClass(int mx0, int my0, int dx0, int dy0) -{ - // Unit size - dx = dx0; - dy = dy0; - - mx = mx0; - my = my0; - force_redraw = false; - - SysInit(mx0, my0, dx0, dy0); -} - -TileRegionClass::~TileRegionClass() -{ - SysDeinit(); -} - -void TileRegionClass::resize(int mx0, int my0, int dx0, int dy0) -{ - if (mx0 != 0) mx = mx0; - if (my0 != 0) my = my0; - if (dx0 != 0) dx = dx0; - if (dy0 != 0) dy = dy0; -} - -MapRegionClass::MapRegionClass(int x, int y, int o_x, int o_y, int marker_len) -{ - int i; - - mx2 = x; - my2 = y; - mx = mx2; - my = my2; - - mbuf = (unsigned char *)malloc(mx2*my2); - - for (i = 0; i < mx2*my2; i++) - mbuf[i] = 0; - - x_margin = o_x; - y_margin = o_y; - marker_length = marker_len; - old_mark_x = old_mark_y = 0; - force_redraw = false; - - SysInit(x, y, o_x, o_y); -} - -MapRegionClass::~MapRegionClass() -{ - SysDeinit(); - free(mbuf); -} - -void MapRegionClass::resize(int mx0, int my0, int dx0, int dy0) -{ - if (mx0 != 0) mx2 = mx0; - if (my0 != 0) my2 = my0; - if (dx0 != 0) dx = dx0; - if (dy0 != 0) dy = dy0; - if (mx0 != 0 || my0 != 0) - { - int i; - free(mbuf); - mbuf = (unsigned char *)malloc(mx2*my2); - for (i = 0; i < mx2*my2; i++) - mbuf[i] = 0; - } -} - -/*------------------------------------------*/ - -bool RegionClass::is_active() -{ - if (!flag) - return (false); - - if (win->active_layer == layer) - return (true); - else - return (false); -} - -void RegionClass::make_active() -{ - if (!flag) - return; - - win->active_layer = layer; -} - -void RegionClass::redraw(int x1, int y1, int x2, int y2) -{ -} - -void RegionClass::redraw() -{ - redraw(0, 0, mx-1, my-1); -} - -void MapRegionClass::redraw() -{ - redraw(0, 0, mx-1, my-1); -} - -void TileRegionClass::redraw() -{ - redraw(0, 0, mx*dx-1, my*dy-1); -} - -void MapRegionClass::set_col(int col, int x, int y) -{ - mbuf[x + y * mx2] = col; -} - -int MapRegionClass::get_col(int x, int y) -{ - return mbuf[x + y * mx2]; -} - -/*------------------------------------------*/ -bool RegionClass::convert_redraw_rect(int x1, int y1, int x2, int y2, - int *rx1, int *ry1, int *rx2, int *ry2) -{ - int cx1 = x1-ox; - int cy1 = y1-oy; - int cx2 = x2-ox; - int cy2 = y2-oy; - - if (cx2 < 0 || cy2 < 0 || cx1 >= dx * mx || cy1 >= dy * my) - return (false); - - cx1 /= dx; - cy1 /= dy; - cx2 /= dx; - cy2 /= dy; - - if (cx2 >= mx - 1) - cx2 = mx - 1; - if (cy2 >= my - 1) - cy2 = my - 1; - if (cx1 < 0) - cx1 = 0; - if (cy1 < 0) - cy1 = 0; - - *rx1 = cx1; - *ry1 = cy1; - *rx2 = cx2; - *ry2 = cy2; - - return (true); -} - -bool TileRegionClass::convert_redraw_rect(int x1, int y1, int x2, int y2, - int *rx1, int *ry1, - int *rx2, int *ry2) -{ - int cx1 = x1-ox; - int cy1 = y1-oy; - int cx2 = x2-ox; - int cy2 = y2-oy; - - int wwx = dx*mx; - int wwy = dy*my; - - if (cx2 < 0 || cy2 < 0 || cx1 >= wwx || cy1 >=wwy) - return (false); - - if (cx2 >= wwx - 1) - cx2 = wwx - 1; - if (cy2 >= wwy - 1) - cy2 = wwy - 1; - if (cx1 < 0) - cx1 = 0; - if (cy1 < 0) - cy1 = 0; - - *rx1 = cx1; - *ry1 = cy1; - *rx2 = cx2; - *ry2 = cy2; - - return (true); -} - -bool RegionClass::mouse_pos(int mouse_x, int mouse_y, int *cx, int *cy) -{ - int x = mouse_x - ox; - int y = mouse_y - oy; - - if (!is_active()) - return (false); - if ( x < 0 || y < 0 ) - return (false); - - x /= dx; - y /= dy; - - if (x >= mx || y >= my) - return (false); - - *cx = x; - *cy = y; - - return (true); -} - -bool MapRegionClass::mouse_pos(int mouse_x, int mouse_y, int *cx, int *cy) -{ - int x = mouse_x - ox - x_margin; - int y = mouse_y - oy - y_margin; - - if (x < 0 || y < 0) - return (false); - - x /= dx; - y /= dy; - - if (x >= mx || y >= my) - return (false); - if (!is_active()) - return (false); - - *cx = x; - *cy = y; - - return (true); -} - -bool TileRegionClass::mouse_pos(int mouse_x, int mouse_y, int *cx, int *cy) -{ - int x = mouse_x - ox; - int y = mouse_y - oy; - - if (!is_active()) - return (false); - if (x < 0 || y < 0) - return (false); - if (x >= dx * mx || y >= dy * my) - return (false); - - x /= dx; - y /= dy; - *cx = x; - *cy = y; - - return (true); -} - -// -// Text related -// - -void TextRegionClass::scroll() -{ - int idx; - - if (!flag) - return; - - for (idx = 0; idx < mx*(my-1); idx++) - { - cbuf[idx] = cbuf[idx + mx]; - abuf[idx] = abuf[idx + mx]; - } - - for (idx = mx*(my-1); idx < mx*my; idx++) - { - cbuf[idx] = ' '; - abuf[idx] = 0; - } - redraw(0, 0, mx-1, my-1); - - if (print_y > 0) - print_y -= 1; - if (cursor_y > 0) - cursor_y -= 1; -} - -void TextRegionClass::adjust_region(int *x1, int *x2, int y) -{ - *x2 = *x2 + 1; -} - -void TextRegionClass::addstr(char *buffer) -{ - int i,j; - char buf2[1024]; - int len = strlen(buffer); - - if (!flag) - return; - - j = 0; - - for (i = 0; i < len + 1; i++) - { - char c = buffer[i]; - bool newline = false; - if (c == '\n' || c == '\r') - { - c = 0; - newline = true; - if (buffer[i+1] == '\n' || buffer[i+1] == '\r') - i++; - } - buf2[j] = c; - j++; - - if (c == 0) - { - if (j-1 != 0) - addstr_aux(buf2, j - 1); // draw it - if (newline) - { - print_x = cx_ofs; - print_y++; - j = 0; - - if (print_y - cy_ofs == my) - scroll(); - } - } - } - if (cursor_flag) - cgotoxy(print_x+1, print_y+1); -} - -void TextRegionClass::addstr_aux(char *buffer, int len) -{ - int i; - int x = print_x - cx_ofs; - int y = print_y - cy_ofs; - int adrs = y * mx; - int head = x; - int tail = x + len - 1; - - if (!flag) - return; - - adjust_region(&head, &tail, y); - - for (i = 0; i < len && x + i < mx; i++) - { - cbuf[adrs+x+i] = buffer[i]; - abuf[adrs+x+i] = text_col; - } - draw_string(head, y, &cbuf[adrs+head], tail-head, text_col); - print_x += len; -} - -void TextRegionClass::redraw(int x1, int y1, int x2, int y2) -{ - int x, y; - if (!flag) - return; - - for (y = y1; y <= y2; y++) - { - unsigned char *a = &abuf[y * mx]; - unsigned char *c = &cbuf[y * mx]; - int head = x1; - int tail = x2; - adjust_region(&head, &tail, y); - - x = head; - int col = a[x]; - - while (x <= tail) - { - int oldcol = col; - if (x == tail) - col = -1; - else - col = a[x]; - - if (oldcol != col) - { - draw_string(head, y, &c[head], x-head, oldcol); - head = x; - } - x++; - } - } - - if (cursor_region == this && cursor_flag == 1) - draw_cursor(cursor_x, cursor_y); - - sys_flush(); -} - -void TextRegionClass::clear_to_end_of_line() -{ - int i; - int cx = print_x - cx_ofs; - int cy = print_y - cy_ofs; - int col = text_col; - int adrs = cy * mx; - - if (!flag) - return; - - ASSERT(adrs + mx - 1 < mx * my); - for (i = cx; i < mx; i++) - { - cbuf[adrs+i] = ' '; - abuf[adrs+i] = col; - } - redraw(cx, cy, mx-1, cy); -} - -void TextRegionClass::clear_to_end_of_screen() -{ - int i; - int cy = print_y - cy_ofs; - int col = text_col; - - if (!flag) - return; - - for (i = cy*mx; i < mx*my; i++) - { - cbuf[i] = ' '; - abuf[i] = col; - } - redraw(0, cy, mx-1, my-1); -} - -void TextRegionClass::putch(unsigned char ch) -{ - if (ch == 0) - ch=32; - addstr_aux((char *)&ch, 1); -} - -void TextRegionClass::writeWChar(unsigned char *ch) -{ - addstr_aux((char *)ch, 2); -} - -void TextRegionClass::textcolor(int color) -{ - text_col = color; -} - -void TextRegionClass::textbackground(int col) -{ - textcolor(col*16 + (text_col & 0xf)); -} - -void TextRegionClass::cgotoxy(int x, int y) -{ - ASSERT(x >= 1); - ASSERT(y >= 1); - print_x = x-1; - print_y = y-1; - - if (cursor_region != NULL && cursor_flag) - { - cursor_region ->erase_cursor(); - cursor_region = NULL; - } - - if (cursor_flag) - { - text_mode->draw_cursor(print_x, print_y); - cursor_x = print_x; - cursor_y = print_y; - cursor_region = text_mode; - } -} - -int TextRegionClass::wherex() -{ - return print_x + 1; -} - -int TextRegionClass::wherey() -{ - return print_y + 1; -} - -void TextRegionClass::_setcursortype(int curstype) -{ - cursor_flag = curstype; - if (cursor_region != NULL) - cursor_region->erase_cursor(); - - if (curstype) - { - text_mode->draw_cursor(print_x, print_y); - cursor_x = print_x; - cursor_y = print_y; - cursor_region = text_mode; - } -} diff --git a/crawl-ref/source/guic.h b/crawl-ref/source/guic.h deleted file mode 100644 index 8aff4756ed..0000000000 --- a/crawl-ref/source/guic.h +++ /dev/null @@ -1,451 +0,0 @@ -/* - * File: guic-win.cc - * Created by: ennewalker on Sat Jan 5 01:33:53 2008 UTC - * - * Modified for Crawl Reference by $Author: j-p-e-g $ on $Date: 2008-03-07 $ - */ - -#ifdef USE_X11 -#include <X11/Xlib.h> -#include <X11/X.h> -bool GuicInit(Display **d, int *s); -void GuicDeinit(); - -#elif defined(WIN32TILES) -#include <windows.h> -#include <commdlg.h> -bool GuicInit(HINSTANCE h, int nCmdShow); -void GuicDeinit(); - -#elif defined(SOME_OS) -#include <some-headers.h> -bool GuicInit(some args); -#endif - -#include <vector> - -/* - * Internal Image types - */ - -#ifdef USE_X11 -/*********** X11 ********/ -typedef XImage *img_type; -#define ImgWidth(img) (img->width) -#define ImgHeight(img) (img->height) - -#elif defined(WIN32TILES) -/********** Windows *****/ -// struct for DIB info -typedef struct dib_pack -{ - LPBITMAPINFO pDib ; - HBITMAP hDib ; - HDC hDC ; - LPBYTE pDibBits ; - LPBYTE pDibZero ; - int Width ; - int Height ; -} dib_pack; -typedef dib_pack *img_type; -#define ImgWidth(img) (img->Width) -#define ImgHeight(img) (img->Height) - -#elif defined(SOME_OS) -typedef sometype *img_type; -#define ImgWidth(img) (img->x) -#define ImgHeight(img) (img->y) -#endif - -// Image overlay/copy between internal images, -// implemented in winclass-*.cc -void ImgCopy(img_type src, int sx, int sy, int wx, int wy, - img_type dest, int dx, int dy, int copy); -// hilight rim color #010101 to magenta -void ImgCopyH(img_type src, int sx, int sy, int wx, int wy, - img_type dest, int dx, int dy, int copy); -// maskout by char array mask -void ImgCopyMasked(img_type src, int sx, int sy, int wx, int wy, - img_type dest, int dx, int dy, char *mask); -// maskout+hilight -void ImgCopyMaskedH(img_type src, int sx, int sy, int wx, int wy, - img_type dest, int dx, int dy, char *mask); - -// create internal buffer (not assosiated to any window) -img_type ImgCreateSimple(int wx, int wy); -// create it from file -img_type ImgLoadFile(const char *name); - -// destroy -void ImgDestroy(img_type img); -// clear by transparent color -void ImgClear(img_type img); -// if it is pix_transparent #476c6c -bool ImgIsTransparentAt(img_type img, int x, int y); -void ImgSetTransparentPix(img_type img); - -/* - * Windows and internal regions (text, dungeon, map, etc) - */ - -class WinClass -{ - public: - int ox; //Offset x in dots - int oy; //Offset y in dots - - int wx; //width in dots - int wy; //height in dots - - std::vector<class RegionClass *> regions; - std::vector<int> layers; - - int active_layer; - - // Pointer to the window -#ifdef USE_X11 - Window win; -#elif defined(WIN32TILES) - HWND hWnd; -#elif defined(SOME_OS) - somewindowtype win; -#endif - - WinClass(); - - void SysInit(); - void SysDeinit(); - - ~WinClass(); - - // fillout with black: Sys dep - void clear(); - // create: Sys dep -#ifdef USE_X11 - void create(char *name); -#elif defined(WIN32TILES) - BOOL create(const char *name); -#elif defined(SOME_OS) - void create(some args); -#endif - - void resize(int wx, int wy); - void resize(); - void move(int ox, int oy); - void move(); - - // place Regions inside it - void placeRegion(class RegionClass *r, int layer, - class RegionClass *neighbor, - int pflag, - int margin_top = 0, int margin_left = 0, - int margin_bottom = 0, int margin_right = 0); - - void placeRegion(class RegionClass *r, int layer, - int x, int y, - int margin_top = 0, int margin_left = 0, - int margin_bottom = 0, int margin_right = 0); - - void removeRegion(class RegionClass *r); - - // fillout a rectangle - void fillrect(int left, int right, int top, int bottom, int color); - - // redraw for exposure, etc - void redraw(int x1, int y1, int x2, int y2); - void redraw(); -}; - -class RegionClass -{ - public: - - WinClass *win; - int layer; - - // Geometry - // <-----------------wx-----------------------> - // sx ox ex - // |margin| text/tile area |margin| - - int ox; //Offset x in dots - int oy; //Offset y in dots - - int dx; //unit width - int dy; //unit height - - int mx; //window width in dx - int my; //window height in dy - - int wx; //width in dots = dx*mx + margins - int wy; //height in dots = dy*my + margins - - int sx; //Left edge pos - int sy; //Top edge pos - int ex; //right edge pos - int ey; //bottom edge pos - - bool flag;// use or no - - int id; // for general purpose - - // pointer to internal backup image buffer - // used for redraw and supplessing flicker - img_type backbuf; -#ifdef WIN32TILES - static void set_std_palette(RGBQUAD *pPal); - static RGBQUAD std_palette[256]; - void init_backbuf(RGBQUAD *pPal = NULL, int ncol = 0); - bool dos_char; -#else - void init_backbuf(); -#endif - void resize_backbuf(); - - // font-related - int fx; // font height and width (can differ from dx, dy) - int fy; -#ifdef USE_X11 - int asc; //font ascent - #ifdef JP - XFontSet font; //fontset - #else - XFontStruct *font; - #endif - void init_font(const char *name); -#elif defined(WIN32TILES) - HFONT font; - void init_font(const char *name, int height); - void change_font(const char *name, int height); -#elif defined(SOME_OS) - sometype font; - void init_font(some args); -#endif - - bool font_copied; - - void copy_font(RegionClass *r); - - // init/deinit - RegionClass(); - virtual ~RegionClass(); - - // system-dependent init/deinit - void SysInit(); - void SysDeinit(); - - // Sys indep - bool is_active(); - void make_active(); - - - //Sys indep - // convert mouse point into logical position - virtual bool mouse_pos(int mouse_x, int mouse_y, int *cx, int *cy); - - virtual bool convert_redraw_rect(int x1, int y1, int x2, int y2, - int *rx1, int *ry1, int *rx2, int *ry2); - - virtual void redraw(int x1, int y1, int x2, int y2); - virtual void redraw(); - void sys_flush(); - - virtual void fillrect(int left, int right, int top, int bottom, int color); - virtual void framerect(int left, int right, int top, int bottom, int color); - - virtual void clear(); -}; - - -class TextRegionClass :public RegionClass -{ - public: - // init/deinit - TextRegionClass(int x, int y , int cx, int cy); - ~TextRegionClass(); - - // os dependent init/deinit - void SysInit(int x, int y, int cx, int cy); - void SysDeinit(); - - // where now printing? what color? - static int print_x; - static int print_y; - static int text_col; - // which region now printing? - static class TextRegionClass *text_mode; - // display cursor? where is the cursor now? - static int cursor_flag; - static class TextRegionClass *cursor_region; - static int cursor_x; - static int cursor_y; - - // class methods - static void cgotoxy(int x, int y); - static int wherex(); - static int wherey(); - //static int get_number_of_lines(void); - static void _setcursortype(int curstype); - static void textbackground(int bg); - static void textcolor(int col); - - // Object's method - void clear_to_end_of_line(void); - void clear_to_end_of_screen(void); - void putch(unsigned char chr); - void writeWChar(unsigned char *ch); - - unsigned char *cbuf; //text backup - unsigned char *abuf; //textcolor backup - - int cx_ofs; //cursor x offset - int cy_ofs; //cursor y offset - - void addstr(char *buffer); - void addstr_aux(char *buffer, int len); - void adjust_region(int *x1, int *x2, int y); - void scroll(); - //bool mouse_pos(int mouse_x, int mouse_y, int *cx, int *cy); - - //Sys dep - void draw_string(int x, int y, unsigned char *buf, int len, int col); - void draw_cursor(int x, int y, int width); - void draw_cursor(int x, int y); - void erase_cursor(); - void clear(); - void init_backbuf(); - void redraw(int x1, int y1, int x2, int y2); - void resize(int x, int y); -}; - -class TileRegionClass :public RegionClass -{ - public: - bool force_redraw; - - void DrawPanel(int left, int top, int width, int height); - void fillrect(int left, int right, int top, int bottom, int color); - void framerect(int left, int right, int top, int bottom, int color); - - bool mouse_pos(int mouse_x, int mouse_y, int *cx, int *cy); - virtual bool convert_redraw_rect(int x1, int y1, int x2, int y2, - int *rx1, int *ry1, int *rx2, int *ry2); - void redraw(int x1, int y1, int x2, int y2); - void redraw(); - void clear(); - - //Sys dep - void resize(int x, int y, int dx, int dy); - -#ifdef WIN32TILES - void init_backbuf(RGBQUAD *pPal = NULL); -#else - void init_backbuf(); -#endif - void resize_backbuf(); - - TileRegionClass(int mx0, int my0, int dx0, int dy0); - - void SysInit(int mx0, int my0, int dx0, int dy0); - void SysDeinit(); - - ~TileRegionClass(); -}; - -class MapRegionClass : public RegionClass -{ -public: - int mx2; - int my2; - int x_margin; - int y_margin; - int marker_length; - unsigned char *mbuf; - bool force_redraw; - bool mouse_pos(int mouse_x, int mouse_y, int *cx, int *cy); - void draw_data(unsigned char *buf, bool show_mark, int mark_x, int mark_y); - void redraw(int x1, int y1, int x2, int y2); - void redraw(); - void clear(); - - //Sys dep - void init_backbuf(); - void resize_backbuf(); - void resize(int mx0, int my0, int dx0, int dy0); - - void set_col(int col, int x, int y); - int get_col(int x, int y); - - MapRegionClass(int x, int y, int o_x, int o_y, int marker_length); - ~MapRegionClass(); - - void SysInit(int x, int y, int o_x, int o_y); - void SysDeinit(); - -protected: - int old_mark_x; - int old_mark_y; -}; - -#define PLACE_RIGHT 0 -#define PLACE_BOTTOM 1 -#define PLACE_FORCE 2 - -// Graphics Colors -#define PIX_BLACK 0 -#define PIX_BLUE 1 -#define PIX_GREEN 2 -#define PIX_CYAN 3 -#define PIX_RED 4 -#define PIX_MAGENTA 5 -#define PIX_BROWN 6 -#define PIX_LIGHTGREY 7 -#define PIX_DARKGREY 8 -#define PIX_LIGHTBLUE 9 -#define PIX_LIGHTGREEN 10 -#define PIX_LIGHTCYAN 11 -#define PIX_LIGHTRED 12 -#define PIX_LIGHTMAGENTA 13 -#define PIX_YELLOW 14 -#define PIX_WHITE 15 -#define MAX_TERM_COL 16 - - -#define MAP_BLACK 0 -#define MAP_DKGREY 1 -#define MAP_MDGREY 2 -#define MAP_LTGREY 3 -#define MAP_WHITE 4 - -#define MAP_BLUE 5 -#define MAP_LTBLUE 6 -#define MAP_DKBLUE 7 - -#define MAP_GREEN 8 -#define MAP_LTGREEN 9 -#define MAP_DKGREEN 10 - -#define MAP_CYAN 11 -#define MAP_LTCYAN 12 -#define MAP_DKCYAN 13 - -#define MAP_RED 14 -#define MAP_LTRED 15 -#define MAP_DKRED 16 - -#define MAP_MAGENTA 17 -#define MAP_LTMAGENTA 18 -#define MAP_DKMAGENTA 19 - -#define MAP_YELLOW 20 -#define MAP_LTYELLOW 21 -#define MAP_DKYELLOW 22 - -#define MAP_BROWN 23 - -#define MAX_MAP_COL 24 - - -extern const int term_colors[MAX_TERM_COL][3]; -extern const int map_colors[MAX_MAP_COL][3]; - diff --git a/crawl-ref/source/initfile.cc b/crawl-ref/source/initfile.cc index 08ca799cb2..da0afef3d9 100644 --- a/crawl-ref/source/initfile.cc +++ b/crawl-ref/source/initfile.cc @@ -30,7 +30,7 @@ #include "files.h" #include "defines.h" #ifdef USE_TILE - #include "guic.h" + #include "tilereg.h" #endif #include "invent.h" #include "item_use.h" @@ -841,6 +841,7 @@ void game_options::reset_options() tile_lava_col = MAP_MDGREY; tile_excluded_col = MAP_DKCYAN; tile_excl_centre_col = MAP_DKBLUE; + tile_window_col = MAP_YELLOW; #endif #ifdef WIN32TILES @@ -2867,6 +2868,11 @@ void game_options::read_option_line(const std::string &str, bool runscript) tile_excl_centre_col = _str_to_tile_colour(field); } + else if (key == "tile_window_col") + { + tile_window_col = + _str_to_tile_colour(field); + } #endif #ifdef WIN32TILES diff --git a/crawl-ref/source/invent.cc b/crawl-ref/source/invent.cc index c2e766f470..f4279e30cd 100644 --- a/crawl-ref/source/invent.cc +++ b/crawl-ref/source/invent.cc @@ -384,24 +384,8 @@ void InvMenu::draw_stock_item(int index, const MenuEntry *me) const const InvEntry *ie = dynamic_cast<const InvEntry*>(me); if (ie && me->quantity > 0) { - int draw_quantity = ie->quantity > 1 ? ie->quantity : -1; - bool is_item_on_floor = true; - bool is_item_tried = false; - char c = 0; - int idx = -1; - if (ie->item) - { - is_item_on_floor = ie->item->x != -1; - is_item_tried = item_type_tried(*ie->item); - c = ie->hotkeys.size() > 0 ? ie->hotkeys[0] : 0; - idx = (is_item_on_floor ? ie->item->index() : - letter_to_index(c)); - } - - TileDrawOneItem(REGION_INV2, get_entry_index(ie), c, - idx, tileidx_item(*ie->item), draw_quantity, - is_item_on_floor, ie->selected(), ie->is_item_equipped(), - is_item_tried, ie->is_item_cursed()); + char key = ie->hotkeys.size() > 0 ? ie->hotkeys[0] : 0; + tiles.update_menu_inventory(get_entry_index(ie), *ie->item, ie->selected(), key); } #endif diff --git a/crawl-ref/source/item_use.cc b/crawl-ref/source/item_use.cc index cf2efd52d2..f77688b29e 100644 --- a/crawl-ref/source/item_use.cc +++ b/crawl-ref/source/item_use.cc @@ -1364,11 +1364,6 @@ void fire_target_behaviour::message_ammo_prompt(const std::string* pre_text) colour_length = (selected_from_inventory ? 11 : 3); } -#ifdef USE_TILE - if (selected_from_inventory) - tile_draw_inv(REGION_INV1); -#endif - formatted_message_history(msg.str() .substr(0, crawl_view.msgsz.x + colour_length), MSGCH_PROMPT); @@ -4053,10 +4048,6 @@ bool enchant_armour( int &ac_change, bool quiet, item_def &arm ) if (is_cursed) do_uncurse_item( arm ); -#ifdef USE_TILE - TilePlayerRefresh(); -#endif - // No additional enchantment. return (true); } @@ -4771,77 +4762,75 @@ bool wearing_slot(int inv_slot) #ifdef USE_TILE // Interactive menu for item drop/use. -void tile_use_item(int idx, InvAction act) + +void tile_item_use_floor(int idx) { - if (act == INV_PICKUP) + if (mitm[idx].base_type == OBJ_CORPSES + && mitm[idx].sub_type != CORPSE_SKELETON + && !food_is_rotten(mitm[idx])) { - pickup_single_item(idx, mitm[idx].quantity); - return; + butchery(idx); } - else if (act == INV_DROP) +} + +void tile_item_pickup(int idx) +{ + pickup_single_item(idx, mitm[idx].quantity); +} + +void tile_item_drop(int idx) +{ + drop_item(idx, you.inv[idx].quantity); +} + +void tile_item_eat_floor(int idx) +{ + if (mitm[idx].base_type == OBJ_CORPSES + && you.species == SP_VAMPIRE + || mitm[idx].base_type == OBJ_FOOD + && you.is_undead != US_UNDEAD && you.species != SP_VAMPIRE) { - TileMoveInvCursor(-1); - drop_item(idx, you.inv[idx].quantity); - return; + if (can_ingest(mitm[idx].base_type, mitm[idx].sub_type, false)) + eat_floor_item(idx); } - else if (act == INV_USE_FLOOR) +} + +void tile_item_use_secondary(int idx) +{ + const item_def item = you.inv[idx]; + + if (item.base_type == OBJ_WEAPONS + && is_throwable(item, player_size(PSIZE_BODY))) { - if (mitm[idx].base_type == OBJ_CORPSES - && mitm[idx].sub_type != CORPSE_SKELETON - && !food_is_rotten(mitm[idx])) - { - butchery(idx); - } - return; + if (check_warning_inscriptions(item, OPER_FIRE)) + fire_thing(idx); // fire weapons } - else if (act == INV_EAT_FLOOR) + else if (item.base_type == OBJ_MISCELLANY + || item.base_type == OBJ_STAVES + && item_is_rod(item)) // unwield rods/misc. items { - if (mitm[idx].base_type == OBJ_CORPSES - && you.species == SP_VAMPIRE - || mitm[idx].base_type == OBJ_FOOD - && you.is_undead != US_UNDEAD && you.species != SP_VAMPIRE) + if (you.equip[EQ_WEAPON] == idx + && check_warning_inscriptions(item, OPER_WIELD)) { - if (can_ingest(mitm[idx].base_type, mitm[idx].sub_type, false)) - eat_floor_item(idx); + wield_weapon(true, PROMPT_GOT_SPECIAL); // unwield } - return; } - else if (act == INV_USE2) // secondary item use + else if (you.equip[EQ_WEAPON] == idx + && check_warning_inscriptions(item, OPER_WIELD)) { - const item_def item = you.inv[idx]; - - if (item.base_type == OBJ_WEAPONS - && is_throwable(item, player_size(PSIZE_BODY))) - { - if (check_warning_inscriptions(item, OPER_FIRE)) - fire_thing(idx); // fire weapons - } - else if (item.base_type == OBJ_MISCELLANY - || item.base_type == OBJ_STAVES - && item_is_rod(item)) // unwield rods/misc. items - { - if (you.equip[EQ_WEAPON] == idx - && check_warning_inscriptions(item, OPER_WIELD)) - { - wield_weapon(true, PROMPT_GOT_SPECIAL); // unwield - } - } - else if (you.equip[EQ_WEAPON] == idx - && check_warning_inscriptions(item, OPER_WIELD)) - { - wield_weapon(true, PROMPT_GOT_SPECIAL); // unwield - } - else if (_valid_weapon_swap(item) - && check_warning_inscriptions(item, OPER_WIELD)) - { - // secondary wield for several spells and such - wield_weapon(true, idx); // wield - } - - return; + wield_weapon(true, PROMPT_GOT_SPECIAL); // unwield } - else if (act != INV_USE) - return; + else if (_valid_weapon_swap(item) + && check_warning_inscriptions(item, OPER_WIELD)) + { + // secondary wield for several spells and such + wield_weapon(true, idx); // wield + } +} + +void tile_item_use(int idx) +{ + const item_def item = you.inv[idx]; // Equipped? bool equipped = false; @@ -4857,9 +4846,6 @@ void tile_use_item(int idx, InvAction act) } } - TileMoveInvCursor(-1); - const item_def item = you.inv[idx]; - // Special case for folks who are wielding something // that they shouldn't be wielding. // Note that this is only a problem for equipables diff --git a/crawl-ref/source/item_use.h b/crawl-ref/source/item_use.h index 4477979152..8bc8662938 100644 --- a/crawl-ref/source/item_use.h +++ b/crawl-ref/source/item_use.h @@ -181,10 +181,12 @@ int item_special_wield_effect(const item_def &item); bool wearing_slot(int inv_slot); #ifdef USE_TILE -/* *********************************************************************** - * called from: acr - * *********************************************************************** */ -void tile_use_item(int idx, InvAction act); +void tile_item_use_floor(int idx); +void tile_item_pickup(int idx); +void tile_item_drop(int idx); +void tile_item_eat_floor(int idx); +void tile_item_use(int idx); +void tile_item_use_secondary(int idx); #endif #endif diff --git a/crawl-ref/source/items.cc b/crawl-ref/source/items.cc index ccce30d015..624d9a81fe 100644 --- a/crawl-ref/source/items.cc +++ b/crawl-ref/source/items.cc @@ -1208,15 +1208,12 @@ void pickup() #ifndef USE_TILE keyin = get_ch(); #else + // TODO enne - why? keyin = getch_ck(); #endif } - if (keyin == '*' || keyin == '?' || keyin == ',' || keyin == 'g' -#ifdef USE_TILE - || keyin == CK_MOUSE_B1 -#endif - ) + if (keyin == '*' || keyin == '?' || keyin == ',' || keyin == 'g') { _pickup_menu(o); break; diff --git a/crawl-ref/source/libgui.cc b/crawl-ref/source/libgui.cc index 6fb7c56f7e..5f032523ad 100644 --- a/crawl-ref/source/libgui.cc +++ b/crawl-ref/source/libgui.cc @@ -1,6 +1,6 @@ /* * File: libgui.cc - * Summary: Functions for x11 + * Summary: Functions that any display port needs to implement. * Written by: M.Itakura * * Modified for Crawl Reference by $Author: j-p-e-g $ on $Date: 2008-03-07 $ @@ -27,7 +27,7 @@ #include "items.h" #include "it_use2.h" #include "externs.h" -#include "guic.h" +#include "tilereg.h" #include "initfile.h" #include "message.h" #include "misc.h" @@ -39,288 +39,16 @@ #include "stuff.h" #include "terrain.h" #include "tiles.h" +#include "tilesdl.h" #include "travel.h" #include "version.h" #include "view.h" +#include <SDL.h> +#include "tilesdl.h" + int tile_dngn_x; int tile_dngn_y; -#define DCX (tile_dngn_x/2) -#define DCY (tile_dngn_y/2) - -// libx11.cc or libwt.cc -extern void update_tip_text(const char *tip); -extern void libgui_init_sys(); -extern void libgui_shutdown_sys(); -extern void GetNextEvent(int *etype, - int *key, bool *shift, bool *ctrl, - int *x1, int *y1, int *x2, int *y2); -#ifdef WIN32TILES -// libwt.cc -extern bool windows_change_font(char *font_name, int *font_size, bool dos); -extern void windows_get_winpos(int *x, int *y); -extern void TileInitWin(); -#endif - -// Main window -WinClass *win_main; -// Regions -TextRegionClass *region_crt = NULL; -MapRegionClass *region_map = NULL; -TileRegionClass *region_tile = NULL; -TextRegionClass *region_stat = NULL; -TextRegionClass *region_msg = NULL; -TextRegionClass *region_dngn = NULL; -TextRegionClass *region_xmap = NULL; -TextRegionClass *region_tip = NULL; - -TileRegionClass *region_item = NULL; -TileRegionClass *region_item2 = NULL; - -// Raw tile images -img_type TileImg; -img_type PlayerImg; -img_type WallImg; - -// for item use gui -#define MAX_ITEMLIST 60 -extern int itemlist[MAX_ITEMLIST]; -extern int itemlist_num[MAX_ITEMLIST]; -extern int itemlist_idx[MAX_ITEMLIST]; -extern char itemlist_key[MAX_ITEMLIST]; -extern int itemlist_iflag[MAX_ITEMLIST]; -extern int itemlist_flag; -extern int itemlist_n; - -static bool gui_smart_cursor = false; - -// Window prefs -static int crt_x = 80; -static int crt_y = 30; -static int map_px = 4; -static int msg_x = 77, msg_y = 10; -static int dngn_x = 19, dngn_y = 17; -static int winox = 0, winoy = 0; -#define MAX_PREF_CHAR 256 - -#ifdef USE_X11 -#define UseDosChar false -static char font_name[MAX_PREF_CHAR+1] = "8x13"; -#endif - -#ifdef WIN32TILES -static char font_name[MAX_PREF_CHAR+1] = "courier"; -#define UseDosChar (Options.use_dos_char) -static char dos_font_name[MAX_PREF_CHAR+1] = "Terminal"; -static int dos_font_size = 16; -#endif - -static int font_size = 12; - -#define PREF_MODE_TILE 0 -#define PREF_MODE_NUM 1 -static const char *pref_mode_name[PREF_MODE_NUM] = { "Tile"}; - -typedef struct prefs -{ - const char *name; - const char *tagname; - char type; - void *ptr; - int min, max; - int dummy_idx; -}prefs; - -#ifdef WIN32TILES -#define MAX_PREFS 11 -#else -#define MAX_PREFS 9 -#endif - -#define MAX_EDIT_PREFS 5 -static int dummy_int[PREF_MODE_NUM][8]; -static char dummy_str[PREF_MODE_NUM][2][MAX_PREF_CHAR+1]; -struct prefs pref_data[MAX_PREFS] = -{ - {"DUNGEON X", "DngnX", 'I', &dngn_x, 17, 35, 0}, - {"DUNGEON Y", "DngnY", 'I', &dngn_y, 17, 35, 1}, - {"MAP PX ", "MapPx", 'I', &map_px, 1, 10, 2}, - {"MSG X ", "MsgX", 'I', &msg_x, 40, 80, 3}, - {"MSG Y ", "MsgY", 'I', &msg_y, 8, 20, 4}, - {"WIN TOP ", "WindowTop", 'I', &winox, -100, 2000, 5}, - {"WIN LEFT ", "WindowLeft",'I', &winoy, -100, 2000, 6}, - {"FONT ", "FontName", 'S', font_name, 0, 0, 0}, - {"FONT SIZE", "FontSize", 'I', &font_size, 8, 24, 7} -#ifdef WIN32TILES - ,{"DOS FONT", "DosFontName", 'S', dos_font_name, 0, 0, 1}, - {"DOS FONT SIZE", "DosFontSize", 'I', &dos_font_size, 8, 24, 8} -#endif -}; - -static int pref_mode = 0; -static void _libgui_load_prefs(); -static void _libgui_save_prefs(); - -//Internal variables - -static int mouse_mode = MOUSE_MODE_NORMAL; -// Hack: prevent clrscr for some region. -static bool region_lock[NUM_REGIONS]; -static bool toggle_telescope; - -/***********************************************************/ -//micromap color array -#define MAP_XMAX GXM -#define MAP_YMAX GYM - -static unsigned char gmap_data[GXM][GYM]; -static int gmap_min_x, gmap_max_x; -static int gmap_min_y, gmap_max_y; -static int gmap_ox, gmap_oy; - -// Redefine color constants with shorter names to save space. -#define PX_0 0 -#define PX_F 1 -#define PX_W 2 -#define PX_D 3 -#define PX_WB 4 -#define PX_I 5 -#define PX_M 6 -#define PX_US 7 -#define PX_DS 8 -#define PX_SS 9 -#define PX_WT 10 -#define PX_LV 11 -#define PX_T 12 -#define PX_MS 13 - -static char _gmap_to_colour(char gm) -{ - switch (gm) - { - case PX_0: // unseen - default: - return Options.tile_unseen_col; - case PX_F: // floor - return Options.tile_floor_col; - case PX_W: // walls - return Options.tile_wall_col; - case PX_WB: // walls detected by Magic Mapping - return Options.tile_mapped_wall_col; - case PX_D: // doors - return Options.tile_door_col; - case PX_I: // items - return Options.tile_item_col; - case PX_M: // (hostile) monsters - return Options.tile_monster_col; - case PX_US: // upstairs - return Options.tile_upstairs_col; - case PX_DS: // downstairs - return Options.tile_downstairs_col; - case PX_MS: // misc. features (altars, portals, fountains, ...) - case PX_SS: // special stairs (?) - return Options.tile_feature_col; - case PX_WT: // water - return Options.tile_water_col; - case PX_LV: // lava - return Options.tile_lava_col; - case PX_T: // traps - return Options.tile_trap_col; - } -} - -static const char gmap_col[256] = { - /* 0x00 */ PX_0, PX_0, PX_0, PX_0, PX_0, PX_0, PX_0, PX_0, - /* 0x08 */ PX_0, PX_0, PX_0, PX_0, PX_0, PX_0, PX_0, PX_0, - /* 0x10 */ PX_0, PX_0, PX_0, PX_0, PX_0, PX_0, PX_0, PX_0, - /* 0x18 */ PX_0, PX_0, PX_0, PX_0, PX_0, PX_0, PX_0, PX_0, - - /* ' ' '!' '"' '#' '$' '%' '&' ''' */ - /* 0x20 */ PX_0, PX_I, PX_I, PX_F, PX_I, PX_I, PX_M, PX_D, - /* '(' ')' '*' '+' ',' '-' '.' '/' */ - /* 0x28 */ PX_I, PX_I, PX_WB,PX_I, PX_F, PX_0, PX_F, PX_I, - /* 0 1 2 3 4 5 6 7 */ - /* 0x30 */ PX_0, PX_M, PX_M, PX_M, PX_M, PX_M, PX_0, PX_0, - /* 8 9 : ; < = > ? */ - /* 0x38 */ PX_MS,PX_0, PX_0, PX_M, PX_US,PX_I, PX_DS,PX_I, - /* @ A B C D E F G */ - /* 0x40 */ PX_M, PX_M, PX_M, PX_M, PX_M, PX_M, PX_M, PX_M, - /* H I J K L M N O */ - /* 0x48 */ PX_M, PX_M, PX_M, PX_M, PX_M, PX_M, PX_M, PX_M, - /* P Q R S T U V W */ - /* 0x50 */ PX_M, PX_M, PX_M, PX_M, PX_M, PX_M, PX_M, PX_M, - /* X Y Z [ \ ] ^ _ */ - /* 0x58 */ PX_M, PX_M, PX_M, PX_I, PX_I, PX_I, PX_T, PX_MS, - /* ` a b c d e f g */ - /* 0x60 */ PX_0, PX_M, PX_M, PX_M, PX_M, PX_M, PX_M, PX_M, - /* h i j k l m n o */ - /* 0x68 */ PX_M, PX_M, PX_M, PX_M, PX_M, PX_M, PX_M, PX_M, - /* p q r s t u v w */ - /* 0x70 */ PX_M, PX_M, PX_M, PX_M, PX_M, PX_M, PX_M, PX_M, - /* x y z { | } ~ WALL */ - /* 0x78 */ PX_M, PX_M, PX_M, PX_WT,PX_0, PX_I, PX_I, PX_W, - /* old cralwj symbols */ - /* �� �s �E �� �� �� �� �� */ - /* 0x80 */ PX_D, PX_SS,PX_F, PX_MS,PX_MS,PX_MS,PX_D, PX_WT, - /* �t �� �� �� �� �� �� */ - /* 0x88 */ PX_SS,PX_W, PX_W, PX_W, PX_W, PX_LV, PX_I, PX_0, - /**/ - /* 0x90 144*/ PX_0, PX_0, PX_0, PX_0, PX_0, PX_0, PX_0, PX_0, - /* 0x98 152*/ PX_0, PX_0, PX_0, PX_0, PX_0, PX_0, PX_0, PX_0, - /* 0xa0 160*/ PX_0, PX_0, PX_0, PX_0, PX_0, PX_0, PX_0, PX_0, - /* 0xa8 168*/ PX_0, PX_0, PX_0, PX_0, PX_0, PX_0, PX_0, PX_0, - /* 0xb0 176*/ PX_WB,PX_W, PX_W, PX_0, PX_0, PX_0, PX_0, PX_0, - /* 0xb8 184*/ PX_0, PX_0, PX_0, PX_0, PX_0, PX_0, PX_0, PX_0, - /* 0xc0 192*/ PX_0, PX_0, PX_0, PX_0, PX_0, PX_0, PX_0, PX_0, - /* 0xc8 200*/ PX_0, PX_0, PX_0, PX_0, PX_0, PX_0, PX_0, PX_0, - /* 0xd0 208*/ PX_0, PX_0, PX_0, PX_0, PX_0, PX_0, PX_0, PX_0, - /* 0xd8 216*/ PX_0, PX_0, PX_0, PX_0, PX_MS, PX_0, PX_0, PX_0, - /* 0xe0 224*/ PX_0, PX_0, PX_0, PX_0, PX_0, PX_0, PX_0, PX_0, - /* 0xe8 232*/ PX_0, PX_0, PX_0, PX_0, PX_0, PX_0, PX_0, PX_MS, - /* 0xf0 240*/ PX_0, PX_0, PX_0, PX_0, PX_MS,PX_0, PX_0, PX_WT, - /* 0xf8 248*/ PX_0, PX_F, PX_F, PX_0, PX_0, PX_0, PX_D, PX_0 -}; - -int mouse_grid_x; -int mouse_grid_y; -bool mouse_in_dngn = false; - -static void _gui_set_mouse_view_pos(bool in_dngn, int cx, int cy) -{ - const coord_def& gc = view2grid(coord_def(cx,cy)); - mouse_grid_x = gc.x; - mouse_grid_y = gc.y; - ASSERT(!in_dngn || gc.x >= 0 && gc.y >= 0 && gc.x < GXM && gc.y < GYM); - - mouse_in_dngn = in_dngn; -} - -bool gui_get_mouse_grid_pos(coord_def &gc) -{ - if (mouse_in_dngn) - { - gc.x = mouse_grid_x; - gc.y = mouse_grid_y; - ASSERT(gc.x >= 0 && gc.y >= 0 && gc.x < GXM && gc.y < GYM); - } - - return mouse_in_dngn; -} - -int inv_idx = 0; -InvAction inv_action = INV_NUMACTIONS; - -static void _gui_set_mouse_inv(int idx, InvAction act) -{ - inv_idx = idx; - inv_action = act; -} - -void gui_get_mouse_inv(int &idx, InvAction &act) -{ - idx = inv_idx; - act = inv_action; -} int tile_idx_unseen_terrain(int x, int y, int what) { @@ -340,517 +68,6 @@ int tile_idx_unseen_terrain(int x, int y, int what) return t; } -void GmapUpdate(int x, int y, int what, bool upd_tile) -{ - // If you can't map the area, the minimap won't show. - if (!player_in_mappable_area()) - return; - - int c; - - if (x == you.x_pos && y == you.y_pos) - c = Options.tile_player_col; // Player position always highlighted. - else - { - const coord_def gc(x,y); - unsigned int feature = grd(gc); - - unsigned int grid_symbol; - unsigned short grid_color; - get_item_symbol(feature, &grid_symbol, &grid_color); - - switch (what) - { - // In some cases (like smoke), update the gmap with the ground color - // instead. This keeps it prettier in the case of lava + smoke. - case '#': - c = _gmap_to_colour(gmap_col[grid_symbol & 0xff]); - break; - default: - c = _gmap_to_colour(gmap_col[what & 0xff]); - break; - } - - if (c == Options.tile_monster_col && mgrd[x][y] != NON_MONSTER) - { - const int grid = mgrd[x][y]; - if (mons_friendly(&menv[grid])) - c = Options.tile_friendly_col; // colour friendly monsters - else if (mons_neutral(&menv[grid])) - c = Options.tile_neutral_col; // colour neutral monsters - else if (mons_class_flag(menv[grid].type, M_NO_EXP_GAIN)) - c = Options.tile_plant_col; // colour zero xp monsters - } - - if (c == Options.tile_floor_col || c == Options.tile_item_col) - { - if (is_exclude_root( coord_def(x,y) )) - c = Options.tile_excl_centre_col; - else if (c == Options.tile_floor_col && is_excluded(coord_def(x,y))) - c = Options.tile_excluded_col; - } - } - - int oldc = gmap_data[x][y]; - gmap_data[x][y] = c; - - // NOTE: In the case of a magic mapping, we really want the - // map to update with the correct feature (stone instead of rock wall, - // fountains instead of TILE_ERROR). tileidx_unseen won't give that - // to us. However, we can't give the player all the information, - // since that might be cheating in some cases. This could be rewritten. - int t = tile_idx_unseen_terrain(x, y, what); - - if (c != 0 && c!= oldc && upd_tile) - { - if (c == PX_I || c == PX_M) - { - env.tile_bk_bg[x][y] = t; - if (env.tile_bk_bg[x][y] == 0) - env.tile_bk_bg[x][y] = tileidx_feature(DNGN_UNSEEN, x, y); - } - else - { - env.tile_bk_bg[x][y] = t; - } - } - else if (c == 0) - { - // Forget map. - env.tile_bk_fg[x][y] = 0; - env.tile_bk_bg[x][y] = t; - return; - } - - if (x < gmap_min_x) - gmap_min_x = x; - else if (x > gmap_max_x) - gmap_max_x = x; - - if (y < gmap_min_y) - gmap_min_y = y; - else if (y > gmap_max_y) - gmap_max_y = y; -} - -void GmapInit(bool upd_tile) -{ - // If you can't map the area, the minimap won't show. - if (!player_in_mappable_area()) - return; - - int x, y; - gmap_min_x = gmap_max_x = you.x_pos - 1; - gmap_min_y = gmap_max_y = you.y_pos - 1; - - for (y = 0; y < GYM; y++) - for (x = 0; x < GXM; x++) - GmapUpdate(x, y, env.map[x][y].glyph(), upd_tile); -} - -void GmapDisplay(int linex, int liney) -{ - static unsigned char buf2[GXM*GYM]; - - int ox, oy; - - for (int x = 0; x < GXM*GYM; x++) - buf2[x] = 0; - - if (!player_in_mappable_area()) - { - // Don't bother in the Abyss or Labyrinth. - region_map->flag = true; - region_map->draw_data(buf2, false, 0, 0); - return; - } - - ox = ( gmap_min_x + (GXM - 1 - gmap_max_x) ) / 2; - oy = ( gmap_min_y + (GYM - 1 - gmap_max_y) ) / 2; - int count = ox + oy * GXM; - gmap_ox = ox - gmap_min_x; - gmap_oy = oy - gmap_min_y; - - for (int y = gmap_min_y; y <= gmap_max_y; y++) - { - for (int x = gmap_min_x; x <= gmap_max_x; x++, count++) - if (count >= 0 && count < GXM*GYM) - buf2[count] = gmap_data[x][y]; - - count += GXM - (gmap_max_x - gmap_min_x + 1); - } - - // Highlight centre of the map (ox, oy). - ox += linex - gmap_min_x; - oy += liney - gmap_min_y; - - // [enne] Maybe we need another colour for the highlight? - // [jpeg] I think reusing the player colour is okay, because that's - // usually where the centre will be. - buf2[ox + oy * GXM] = Options.tile_player_col; - - region_map->flag = true; - region_map->draw_data(buf2, true, ox, oy); -} - -// Initialize routines. -static void _do_layout() -{ - // buffer between map region and stat region - const int map_stat_buffer = 5; - -#define LAYER_NML 0 -#define LAYER_CRT 1 -#define LAYER_XMAP 2 - win_main->wx = win_main->wy = 10; - - int tm = region_crt->dx; - - if (UseDosChar) - win_main->placeRegion(region_xmap, LAYER_XMAP, 0, 0, tm, tm, tm, tm); - - RegionClass *lowest; - - // tile 2d mode - win_main->placeRegion(region_tile, LAYER_NML, 0, 0); - win_main->placeRegion(region_msg, LAYER_NML, region_tile, PLACE_BOTTOM, - tm, tm, tm, tm); - - int sx = std::max(region_msg->ex + region_msg->dx, region_tile->ex) - + map_stat_buffer; - int sy = 0; - win_main->placeRegion(region_stat, LAYER_NML, sx, sy); - - win_main->placeRegion(region_map, LAYER_NML, region_stat, PLACE_BOTTOM); - - if (region_tip) - { - win_main->placeRegion(region_tip, LAYER_NML, region_map, PLACE_BOTTOM); - lowest = region_tip; - } - else - lowest = region_map; - - int item_x = (win_main->wx-2*tm) / TILE_X; - int item_y = (52 + item_x -1) / item_x; - - region_item2 -> resize(item_x, item_y, TILE_X, TILE_Y); - - // Update crt size appropriately, based on the window size. - int crt_pwx = win_main->wx; - int crt_wx = crt_pwx / region_crt->dx; - int crt_pwy = win_main->wy - 2*tm - item_y * region_item2->dy; - int crt_wy = crt_pwy / region_crt->dy; - region_crt->resize(crt_wx, crt_wy); - - win_main->placeRegion(region_crt, LAYER_CRT, 0, 0, tm, tm, tm, tm); - win_main->placeRegion(region_item2, LAYER_CRT, region_crt, PLACE_BOTTOM, - tm, tm, tm, tm); - - if (Options.tile_show_items[0] != 0) - { - item_x = (win_main->wx - lowest->sx) / TILE_X; - item_y = (win_main->wy - lowest->ey) / TILE_Y; - RegionClass *r0 = lowest; - int place = PLACE_BOTTOM; - - int item_x2 = (win_main->wx - region_msg->ex) / TILE_X; - int item_y2 = (win_main->wy - region_msg->sy) / TILE_Y; - - if (item_x * item_y < item_x2 * item_y2 - && lowest->ey < region_msg->sy) - { - item_x = item_x2; - item_y = item_y2; - r0 = region_msg; - place = PLACE_RIGHT; - } - while (item_x * item_y < 40) - item_y++; - - region_item -> resize(item_x, item_y, TILE_X, TILE_Y); - win_main->placeRegion (region_item, LAYER_NML, r0, place); - } -} - -void libgui_init() -{ - int i; - int map_margin = 2; - - libgui_init_sys(); - - for (i = 0; i < NUM_REGIONS; i++) - region_lock[i] = false; - - pref_mode = PREF_MODE_TILE; - - _libgui_load_prefs(); - - // Adjust sizes. - if (dngn_x & 1 == 0) dngn_x++; - if (dngn_y & 1 == 0) dngn_y++; - if (font_size & 1 == 1) font_size--; - - tile_dngn_x = dngn_x; - tile_dngn_y = dngn_y; - - /****************************************************/ - - win_main = new WinClass(); - win_main->ox = winox; - win_main->oy = winoy; - - - region_crt = new TextRegionClass(crt_x, crt_y, 0, 0); - region_crt->id = REGION_CRT; - TextRegionClass::text_mode = region_crt; - - region_map = - new MapRegionClass(MAP_XMAX+map_margin, - MAP_YMAX+map_margin, - map_margin, map_margin, - 2); - region_map->id = REGION_MAP; - region_map->dx = map_px; - region_map->dy = map_px; - - TileInit(); - -#ifdef WIN32TILES - TileInitWin(); -#endif - - if (Options.tile_show_items[0] != 0) - { - // temporal size - region_item = new TileRegionClass(1, 1, TILE_X, TILE_Y); - region_item->id = REGION_INV1; - } - // temporal size - region_item2 = new TileRegionClass(1, 1, TILE_X, TILE_Y); - region_item2->id = REGION_INV2; - - region_tile = - new TileRegionClass(tile_dngn_x, tile_dngn_y, - TILE_UX_NORMAL, TILE_UY_NORMAL); - region_tile->id = REGION_DNGN; - -#if DEBUG_DIAGNOSTICS - // One more line for debug GPS. - region_stat = new TextRegionClass(crawl_view.hudsz.x, - crawl_view.hudsz.y + 1, 0, 0); -#else - region_stat = new TextRegionClass(crawl_view.hudsz.x, - crawl_view.hudsz.y, 0, 0); -#endif - region_stat->id = REGION_STAT; - region_msg = new TextRegionClass(msg_x, msg_y, 0, 0); - region_msg->id = REGION_MSG; - - if (UseDosChar) - { - region_xmap = new TextRegionClass(crt_x, crt_y, 0, 0); - region_xmap->id = REGION_XMAP; - } - -#ifdef WIN32TILES - region_crt->init_font(font_name, font_size); - region_stat->copy_font(region_crt); - region_msg->copy_font(region_crt); - - if (UseDosChar) - { - region_xmap->dos_char = true; - region_xmap->init_font(dos_font_name, dos_font_size); - } - -#elif defined(USE_X11) - const unsigned int region_tip_height = 3; - region_tip = new TextRegionClass(region_stat->mx, region_tip_height, 0, 0); - region_tip->id = REGION_TIP; - - region_crt->init_font(font_name); - region_stat->init_font(font_name); - region_msg->init_font(font_name); - region_tip->init_font(font_name); - - if (region_dngn) - region_dngn->init_font(font_name); -#endif -} - -void libgui_shutdown() -{ - - if (TileImg) - ImgDestroy(TileImg); - if (PlayerImg) - ImgDestroy(PlayerImg); - if (WallImg) - ImgDestroy(WallImg); - - // Do this before delete win_main. - _libgui_save_prefs(); - - std::vector<RegionClass *>::iterator r; - for (r = win_main->regions.begin();r != win_main->regions.end();r++) - { - RegionClass* pRegion = *r; - delete (pRegion); - } - - delete win_main; - - libgui_shutdown_sys(); -} - -// Save, Load, and Edit window prefs. -static void _libgui_load_prefs() -{ - int i, mode; - FILE *fp; - char buf[256]; - char tagbuf[256]; - - // set default - for (mode = 0; mode < PREF_MODE_NUM; mode++) - { - for (i = 0; i < MAX_PREFS; i++) - { - struct prefs *p = &pref_data[i]; - int idx = p->dummy_idx; - if (p->type == 'I') - dummy_int[mode][idx] = *(int *)p->ptr; - else if (p->type == 'S') - strncpy(dummy_str[mode][idx], (char *)p->ptr, MAX_PREF_CHAR); - } - } - - const char *baseTxt = "wininit.txt"; - std::string winTxtString = datafile_path(baseTxt, false, true); - const char *winTxt = (winTxtString.c_str()[0] == 0 ? baseTxt - : winTxtString.c_str()); - - if ( (fp = fopen(winTxt, "r")) != NULL ) - { - while (!feof(fp)) - { - fgets(buf, 250, fp); - i = 0; - while (buf[i] >= 32 && i < 120) - { - i++; - } - buf[i] = 0; - - for (i = 0; i < MAX_PREFS; i++) - { - struct prefs *p = &pref_data[i]; - for (mode = 0; mode < PREF_MODE_NUM; mode++) - { - sprintf(tagbuf, "%s:%s", pref_mode_name[mode], p->tagname); - if (strncmp(buf, tagbuf, strlen(tagbuf)) == 0) - { - char *dat = &buf[strlen(tagbuf)+1]; - if (p->type == 'I') - { - int val = atoi(dat); - if (val > p->max) - val = p->max; - if (val < p->min) - val = p->min; - - dummy_int[mode][p->dummy_idx] = val; - if (mode == pref_mode) - *(int *)p->ptr = val; - } - else if (p->type == 'S') - { - strncpy(dummy_str[mode][p->dummy_idx], dat, - MAX_PREF_CHAR); - - if (mode == pref_mode) - strncpy((char *)p->ptr, dat, MAX_PREF_CHAR); - } - break; - } - } - } - } // while (!end of file) - } -} - -static void _libgui_save_prefs() -{ - int i, mode; - FILE *fp; - - if (!win_main) - return; - - winox = win_main->ox; - winoy = win_main->oy; -#ifdef WIN32TILES - windows_get_winpos(&winox, &winoy); -#endif - - for (i = 0; i < MAX_PREFS; i++) - { - struct prefs *p = &pref_data[i]; - int idx = p->dummy_idx; - if (p->type == 'I') - dummy_int[pref_mode][idx] = *(int *)p->ptr; - else if (p->type == 'S') - strncpy(dummy_str[pref_mode][idx], (char *)p->ptr, MAX_PREF_CHAR); - } - - // Use the same directory as for macros. - // (Yes, this is an arbitrary decision.) - std::string dir = !Options.macro_dir.empty() ? Options.macro_dir : - !SysEnv.crawl_dir.empty() ? SysEnv.crawl_dir : ""; - - if (!dir.empty()) - { -#ifndef DGL_MACRO_ABSOLUTE_PATH - if (dir[dir.length() - 1] != FILE_SEPARATOR) - dir += FILE_SEPARATOR; -#endif - } - - const char *baseTxt = "wininit.txt"; - std::string winTxtString = dir + baseTxt; - if ( (fp = fopen(winTxtString.c_str(), "w")) == NULL ) - winTxtString = datafile_path(baseTxt, false, true); - const char *winTxt = winTxtString.c_str()[0] == 0 ? baseTxt - : winTxtString.c_str(); - - if ( (fp = fopen(winTxt, "w")) != NULL ) - { - for (mode = 0; mode < PREF_MODE_NUM; mode++) - { - for (i = 0; i < MAX_PREFS; i++) - { - struct prefs *p = &pref_data[i]; - int idx = p->dummy_idx; - - if (p->type == 'I') - { - fprintf(fp, "%s:%s=%d\n", pref_mode_name[mode], - p->tagname, dummy_int[mode][idx]); - } - else if (p->type == 'S') - { - fprintf(fp, "%s:%s=%s\n", pref_mode_name[mode], - p->tagname, dummy_str[mode][idx]); - } - } - fprintf(fp, "\n"); - } - fclose(fp); - } -} - static void _draw_hgauge(int x, int y, int ofs, int region, int len, int col) { int i; @@ -879,1154 +96,6 @@ static void _draw_vgauge(int x, int y, int ofs, int region, int len, int col) } } -void edit_prefs() -{ - int i; - int cur_pos = 0; - cursor_control cs(false); - bool need_draw_stat = true; - bool need_draw_msg = true; - - if (region_tip) - region_tip->clear(); - region_stat->clear(); - region_msg->clear(); - viewwindow(true, false); - - while (true) - { - bool upd_msg = false; - bool upd_dngn = false; - bool upd_crt = false; - bool upd_map = false; - bool need_resize = false; - int inc = 0; - - if (need_draw_msg) - { - textcolor(LIGHTGREY); - region_msg->clear(); - - textcolor(WHITE); - cgotoxy (4, 4, GOTO_MSG); - cprintf("j, k, up, down : Select pref"); - cgotoxy (4, 5, GOTO_MSG); - cprintf("h, l, left, right : Decrease/Increase"); - cgotoxy (4, 6, GOTO_MSG); - cprintf("H, L : Dec/Inc by 10"); - need_draw_msg = false; - } - - if (need_draw_stat) - { - region_stat->clear(); - for (i = 0; i < MAX_EDIT_PREFS; i++) - { - struct prefs *p = &pref_data[i]; - cgotoxy(2, i+2, GOTO_STAT); - if (i == cur_pos) - { - textcolor(0xf0); - cprintf(">"); - } - else - { - textcolor(LIGHTGREY); - cprintf(" "); - } - - if (pref_data[i].type == 'I') - cprintf(" %s: %3d ", p->name, *(int *)p->ptr); - else - cprintf(" %s: %s", p->name, (char *)p->ptr); - } - textcolor(LIGHTGREY); - -#ifdef WIN32TILES - cgotoxy(4, MAX_EDIT_PREFS+3, GOTO_STAT); - cprintf("FONT: %s %d",font_name, font_size); - if (UseDosChar) - { - cgotoxy(4, MAX_EDIT_PREFS+4, GOTO_STAT); - cprintf("DOSFONT: %s %d", dos_font_name, dos_font_size); - } -#else - cgotoxy(4, MAX_EDIT_PREFS+3, GOTO_STAT); - cprintf("FONT: %s",font_name); -#endif - - int *dat = (int *)pref_data[cur_pos].ptr; -#define WHITEIF(x) (dat == &x)?0xf0:LIGHTGREY - - _draw_hgauge(3, 1, 3, GOTO_MSG, msg_x-2, WHITEIF(msg_x)); - clear_to_end_of_line(); - _draw_vgauge(1, 1, 1, GOTO_MSG, msg_y, WHITEIF(msg_y)); - need_draw_stat = false; - } - - int key = getch(); - - struct prefs *p = &pref_data[cur_pos]; - int *dat = (int *)p->ptr; - - if (key == 0x1b || key == '\r') - break; - - if (key == 'j' || key == CK_DOWN) - { - cur_pos++; - need_draw_stat = true; - } - if (key == 'k' || key == CK_UP) - { - cur_pos--; - need_draw_stat = true; - } - if (key == CK_LEFT) - key = 'h'; - if (key == CK_RIGHT) - key = 'l'; - - cur_pos = (cur_pos + MAX_EDIT_PREFS) % MAX_EDIT_PREFS; - - switch(key) - { - case 'l': inc = 1; break; - case 'L': inc = 10; break; - case 'h': inc = -1; break; - case 'H': inc = -10; break; - } - - int crt_x_old = crt_x; - int crt_y_old = crt_y; - int map_px_old = map_px; - int msg_x_old = msg_x; - int msg_y_old = msg_y; - int dngn_x_old = dngn_x; - int dngn_y_old = dngn_y; - - if (p->type == 'I' && inc != 0) - { - if (dat == &dngn_x || dat == &dngn_y) - { - if (inc == 1) - inc++; - else if (inc == -1) - inc--; - } - - int olddat = *dat; - (*dat)+= inc; - - if (*dat > p->max) - *dat = p->max; - if (*dat < p->min) - *dat = p->min; - - if (olddat == *dat) - continue; - need_resize = true; - } - - if (need_resize) - { - need_draw_stat = need_draw_msg = true; - - // crt screen layouts - - // Resize msg? - if (msg_x != msg_x_old || msg_y != msg_y_old) - { - upd_msg = true; - region_msg->resize(msg_x, msg_y); - } - // Resize crt? - if (crt_x != crt_x_old || crt_y != crt_y_old) - { - upd_crt = true; - region_crt->resize(crt_x, crt_y); - } - // Resize map? - if (map_px != map_px_old) - { - upd_map = true; - region_map->resize( 0, 0, map_px, map_px); - } - - // Resize dngn tile screen? - if (dngn_x != dngn_x_old || dngn_y != dngn_y_old) - { - clrscr(); - upd_dngn = true; - tile_dngn_x = dngn_x; - tile_dngn_y = dngn_y; - region_tile->resize(dngn_x, dngn_y, 0, 0); - } - - _do_layout(); - win_main->resize(); - win_main->clear(); - - // Now screens are all black. - - if (upd_map) - region_map->resize_backbuf(); - - if (upd_dngn) - { - region_tile -> resize_backbuf(); - tile_set_force_redraw_tiles(true); - TileResizeScreen(dngn_x, dngn_y); - } - - if (region_item) - region_item->resize_backbuf(); - if (region_item2) - region_item2->resize_backbuf(); - - tile_set_force_redraw_inv(true); - tile_draw_inv(REGION_INV1); - - region_map->force_redraw = true; - viewwindow(true, true); - region_tile->redraw(); - region_item->redraw(); - } // need resize - } // while-loop - - clrscr(); - redraw_screen(); - mpr("Done."); -} - -// Tiptext help info -typedef struct tip_info -{ - int sx; - int ex; - int sy; - int ey; - const char *tiptext; - const char *tipfilename; -} tip_info; - -static int old_tip_idx = -1; - -static void _tip_grid(int gx, int gy, bool do_null = true, int minimap = 0) -{ - mesclr(); - const coord_def gc(gx,gy); - terse_describe_square(gc); -} - -int tile_cursor_x = -1; -int tile_cursor_y = -1; -int tile_cursor_flag = 0; - -void tile_place_cursor(int x, int y, bool display) -{ - if (tile_cursor_x != -1) - { - // erase old cursor - TileDrawCursor(tile_cursor_x, tile_cursor_y, tile_cursor_flag); - } - if (!display) - { - tile_cursor_x = -1; - return; - } - - int new_flag = TILE_FLAG_CURSOR1; - const coord_def vp(x+1, y+1); - const coord_def gc = view2grid(vp); - const coord_def ep = grid2show(gc); - if (gc.x < 0 || gc.y < 0 || gc.x >= GXM || gc.y >= GYM) - { - // off the dungeon... - tile_cursor_x = -1; - return; - } - else if (!crawl_view.in_grid_los(gc) || !env.show(ep)) - { - new_flag = TILE_FLAG_CURSOR2; - } - - tile_cursor_x = x; - tile_cursor_y = y; - tile_cursor_flag = TileDrawCursor(x, y, new_flag); -} - -int convert_cursor_pos(int mx, int my, int *cx, int *cy) -{ - std::vector <RegionClass *>::iterator r; - WinClass *w = win_main; - int id = REGION_NONE; - int x, y; - int mx0 = 0; - - for (r = w->regions.begin();r != w->regions.end();r++) - { - if (! (*r)->is_active()) - continue; - - if ( (*r)->mouse_pos(mx, my, cx, cy) ) - { - id = (*r)->id; - mx0 = (*r)->mx; - break; - } - } - - x = *cx; - y = *cy; - -/********************************************/ - if (id == REGION_TDNGN) - { - x--; - if (!in_viewport_bounds(x+1,y+1)) - return REGION_NONE; - } - - if (id == REGION_MAP) - { - x -= gmap_ox - region_map->marker_length + 1; - y -= gmap_oy - region_map->marker_length + 1; - } - - if (id == REGION_INV1 || id == REGION_INV2) - { - x = x + y * mx0; - y = 0; - } - - if (id == REGION_DNGN) - { - // Out of LOS range - if (!in_viewport_bounds(x+1,y+1)) - return REGION_NONE; - } - - *cx = x; - *cy = y; - - return id; -} - -// NOTE: Assumes the item is equipped in the first place! -static bool _is_true_equipped_item(item_def item) -{ - // Weapons and staves are only truly equipped if wielded. - if (item.link == you.equip[EQ_WEAPON]) - return (item.base_type == OBJ_WEAPONS || item.base_type == OBJ_STAVES); - - // Cursed armour and rings are only truly equipped if *not* wielded. - return (item.link != you.equip[EQ_WEAPON]); -} - -// Returns whether there's any action you can take with an item in inventory -// apart from dropping it. -static bool _can_use_item(item_def item, bool equipped) -{ - // Vampires can drain corpses. - if (item.base_type == OBJ_CORPSES) - { - return (you.species == SP_VAMPIRE - && item.sub_type != CORPSE_SKELETON - && !food_is_rotten(item) - && mons_has_blood(item.plus)); - } - - if (equipped && item_cursed(item)) - { - // Misc. items/rods can always be evoked, cursed or not. - if (item.base_type == OBJ_MISCELLANY || item_is_rod(item)) - return (true); - - // You can't unwield/fire a wielded cursed weapon/staff - // but cursed armour and rings can be unwielded without problems. - return (!_is_true_equipped_item(item)); - } - - // Mummies can't do anything with food or potions. - if (you.species == SP_MUMMY) - return (item.base_type != OBJ_POTIONS && item.base_type != OBJ_FOOD); - - // In all other cases you can use the item in some way. - return (true); -} - -static int _handle_mouse_motion(int mouse_x, int mouse_y, bool init) -{ - int cx = -1; - int cy = -1; - int mode = 0; - - static int oldcx = -1; - static int oldcy = -1; - static int oldmode = -1; - static int olditem = -1; - - if (init) - { - oldcx = -1; - oldcy = -1; - oldmode = -1; - old_tip_idx = -1; - olditem = -1; - return 0; - } - - switch(mouse_mode) - { - case MOUSE_MODE_NORMAL: - case MOUSE_MODE_MORE: - case MOUSE_MODE_MACRO: - return 0; - break; - } - - if (mouse_x < 0) - { - mode = 0; - oldcx = oldcy = -10; - } - else - mode = convert_cursor_pos(mouse_x, mouse_y, &cx, &cy); - - if (oldcx == cx && oldcy == cy && oldmode == mode) - return 0; - - // erase old cursor - if (oldmode == REGION_DNGN && mode != oldmode) - { - oldcx = -10; - //_setcursortype(0); - } - - if (olditem != -1) - { - oldcx = -10; - TileMoveInvCursor(-1); - olditem = -1; - } - - if ( oldmode == REGION_DNGN && mode != oldmode) - { - oldcx = -10; - tile_place_cursor(0, 0, false); - } - - if (toggle_telescope && mode != REGION_MAP) - { - TileDrawDungeon(NULL); - toggle_telescope = false; - } - - bool valid_tip_region = (mode == REGION_MAP || mode == REGION_DNGN - || mode == REGION_INV1 || mode == REGION_INV2 - || mode == REGION_MSG || mode == REGION_STAT); - - if (valid_tip_region && mode != oldmode) - update_tip_text(""); - - if (toggle_telescope && mode == REGION_MAP) - { - oldmode = mode; - oldcx = cx; - oldcy = cy; - _tip_grid(cx-1, cy-1, 1); - TileDrawFarDungeon(cx-1, cy-1); - return 0; - } - - if (mode == REGION_INV1 || mode == REGION_INV2) - { - oldcx = cx; - oldcy = cy; - oldmode = mode; - int ix = TileInvIdx(cx); - std::string desc; - if (ix != -1) - { - bool display_actions = (mode == REGION_INV1); - - if (itemlist_iflag[cx] & TILEI_FLAG_FLOOR) - { - const item_def item = mitm[ix]; - - if (itemlist_key[cx]) - { - desc = itemlist_key[cx]; - desc += " - "; - } - desc += item.name(DESC_NOCAP_A); - if (display_actions) - desc += EOL "[L-Click] Pick up (g)"; - - if (item.base_type == OBJ_CORPSES - && item.sub_type != CORPSE_SKELETON - && !food_is_rotten(item)) - { - desc += EOL "[Shift-L-Click] "; - if (can_bottle_blood_from_corpse( item.plus)) - desc += "Bottle blood"; - else - desc += "Chop up"; - desc += " (c)"; - - if (you.species == SP_VAMPIRE) - desc += EOL "[Shift-R-Click] Drink blood (e)"; - } - else if (item.base_type == OBJ_FOOD - && you.is_undead != US_UNDEAD - && you.species != SP_VAMPIRE) - { - desc += EOL "[Shift-R-Click] Eat (e)"; - } - } - else // in inventory - { - const item_def item = you.inv[ix]; - - desc = item.name(DESC_INVENTORY_EQUIP); - - if (display_actions) - { - int type = item.base_type; - const bool equipped = itemlist_iflag[cx] & TILEI_FLAG_EQUIP; - bool wielded = (you.equip[EQ_WEAPON] == ix); - desc += EOL; - - if (_can_use_item(you.inv[ix], equipped)) - { - desc += "[L-Click] "; - - if (equipped) - { - if (wielded - && type != OBJ_MISCELLANY - && !item_is_rod(item)) - { - if (type == OBJ_JEWELLERY || type == OBJ_ARMOUR - || type == OBJ_WEAPONS || type == OBJ_STAVES) - { - type = OBJ_WEAPONS + 18; - } - } - else - type += 18; - } - - switch (type) - { - // first equipable categories - case OBJ_WEAPONS: - case OBJ_STAVES: - case OBJ_MISCELLANY: - desc += "Wield (w)"; - if (is_throwable(item, player_size(PSIZE_BODY))) - desc += EOL "[Ctrl-L-Click] Fire (f)"; - break; - case OBJ_WEAPONS + 18: - desc += "Unwield"; - if (is_throwable(item, player_size(PSIZE_BODY))) - desc += EOL "[Ctrl-L-Click] Fire (f)"; - break; - case OBJ_MISCELLANY + 18: - if (item.sub_type >= MISC_DECK_OF_ESCAPE - && item.sub_type <= MISC_DECK_OF_DEFENCE) - { - desc += "Draw a card (v)"; - desc += EOL "[Ctrl-L-Click] Unwield"; - break; - } - // else fall-through - case OBJ_STAVES + 18: // rods - other staves handled above - desc += "Evoke (v)"; - desc += EOL "[Ctrl-L-Click] Unwield"; - break; - case OBJ_ARMOUR: - desc += "Wear (W)"; - break; - case OBJ_ARMOUR + 18: - desc += "Take off (T)"; - break; - case OBJ_JEWELLERY: - desc += "Put on (P)"; - break; - case OBJ_JEWELLERY + 18: - desc += "Remove (R)"; - break; - case OBJ_MISSILES: - desc += "Fire (f)"; - - if (wielded) - desc += EOL "[Ctrl-L-Click] Unwield"; - else if ( item.sub_type == MI_STONE - && player_knows_spell(SPELL_SANDBLAST) - || item.sub_type == MI_ARROW - && player_knows_spell( - SPELL_STICKS_TO_SNAKES) ) - { - // For Sandblast and Sticks to Snakes, - // respectively. - desc += EOL "[Ctrl-L-Click] Wield (w)"; - } - break; - case OBJ_WANDS: - desc += "Zap (Z)"; - if (wielded) - desc += EOL "[Ctrl-L-Click] Unwield"; - break; - case OBJ_BOOKS: - if (item_type_known(item) - && item.sub_type != BOOK_MANUAL - && item.sub_type != BOOK_DESTRUCTION) - { - desc += "Memorise (M)"; - if (wielded) - desc += EOL "[Ctrl-L-Click] Unwield"; - break; - } - // else fall-through - case OBJ_SCROLLS: - desc += "Read (r)"; - if (wielded) - desc += EOL "[Ctrl-L-Click] Unwield"; - break; - case OBJ_POTIONS: - desc += "Quaff (q)"; - // For Sublimation of Blood. - if (wielded) - desc += EOL "[Ctrl-L-Click] Unwield"; - else if ( item_type_known(item) - && is_blood_potion(item) - && player_knows_spell( - SPELL_SUBLIMATION_OF_BLOOD) ) - { - desc += EOL "[Ctrl-L-Click] Wield (w)"; - } - break; - case OBJ_FOOD: - desc += "Eat (e)"; - // For Sublimation of Blood. - if (wielded) - desc += EOL "[Ctrl-L-Click] Unwield"; - else if (item.sub_type == FOOD_CHUNK - && player_knows_spell( - SPELL_SUBLIMATION_OF_BLOOD)) - { - desc += EOL "[Ctrl-L-Click] Wield (w)"; - } - break; - case OBJ_CORPSES: - if (you.species == SP_VAMPIRE) - desc += "Drink blood (e)"; - - if (wielded) - { - if (you.species == SP_VAMPIRE) - desc += EOL; - desc += "[Ctrl-L-Click] Unwield"; - } - break; - default: - desc += "Use"; - } - } - - // For Boneshards. - // Special handling since skeletons have no primary action. - if (item.base_type == OBJ_CORPSES - && item.sub_type == CORPSE_SKELETON) - { - if (wielded) - desc += EOL "[Ctrl-L-Click] Unwield"; - else if (player_knows_spell(SPELL_BONE_SHARDS)) - desc += EOL "[Ctrl-L-Click] Wield (w)"; - } - - desc += EOL "[R-Click] Info"; - // Has to be non-equipped or non-cursed to drop. - if (!equipped || !_is_true_equipped_item(you.inv[ix]) - || !item_cursed(you.inv[ix])) - { - desc += EOL "[Shift-L-Click] Drop (d)"; - } - } - } - update_tip_text(desc.c_str()); - itemlist_flag = mode; - TileMoveInvCursor(cx); - olditem = cx; - } - else - update_tip_text(""); - - return 0; - } - - if (mouse_mode == MOUSE_MODE_TARGET - || mouse_mode == MOUSE_MODE_TARGET_DIR) - { - if (mode == REGION_DNGN || mode == REGION_TDNGN) - { - oldcx = cx; - oldcy = cy; - oldmode = mode; - - _gui_set_mouse_view_pos(true, cx+1, cy+1); - - return CK_MOUSE_MOVE; - } - } - - _gui_set_mouse_view_pos(false, -1, -1); - - if (mode == REGION_TDNGN || mode == REGION_DNGN) - { - if (mode == oldmode && oldcx == DCX && oldcy == DCY) - update_tip_text(""); - - oldcx = cx; - oldcy = cy; - oldmode = mode; - - if (mode == REGION_DNGN) - tile_place_cursor(cx, cy, true); - else if (mode == REGION_TDNGN) - cgotoxy(cx+2, cy+1, GOTO_DNGN); - - const int gx = view2gridX(cx) + 1; - const int gy = view2gridY(cy) + 1; - - _tip_grid(gx, gy); - - // mouse-over info on player - if (cx == DCX && cy == DCY) - { - std::string desc = you.your_name; - desc += " ("; - desc += get_species_abbrev(you.species); - desc += get_class_abbrev(you.char_class); - desc += ")"; - - if (igrd[you.x_pos][you.y_pos] != NON_ITEM) - desc += EOL "[L-Click] Pick up items (g)"; - - if (grid_stair_direction( grd[gx][gy] ) != CMD_NO_CMD) - desc += EOL "[Shift-L-Click] use stairs (</>)"; - - // Character overview. - desc += EOL "[R-Click] Overview (%)"; - - // Religion. - if (you.religion != GOD_NO_GOD) - desc += EOL "[Shift-R-Click] Religion (^)"; - - update_tip_text(desc.c_str()); - } - - return 0; - } - - if (mode == REGION_MAP && mouse_mode == MOUSE_MODE_COMMAND) - { - if (oldmode != REGION_MAP) - update_tip_text("[L-Click] Travel / [R-Click] View"); - else - _tip_grid(cx - 1, cy - 1, false, 1); - - oldmode = mode; - oldcx = cx; - oldcy = cy; - - return 0; - } - - if (mode == REGION_MSG && mouse_mode == MOUSE_MODE_COMMAND) - { - if (oldmode != REGION_MSG) - update_tip_text("[L-Click] Browse message history"); - - oldmode = mode; - oldcx = cx; - oldcy = cy; - return 0; - } - - if (mode == REGION_STAT && mouse_mode == MOUSE_MODE_COMMAND) - { - if (oldmode != REGION_STAT) - update_tip_text("[L-Click] Rest / Search for a while"); - - oldmode = mode; - oldcx = cx; - oldcy = cy; - return 0; - } - - return 0; -} - -static int _handle_mouse_button(int mx, int my, int button, - bool shift, bool ctrl) -{ - int dir; - const int dx[9] = {-1, 0, 1, - -1, 0, 1, - -1, 0, 1}; - - const int dy[9] = { 1, 1, 1, - 0, 0, 0, - -1,-1,-1}; - - const int cmd_n[9] = {'b', 'j', 'n', 'h', '.', 'l', 'y', 'k', 'u'}; - const int cmd_s[9] = {'B', 'J', 'N', 'H', '5', 'L', 'Y', 'K', 'U'}; - - const int cmd_c[9] = { - CONTROL('B'), CONTROL('J'), CONTROL('N'), CONTROL('H'), - 'X', CONTROL('L'), CONTROL('Y'), CONTROL('K'), CONTROL('U'), - }; - const int cmd_dir[9] = {'1','2','3','4','5','6','7','8','9'}; - - int trig = CK_MOUSE_B1; - switch (button) - { - case 2: trig = CK_MOUSE_B2; break; - case 3: trig = CK_MOUSE_B3; break; - case 4: trig = CK_MOUSE_B4; break; - case 5: trig = CK_MOUSE_B5; break; - default: break; - } - - if (shift) - trig |= 512; - if (ctrl) - trig |= 1024; - - switch (mouse_mode) - { - case MOUSE_MODE_NORMAL: - return trig; - case MOUSE_MODE_MORE: - return '\r'; - } - - int cx,cy; - int mode; - static int oldcx = -1; - static int oldcy = -1; - - static bool enable_wheel = true; - static int old_button = 0; - static int old_hp = 0; - - mode = convert_cursor_pos(mx, my, &cx, &cy); - - // Prevent accidental wheel slip and subsequent char death. - if (mouse_mode == MOUSE_MODE_COMMAND && (button == 4 || button == 5) - && button == old_button && oldcx == cx && oldcy == cy) - { - if (!enable_wheel) - return 0; - if (you.hp < old_hp) - { - mpr("Wheel move aborted (rotate opposite to resume)"); - enable_wheel = false; - return 0; - } - } - old_hp = you.hp; - enable_wheel = true; - old_button = button; - oldcx = cx; - oldcy = cy; - - if (toggle_telescope) - { - // Quit telescope mode. - TileDrawDungeon(NULL); - toggle_telescope = false; - } - - if (mode == REGION_INV2) - { - int ix = TileInvIdx(cx); - int key = itemlist_key[cx]; - if (ix != -1 && key) - return key; - else - return 0; - } - - // Clicked on item. - if (mode == REGION_INV1) - { - int ix = TileInvIdx(cx); - if (ix != -1) - { - if (button == 2) - { - // Describe item. - if (itemlist_iflag[cx] & TILEI_FLAG_FLOOR) - { - if (shift) - { - _gui_set_mouse_inv(ix, INV_EAT_FLOOR); - return CK_MOUSE_B1ITEM; - } - else - _gui_set_mouse_inv(-ix, INV_VIEW); - } - else - _gui_set_mouse_inv(ix, INV_VIEW); - - TileMoveInvCursor(-1); - return CK_MOUSE_B2ITEM; - } - else if (button == 1) - { - // Floor item - if (itemlist_iflag[cx] & TILEI_FLAG_FLOOR) - { - // Try to pick up one item. - if (!shift) - _gui_set_mouse_inv(ix, INV_PICKUP); - else - _gui_set_mouse_inv(ix, INV_USE_FLOOR); - - return CK_MOUSE_B1ITEM; - } - - // Use item. - if (shift) - _gui_set_mouse_inv(ix, INV_DROP); - else if (ctrl) - _gui_set_mouse_inv(ix, INV_USE2); - else - _gui_set_mouse_inv(ix, INV_USE); - - return CK_MOUSE_B1ITEM; - } - } - return trig; - } - - if (mode == REGION_MSG && mouse_mode == MOUSE_MODE_COMMAND) - { - return CONTROL('P'); - } - - if (mode == REGION_STAT && mouse_mode == MOUSE_MODE_COMMAND) - { - return '5'; - } - - if ((mouse_mode == MOUSE_MODE_COMMAND || mouse_mode == MOUSE_MODE_MACRO) - && (mode == REGION_DNGN || mode == REGION_TDNGN)) - { - if (button == 1 && cx == DCX && cy == DCY) - { - // Pick up items. - if (!shift) - return 'g'; - - // Else attempt to use stairs on square. - const int gx = view2gridX(cx) + 1; - const int gy = view2gridY(cy) + 1; - switch (grid_stair_direction( grd[gx][gy] )) - { - case CMD_GO_DOWNSTAIRS: - return ('>'); - case CMD_GO_UPSTAIRS: - return ('<'); - default: - break; - } - } - - if (button == 2) - { - // Describe yourself. - if (cx == DCX && cy == DCY) - { - if (!shift) - return '%'; // Character overview. - - if (you.religion != GOD_NO_GOD) - return '^'; // Religion screen. - } - - // trigger - if (mouse_mode == MOUSE_MODE_MACRO) - return trig; - - // R-Click: try to describe grid; otherwise return trigger key. - if (!in_los_bounds(cx+1,cy+1)) - return CK_MOUSE_B2; - - const int gx = view2gridX(cx) + 1; - const int gy = view2gridY(cy) + 1; - full_describe_square(coord_def(gx,gy)); - return CK_MOUSE_DONE; - } - - // button = 1 or 4, 5 - // First check if 3x3 grid around @ is clicked. - // If so, return equivalent numpad key. - int adir = -1; - for (dir = 0; dir < 9; dir++) - { - if (DCX + dx[dir] == cx && DCY + dy[dir] == cy) - { - adir = dir; - break; - } - } - - if (adir != -1) - { - if (shift) - return cmd_s[adir]; - else if (ctrl) - return cmd_c[adir]; - else - return cmd_n[dir]; - } - if (button != 1) - return trig; - - // Otherwise travel to that grid. - const coord_def gc = view2grid(coord_def(cx+1, cy+1)); - if (!map_bounds(gc)) - return 0; - - // Activate travel. - start_travel(gc.x, gc.y); - return CK_MOUSE_DONE; - } - - if (mouse_mode == MOUSE_MODE_COMMAND && mode == REGION_MAP) - { - // Begin telescope mode. - if (button == 2) - { - toggle_telescope = true; - StoreDungeonView(NULL); - TileDrawFarDungeon(cx-1,cy-1); - return 0; - } - - if (button != 1) - return trig; - - // L-click: try to travel to the grid. - const coord_def gc(cx-1, cy-1); - if (!map_bounds(gc)) - return 0; - - // Activate travel. - start_travel(gc.x, gc.y); - return CK_MOUSE_DONE; - } - - // target selection - if ((mouse_mode == MOUSE_MODE_TARGET || mouse_mode == MOUSE_MODE_TARGET_DIR) - && button == 1 && (mode == REGION_DNGN || mode == REGION_TDNGN)) - { - _gui_set_mouse_view_pos(true, cx+1, cy+1); - return CK_MOUSE_CLICK; - } - - _gui_set_mouse_view_pos(false, 0, 0); - - if (mouse_mode == MOUSE_MODE_TARGET_DIR && button == 1 - && (mode == REGION_DNGN || mode == REGION_TDNGN)) - { - if (cx < DCX-1 || cy < DCY-1 || cx > DCX+1 || cy > DCY+1) - return 0; - - for (dir = 0; dir < 9; dir++) - if (DCX + dx[dir] == cx && DCY + dy[dir] == cy) - return cmd_dir[dir]; - - return 0; - } - - return trig; -} - -static int _handle_mouse_unbutton(int mx, int my, int button) -{ - if (toggle_telescope) - TileDrawDungeon(NULL); - - toggle_telescope = false; - return 0; -} - -int getch_ck() -{ - int etype = 0; - int x1,y1,x2,y2; - int key; - bool sh, ct; - int k; - - while (true) - { - k = 0; - GetNextEvent(&etype, &key, &sh, &ct, &x1, &y1, &x2, &y2); - switch(etype) - { - case EV_BUTTON: - k = _handle_mouse_button(x1, y1, key, sh, ct); - break; - - case EV_MOVE: - k = _handle_mouse_motion(x1, y1, false); - break; - - case EV_UNBUTTON: - k = _handle_mouse_unbutton(x1, y1, key); - break; - - case EV_KEYIN: - k = key; - break; - - default: - break; - } - - if (k != 0) - break; - } - - return k; -} - -int getch() -{ - static int ck_tr[] = - { - 'k', 'j', 'h', 'l', '.', 'y', 'b', '.', 'u', 'n', - 'K', 'J', 'H', 'L', '5', 'Y', 'B', '5', 'U', 'N', - 11, 10, 8, 12, '0', 25, 2, 'C', 21, 14 - }; - - int keyin = getch_ck(); - if (keyin >= CK_UP && keyin <= CK_CTRL_PGDN) - return ck_tr[ keyin - CK_UP ]; - - if (keyin == CK_DELETE) - return '.'; - - return keyin; -} - int m_getch() { return getch(); @@ -2037,28 +106,6 @@ void set_mouse_enabled(bool enabled) crawl_state.mouse_enabled = enabled; } -void mouse_set_mode(int mode) -{ - mouse_mode = mode; - // Init cursor etc. - _handle_mouse_motion(0, 0, true); -} - -int mouse_get_mode() -{ - return mouse_mode; -} - -static void _init_regions() -{ - win_main->create((char*)(CRAWL " " VERSION)); - - region_map->init_backbuf(); - region_tile->init_backbuf(); - region_item2->init_backbuf(); - region_item->init_backbuf(); -} - void gui_init_view_params(crawl_view_geometry &geom) { // The tile version handles its own layout on a pixel-by-pixel basis. @@ -2069,102 +116,26 @@ void gui_init_view_params(crawl_view_geometry &geom) geom.viewp.x = 1; geom.viewp.y = 1; - geom.viewsz.x = tile_dngn_x; - geom.viewsz.y = tile_dngn_y; geom.hudp.x = 1; geom.hudp.y = 1; geom.msgp.x = 1; geom.msgp.y = 1; - geom.msgsz.x = msg_x; - geom.msgsz.y = msg_y; geom.mlistp.x = 1; geom.mlistp.y = 1; geom.mlistsz.x = 0; geom.mlistsz.y = 0; - if (region_tip) - region_tip->resize(geom.hudsz.x, 3); - region_msg->resize(geom.msgsz.x, geom.msgsz.y); - region_stat->resize(geom.hudsz.x, geom.hudsz.y); - - _do_layout(); - _init_regions(); -} - -void lock_region(int r) -{ - if (r >= 0 && r < NUM_REGIONS) - region_lock[r] = true; -} - -void unlock_region(int r) -{ - if (r >= 0 && r < NUM_REGIONS) - region_lock[r] = false; -} - -/* - * Wrapper - */ - -void clrscr() -{ - win_main->clear(); - TextRegionClass::cursor_region = NULL; - - // Clear Text regions. - if (!region_lock[REGION_CRT]) - region_crt->clear(); - - if (region_msg && !region_lock[REGION_MSG]) - region_msg->clear(); - - if (region_stat && !region_lock[REGION_STAT]) - region_stat->clear(); - - if (region_dngn && !region_lock[REGION_TDNGN]) - region_dngn->clear(); - - if (region_tip && !region_lock[REGION_TIP]) - region_tip->clear(); - - // Hack: Do not erase the backbuffer; instead just hide it. - if (region_map) - { - if (region_lock[REGION_MAP]) - region_map->redraw(); - else - region_map->flag = false; - } - if (region_item) - { - if (region_lock[REGION_INV1]) - region_item->redraw(); - else - region_item->flag = false; - } - if (region_item2) - { - - if (region_lock[REGION_INV2]) - region_item2->redraw(); - else - { - TileClearInv(REGION_INV2); - region_item2->flag = false; - } - } - - cgotoxy(1, 1); + geom.viewsz.x = 17; + geom.viewsz.y = 17; } void putch(unsigned char chr) { // object's method - TextRegionClass::text_mode->putch(chr); + TextRegion::text_mode->putch(chr); } void putwch(unsigned chr) @@ -2176,19 +147,13 @@ void putwch(unsigned chr) void writeWChar(unsigned char *ch) { // object's method - TextRegionClass::text_mode->writeWChar(ch); + TextRegion::text_mode->writeWChar(ch); } void clear_to_end_of_line() { // object's method - TextRegionClass::text_mode->clear_to_end_of_line(); -} - -void clear_to_end_of_screen() -{ - // object's method - TextRegionClass::text_mode->clear_to_end_of_screen(); + TextRegion::text_mode->clear_to_end_of_line(); } void get_input_line_gui(char *const buff, int len) @@ -2198,14 +163,11 @@ void get_input_line_gui(char *const buff, int len) int prev = 0; int done = 0; int kin; - TextRegionClass *r = TextRegionClass::text_mode; + TextRegion *r = TextRegion::text_mode; static char last[128]; static int lastk = 0; - if (!r->flag) - return; - // Locate the cursor. x = wherex(); y = wherey(); @@ -2214,7 +176,7 @@ void get_input_line_gui(char *const buff, int len) if (len < 1) len = 1; - // Restrict the length. + /* Restrict the length */ if (x + len > r->mx) len = r->mx - x; if (len > 40) @@ -2317,66 +279,30 @@ void cprintf(const char *format,...) vsprintf(buffer, format, argp); va_end(argp); // object's method - TextRegionClass::text_mode->addstr(buffer); - TextRegionClass::text_mode->make_active(); + TextRegion::text_mode->addstr(buffer); } void textcolor(int color) { - TextRegionClass::textcolor(color); + TextRegion::textcolor(color); } void textbackground(int bg) { - TextRegionClass::textbackground(bg); -} - -void cgotoxy(int x, int y, int region) -{ - if (region == GOTO_LAST) - { - // nothing - } - else if (region == GOTO_CRT) - TextRegionClass::text_mode = region_crt; - else if (region == GOTO_MSG) - TextRegionClass::text_mode = region_msg; - else if (region == GOTO_STAT) - TextRegionClass::text_mode = region_stat; - - TextRegionClass::text_mode->flag = true; - TextRegionClass::cgotoxy(x, y); -} - -void _setcursortype(int curstype) -{ - TextRegionClass::_setcursortype(curstype); -} - -void enable_smart_cursor(bool cursor) -{ - gui_smart_cursor = cursor; -} - -bool is_smart_cursor_enabled() -{ - return (gui_smart_cursor); + TextRegion::textbackground(bg); } void set_cursor_enabled(bool enabled) { - if (gui_smart_cursor) - return; - if (enabled) - TextRegionClass::_setcursortype(1); + TextRegion::_setcursortype(1); else - TextRegionClass::_setcursortype(0); + TextRegion::_setcursortype(0); } bool is_cursor_enabled() { - if (TextRegionClass::cursor_flag) + if (TextRegion::cursor_flag) return (true); return (false); @@ -2384,179 +310,141 @@ bool is_cursor_enabled() int wherex() { - return TextRegionClass::wherex(); + return TextRegion::wherex(); } int wherey() { - return TextRegionClass::wherey(); + return TextRegion::wherey(); } int get_number_of_lines() { -#ifdef USE_X11 - // Lie about the number of lines so that we can reserve the - // bottom one for tooltips... - return region_crt->my - 1; -#else - return region_crt->my; -#endif + return 30; } int get_number_of_cols() { - return std::min(region_crt->mx, region_msg->mx); + return 80; } -void message_out(int which_line, int colour, const char *s, int firstcol, - bool newline) +void put_colour_ch(int colour, unsigned ch) { - if (!firstcol) - firstcol = Options.delay_message_clear ? 2 : 1; - - cgotoxy(firstcol, which_line + 1, GOTO_MSG); textcolor(colour); + putwch(ch); +} - cprintf("%s", s); +void window(int x1, int y1, int x2, int y2) +{ +} - if (newline && which_line == crawl_view.msgsz.y - 1) - region_msg->scroll(); +int getch() +{ + return (tiles.getch()); } -void clear_message_window() +int getch_ck() { - region_msg->clear(); + return (tiles.getch_ck()); } -void put_colour_ch(int colour, unsigned ch) +void clrscr() { - textcolor(colour); - putwch(ch); + return (tiles.clrscr()); } -void puttext(int sx, int sy, int ex, int ey, unsigned char *buf, bool mono, - int where) +void message_out(int which_line, int colour, const char *s, int firstcol, bool newline) { - TextRegionClass *r = (where == 1) ?region_crt:region_dngn; + tiles.message_out(which_line, colour, s, firstcol, newline); +} - if (where == 1 && UseDosChar) - r = region_xmap; +void cgotoxy(int x, int y, int region) +{ + tiles.cgotoxy(x, y, region); +} - int xx, yy; - unsigned char *ptr = buf; - //cgotoxy(1, 1, GOTO_CRT); - for (yy = sy-1; yy <= ey-1; yy++) - { - unsigned char *c = &(r->cbuf[yy*(r->mx)+sx-1]); - unsigned char *a = &(r->abuf[yy*(r->mx)+sx-1]); - for (xx = sx-1; xx <= ex-1; xx++) - { - *c = *ptr; +void clear_message_window() +{ + tiles.clear_message_window(); +} - if (*c == 0) - *c = 32; +void delay(int ms) +{ + tiles.redraw(); + SDL_Delay(ms); +} - ptr++; - if (mono) - *a = WHITE; - else - { - *a = *ptr; - ptr++; - } - c++; - a++; - } - } - r->make_active(); - r->redraw(sx-1, sy-1, ex-1, ey-1); +void update_screen() +{ + tiles.redraw(); } -void ViewTextFile(const char *name) +int kbhit() { - FILE *fp = fopen(name, "r"); - int max = get_number_of_lines(); + // Look for the presence of any keyboard events in the queue. + SDL_Event store; + int count = SDL_PeepEvents(&store, 1, SDL_PEEKEVENT, + SDL_EVENTMASK(SDL_KEYDOWN)); - // Hack -#define MAXTEXTLINES 100 + // SDL Error? + ASSERT(count != -1); -#define DELIMITER_END "-------------------------------------------------------------------------------" -#define DELIMITER_MORE "...(more)... " - unsigned char buf[80*MAXTEXTLINES], buf2[84]; - int nlines = 0; - int cline = 0; - int i; + return (count == 1 ? 1 : 0); +} + +#ifdef UNIX +int itoa(int value, char *strptr, int radix) +{ + unsigned int bitmask = 32768; + int ctr = 0; + int startflag = 0; - if (!fp) + if (radix == 10) { - mpr("Couldn't open file."); - return; + sprintf(strptr, "%i", value); } - - for (i = 0; i < 80*MAXTEXTLINES; i++) - buf[i] = ' '; - - while (nlines < MAXTEXTLINES) + else if (radix == 2) /* int to "binary string" */ { - fgets((char *)buf2, 82, fp); + while (bitmask) + { + if (value & bitmask) + { + startflag = 1; + sprintf(strptr + ctr, "1"); + } + else if (startflag) + { + sprintf(strptr + ctr, "0"); + } - if (feof(fp)) - break; + bitmask = bitmask >> 1; + if (startflag) + ctr++; + } - i = 0; - while (i < 79 && buf2[i] != 13 && buf2[i] != 10) - i++; + if (!startflag) /* Special case if value == 0 */ + sprintf((strptr + ctr++), "0"); - memcpy(&buf[nlines*80], buf2, i); - nlines++; + strptr[ctr] = (char) NULL; } - fclose(fp); - clrscr(); + return (0); /* Me? Fail? Nah. */ +} - while (true) - { - cgotoxy(1, 1); - if (cline == 0) - cprintf(DELIMITER_END); - else - cprintf(DELIMITER_MORE); - - puttext(1, 2, 80, max, &buf[cline*80], true, 1); - - cgotoxy(1, max); - - if (cline + max-2 >= nlines) - cprintf(DELIMITER_END); - else - cprintf(DELIMITER_MORE); - - cgotoxy(14, max); - cprintf("[j/k/+/-/SPACE/b: scroll q/ESC/RETURN: exit]"); - mouse_set_mode(MOUSE_MODE_MORE); - int key = getch(); - mouse_set_mode(MOUSE_MODE_NORMAL); - if (key == 'q' || key == ESCAPE || key =='\r') - break; - else if (key == '-' || key == 'b') - cline -= max-2; - else if (key == 'k') - cline --; - else if (key == '+' || key == ' ') - cline += max-2; - else if (key == 'j') - cline++; - else if (key == CK_MOUSE_B4) - cline--; - else if (key == CK_MOUSE_B5) - cline++; - - if (cline + max-2 > nlines) - cline = nlines-max + 2; - if (cline < 0) - cline = 0; - } + +// Convert string to lowercase. +char *strlwr(char *str) +{ + unsigned int i; + + for (i = 0; i < strlen(str); i++) + str[i] = tolower(str[i]); + + return (str); } -void window(int x1, int y1, int x2, int y2) +int stricmp(const char *str1, const char *str2) { + return (strcmp(str1, str2)); } + +#endif // #ifdef UNIX diff --git a/crawl-ref/source/libgui.h b/crawl-ref/source/libgui.h index 30bbafdf3f..1c2b3f747a 100644 --- a/crawl-ref/source/libgui.h +++ b/crawl-ref/source/libgui.h @@ -6,68 +6,22 @@ * Modified for Crawl Reference by $Author: j-p-e-g $ on $Date: 2008-03-07 $ */ +// TODO enne - slowly morph this into tilesdl.h + #ifndef LIBGUI_H #define LIBGUI_H #ifdef USE_TILE -#ifdef USE_X11 - #include <X11/Xlib.h> - #include <X11/X.h> -#elif defined(WINDOWS) - #include <windows.h> - // windows.h defines 'near' as an empty string for compatibility. - // This breaks the use of that as a variable name. Urgh. - #ifdef near - #undef near - #endif - #include <commdlg.h> -#endif - #include "defines.h" typedef unsigned int screen_buffer_t; -void libgui_init(); -void libgui_shutdown(); - -void edit_prefs(); -/* *********************************************************************** - Minimap related - * called from: misc view spells2 - * *********************************************************************** */ -void GmapInit(bool upd_tile); -void GmapDisplay(int linex, int liney); -void GmapUpdate(int x, int y, int what, bool upd_tile = true); - //dungeon display size extern int tile_dngn_x; extern int tile_dngn_y; void set_mouse_enabled(bool enabled); -// mouse ops -// set mouse op mode -void mouse_set_mode(int mode); -// get mouse mode -int mouse_get_mode(); - -class mouse_control -{ -public: - mouse_control(int mode) - { - oldmode = mouse_get_mode(); - mouse_set_mode(mode); - } - - ~mouse_control() - { - mouse_set_mode(oldmode); - } -private: - int oldmode; -}; - struct coord_def; struct crawl_view_geometry; @@ -77,49 +31,9 @@ void gui_init_view_params(crawl_view_geometry &geom); // Otherwise, it just returns false. bool gui_get_mouse_grid_pos(coord_def &gc); -enum InvAction -{ - INV_DROP, - INV_USE, // primary inventory use - INV_USE2, // secondary inventory use - INV_PICKUP, - INV_VIEW, - INV_USE_FLOOR, - INV_EAT_FLOOR, - INV_SELECT, - INV_NUMACTIONS -}; - -void gui_get_mouse_inv(int &idx, InvAction &act); - -void tile_place_cursor(int x, int y, bool display); - -void lock_region(int r); -void unlock_region(int r); - -enum ScreenRegion -{ - REGION_NONE, - REGION_CRT, - REGION_STAT, // stat area - REGION_MSG, // message area - REGION_MAP, // overview map area - REGION_DNGN, - REGION_TDNGN, - REGION_INV1, // items in inventory - REGION_INV2, // items in inventory? - REGION_XMAP, - REGION_TIP, - NUM_REGIONS -}; - /* text display */ void clrscr(void); void textcolor(int color); -void cgotoxy(int x, int y, int region = GOTO_CRT); -void message_out(int mline, int colour, const char *str, int firstcol = 0, - bool newline = true); -void clear_message_window(); int wherex(); int wherey(); void cprintf(const char *format,...); @@ -136,39 +50,30 @@ void putwch(unsigned chr); void put_colour_ch(int colour, unsigned ch); void writeWChar(unsigned char *ch); -void puttext(int x, int y, int lx, int ly, unsigned char *buf, - bool mono = false, int where = 0); -void ViewTextFile(const char *name); - #define textattr(x) textcolor(x) void set_cursor_enabled(bool enabled); bool is_cursor_enabled(); -void enable_smart_cursor(bool); -bool is_smart_cursor_enabled(); +inline void enable_smart_cursor(bool) { } +inline bool is_smart_cursor_enabled() { return false; } -#ifdef USE_X11 -char *strlwr(char *str); // non-unix -int itoa(int value, char *strptr, int radix); // non-unix -int stricmp(const char *str1, const char *str2); // non-unix -#endif -void delay(unsigned long time); -int kbhit(void); void window(int x1, int y1, int x2, int y2); -void update_screen(void); + int getch(); int getch_ck(); - -// types of events -#define EV_KEYIN 1 -#define EV_MOVE 2 -#define EV_BUTTON 3 -#define EV_UNBUTTON 4 - -#define _NORMALCURSOR 1 -#define _NOCURSOR 0 - -#define textcolor_cake(col) textcolor((col)<<4 | (col)) +void clrscr(); +void message_out(int which_line, int colour, const char *s, int firstcol = 0, bool newline = true); +void cgotoxy(int x, int y, int region = GOTO_CRT); +void clear_message_window(); +void delay(int ms); +void update_screen(); +int kbhit(); + +#ifdef UNIX +char *strlwr(char *str); +int itoa(int value, char *strptr, int radix); +int stricmp(const char *str1, const char *str2); +#endif #endif // USE_TILE #endif // LIBGUI_H diff --git a/crawl-ref/source/libutil.cc b/crawl-ref/source/libutil.cc index 17a87b7780..a2fe007cc1 100644 --- a/crawl-ref/source/libutil.cc +++ b/crawl-ref/source/libutil.cc @@ -812,3 +812,6 @@ bool pattern_match(void *compiled_pattern, const char *text, int length) } #endif + +mouse_mode mouse_control::ms_current_mode = MOUSE_MODE_NORMAL; + diff --git a/crawl-ref/source/libutil.h b/crawl-ref/source/libutil.h index c7bfbeab01..5c874a72f4 100644 --- a/crawl-ref/source/libutil.h +++ b/crawl-ref/source/libutil.h @@ -324,4 +324,26 @@ basic_text_pattern<compile_glob_pattern, free_compiled_glob_pattern, glob_pattern_match> glob_pattern; + +class mouse_control +{ +public: + mouse_control(mouse_mode mode) + { + m_previous_mode = ms_current_mode; + ms_current_mode = mode; + } + + ~mouse_control() + { + ms_current_mode = m_previous_mode; + } + + static mouse_mode current_mode() { return ms_current_mode; } + +private: + mouse_mode m_previous_mode; + static mouse_mode ms_current_mode; +}; + #endif diff --git a/crawl-ref/source/libwt.cc b/crawl-ref/source/libwt.cc deleted file mode 100644 index df86c5fe87..0000000000 --- a/crawl-ref/source/libwt.cc +++ /dev/null @@ -1,562 +0,0 @@ -/* - * File: guic-win.cc - * Created by: ennewalker on Sat Jan 5 01:33:53 2008 UTC - * - * Modified for Crawl Reference by $Author: j-p-e-g $ on $Date: 2008-03-07 $ - */ - -#define _WIN32_WINNT 0x0501 - -#include <windows.h> -#include <windowsx.h> -#include <commdlg.h> -#include <commctrl.h> - -// GDT_NONE in commctrl.h conflicts with enum.h -#ifdef GDT_NONE -#undef GDT_NONE -#endif - -#include <stdio.h> -#include <stdlib.h> -#include <malloc.h> -#include <memory.h> -#include <tchar.h> -#include <fcntl.h> - -#include "AppHdr.h" -#include "cio.h" -#include "debug.h" -#include "externs.h" -#include "files.h" -#include "guic.h" -#include "itemprop.h" -#include "state.h" -#include "tiles.h" - -extern int old_main(int argc, char *argv[]); - -extern WinClass *win_main; -extern TileRegionClass *region_tile; -extern img_type TileImg; -extern BYTE pix_transparent; - -typedef struct ev_data -{ - int type; - int key; - int x1, y1; - bool sh, ct; -}ev_data; - -#define EV_MAX 1024 -struct ev_data ev_cue[EV_MAX]; - -static int ev_head = 0; -static int ev_tail = 0; -void ev_push(struct ev_data *e); -static bool skip_key = false; - -// Tip text -static TOOLINFO tiTip; -static HWND hTool; -static HWND pWin; - -#ifdef USE_TILE -#define PAL_STD 0 //standard palette -#define PAL_BER 1 //berserk palette -#define PAL_SHA 2 //shadow palette -static int palette = PAL_STD; -LPBYTE lpPalettes[3] ; -#endif - -#define DF_TOOLTIP_WIDTH 300 - -ATOM MyRegisterClass( HINSTANCE hInstance ); -BOOL InitInstance( HINSTANCE, int ); -LRESULT CALLBACK WndProc( HWND, UINT, WPARAM, LPARAM ); - -bool libgui_init_sys(); -void libgui_shutdown_sys(); -void update_tip_text(const char *tip); - -void GetNextEvent(int *etype, int *key, bool *shift, bool *ctrl, - int *x1, int *y1, int *x2, int *y2); -void TileInitWin(); -void delay(unsigned long ms); -int kbhit(); - -/***************************/ -void TileInitWin() -{ - int i; - - TileImg->pDib->bmiColors[pix_transparent].rgbRed = 0; - TileImg->pDib->bmiColors[pix_transparent].rgbGreen = 0; - TileImg->pDib->bmiColors[pix_transparent].rgbBlue = 0; - - RegionClass::set_std_palette(&TileImg->pDib->bmiColors[0]); - - WORD chcol; - lpPalettes[0] = (LPBYTE) (&TileImg->pDib->bmiColors[0]); - lpPalettes[1] = (LPBYTE)GlobalAlloc(GPTR, 256 * sizeof(RGBQUAD) ); - lpPalettes[2] = (LPBYTE)GlobalAlloc(GPTR, 256 * sizeof(RGBQUAD) ); - for (i = 0; i < 256; i++) - { - chcol = (TileImg->pDib->bmiColors[i].rgbRed * 30 - + TileImg->pDib->bmiColors[i].rgbGreen * 59 - + TileImg->pDib->bmiColors[i].rgbBlue * 11) / 100; - LPBYTE ptr = lpPalettes[1] + i * sizeof(RGBQUAD); - ptr[2] = (BYTE)chcol; - ptr[0] = (BYTE)( (chcol +1)/6 ); - ptr[1] = (BYTE)( (chcol +1)/6 ); - - ptr = lpPalettes[2] + i * sizeof(RGBQUAD); - ptr[2] = ptr[0] = ptr[1] = (BYTE)chcol; - } -} - -void update_tip_text(const char *tip) -{ -#define MAXTIP 512 - static char oldtip[MAXTIP+1]; - if (strncmp(oldtip, tip, MAXTIP) == 0) - return; - - strncpy(oldtip, tip, MAXTIP); - tiTip.lpszText = (char *)tip; - SendMessage(hTool, TTM_UPDATETIPTEXT, 0, (LPARAM)&tiTip); -} - -bool libgui_init_sys( ) -{ - return (true); -} - -void libgui_shutdown_sys() -{ - GlobalFree(lpPalettes[1]); - GlobalFree(lpPalettes[2]); - DestroyWindow( pWin ); -} - -void GetNextEvent(int *etype, int *key, bool *sh, bool *ct, - int *x1, int *y1, int *x2, int *y2) -{ - MSG msg; - - while ( GetMessage(&msg, NULL, 0, 0) ) - { - TranslateMessage( &msg ); - DispatchMessage( &msg ); - if (ev_tail != ev_head) - break; - } - struct ev_data *e = &ev_cue[ev_head]; - ev_head++; - if (ev_head == EV_MAX) - ev_head = 0; - - *etype = e->type; - *key = e->key; - *sh = e->sh; - *ct = e->ct; - *x1 = e->x1; - *y1 = e->y1; -} - -void ev_push(struct ev_data *e) -{ - ev_cue[ev_tail] = *e; - ev_tail++; - if (ev_tail == EV_MAX) - ev_tail = 0; -} - -int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, - LPSTR lpCmdLine, int nCmdShow ) -{ - MSG msg; - - MyRegisterClass( hInstance ); - - GuicInit(hInstance, nCmdShow); - - // Redirect output to the console - AttachConsole(ATTACH_PARENT_PROCESS); - freopen("CONOUT$", "wb", stdout); - freopen("CONOUT$", "wb", stderr); - - // I'll be damned if I have to parse lpCmdLine myself... - int argc; - LPWSTR *wargv = CommandLineToArgvW(GetCommandLineW(), &argc); - char **argv = new char*[argc]; - int args_len = wcslen(GetCommandLineW()) + argc; - char *args = new char[args_len]; - - char *ptr = args; - for (int i = 0; i < argc; i++) - { - wsprintfA(ptr, "%S", wargv[i]); - argv[i] = ptr; - ptr += strlen(argv[i]) + 1; - } - ASSERT(ptr <= args + args_len); - - old_main(argc, argv); - - delete args; - delete argv; - - FreeConsole(); - - return msg.wParam; -} - - -ATOM MyRegisterClass( HINSTANCE hInstance ) -{ - WNDCLASSEX wcex; - - wcex.cbSize = sizeof(WNDCLASSEX); - - wcex.style = CS_HREDRAW | CS_VREDRAW; - wcex.lpfnWndProc = (WNDPROC)WndProc; - wcex.cbClsExtra = 0; - wcex.cbWndExtra = 0; - wcex.hInstance = hInstance; - wcex.hIcon = LoadIcon(hInstance, TEXT("CRAWL_ICON")); - wcex.hCursor = LoadCursor(NULL, IDC_ARROW); - wcex.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); - wcex.lpszMenuName = "CRAWL"; - wcex.lpszClassName = "CrawlList"; - wcex.hIconSm = NULL;//LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL); - - return RegisterClassEx( &wcex ); -} - -LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) -{ - int wmId, wmEvent; - PAINTSTRUCT ps; - HDC hdc; - - struct ev_data ev; - static int clix = 0; - static int cliy = 0; - - // For keypad - const unsigned char ck_table[9] = - { - CK_END, CK_DOWN, CK_PGDN, - CK_LEFT, CK_INSERT, CK_RIGHT, - CK_HOME, CK_UP, CK_PGUP - }; - - switch( message ) - { - case WM_CREATE: - { - pWin = hWnd; - - // Example taken from - // http://black.sakura.ne.jp/~third/system/winapi/common10.html - InitCommonControls(); - hTool = CreateWindowEx( 0 , TOOLTIPS_CLASS , - NULL , TTS_ALWAYSTIP , - CW_USEDEFAULT , CW_USEDEFAULT , - CW_USEDEFAULT , CW_USEDEFAULT , - hWnd , NULL , ((LPCREATESTRUCT)(lParam))->hInstance , - NULL - ); - GetClientRect(hWnd , &tiTip.rect); - - tiTip.cbSize = sizeof (TOOLINFO); - tiTip.uFlags = TTF_SUBCLASS; - tiTip.hwnd = hWnd; - tiTip.lpszText = (char *) - "This text will tell you" EOL - " what you are pointing"; - SendMessage(hTool, TTM_ADDTOOL , 0 , (LPARAM)&tiTip); - // Allow line wrap - SendMessage(hTool, TTM_SETMAXTIPWIDTH, 0, DF_TOOLTIP_WIDTH); - return 0; - } - - case WM_RBUTTONDOWN: - case WM_LBUTTONDOWN: - case WM_MBUTTONDOWN: - { - ev.type = EV_BUTTON; - ev.x1 = LOWORD(lParam); - ev.y1 = HIWORD(lParam); - ev.key = 1; - ev.sh = ((GetKeyState(VK_SHIFT) & 0x80) != 0)? true : false; - ev.ct = ((GetKeyState(VK_CONTROL) & 0x80) != 0)? true : false; - if (message == WM_RBUTTONDOWN) ev.key = 2; - if (message == WM_MBUTTONDOWN) ev.key = 3; - ev_push(&ev); - return 0; - } - - case WM_RBUTTONUP: - { - ev.type = EV_UNBUTTON; - ev.x1 = LOWORD(lParam); - ev.y1 = HIWORD(lParam); - ev.key = 1; - if (message == WM_RBUTTONUP) ev.key = 2; - if (message == WM_MBUTTONUP) ev.key = 3; - ev_push(&ev); - return 0; - } - - case WM_MOUSEWHEEL: - { - int z = (short)HIWORD(wParam); - ev.x1 = LOWORD(lParam) - clix; - ev.y1 = HIWORD(lParam) - cliy; - ev.type = EV_BUTTON; - ev.sh = ((GetKeyState(VK_SHIFT) & 0x80) != 0) ? true : false; - ev.ct = ((GetKeyState(VK_CONTROL) & 0x80) != 0) ? true : false; - ev.key = (z > 0) ? 4 : 5; - ev_push(&ev); - return 0; - } - - case WM_MOUSEMOVE: - { - ev.type = EV_MOVE; - ev.x1 = LOWORD(lParam); - ev.y1 = HIWORD(lParam); - ev_push(&ev); - return 0; - } - - case WM_KEYDOWN: - { - int ch = (int) wParam; - int result = 0; - int dir = 0; - bool fs = ((GetKeyState(VK_SHIFT) & 0x80) != 0)? true : false; - bool fc = ((GetKeyState(VK_CONTROL)& 0x80) != 0)? true : false; - bool fa = ((GetKeyState(VK_MENU) & 0x80) != 0)? true : false; - - if (ch >= VK_NUMPAD1 && ch <= VK_NUMPAD9) - { - skip_key = true; - dir = ch - VK_NUMPAD0; - } - else if (VK_PRIOR <= ch && ch <= VK_DOWN || ch == VK_CLEAR) - { - switch(ch) - { - case VK_LEFT: dir = 4; break; - case VK_RIGHT: dir = 6; break; - case VK_UP: dir = 8; break; - case VK_DOWN: dir = 2; break; - case VK_HOME: dir = 7; break; - case VK_PRIOR: dir = 9; break; - case VK_NEXT: dir = 3; break; - case VK_END: dir = 1; break; - case VK_CLEAR: dir = 5; break; - } - } - - if (dir != 0) - { - ch = ck_table[dir-1]; - if (fc) - ch += CK_CTRL_UP - CK_UP; - if (fs) - ch += CK_SHIFT_UP - CK_UP; - - if (fa) - ch |= 2048; - ev.key = ch; - ev.type = EV_KEYIN; - ev_push(&ev); - return 0; - } - else if (ch >= VK_PAUSE - && (ch < VK_CAPITAL || ch > VK_SPACE) - && ch != VK_PROCESSKEY - && ch != VK_NUMLOCK - && (ch < VK_LSHIFT || ch > VK_RMENU) - && (ch < 0x30 || ch > 0x39) - && (ch < 0x41 || ch > 0x5a) - && (ch < 0xa6 || ch > 0xe4)) - { - result = 300 + ch; - } - - if (result) - { - if (fs) result |= 512; - if (fc) result |= 1024; - if (fa) result |= 2048; - ev.key = result; - ev.type = EV_KEYIN; - ev_push(&ev); - } - - return 0; - } - - case WM_CHAR: - { - if (skip_key) - { - skip_key = false; - return 0; - } - ev.key = (int)wParam; - ev.type = EV_KEYIN; - ev_push(&ev); - return 0; - } - - case WM_PAINT: - { - hdc = BeginPaint(hWnd, &ps); - win_main->redraw(); - EndPaint(hWnd, &ps); - return 0; - } - - case WM_MOVE: - { - clix = LOWORD(lParam); - cliy = HIWORD(lParam); - return 0; - } - - case WM_COMMAND: - { - wmId = LOWORD(wParam); - wmEvent = HIWORD(wParam); - switch( wmId ) - { - // XXX: Isn't that always the case? - default: - return DefWindowProc( hWnd, message, wParam, lParam ); - } - return 0; - } - case WM_CLOSE: - if (mouse_get_mode() == MOUSE_MODE_COMMAND - || !crawl_state.need_save ) - { - if (crawl_state.need_save) - save_game(true); - - libgui_shutdown(); - } - break; - - case WM_DESTROY: - { - PostQuitMessage( 0 ); - exit(0); - break; - } - default: - return DefWindowProc( hWnd, message, wParam, lParam ); - } - return 0; -} - -#ifdef USE_TILE -void TileDrawDungeonAux() -{ - dib_pack *pBuf = region_tile->backbuf; - - int new_palette = PAL_STD; // standard - if (you.duration[DUR_BERSERKER]) - new_palette = PAL_BER; - - // XXX: is this supposed to override Berserk? - if (you.special_wield == SPWLD_SHADOW) - new_palette = PAL_SHA; - - if (new_palette != palette) - { - palette = new_palette; - SetDIBColorTable(pBuf->hDC, 0, 256, (RGBQUAD *)lpPalettes[palette]); - } -} -#endif - -bool windows_change_font(char *font_name, int *font_size, bool dos) -{ - CHOOSEFONT cf; - - memset(&cf, 0, sizeof(cf)); - cf.lStructSize = sizeof(cf); - cf.iPointSize = *font_size; - cf.nSizeMin = 8; - cf.nSizeMax = 24; - cf.Flags = CF_SCREENFONTS | CF_FIXEDPITCHONLY | CF_NOVERTFONTS - | CF_INITTOLOGFONTSTRUCT | CF_LIMITSIZE | CF_FORCEFONTEXIST; - - LOGFONT lf; - strcpy(lf.lfFaceName, font_name); - lf.lfHeight = 16; - lf.lfWidth = 0; - lf.lfEscapement = 0; - lf.lfOrientation = lf.lfEscapement; - lf.lfWeight = FW_NORMAL; - lf.lfItalic = FALSE; - lf.lfUnderline = FALSE; - lf.lfStrikeOut = FALSE; - lf.lfOutPrecision = OUT_DEFAULT_PRECIS; - lf.lfClipPrecision = CLIP_DEFAULT_PRECIS; - lf.lfQuality = DEFAULT_QUALITY; - lf.lfPitchAndFamily = FF_MODERN | FIXED_PITCH; - lf.lfCharSet = (dos)? OEM_CHARSET:ANSI_CHARSET; - cf.lpLogFont = &lf; - - if (ChooseFont(&cf)) - { - *font_size = (cf.iPointSize / 10); - strcpy(font_name, lf.lfFaceName); - return (true); - } - return (false); -} - -void windows_get_winpos(int *x, int *y) -{ - WINDOWPLACEMENT wndpl; - - // set length - wndpl.length = sizeof( WINDOWPLACEMENT ); - - if (GetWindowPlacement( win_main->hWnd, &wndpl ) != 0) - { - *x = wndpl.rcNormalPosition.top; - *y = wndpl.rcNormalPosition.left; - } -} - -void delay(unsigned long ms) -{ - Sleep((DWORD)ms); -} - -int kbhit() -{ - MSG msg; - - if (PeekMessage(&msg, NULL, WM_CHAR, WM_CHAR, PM_NOREMOVE) - || PeekMessage(&msg, NULL, WM_KEYDOWN, WM_KEYDOWN, PM_NOREMOVE)) - { - return 1; - } - else - return 0; -} - -void update_screen() -{ -} diff --git a/crawl-ref/source/libx11.cc b/crawl-ref/source/libx11.cc deleted file mode 100644 index aec3c53221..0000000000 --- a/crawl-ref/source/libx11.cc +++ /dev/null @@ -1,492 +0,0 @@ -/* - * File: guic-win.cc - * Created by: ennewalker on Sat Jan 5 01:33:53 2008 UTC - * - * Modified for Crawl Reference by $Author: j-p-e-g $ on $Date: 2008-03-07 $ - */ - -#include "AppHdr.h" -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#ifdef USE_X11 //Sys dep -#include <X11/Xlib.h> -#include <X11/X.h> -#include <X11/Xutil.h> -#include <X11/Xlocale.h> -#include <X11/keysym.h> -#include <X11/keysymdef.h> -#include <X11/Xmd.h> -#endif - -#include "cio.h" -#include "enum.h" -#include "externs.h" -#include "guic.h" -#include "libutil.h" - -/* - * Tile related stuff - */ -#ifdef USE_TILE - -#include "tiles.h" - -static Display *display=NULL; -static int screen; - -static int x11_keypress(XKeyEvent *xev); -static void x11_check_exposure(XEvent *xev); - -extern WinClass *win_main; - -void GetNextEvent(int *etype, int *key, bool *shift, bool *ctrl, - int *x1, int *y1, int *x2, int *y2) -{ - XEvent xev; - - while (true) - { - XNextEvent(display, &xev); - - if (xev.type == KeyPress) - { - *etype = EV_KEYIN; - *key = x11_keypress(&(xev.xkey)); - break; - } - else if (xev.type == Expose) - { - x11_check_exposure(&xev); - } - else if (xev.type == ConfigureNotify) - { - win_main->ox = xev.xconfigure.x; - win_main->oy = xev.xconfigure.y; - break; - } - else if (xev.type == ButtonPress) - { - *etype = EV_BUTTON; - int button = xev.xbutton.button; - *shift = (xev.xkey.state & ShiftMask) ? true : false; - *ctrl = (xev.xkey.state & ControlMask) ? true : false; - *x1 = xev.xbutton.x; - *y1 = xev.xbutton.y; - - if (button == 3) - button = 2; - else if (button == 2) - button = 3; - - *key = button; - break; - } - else if (xev.type == MotionNotify || xev.type == EnterNotify) - { - *etype = EV_MOVE; - *x1 = xev.xbutton.x; - *y1 = xev.xbutton.y; - break; - } - else if (xev.type == LeaveNotify) - { - *etype = EV_MOVE; - *x1 = -100; - *y1 = -100; - break; - } - else if (xev.type == ButtonRelease) - { - *etype = EV_UNBUTTON; - int button = xev.xbutton.button; - if (button == 3) - button = 2; - else if (button == 2) - button = 3; - - *x1 = xev.xbutton.x; - *y1 = xev.xbutton.y; - *key = button; - break; - } - } -} - -char *my_getenv(const char *envname, const char *def) -{ - const char *result = getenv(envname); - if (!result) - result = def; - - return (char *)result; -} - -int my_getenv_int(const char *envname, int def) -{ - const char *rstr = getenv(envname); - if (!rstr) - return def; - - return atoi(rstr); -} - -extern WinClass *win_main; -extern TextRegionClass *region_tip; -extern TextRegionClass *region_crt; -void update_tip_text(const char *tip) -{ - const unsigned int tip_size = 512; - static char old_tip[tip_size]; - char new_tip[tip_size]; - - if (strncmp(old_tip, tip, tip_size) == 0) - return; - - const bool is_main_screen = (win_main->active_layer == 0); - const unsigned int height = is_main_screen ? region_tip->my : 1; - - const unsigned int width = is_main_screen ? region_tip->mx - : region_crt->mx; - - strncpy(new_tip, tip, tip_size); - strncpy(old_tip, new_tip, tip_size); - - if (is_main_screen) - region_tip->clear(); - - char *next_tip = new_tip; - for (unsigned int i = 0; next_tip && i < height; i++) - { - char *this_tip = next_tip; - - // find end of line - char *pc = strchr(next_tip, '\n'); - if (pc) - { - *pc = 0; - next_tip = pc + 1; - } - else - next_tip = 0; - - if (strlen(this_tip) > width) - { - // try to remove inscriptions - char *ins = strchr(this_tip, '{'); - if (ins && ins[-1] == ' ') - ins--; - if (ins && (ins - this_tip <= (int)width)) - { - *ins = 0; - } - else - { - // try to remove state, e.g. "(worn)" - char *state = strchr(this_tip, '('); - if (state && state[-1] == ' ') - state--; - if (state && (state - this_tip <= (int)width)) - { - *state = 0; - } - else - { - // if nothing else... - this_tip[width] = 0; - this_tip[width-1] = '.'; - this_tip[width-2] = '.'; - } - } - } - - if (is_main_screen) - { - region_tip->cgotoxy(1, 1 + i); - region_tip->addstr(this_tip); - region_tip->make_active(); - } - else - { - ASSERT(i == 0); - textattr(WHITE); - cgotoxy(1, get_number_of_lines() + 1); - cprintf("%s", this_tip); - clear_to_end_of_line(); - } - } -} - -void TileDrawDungeonAux() -{ -} - -#endif /* USE_TILE */ - -/* X11 */ -void x11_check_exposure(XEvent *xev) -{ - int sx, sy, ex, ey; - - sx = xev->xexpose.x; - ex = xev->xexpose.x + (xev->xexpose.width) - 1; - sy = xev->xexpose.y; - ey = xev->xexpose.y + (xev->xexpose.height) - 1; - - if (xev->xany.window != win_main->win) - return; - - win_main->redraw(sx,sy,ex,ey); -} - -/* X11 */ -// This routine is taken from Angband main-x11.c -int x11_keypress(XKeyEvent *xev) -{ - -#define IsSpecialKey(keysym) \ - ((unsigned)(keysym) >= 0xFF00) - - const unsigned int ck_table[9] = - { - CK_END, CK_DOWN, CK_PGDN, - CK_LEFT, CK_INSERT, CK_RIGHT, - CK_HOME, CK_UP, CK_PGUP - }; - - int dir, base; - - int n; - bool mc, ms, ma; - unsigned int ks1; - - XKeyEvent *ev = (XKeyEvent*)(xev); - KeySym ks; - char buf[256]; - - n = XLookupString(ev, buf, 125, &ks, NULL); - buf[n] = '\0'; - - if (IsModifierKey(ks)) return 0; - - /* Extract "modifier flags" */ - mc = (ev->state & ControlMask) ? true : false; - ms = (ev->state & ShiftMask) ? true : false; - ma = (ev->state & Mod1Mask) ? true : false; - - /* Normal keys */ - if (n && !IsSpecialKey(ks)) - { - buf[n] = 0; - - // Hack Ctrl + [0-9] etc. - if (mc && ((ks >= '0' && ks <= '9') || buf[0] >= ' ')) - return 1024 | ks; - - if (!ma) - return buf[0]; - - /* Alt + ? */ - return 2048|buf[0]; - } - - /* Hack -- convert into an unsigned int */ - ks1 = (uint)(ks); - - /* Handle a few standard keys (bypass modifiers) XXX XXX XXX */ - base = dir = 0; - switch (ks1) - { - case XK_Escape: - base = 0x1b; - break; - case XK_Return: - base = '\r'; - break; - case XK_Tab: - base = '\t'; - break; - case XK_Delete: - case XK_BackSpace: - base = '\010'; - break; - - // for menus - case XK_Down: - return CK_DOWN; - case XK_Up: - return CK_UP; - case XK_Left: - return CK_LEFT; - case XK_Right: - return CK_RIGHT; - - // Keypad - case XK_KP_1: - case XK_KP_End: - dir = 1; - break; - - case XK_KP_2: - case XK_KP_Down: - dir = 2; - break; - - case XK_KP_3: - case XK_KP_Page_Down: - dir = 3; - break; - - case XK_KP_6: - case XK_KP_Right: - dir = 6; - break; - - case XK_KP_9: - case XK_KP_Page_Up: - dir = 9; - break; - - case XK_KP_8: - case XK_KP_Up: - dir = 8; - break; - - case XK_KP_7: - case XK_KP_Home: - dir = 7; - break; - - case XK_KP_4: - case XK_KP_Left: - dir = 4; - break; - - case XK_KP_5: - dir = 5; - break; - } - - //Handle keypad first - if (dir != 0) - { - int result = ck_table[dir-1]; - - if (ms) result += CK_SHIFT_UP - CK_UP; - if (mc) result += CK_CTRL_UP - CK_UP; - - return result; - } - - if (base != 0) - { - if (ms) base |= 1024; - if (mc) base |= 2048; - if (ma) base |= 4096; - - return base; - } - - //Hack Special key - if (ks1 >= -0xff00) - { - base = 512 + ks1 - 0xff00; - - if (ms) base |= 1024; - if (mc) base |= 2048; - if (ma) base |= 4096; - - return base; - } - - return 0; -} - -void libgui_init_sys() -{ - GuicInit(&display, &screen); -} - -void libgui_shutdown_sys() -{ - GuicDeinit(); -} - -void update_screen() -{ - XFlush(display); -} - -int kbhit() -{ - XEvent xev; - - if (XCheckMaskEvent(display, KeyPressMask | ButtonPressMask, &xev)) - { - XPutBackEvent(display, &xev); - return 1; - } - return 0; -} - -void delay( unsigned long time ) -{ - usleep( time * 1000 ); -} - -/* Convert value to string */ -int itoa(int value, char *strptr, int radix) -{ - unsigned int bitmask = 32768; - int ctr = 0; - int startflag = 0; - - if (radix == 10) - { - sprintf(strptr, "%i", value); - } - else if (radix == 2) /* int to "binary string" */ - { - while (bitmask) - { - if (value & bitmask) - { - startflag = 1; - sprintf(strptr + ctr, "1"); - } - else if (startflag) - { - sprintf(strptr + ctr, "0"); - } - - bitmask = bitmask >> 1; - if (startflag) - ctr++; - } - - if (!startflag) /* Special case if value == 0 */ - sprintf((strptr + ctr++), "0"); - - strptr[ctr] = (char) NULL; - } - return (0); /* Me? Fail? Nah. */ -} - - -// Convert string to lowercase. -char *strlwr(char *str) -{ - unsigned int i; - - for (i = 0; i < strlen(str); i++) - str[i] = tolower(str[i]); - - return (str); -} - -int stricmp( const char *str1, const char *str2 ) -{ - return (strcmp(str1, str2)); -} diff --git a/crawl-ref/source/macro.cc b/crawl-ref/source/macro.cc index 712cd8c39d..7f9526ea7e 100644 --- a/crawl-ref/source/macro.cc +++ b/crawl-ref/source/macro.cc @@ -763,9 +763,7 @@ void macro_add_query( void ) (keymap ? "keymap" : "macro") ); keyseq key; -#ifdef USE_TILE mouse_control mc(MOUSE_MODE_MACRO); -#endif key = getch_mul(); cprintf( "%s" EOL, (vtostr( key )).c_str() ); // echo key to screen diff --git a/crawl-ref/source/makefile b/crawl-ref/source/makefile index 9e1ded2ab6..b2c4fa5648 100644 --- a/crawl-ref/source/makefile +++ b/crawl-ref/source/makefile @@ -9,7 +9,7 @@ MAKEFILE ?= makefile.unix #MAKEFILE ?= makefile.osx #MAKEFILE ?= makefile.mgw #MAKEFILE ?= makefile_tiles.mgw -#MAKEFILE ?= makefile.x11 +#MAKEFILE ?= makefile_tiles.unix #jmf: number of concurrent jobs -- good value is (#_of_CPUs * 2) + 1 # cuts build time a lot on multi-cpu machines diff --git a/crawl-ref/source/makefile_tiles.mgw b/crawl-ref/source/makefile_tiles.mgw index fed4392b7a..1dacdea1b8 100644 --- a/crawl-ref/source/makefile_tiles.mgw +++ b/crawl-ref/source/makefile_tiles.mgw @@ -15,6 +15,11 @@ CXX = g++ DELETE = del COPY = copy OS_TYPE = WIN32TILES +EXTRA_DEFINES = -DUSE_TILE -DCLUA_BINDINGS + +SDL_PREFIX ?= C:/mingw +SDL_CFLAGS := -D_GNU_SOURCE=1 -Dmain=SDL_main -I$(SDL_PREFIX)/include/SDL +SDL_LDFLAGS := -lmingw32 -lSDLmain -lSDL -mwindows INSTALLDIR := $(OPATH) @@ -36,8 +41,8 @@ SQLLIB := sqlite3 SQLIBA := lib$(SQLLIB).a FSQLLIBA := $(SQLLIB)\$(SQLIBA) -LIB = -static -lwinmm -mwindows -lcomctl32 -L$(LUASRC) -l$(LUALIB) -L$(SQLSRC) -l$(SQLLIB) -lpcre -INCLUDES := -Iutil -I. -I$(LUASRC) -I$(SQLSRC) +LIB = -lwinmm -mwindows -lcomctl32 -L$(LUASRC) -l$(LUALIB) -L$(SQLSRC) -l$(SQLLIB) -lpng $(SDL_LDFLAGS) -lopengl32 -lglu32 -lSDL_image -lfreetype +INCLUDES := -Iutil -I. -I$(LUASRC) -I$(SQLSRC) $(EXTRA_INCLUDES) CFWARN := -Wall -Wwrite-strings -pedantic @@ -47,12 +52,13 @@ CFOTHERS := -fsigned-char \ -O2 \ -D$(OS_TYPE) $(EXTRA_FLAGS) \ -DWINMM_PLAY_SOUNDS -DCLUA_BINDINGS \ - -DUSE_TILE -DWINVER=0x0400 -D_WIN32_IE=0x0400 + -DWINVER=0x0400 -D_WIN32_IE=0x0400 \ + $(EXTRA_DEFINES) \ -CFLAGS := $(INCLUDES) $(CFWARN) $(CFOTHERS) +CFLAGS := $(INCLUDES) $(CFWARN) $(CFOTHERS) $(SDL_CFLAGS) YCFLAGS := $(INCLUDES) $(CFOTHERS) -OBJECTS := $(OBJECTS) libgui.o tile1.o tile2.o libwt.o guic.o guic-win.o +OBJECTS := $(OBJECTS) libgui.o tilepick.o tile2.o tilereg.o tilesdl.o tilefont.o tiletex.o LDFLAGS = @@ -66,15 +72,16 @@ RLTILES = rltiles TILEHEADERS = \ tiledef.h \ tiledef-p.h \ -tiledef-w2d.h \ -tilecount-w2d.h \ -tilep-cmt.h +tilep-cmt.h \ +tiledef-dngn.h \ +tilecount-dngn.h TILEFILES = \ -tile.bmp \ -player.bmp \ -wall2d.bmp \ -title.bmp +tile.png \ +player.png \ +title.png \ +dngn.png + DESTTILEFILES = $(TILEFILES:%=dat/tiles/%) ifeq ($(LEX),) diff --git a/crawl-ref/source/makefile.x11 b/crawl-ref/source/makefile_tiles.unix index 3ec62a8327..f4d1c9ed0c 100644 --- a/crawl-ref/source/makefile.x11 +++ b/crawl-ref/source/makefile_tiles.unix @@ -10,20 +10,36 @@ GAME = crawl # it will make a variable called OBJECTS that contains all the libraries include makefile.obj -OBJECTS += libgui.o tile1.o tile2.o libx11.o guic.o guic-x11.o +OBJECTS += libgui.o tilepick.o tile2.o tilereg.o tilesdl.o tilefont.o tiletex.o + +SDL_CFLAGS := $(shell sdl-config --cflags) +SDL_LDFLAGS := $(shell sdl-config --libs) -lSDLmain CXX = g++ DELETE = rm -f COPY = cp OS_TYPE = UNIX -EXTRA_INCLUDES = -DUSE_X11 -DUSE_TILE +EXTRA_INCLUDES = -DUSE_TILE -DCLUA_BINDINGS + +# Change this to y if you want to use Unicode glyphs in the map, and you have +# libncursesw available. +UNICODE_GLYPHS = n ifeq ($(strip $(OSX)),y) PNG_INCLUDE := -I/sw/include PNG_LIB := -L/sw/lib +FREETYPE_INCLUDE := -I/sw/include/freetype2 + +# 10.5 Fink bug +FINK_OPENGL_WORKAROUND := -Wl,-dylib_file,/System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/libGL.dylib:/System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/libGL.dylib + +SDL_LDFLAGS += -framework Cocoa -L/usr/X11/lib $(FINK_OPENGL_WORKAROUND) + +EXTRA_INCLUDES += -I/sw/include else PNG_INCLUDE := PNG_LIB := +FREETYPE_INCLUDE := -I/usr/include/freetype2 endif # If you have lex and yacc, set DOYACC to y (lowercase y). @@ -36,8 +52,9 @@ MCHMOD := 2755 MCHMOD_SAVEDIR := 775 # The user:group to install the game as. -INSTALL_UGRP ?= games:games -INSTALLDIR ?= /usr/games/crawl +INSTALL_UGRP := games:games + +INSTALLDIR := /usr/games/crawl # If you're installing Crawl for multiple users, you *must* set this to a # valid path before building Crawl. This is not necessary if you are building @@ -84,9 +101,9 @@ EXTRA_INCLUDES += -I$(SQLSRC) EXTRA_DEPENDS += $(FSQLLIBA) endif -LIB = -L$(LUASRC) -l$(LUALIB) $(LIBDBM) -L/usr/X11R6/lib -lX11 -lpng $(PNG_LIB) +LIB = -L$(LUASRC) -l$(LUALIB) $(LIBDBM) -lpng $(SDL_LDFLAGS) -lGL -lGLU -lSDL_image -lfreetype -INCLUDES := $(INCLUDES) -Iutil -I. -I$(LUASRC) $(EXTRA_INCLUDES) $(PNG_INCLUDE) +INCLUDES := $(INCLUDES) -Iutil -I. -I$(LUASRC) $(EXTRA_INCLUDES) $(PNG_INCLUDE) $(FREETYPE_INCLUDE) CFWARN := -Wall -Wwrite-strings -Wshadow -pedantic @@ -109,7 +126,7 @@ endif CFOTHERS += $(SELDBM) -CFLAGS := $(INCLUDES) $(CFWARN) $(CFOTHERS) +CFLAGS := $(INCLUDES) $(CFWARN) $(CFOTHERS) $(SDL_CFLAGS) YCFLAGS := $(INCLUDES) $(CFOTHERS) UTIL = util/ @@ -122,15 +139,15 @@ RLTILES = rltiles/ TILEHEADERS = \ tiledef.h \ tiledef-p.h \ -tiledef-w2d.h \ -tilecount-w2d.h \ -tilep-cmt.h +tilep-cmt.h \ +tiledef-dngn.h \ +tilecount-dngn.h TILEFILES = \ tile.png \ player.png \ - wall2d.png \ - title.png + title.png \ + dngn.png DESTTILEFILES = $(TILEFILES:%=dat/tiles/%) EXTRA_DEPENDS += $(TILEHEADERS) $(DESTTILEFILES) diff --git a/crawl-ref/source/menu.cc b/crawl-ref/source/menu.cc index 672bb3d14d..03dba10ef3 100644 --- a/crawl-ref/source/menu.cc +++ b/crawl-ref/source/menu.cc @@ -210,10 +210,6 @@ void Menu::do_menu() alive = true; while (alive) { -#ifdef USE_TILE - TileRedrawInv(REGION_INV2); - mouse_control mc(MOUSE_MODE_COMMAND); -#endif int keyin = getchm(KC_NONE, c_getch); if (!process_key( keyin )) @@ -687,10 +683,6 @@ void Menu::draw_menu() cgotoxy( 1, y_offset + pagesize - count_linebreaks(more) ); more.display(); } - -#ifdef USE_TILE - TileRedrawInv(REGION_INV2); -#endif } void Menu::update_title() @@ -1618,15 +1610,11 @@ bool formatted_scroller::process_key( int keyin ) case CK_ESCAPE: return (false); case ' ': case '+': case '=': case CK_PGDN: case '>': case '\'': -#ifdef USE_TILE case CK_MOUSE_B5: -#endif repaint = page_down(); break; case '-': case CK_PGUP: case '<': case ';': -#ifdef USE_TILE case CK_MOUSE_B4: -#endif repaint = page_up(); break; case CK_UP: diff --git a/crawl-ref/source/message.cc b/crawl-ref/source/message.cc index 8cb38c1102..372becdf55 100644 --- a/crawl-ref/source/message.cc +++ b/crawl-ref/source/message.cc @@ -881,10 +881,7 @@ void more(void) LIGHTGREY, "--more--", 2, false); } -#ifdef USE_TILE mouse_control mc(MOUSE_MODE_MORE); -#endif - do { keypress = getch(); diff --git a/crawl-ref/source/output.cc b/crawl-ref/source/output.cc index 8c7fdaf49d..b05dbbc515 100644 --- a/crawl-ref/source/output.cc +++ b/crawl-ref/source/output.cc @@ -796,11 +796,6 @@ void print_stats(void) { textcolor(LIGHTGREY); -#ifdef USE_TILE - if (you.redraw_armour_class || you.wield_change) - TilePlayerRefresh(); -#endif - // Displayed evasion is now tied to dex. if (you.redraw_dexterity) you.redraw_evasion = true; diff --git a/crawl-ref/source/player.cc b/crawl-ref/source/player.cc index cfa61aadd7..f21bba49f5 100644 --- a/crawl-ref/source/player.cc +++ b/crawl-ref/source/player.cc @@ -300,17 +300,6 @@ bool move_player_to_grid( int x, int y, bool stepped, bool allow_shift, // Move the player to new location. you.moveto(x, y); -#ifdef USE_TILE - // We could check for this above, but we need to do this post-move - // to force the merfolk tile to be out of water. - if ((!grid_is_water(new_grid) && grid_is_water(old_grid) - || grid_is_water(new_grid) && !grid_is_water(old_grid)) - && you.species == SP_MERFOLK) - { - TilePlayerRefresh(); - } -#endif - viewwindow( true, false ); // Other Effects: @@ -2859,7 +2848,7 @@ void forget_map(unsigned char chance_forgotten, bool force) } #ifdef USE_TILE - GmapInit(false); + tiles.clear_minimap(); tile_clear_buf(); #endif } @@ -3219,9 +3208,6 @@ void level_change(bool skip_attribute_increase) case SP_BASE_DRACONIAN: if (you.experience_level == 7) { -#ifdef USE_TILE - TilePlayerRefresh(); -#endif switch (you.species) { case SP_RED_DRACONIAN: diff --git a/crawl-ref/source/rltiles/dc-2d.txt b/crawl-ref/source/rltiles/dc-2d.txt index 3b0e06c2e7..dff5fe74ba 100644 --- a/crawl-ref/source/rltiles/dc-2d.txt +++ b/crawl-ref/source/rltiles/dc-2d.txt @@ -1,13 +1,13 @@ %tiledef tiledef.h
-%width 30
+%width 32
%back none
#%htmlfile tile.htm
#%tilelist tile.txt
#%htmlbody
%name tile
-## Dungeon features
-%include dc-dngn.txt
+# idx == 0 must be invalid.
+dc-dngn/dngn_unseen
## Set black rim
## Items
diff --git a/crawl-ref/source/rltiles/dc-dngn.txt b/crawl-ref/source/rltiles/dc-dngn.txt deleted file mode 100644 index ab2e6b96a6..0000000000 --- a/crawl-ref/source/rltiles/dc-dngn.txt +++ /dev/null @@ -1,188 +0,0 @@ -%sdir dc-dngn - -blank BLANK -dngn_unseen DNGN_UNSEEN - -# Do not separate basic floors and rock walls. They get overwritten by -# branch-specific floors and walls and will overwrite anything in between. -floor/pebble_gray0 DNGN_FLOOR -floor/pebble_gray1 -floor/pebble_gray2 -floor/pebble_gray3 -floor/pebble_gray3 -floor/pebble_gray3 -floor/pebble_gray3 -floor/pebble_gray3 DNGN_FLOOR_SPECIAL -wall/brick_brown0 DNGN_ROCK_WALL_OFS -wall/brick_brown1 -wall/brick_brown2 -wall/brick_brown3 -wall/brick_brown3 -wall/brick_brown3 -wall/brick_brown3 -wall/brick_brown3 -wall/brick_brown3 -wall/brick_brown3 -wall/brick_brown3 -wall/brick_brown3 - -floor/floor_nerves0 DNGN_FLOOR_CORRUPT -floor/floor_nerves1 -floor/floor_nerves2 -floor/floor_nerves3 -wall/undead0 DNGN_WALL_CORRUPT -wall/undead1 -wall/undead2 -wall/undead3 - -floor/lava0 DNGN_LAVA -floor/lava1 -floor/lava2 -floor/lava3 -dngn_deep_water DNGN_DEEP_WATER -dngn_deep_water -dngn_deep_water -dngn_deep_water -dngn_shallow_water DNGN_SHALLOW_WATER -dngn_shallow_water -dngn_shallow_water -dngn_shallow_water - -wall/stone2_gray0 DNGN_STONE_WALL -wall/stone2_gray1 -wall/stone2_gray2 -wall/stone2_gray3 -dngn_metal_wall DNGN_METAL_WALL -dngn_green_crystal_wall DNGN_GREEN_CRYSTAL_WALL -dngn_wax_wall DNGN_WAX_WALL -dngn_transparent_wall DNGN_TRANSPARENT_WALL - -#dngn_rock_wall_00 DNGN_ROCK_WALL_OFS -#dngn_rock_wall_01 IGNORE_COMMENT -#dngn_rock_wall_02 IGNORE_COMMENT -#dngn_rock_wall_03 IGNORE_COMMENT -#dngn_rock_wall_04 IGNORE_COMMENT -#dngn_rock_wall_05 IGNORE_COMMENT -#dngn_rock_wall_06 IGNORE_COMMENT -#dngn_rock_wall_07 IGNORE_COMMENT -#dngn_rock_wall_08 IGNORE_COMMENT -#dngn_rock_wall_09 IGNORE_COMMENT -#dngn_rock_wall_10 IGNORE_COMMENT -#dngn_rock_wall_11 IGNORE_COMMENT -#dngn_rock_wall_12 IGNORE_COMMENT -#dngn_rock_wall_13 IGNORE_COMMENT -#dngn_rock_wall_14 IGNORE_COMMENT -#dngn_rock_wall_15 IGNORE_COMMENT -#dngn_stone_wall DNGN_STONE_WALL - -dngn_closed_door DNGN_CLOSED_DOOR -gate_closed_left DNGN_GATE_CLOSED_LEFT -gate_closed_middle DNGN_GATE_CLOSED_MIDDLE -gate_closed_right DNGN_GATE_CLOSED_RIGHT -dngn_open_door DNGN_OPEN_DOOR -gate_open_left DNGN_GATE_OPEN_LEFT -gate_open_middle DNGN_GATE_OPEN_MIDDLE -gate_open_right DNGN_GATE_OPEN_RIGHT -###dc/wal8 DNGN_SECRET_DOOR -dngn_orcish_idol DNGN_ORCISH_IDOL -dngn_silver_statue DNGN_SILVER_STATUE -dngn_granite_statue DNGN_GRANITE_STATUE -dngn_orange_crystal_statue DNGN_ORANGE_CRYSTAL_STATUE -dngn_ice_statue DNGN_ICE_STATUE - -###dc/wal1 DNGN_PERMAROCK_WALL -###dc/wal1 DNGN_LAST_SOLID_TILE - -%rim 1 -dngn_enter_hell DNGN_ENTER_HELL -%rim 0 -dngn_branch_stairs DNGN_BRANCH_STAIRS -dngn_trap_dart DNGN_TRAP_DART -dngn_trap_arrow DNGN_TRAP_ARROW -dngn_trap_spear DNGN_TRAP_SPEAR -dngn_trap_axe DNGN_TRAP_AXE -dngn_trap_teleport DNGN_TRAP_TELEPORT -dngn_trap_alarm DNGN_TRAP_ALARM -dngn_trap_blade DNGN_TRAP_BLADE -dngn_trap_bolt DNGN_TRAP_BOLT -dngn_trap_net DNGN_TRAP_NET -dngn_trap_zot DNGN_TRAP_ZOT -dngn_trap_needle DNGN_TRAP_NEEDLE -dngn_trap_shaft DNGN_TRAP_SHAFT -###847 DNGN_UNDISCOVERED_TRAP -stone_stairs_down DNGN_STONE_STAIRS_DOWN -#nh-dngn/staircase_down DNGN_STONE_STAIRS_DOWN_II -#nh-dngn/staircase_down DNGN_STONE_STAIRS_DOWN_III -rock_stairs_down DNGN_ROCK_STAIRS_DOWN -stone_stairs_up DNGN_STONE_STAIRS_UP -#nh-dngn/staircase_up DNGN_STONE_STAIRS_UP_II -#nh-dngn/staircase_up DNGN_STONE_STAIRS_UP_III -rock_stairs_up DNGN_ROCK_STAIRS_UP - -dngn_enter_shop DNGN_ENTER_SHOP -dngn_enter_labyrinth DNGN_ENTER_LABYRINTH -dngn_enter_dis DNGN_ENTER_DIS -dngn_enter_gehenna DNGN_ENTER_GEHENNA -dngn_enter_cocytus DNGN_ENTER_COCYTUS -dngn_enter_tartarus DNGN_ENTER_TARTARUS - -dngn_enter_abyss DNGN_ENTER_ABYSS -dngn_exit DNGN_EXIT_ABYSS - -dngn_stone_arch DNGN_STONE_ARCH -dngn_enter_pandemonium DNGN_ENTER_PANDEMONIUM -dngn_exit DNGN_EXIT_PANDEMONIUM -%rim 1 -dngn_transit_pandemonium DNGN_TRANSIT_PANDEMONIUM -%rim 0 -####846 DNGN_BUILDER_SPECIAL_WALL -####846 DNGN_BUILDER_SPECIAL_FLOOR -dngn_enter DNGN_ENTER -#851 DNGN_ENTER_ORCISH_MINES -#851 DNGN_ENTER_HIVE -#851 DNGN_ENTER_LAIR -#851 DNGN_ENTER_SLIME_PITS -#851 DNGN_ENTER_VAULTS -#851 DNGN_ENTER_CRYPT -#851 DNGN_ENTER_HALL_OF_BLADES -#851 DNGN_ENTER_ZOT -#851 DNGN_ENTER_TEMPLE -#851 DNGN_ENTER_SNAKE_PIT -#851 DNGN_ENTER_ELVEN_HALLS -#851 DNGN_ENTER_TOMB -#851 DNGN_ENTER_SWAMP -%rim 1 -dngn_return DNGN_RETURN -%rim 0 -#850 DNGN_RETURN_FROM_ORCISH_MINES -#850 DNGN_RETURN_FROM_HIVE -#850 DNGN_RETURN_FROM_LAIR -#850 DNGN_RETURN_FROM_SLIME_PITS -#850 DNGN_RETURN_FROM_VAULTS -#850 DNGN_RETURN_FROM_CRYPT -#850 DNGN_RETURN_FROM_HALL_OF_BLADES -#850 DNGN_RETURN_FROM_ZOT -#850 DNGN_RETURN_FROM_TEMPLE -#850 DNGN_RETURN_FROM_SNAKE_PIT -#850 DNGN_RETURN_FROM_ELVEN_HALLS -#850 DNGN_RETURN_FROM_TOMB -#850 DNGN_RETURN_FROM_SWAMP -dngn_altar_zin DNGN_ALTAR_ZIN -dngn_altar_shining_one DNGN_ALTAR_SHINING_ONE -dngn_altar_kikubaaqudgha DNGN_ALTAR_KIKUBAAQUDGHA -dngn_altar_yredelemnul DNGN_ALTAR_YREDELEMNUL -dngn_altar_xom DNGN_ALTAR_XOM -dngn_altar_vehumet DNGN_ALTAR_VEHUMET -dngn_altar_okawaru DNGN_ALTAR_OKAWARU -dngn_altar_makhleb DNGN_ALTAR_MAKHLEB -dngn_altar_sif_muna DNGN_ALTAR_SIF_MUNA -dngn_altar_trog DNGN_ALTAR_TROG -dngn_altar_nemelex_xobeh DNGN_ALTAR_NEMELEX_XOBEH -dngn_altar_elyvilon DNGN_ALTAR_ELYVILON -dngn_altar_lugonu DNGN_ALTAR_LUGONU -dngn_altar_beogh DNGN_ALTAR_BEOGH -dngn_blue_fountain DNGN_BLUE_FOUNTAIN -dngn_sparkling_fountain DNGN_SPARKLING_FOUNTAIN -dngn_blood_fountain DNGN_BLOOD_FOUNTAIN -dngn_dry_fountain DNGN_DRY_FOUNTAIN -#858 DNGN_PERMADRY_FOUNTAIN diff --git a/crawl-ref/source/rltiles/dc-misc.txt b/crawl-ref/source/rltiles/dc-misc.txt index 0c89b0b41a..08a71c27c7 100644 --- a/crawl-ref/source/rltiles/dc-misc.txt +++ b/crawl-ref/source/rltiles/dc-misc.txt @@ -25,11 +25,8 @@ cloud_grey_smoke CLOUD_GREY_SMOKE cloud_miasma CLOUD_MIASMA
cloud_purp_smoke CLOUD_PURP_SMOKE
-sanctuary SANCTUARY
-
#########MAP
%sdir dc-misc
-halo HALO
%corpse 0
%back none
%mesh 0
@@ -41,23 +38,18 @@ unseen_item UNSEEN_ITEM %back dc-misc/blood_red
unseen_monster UNSEEN_CORPSE
%corpse 0
-dc-misc/blood_red BLOOD0
-dc-misc/blood_red1 BLOOD1
-dc-misc/blood_red2 BLOOD2
-dc-misc/blood_red3 BLOOD3
-dc-misc/blood_red4 BLOOD4
%back none
dc-dngn/dngn_altar UNSEEN_ALTAR
dc-dngn/dngn_entrance UNSEEN_ENTRANCE
%back none
-#mask_deep_water MASK_DEEP_WATER
-#mask_shallow_water MASK_SHALLOW_WATER
-#mask_lava MASK_LAVA
-sink_mask SINK_MASK
+mask_deep_water MASK_DEEP_WATER
+mask_shallow_water MASK_SHALLOW_WATER
+mask_lava MASK_LAVA
cursor CURSOR
cursor_red CURSOR2
cursor_green CURSOR3
+tutorial_cursor TUTORIAL_CURSOR
%rim 1
heart HEART
neutral NEUTRAL
@@ -71,15 +63,14 @@ unseen PLAYER blank MESH
%mesh 0
magicmap MAGIC_MAP_MESH
-ray RAY_MESH
txt1 TEXT_PARTS_J
txt2 TEXT_DOLLS_J
txt3 TEXT_PARTS_E
txt4 TEXT_DOLLS_E
something_under SOMETHING_UNDER
error ERROR
-travel_exclusion TRAVEL_EXCLUSION
-travel_exclusion_centre TRAVEL_EXCL_CENTRE
+travel_exclusion TRAVEL_EXCLUSION_FG
+travel_exclusion_centre TRAVEL_EXCLUSION_CENTRE_FG
%rim 1
todo TODO
new_stair NEW_STAIR
@@ -98,89 +89,11 @@ char68 char70
char78
-slot ITEM_SLOT
slot_eq ITEM_SLOT_EQUIP
slot_cursed ITEM_SLOT_CURSED
slot_eq_cursed ITEM_SLOT_EQUIP_CURSED
+ray ITEM_SLOT_SELECTED
%back unseen
dc-misc/unseen_monster MCACHE_START
-dc-misc/unseen_monster
-dc-misc/unseen_monster
-dc-misc/unseen_monster
-dc-misc/unseen_monster
-dc-misc/unseen_monster
-dc-misc/unseen_monster
-dc-misc/unseen_monster
-dc-misc/unseen_monster
-dc-misc/unseen_monster
-dc-misc/unseen_monster
-dc-misc/unseen_monster
-dc-misc/unseen_monster
-dc-misc/unseen_monster
-dc-misc/unseen_monster
-dc-misc/unseen_monster
-dc-misc/unseen_monster
-dc-misc/unseen_monster
-dc-misc/unseen_monster
-dc-misc/unseen_monster
-dc-misc/unseen_monster
-dc-misc/unseen_monster
-dc-misc/unseen_monster
-dc-misc/unseen_monster
-dc-misc/unseen_monster
-dc-misc/unseen_monster
-dc-misc/unseen_monster
-dc-misc/unseen_monster
-dc-misc/unseen_monster
-dc-misc/unseen_monster
-dc-misc/unseen_monster
-dc-misc/unseen_monster
-dc-misc/unseen_monster
-dc-misc/unseen_monster
-dc-misc/unseen_monster
-dc-misc/unseen_monster
-dc-misc/unseen_monster
-dc-misc/unseen_monster
-dc-misc/unseen_monster
-dc-misc/unseen_monster
-dc-misc/unseen_monster
-dc-misc/unseen_monster
-dc-misc/unseen_monster
-dc-misc/unseen_monster
-dc-misc/unseen_monster
-dc-misc/unseen_monster
-dc-misc/unseen_monster
-dc-misc/unseen_monster
-dc-misc/unseen_monster
-dc-misc/unseen_monster
-dc-misc/unseen_monster
-dc-misc/unseen_monster
-dc-misc/unseen_monster
-dc-misc/unseen_monster
-dc-misc/unseen_monster
-dc-misc/unseen_monster
-dc-misc/unseen_monster
-dc-misc/unseen_monster
-dc-misc/unseen_monster
-dc-misc/unseen_monster
-dc-misc/unseen_monster
-dc-misc/unseen_monster
-dc-misc/unseen_monster
-dc-misc/unseen_monster
-dc-misc/unseen_monster
-dc-misc/unseen_monster
-dc-misc/unseen_monster
-dc-misc/unseen_monster
-dc-misc/unseen_monster
-dc-misc/unseen_monster
-dc-misc/unseen_monster
-dc-misc/unseen_monster
-dc-misc/unseen_monster
-dc-misc/unseen_monster
-dc-misc/unseen_monster
-dc-misc/unseen_monster
-dc-misc/unseen_monster
-dc-misc/unseen_monster
-dc-misc/unseen_monster
dc-misc/unseen_monster MCACHE_END
diff --git a/crawl-ref/source/rltiles/dc-misc/tutorial_cursor.bmp b/crawl-ref/source/rltiles/dc-misc/tutorial_cursor.bmp Binary files differnew file mode 100644 index 0000000000..3d9f23a6fe --- /dev/null +++ b/crawl-ref/source/rltiles/dc-misc/tutorial_cursor.bmp diff --git a/crawl-ref/source/rltiles/dc-misc/unseen_water_monster.bmp b/crawl-ref/source/rltiles/dc-misc/unseen_water_monster.bmp Binary files differnew file mode 100644 index 0000000000..01b75a80bb --- /dev/null +++ b/crawl-ref/source/rltiles/dc-misc/unseen_water_monster.bmp diff --git a/crawl-ref/source/rltiles/dc-mon.txt b/crawl-ref/source/rltiles/dc-mon.txt index 00cece283e..8ef8749521 100644 --- a/crawl-ref/source/rltiles/dc-mon.txt +++ b/crawl-ref/source/rltiles/dc-mon.txt @@ -498,3 +498,8 @@ merfolk_fighter_water MONS_MERFOLK_FIGHTER_WATER mermaid MONS_MERMAID
mermaid_water MONS_MERMAID_WATER
rock_worm MONS_ROCK_WORM
+
+%sdir dc-dngn
+dngn_orange_crystal_statue DNGN_ORANGE_CRYSTAL_STATUE
+dngn_ice_statue DNGN_ICE_STATUE
+%sdir dc-mon
diff --git a/crawl-ref/source/rltiles/dc-pl.txt b/crawl-ref/source/rltiles/dc-pl.txt index af130b5e05..5f057b9b7f 100644 --- a/crawl-ref/source/rltiles/dc-pl.txt +++ b/crawl-ref/source/rltiles/dc-pl.txt @@ -1,4 +1,4 @@ -%width 20
+%width 32
%back none
%name player
diff --git a/crawl-ref/source/rltiles/dc-wall2d.txt b/crawl-ref/source/rltiles/dngn.txt index d3e7054da9..a2c290056f 100644 --- a/crawl-ref/source/rltiles/dc-wall2d.txt +++ b/crawl-ref/source/rltiles/dngn.txt @@ -1,345 +1,425 @@ -%enumprefix W2D_
-%tiledef tiledef-w2d.h
-%tilecount tilecount-w2d.h
-%width 16
-%back none
-%name wall2d
-
-%sdir dc-dngn
-
-wall/brick_brown0 WALL_NORMAL
-wall/brick_brown1
-wall/brick_brown2
-wall/brick_brown3
-floor/pebble_gray0 FLOOR_NORMAL
-floor/pebble_gray1
-floor/pebble_gray2
-floor/pebble_gray3
-floor/pebble_gray4
-
-wall/relief0 WALL_HALL
-wall/relief1
-wall/relief2
-wall/relief3
-floor/mesh0 FLOOR_HALL
-floor/mesh1
-floor/mesh2
-floor/mesh3
-
-wall/hive0 WALL_HIVE
-wall/hive1
-wall/hive2
-wall/hive3
-floor/hive0 FLOOR_HIVE
-floor/hive1
-floor/hive2
-floor/hive3
-
-wall/ice0 WALL_ICE
-wall/ice1
-wall/ice2
-wall/ice3
-floor/ice0 FLOOR_ICE
-floor/ice1
-floor/ice2
-floor/ice3
-
-wall/lair0 WALL_LAIR
-wall/lair1
-wall/lair2
-wall/lair3
-floor/lair0 FLOOR_LAIR
-floor/lair1
-floor/lair2
-floor/lair3
-
-## orcs don't have their own floor or walls yet...
-wall/lair0 WALL_ORC
-wall/lair1
-wall/lair2
-wall/lair3
-floor/hive0 FLOOR_ORC
-floor/hive1
-floor/hive2
-floor/hive3
-
-wall/slime0 WALL_SLIME
-wall/slime1
-wall/slime2
-wall/slime3
-floor/bog_green0 FLOOR_SLIME
-floor/bog_green1
-floor/bog_green2
-floor/bog_green3
-
-wall/snake0 WALL_SNAKE
-wall/snake1
-wall/snake2
-wall/snake3
-floor/snake0 FLOOR_SNAKE
-floor/snake1
-floor/snake2
-floor/snake3
-
-## swamp also doesn't have any unique walls...
-wall/lair0 WALL_SWAMP
-wall/lair1
-wall/lair2
-wall/lair3
-floor/swamp0 FLOOR_SWAMP
-floor/swamp1
-floor/swamp2
-floor/swamp3
-
-wall/tomb0 WALL_TOMB
-wall/tomb1
-wall/tomb2
-wall/tomb3
-floor/tomb0 FLOOR_TOMB
-floor/tomb1
-floor/tomb2
-floor/tomb3
-
-wall/undead0 WALL_UNDEAD
-wall/undead1
-wall/undead2
-wall/undead3
-floor/tomb0 FLOOR_UNDEAD
-floor/tomb1
-floor/tomb2
-floor/tomb3
-
-wall/vault0 WALL_VAULT
-wall/vault1
-wall/vault2
-wall/vault3
-floor/rect_gray0 FLOOR_VAULT
-floor/rect_gray1
-floor/rect_gray2
-floor/rect_gray3
-
-wall/zot_blue0 WALL_ZOT_BLUE
-wall/zot_blue1
-wall/zot_blue2
-wall/zot_blue3
-floor/tomb0 FLOOR_ZOT_BLUE
-floor/tomb1
-floor/tomb2
-floor/tomb3
-
-wall/zot_cyan0 WALL_ZOT_CYAN
-wall/zot_cyan1
-wall/zot_cyan2
-wall/zot_cyan3
-floor/tomb0 FLOOR_ZOT_CYAN
-floor/tomb1
-floor/tomb2
-floor/tomb3
-
-wall/zot_gray0 WALL_ZOT_GRAY
-wall/zot_gray1
-wall/zot_gray2
-wall/zot_gray3
-floor/tomb0 FLOOR_ZOT_GRAY
-floor/tomb1
-floor/tomb2
-floor/tomb3
-
-wall/zot_green0 WALL_ZOT_GREEN
-wall/zot_green1
-wall/zot_green2
-wall/zot_green3
-floor/tomb0 FLOOR_ZOT_GREEN
-floor/tomb1
-floor/tomb2
-floor/tomb3
-
-wall/zot_magenta0 WALL_ZOT_MAGENTA
-wall/zot_magenta1
-wall/zot_magenta2
-wall/zot_magenta3
-floor/tomb0 FLOOR_ZOT_MAGENTA
-floor/tomb1
-floor/tomb2
-floor/tomb3
-
-wall/zot_red0 WALL_ZOT_RED
-wall/zot_red1
-wall/zot_red2
-wall/zot_red3
-floor/tomb0 FLOOR_ZOT_RED
-floor/tomb1
-floor/tomb2
-floor/tomb3
-
-wall/zot_yellow0 WALL_ZOT_YELLOW
-wall/zot_yellow1
-wall/zot_yellow2
-wall/zot_yellow3
-floor/tomb0 FLOOR_ZOT_YELLOW
-floor/tomb1
-floor/tomb2
-floor/tomb3
-
-wall/wall_flesh0 WALL_FLESH
-wall/wall_flesh1
-wall/wall_flesh2
-wall/wall_flesh3
-wall/wall_flesh4
-wall/wall_flesh5
-wall/wall_flesh6
-
-floor/floor_nerves0 FLOOR_NERVES
-floor/floor_nerves1
-floor/floor_nerves2
-floor/floor_nerves3
-floor/floor_nerves4
-floor/floor_nerves5
-floor/floor_nerves6
-
-wall/wall_vines0 WALL_VINES
-wall/wall_vines1
-wall/wall_vines2
-wall/wall_vines3
-wall/wall_vines4
-wall/wall_vines5
-wall/wall_vines6
-
-floor/floor_vines0 FLOOR_VINES
-floor/floor_vines1
-floor/floor_vines2
-floor/floor_vines3
-floor/floor_vines4
-floor/floor_vines5
-floor/floor_vines6
-
-wall/pebble_red0 WALL_PEBBLE_RED
-wall/pebble_red1
-wall/pebble_red2
-wall/pebble_red3
-
-floor/rough_red0 FLOOR_ROUGH_RED
-floor/rough_red1
-floor/rough_red2
-floor/rough_red3
-
-floor/floor_sand_stone0 FLOOR_SAND_STONE
-floor/floor_sand_stone1
-floor/floor_sand_stone2
-floor/floor_sand_stone3
-floor/floor_sand_stone4
-floor/floor_sand_stone5
-floor/floor_sand_stone6
-floor/floor_sand_stone7
-
-wall/wall_yellow_rock0 WALL_YELLOW_ROCK
-wall/wall_yellow_rock1
-wall/wall_yellow_rock2
-wall/wall_yellow_rock3
-
-wall/brick_gray0 WALL_BAZAAR_GRAY
-wall/brick_gray1
-wall/brick_gray2
-wall/brick_gray3
-
-wall/stone_gray0 WALL_BAZAAR_STONE
-wall/stone_gray1
-wall/stone_gray2
-wall/stone_gray3
-
-floor/grass0 FLOOR_BAZAAR_GRASS
-floor/grass1
-floor/grass2
-
-floor/grass_n FLOOR_BAZAAR_GRASS1_SPECIAL
-floor/grass_ne
-floor/grass_e
-floor/grass_se
-floor/grass_s
-floor/grass_sw
-floor/grass_w
-floor/grass_nw
-floor/grass_full
-
-%start
-%compose floor/grass0
-%compose floor/pedestal_n
-%finish FLOOR_BAZAAR_GRASS2_SPECIAL
-%start
-%compose floor/grass1
-%compose floor/pedestal_ne
-%finish
-%start
-%compose floor/grass2
-%compose floor/pedestal_e
-%finish
-%start
-%compose floor/grass1
-%compose floor/pedestal_se
-%finish
-%start
-%compose floor/grass0
-%compose floor/pedestal_s
-%finish
-%start
-%compose floor/grass1
-%compose floor/pedestal_sw
-%finish
-%start
-%compose floor/grass2
-%compose floor/pedestal_w
-%finish
-%start
-%compose floor/grass0
-%compose floor/pedestal_nw
-%finish
-floor/pedestal_full
-
-%start
-%compose floor/rect_gray0
-%compose floor/pedestal_n
-%finish FLOOR_BAZAAR_VAULT_SPECIAL
-%start
-%compose floor/rect_gray1
-%compose floor/pedestal_ne
-%finish
-%start
-%compose floor/rect_gray2
-%compose floor/pedestal_e
-%finish
-%start
-%compose floor/rect_gray3
-%compose floor/pedestal_se
-%finish
-%start
-%compose floor/rect_gray2
-%compose floor/pedestal_s
-%finish
-%start
-%compose floor/rect_gray1
-%compose floor/pedestal_sw
-%finish
-%start
-%compose floor/rect_gray0
-%compose floor/pedestal_w
-%finish
-%start
-%compose floor/rect_gray3
-%compose floor/pedestal_nw
-%finish
-floor/pedestal_full
-
-floor/dirt0 FLOOR_BAZAAR_DIRT
-floor/dirt1
-floor/dirt2
-
-floor/dirt_n FLOOR_BAZAAR_DIRT_SPECIAL
-floor/dirt_ne
-floor/dirt_e
-floor/dirt_se
-floor/dirt_s
-floor/dirt_sw
-floor/dirt_w
-floor/dirt_nw
-floor/dirt_full
-
+%enumprefix DNGN_ +%tiledef tiledef-dngn.h +%tilecount tilecount-dngn.h +%width 16 +%back none +%name dngn + +%sdir dc-dngn + +dngn_unseen DNGN_UNSEEN + + +wall/brick_brown0 WALL_NORMAL +wall/brick_brown1 +wall/brick_brown2 +wall/brick_brown3 +floor/pebble_gray0 FLOOR_NORMAL +floor/pebble_gray1 +floor/pebble_gray2 +floor/pebble_gray3 +floor/pebble_gray4 + +wall/relief0 WALL_HALL +wall/relief1 +wall/relief2 +wall/relief3 +floor/mesh0 FLOOR_HALL +floor/mesh1 +floor/mesh2 +floor/mesh3 + +wall/hive0 WALL_HIVE +wall/hive1 +wall/hive2 +wall/hive3 +floor/hive0 FLOOR_HIVE +floor/hive1 +floor/hive2 +floor/hive3 + +wall/ice0 WALL_ICE +wall/ice1 +wall/ice2 +wall/ice3 +floor/ice0 FLOOR_ICE +floor/ice1 +floor/ice2 +floor/ice3 + +wall/lair0 WALL_LAIR +wall/lair1 +wall/lair2 +wall/lair3 +floor/lair0 FLOOR_LAIR +floor/lair1 +floor/lair2 +floor/lair3 + +## orcs don't have their own floor or walls yet... +wall/lair0 WALL_ORC +wall/lair1 +wall/lair2 +wall/lair3 +floor/hive0 FLOOR_ORC +floor/hive1 +floor/hive2 +floor/hive3 + +wall/slime0 WALL_SLIME +wall/slime1 +wall/slime2 +wall/slime3 +floor/bog_green0 FLOOR_SLIME +floor/bog_green1 +floor/bog_green2 +floor/bog_green3 + +wall/snake0 WALL_SNAKE +wall/snake1 +wall/snake2 +wall/snake3 +floor/snake0 FLOOR_SNAKE +floor/snake1 +floor/snake2 +floor/snake3 + +## swamp also doesn't have any unique walls... +wall/lair0 WALL_SWAMP +wall/lair1 +wall/lair2 +wall/lair3 +floor/swamp0 FLOOR_SWAMP +floor/swamp1 +floor/swamp2 +floor/swamp3 + +wall/tomb0 WALL_TOMB +wall/tomb1 +wall/tomb2 +wall/tomb3 +floor/tomb0 FLOOR_TOMB +floor/tomb1 +floor/tomb2 +floor/tomb3 + +wall/vault0 WALL_VAULT +wall/vault1 +wall/vault2 +wall/vault3 +floor/rect_gray0 FLOOR_VAULT +floor/rect_gray1 +floor/rect_gray2 +floor/rect_gray3 + +wall/zot_blue0 WALL_ZOT_BLUE +wall/zot_blue1 +wall/zot_blue2 +wall/zot_blue3 + +wall/zot_cyan0 WALL_ZOT_CYAN +wall/zot_cyan1 +wall/zot_cyan2 +wall/zot_cyan3 + +wall/zot_gray0 WALL_ZOT_GRAY +wall/zot_gray1 +wall/zot_gray2 +wall/zot_gray3 + +wall/zot_green0 WALL_ZOT_GREEN +wall/zot_green1 +wall/zot_green2 +wall/zot_green3 + +wall/zot_magenta0 WALL_ZOT_MAGENTA +wall/zot_magenta1 +wall/zot_magenta2 +wall/zot_magenta3 + +wall/zot_red0 WALL_ZOT_RED +wall/zot_red1 +wall/zot_red2 +wall/zot_red3 + +wall/zot_yellow0 WALL_ZOT_YELLOW +wall/zot_yellow1 +wall/zot_yellow2 +wall/zot_yellow3 + +wall/wall_flesh0 WALL_FLESH +wall/wall_flesh1 +wall/wall_flesh2 +wall/wall_flesh3 +wall/wall_flesh4 +wall/wall_flesh5 +wall/wall_flesh6 + +wall/wall_vines0 WALL_VINES +wall/wall_vines1 +wall/wall_vines2 +wall/wall_vines3 +wall/wall_vines4 +wall/wall_vines5 +wall/wall_vines6 + +floor/floor_vines0 FLOOR_VINES +floor/floor_vines1 +floor/floor_vines2 +floor/floor_vines3 +floor/floor_vines4 +floor/floor_vines5 +floor/floor_vines6 + +wall/pebble_red0 WALL_PEBBLE_RED +wall/pebble_red1 +wall/pebble_red2 +wall/pebble_red3 + +floor/rough_red0 FLOOR_ROUGH_RED +floor/rough_red1 +floor/rough_red2 +floor/rough_red3 + +floor/floor_sand_stone0 FLOOR_SAND_STONE +floor/floor_sand_stone1 +floor/floor_sand_stone2 +floor/floor_sand_stone3 +floor/floor_sand_stone4 +floor/floor_sand_stone5 +floor/floor_sand_stone6 +floor/floor_sand_stone7 + +wall/wall_yellow_rock0 WALL_YELLOW_ROCK +wall/wall_yellow_rock1 +wall/wall_yellow_rock2 +wall/wall_yellow_rock3 + +wall/brick_gray0 WALL_BAZAAR_GRAY +wall/brick_gray1 +wall/brick_gray2 +wall/brick_gray3 + +wall/stone_gray0 WALL_BAZAAR_STONE +wall/stone_gray1 +wall/stone_gray2 +wall/stone_gray3 + +floor/grass0 FLOOR_BAZAAR_GRASS +floor/grass1 +floor/grass2 + +floor/grass_n FLOOR_BAZAAR_GRASS1_SPECIAL +floor/grass_ne +floor/grass_e +floor/grass_se +floor/grass_s +floor/grass_sw +floor/grass_w +floor/grass_nw +floor/grass_full + +## NOTE: wall_undead and floor_nerves are used for the corruption effect. +## They need to go last. +wall/undead0 WALL_UNDEAD +wall/undead1 +wall/undead2 +wall/undead3 + +floor/floor_nerves0 FLOOR_NERVES +floor/floor_nerves1 +floor/floor_nerves2 +floor/floor_nerves3 +floor/floor_nerves4 +floor/floor_nerves5 +floor/floor_nerves6 + +%start +%compose floor/grass0 +%compose floor/pedestal_n +%finish FLOOR_BAZAAR_GRASS2_SPECIAL +%start +%compose floor/grass1 +%compose floor/pedestal_ne +%finish +%start +%compose floor/grass2 +%compose floor/pedestal_e +%finish +%start +%compose floor/grass1 +%compose floor/pedestal_se +%finish +%start +%compose floor/grass0 +%compose floor/pedestal_s +%finish +%start +%compose floor/grass1 +%compose floor/pedestal_sw +%finish +%start +%compose floor/grass2 +%compose floor/pedestal_w +%finish +%start +%compose floor/grass0 +%compose floor/pedestal_nw +%finish +floor/pedestal_full + +%start +%compose floor/rect_gray0 +%compose floor/pedestal_n +%finish FLOOR_BAZAAR_VAULT_SPECIAL +%start +%compose floor/rect_gray1 +%compose floor/pedestal_ne +%finish +%start +%compose floor/rect_gray2 +%compose floor/pedestal_e +%finish +%start +%compose floor/rect_gray3 +%compose floor/pedestal_se +%finish +%start +%compose floor/rect_gray2 +%compose floor/pedestal_s +%finish +%start +%compose floor/rect_gray1 +%compose floor/pedestal_sw +%finish +%start +%compose floor/rect_gray0 +%compose floor/pedestal_w +%finish +%start +%compose floor/rect_gray3 +%compose floor/pedestal_nw +%finish +floor/pedestal_full + +floor/dirt0 FLOOR_BAZAAR_DIRT +floor/dirt1 +floor/dirt2 + +floor/dirt_n FLOOR_BAZAAR_DIRT_SPECIAL +floor/dirt_ne +floor/dirt_e +floor/dirt_se +floor/dirt_s +floor/dirt_sw +floor/dirt_w +floor/dirt_nw +floor/dirt_full + +floor/lava0 DNGN_LAVA +floor/lava1 +floor/lava2 +floor/lava3 +dngn_deep_water DNGN_DEEP_WATER +dngn_deep_water +dngn_deep_water +dngn_deep_water +dngn_shallow_water DNGN_SHALLOW_WATER +dngn_shallow_water +dngn_shallow_water +dngn_shallow_water + +wall/stone2_gray0 DNGN_STONE_WALL +wall/stone2_gray1 +wall/stone2_gray2 +wall/stone2_gray3 +dngn_metal_wall DNGN_METAL_WALL +dngn_green_crystal_wall DNGN_GREEN_CRYSTAL_WALL + +dngn_wax_wall DNGN_WAX_WALL +dngn_transparent_wall DNGN_TRANSPARENT_WALL + +dngn_closed_door DNGN_CLOSED_DOOR +gate_closed_left DNGN_GATE_CLOSED_LEFT +gate_closed_middle DNGN_GATE_CLOSED_MIDDLE +gate_closed_right DNGN_GATE_CLOSED_RIGHT +dngn_open_door DNGN_OPEN_DOOR +gate_open_left DNGN_GATE_OPEN_LEFT +gate_open_middle DNGN_GATE_OPEN_MIDDLE +gate_open_right DNGN_GATE_OPEN_RIGHT +dngn_orcish_idol DNGN_ORCISH_IDOL +dngn_silver_statue DNGN_SILVER_STATUE +dngn_granite_statue DNGN_GRANITE_STATUE + +%rim 1 +dngn_enter_hell DNGN_ENTER_HELL +%rim 0 +dngn_branch_stairs DNGN_BRANCH_STAIRS +dngn_trap_dart DNGN_TRAP_DART +dngn_trap_arrow DNGN_TRAP_ARROW +dngn_trap_spear DNGN_TRAP_SPEAR +dngn_trap_axe DNGN_TRAP_AXE +dngn_trap_teleport DNGN_TRAP_TELEPORT +dngn_trap_alarm DNGN_TRAP_ALARM +dngn_trap_blade DNGN_TRAP_BLADE +dngn_trap_bolt DNGN_TRAP_BOLT +dngn_trap_net DNGN_TRAP_NET +dngn_trap_zot DNGN_TRAP_ZOT +dngn_trap_needle DNGN_TRAP_NEEDLE +dngn_trap_shaft DNGN_TRAP_SHAFT +stone_stairs_down DNGN_STONE_STAIRS_DOWN +rock_stairs_down DNGN_ROCK_STAIRS_DOWN +stone_stairs_up DNGN_STONE_STAIRS_UP +rock_stairs_up DNGN_ROCK_STAIRS_UP + +dngn_enter_shop DNGN_ENTER_SHOP +dngn_enter_labyrinth DNGN_ENTER_LABYRINTH +dngn_enter_dis DNGN_ENTER_DIS +dngn_enter_gehenna DNGN_ENTER_GEHENNA +dngn_enter_cocytus DNGN_ENTER_COCYTUS +dngn_enter_tartarus DNGN_ENTER_TARTARUS + +dngn_enter_abyss DNGN_ENTER_ABYSS +dngn_exit DNGN_EXIT_ABYSS + +dngn_stone_arch DNGN_STONE_ARCH +dngn_enter_pandemonium DNGN_ENTER_PANDEMONIUM +dngn_exit DNGN_EXIT_PANDEMONIUM +%rim 1 +dngn_transit_pandemonium DNGN_TRANSIT_PANDEMONIUM +%rim 0 +dngn_enter DNGN_ENTER +%rim 1 +dngn_return DNGN_RETURN +%rim 0 +dngn_altar_zin DNGN_ALTAR_ZIN +dngn_altar_shining_one DNGN_ALTAR_SHINING_ONE +dngn_altar_kikubaaqudgha DNGN_ALTAR_KIKUBAAQUDGHA +dngn_altar_yredelemnul DNGN_ALTAR_YREDELEMNUL +dngn_altar_xom DNGN_ALTAR_XOM +dngn_altar_vehumet DNGN_ALTAR_VEHUMET +dngn_altar_okawaru DNGN_ALTAR_OKAWARU +dngn_altar_makhleb DNGN_ALTAR_MAKHLEB +dngn_altar_sif_muna DNGN_ALTAR_SIF_MUNA +dngn_altar_trog DNGN_ALTAR_TROG +dngn_altar_nemelex_xobeh DNGN_ALTAR_NEMELEX_XOBEH +dngn_altar_elyvilon DNGN_ALTAR_ELYVILON +dngn_altar_lugonu DNGN_ALTAR_LUGONU +dngn_altar_beogh DNGN_ALTAR_BEOGH +dngn_blue_fountain DNGN_BLUE_FOUNTAIN +dngn_sparkling_fountain DNGN_SPARKLING_FOUNTAIN +dngn_blood_fountain DNGN_BLOOD_FOUNTAIN +dngn_dry_fountain DNGN_DRY_FOUNTAIN + +## Miscellaneous entries that get drawn on the background +dc-misc/blood_red BLOOD +dc-misc/blood_red1 +dc-misc/blood_red2 +dc-misc/blood_red3 +dc-misc/blood_red4 +dc-misc/halo HALO +dc-misc/ray RAY_MESH +dc-misc/travel_exclusion TRAVEL_EXCLUSION_BG +dc-misc/travel_exclusion_centre TRAVEL_EXCLUSION_CENTRE_BG +dc-misc/slot ITEM_SLOT +effect/sanctuary SANCTUARY diff --git a/crawl-ref/source/rltiles/license.txt b/crawl-ref/source/rltiles/license.txt index 7b9526fccf..3c350d53f7 100644 --- a/crawl-ref/source/rltiles/license.txt +++ b/crawl-ref/source/rltiles/license.txt @@ -1,17 +1,11 @@ Part of the graphic tiles used in this program are from the public -domain roguelike tileset "RLTiles". - -Some of the tiles have been modified by Enne Walker (enne.walker@gmail.com) +domain roguelike tileset "RLTiles". Some of the tiles have been modified. You can find the original tileset at: http://rltiles.sf.net - - Part of the source code used in this program is from the public -domain program "RLTiles". - -Some of the source code has been modified by Enne Walker (enne.walker@gmail.com) +domain program "RLTiles". Some of the source code has been modified. You can find the original source code at: http://sourceforge.net/projects/rltiles/ diff --git a/crawl-ref/source/rltiles/makefile.mgw b/crawl-ref/source/rltiles/makefile.mgw index 040110d4e7..a0e1cfb9f8 100644 --- a/crawl-ref/source/rltiles/makefile.mgw +++ b/crawl-ref/source/rltiles/makefile.mgw @@ -32,8 +32,8 @@ HEADERS = \ tiledef.h \ tiledef-p.h \ tilep-cmt.h \ -tiledef-w2d.h \ -tilecount-w2d.h \ +tiledef-dngn.h \ +tilecount-dngn.h \ map.htm ALLTOOLS = $(TOOLS) $(EXTRATOOLS) @@ -41,7 +41,7 @@ ALLTOOLS = $(TOOLS) $(EXTRATOOLS) GENERATEDBMP = \ tile.bmp \ player.bmp \ -wall2d.bmp +dngn.bmp TILEBMP = \ $(GENERATEDBMP) \ @@ -57,7 +57,7 @@ all: tools tiles tools: $(TOOLS) -tiles: $(TILEBMP) +tiles: $(TILEBMP) $(TILEPNG) ########################################################################## # Tools @@ -96,15 +96,15 @@ tile.bmp: dc-2d.txt dctile.exe player.bmp: dc-pl.txt dcpl.exe ./dcpl dc-pl.txt -wall2d.bmp: dc-wall2d.txt dctile.exe - ./dctile dc-wall2d.txt +dngn.bmp: dngn.txt dctile.exe + ./dctile dngn.txt ########################################################################## # PNG Conversion # $(B2PTOOL): - pushd $(B2PSRC) && $(MAKE) -f makefile.mgw $(B2P) && popd + pushd $(B2PSRC) && $(MAKE) -f makefile.lin $(B2P) && popd %.png: %.bmp $(B2PTOOL) $(DELETE) $@ diff --git a/crawl-ref/source/rltiles/makefile.unix b/crawl-ref/source/rltiles/makefile.unix index 1fb2efe23e..33d3a6b6e2 100644 --- a/crawl-ref/source/rltiles/makefile.unix +++ b/crawl-ref/source/rltiles/makefile.unix @@ -31,8 +31,8 @@ HEADERS = \ tiledef.h \ tiledef-p.h \ tilep-cmt.h \ -tiledef-w2d.h \ -tilecount-w2d.h \ +tiledef-dngn.h \ +tilecount-dngn.h \ map.htm ALLTOOLS = $(TOOLS) $(EXTRATOOLS) @@ -40,7 +40,7 @@ ALLTOOLS = $(TOOLS) $(EXTRATOOLS) GENERATEDBMP = \ tile.bmp \ player.bmp \ -wall2d.bmp +dngn.bmp TILEBMP = \ $(GENERATEDBMP) \ @@ -90,6 +90,9 @@ dcreverse: $(SRC)dcreverse.o $(SRC)bm.o # and then output the .bmp and .txt dependencies for it. It's kind # of a low priority though, as tiles will be rebuilt infrequently. +dngn.bmp: dngn.txt dctile + ./dctile dngn.txt + tile.bmp: dc-2d.txt dctile ./dctile dc-2d.txt diff --git a/crawl-ref/source/rltiles/tool/dctile.c b/crawl-ref/source/rltiles/tool/dctile.c index 4bc2c0af9e..a6e01210b4 100644 --- a/crawl-ref/source/rltiles/tool/dctile.c +++ b/crawl-ref/source/rltiles/tool/dctile.c @@ -12,7 +12,7 @@ FILE *cfp=NULL; // lengths of tile counts int tilecount = 0; int tilecountidx = -1; int counts[1024]; -int countnames[100][100]; +int countnames[512][100]; char outname[1024], ctgname[100], subsname[100]; char sdir[300]; @@ -379,7 +379,6 @@ void process_config(char *fname) } fprintf(cfp,"/* Automatically generated by tile generator. */\n"); fprintf(cfp,"#include \"%s\"\n", tiledefname); - fprintf(cfp, "enum TILE_%sCOUNT_IDX {\n", enumprefix); continue; } @@ -553,8 +552,7 @@ void process_config(char *fname) tilecountidx++; else counts[tilecountidx++] = tilecount; - fprintf(cfp, " IDX_%s,\n",st); - sprintf(countnames[tilecountidx], "TILE_%s", st); + sprintf(countnames[tilecountidx], "%s", st); tilecount = 1; } } @@ -603,13 +601,6 @@ char *argv[]; strcpy(fn,argv[1]); process_config(fn); - if (sfp) - { - fprintf(sfp, "TILE_%sTOTAL};\n\n", enumprefix); - fprintf(sfp,"#define TILE_%sPER_ROW %d\n", enumprefix, xx0); - fclose(sfp); - } - if(mfp) { fprintf(mfp,"</map>\n<img src=%s usemap=\"#nhmap\" >\n", imgname); @@ -617,14 +608,28 @@ char *argv[]; fclose(mfp); } + if (sfp) + { + fprintf(sfp, "TILE_%sTOTAL};\n\n", enumprefix); + fprintf(sfp,"#define TILE_%sPER_ROW %d\n", enumprefix, xx0); + } + if (cfp) { int i; - fprintf(cfp, " IDX_%sTOTAL\n};\n\n", enumprefix); - counts[tilecountidx++] = tilecount; + fprintf(sfp, "\n\n"); + fprintf(sfp, "enum TILE_%sCOUNT_IDX {\n", enumprefix); + for (i = 0; i < tilecountidx; i++) + { + fprintf(sfp, " IDX_%s,\n", countnames[i]); + } + fprintf(sfp, " IDX_%sTOTAL\n};\n\n", enumprefix); + fprintf(sfp, "extern int tile_%scount[IDX_%sTOTAL];\n", enumprefix, enumprefix); + fprintf(sfp, "extern int tile_%sstart[IDX_%sTOTAL];\n\n", enumprefix, enumprefix); + fprintf(cfp, "int tile_%scount[IDX_%sTOTAL] =\n{\n", enumprefix, enumprefix); @@ -641,7 +646,7 @@ char *argv[]; for (i = 0; i < tilecountidx; i++) { - fprintf(cfp, (i < tilecountidx - 1) ? " %s,\n" : " %s\n", + fprintf(cfp, (i < tilecountidx - 1) ? " TILE_%s,\n" : " TILE_%s\n", countnames[i]); } @@ -649,6 +654,11 @@ char *argv[]; close(cfp); } + if (sfp) + { + fclose(sfp); + } + if(tfp) { fclose(tfp); diff --git a/crawl-ref/source/stuff.cc b/crawl-ref/source/stuff.cc index 3406decaa9..61784732d7 100644 --- a/crawl-ref/source/stuff.cc +++ b/crawl-ref/source/stuff.cc @@ -638,9 +638,7 @@ void cio_init() { crawl_state.io_inited = true; -#if defined(USE_TILE) - libgui_init(); -#elif defined(UNIX) +#if defined(UNIX) && !defined(USE_TILE) unixcurses_startup(); #endif @@ -654,6 +652,10 @@ void cio_init() crawl_view.init_geometry(); +#ifdef USE_TILE + tiles.resize(); +#endif + if (Options.char_set == CSET_UNICODE && !crawl_state.unicode_ok) { crawl_state.add_startup_error( @@ -668,7 +670,7 @@ void cio_cleanup() return; #if defined(USE_TILE) - libgui_shutdown(); + tiles.shutdown(); #elif defined(UNIX) unixcurses_shutdown(); #endif diff --git a/crawl-ref/source/tags.cc b/crawl-ref/source/tags.cc index ea38dd05b1..8fa1ecd72e 100644 --- a/crawl-ref/source/tags.cc +++ b/crawl-ref/source/tags.cc @@ -1928,9 +1928,9 @@ void tag_construct_level_tiles(writer &th) for (int count_x = 0; count_x < GXM; count_x++) for (int count_y = 0; count_y < GYM; count_y++) { - marshallByte(th, env.tile_flavor[count_x][count_y].wall); - marshallByte(th, env.tile_flavor[count_x][count_y].floor); - marshallByte(th, env.tile_flavor[count_x][count_y].special); + marshallByte(th, env.tile_flv[count_x][count_y].wall); + marshallByte(th, env.tile_flv[count_x][count_y].floor); + marshallByte(th, env.tile_flv[count_x][count_y].special); } #endif @@ -2243,9 +2243,9 @@ void tag_read_level_tiles(struct reader &th) for (int x = 0; x < gx; x++) for (int y = 0; y < gy; y++) { - env.tile_flavor[x][y].wall = unmarshallByte(th); - env.tile_flavor[x][y].floor = unmarshallByte(th); - env.tile_flavor[x][y].special = unmarshallByte(th); + env.tile_flv[x][y].wall = unmarshallByte(th); + env.tile_flv[x][y].floor = unmarshallByte(th); + env.tile_flv[x][y].special = unmarshallByte(th); } #endif diff --git a/crawl-ref/source/tile2.cc b/crawl-ref/source/tile2.cc index e66ae39e74..79be158bc0 100644 --- a/crawl-ref/source/tile2.cc +++ b/crawl-ref/source/tile2.cc @@ -18,7 +18,7 @@ #include "dungeon.h" #include "files.h" #include "ghost.h" -#include "guic.h" +#include "tilereg.h" #include "itemprop.h" #include "it_use2.h" #include "place.h" @@ -26,76 +26,9 @@ #include "spells3.h" #include "stuff.h" #include "tiles.h" -#include "tilecount-w2d.h" -#include "tiledef-p.h" +#include "tilecount-dngn.h" #include "transfor.h" -// normal tile count + iso tile count -#define TILE_TOTAL2 (TILE_TOTAL) -// normal tile count -#define TILE_NORMAL TILE_TOTAL - -extern void TileDrawDungeonAux(); - -// Raw tile images -extern img_type TileImg; -extern img_type PlayerImg; -extern img_type WallImg; -extern img_type ScrBufImg; - -extern WinClass *win_main; -// Regions -extern TileRegionClass *region_tile; -extern TextRegionClass *region_crt; -extern TextRegionClass *region_stat; -extern TextRegionClass *region_tip; -extern TextRegionClass *region_msg; - -extern TileRegionClass *region_item; -extern TileRegionClass *region_item2; - -#define ScrBufImg (region_tile->backbuf) - -//Internal -static img_type DollCacheImg; - -static void _tile_draw_grid(int xx, int yy); -static void _clear_tcache(); -static void _init_tcache(); -static void _register_tile_mask(int tile, int *cp, - char *ms, bool smalltile = false); -static void _tcache_compose_normal(int ix, int *fg, int *bg); - -static void _mcache_init(); - -//Internal variables - -static bool force_redraw_tile = false; -static bool force_redraw_inv = false; - -void tile_set_force_redraw_tiles(bool redraw) -{ - force_redraw_tile = redraw; -} - -void tile_set_force_redraw_inv(bool redraw) -{ - force_redraw_inv = redraw; -} - -static unsigned int t1buf[TILE_DAT_XMAX+2][TILE_DAT_YMAX+2], - t2buf[TILE_DAT_XMAX+2][TILE_DAT_YMAX+2]; -static unsigned int tb_bk[TILE_DAT_YMAX*TILE_DAT_XMAX*2]; - -#define MAX_ITEMLIST 200 -int itemlist[MAX_ITEMLIST]; -int itemlist_num[MAX_ITEMLIST]; -int itemlist_idx[MAX_ITEMLIST]; -char itemlist_key[MAX_ITEMLIST]; -int itemlist_iflag[MAX_ITEMLIST]; -int itemlist_flag = -1; -int itemlist_n = 0; - static int wall_flavors = 0; static int floor_flavors = 0; static int special_flavors = 0; @@ -133,796 +66,13 @@ int get_floor_special_tile_idx() return special_tile_idx; } -/******** Cache buffer for transparency operation *****/ -static int last_cursor = -1; - -//Internal cache Image buffer -static img_type tcache_image = 0; - -//Start of a pointer string -static int tcache_head; - -typedef struct tile_cache -{ - unsigned int id[2]; - int idx; - tile_cache *next; - tile_cache *prev; -} tile_cache; - -// number of tile grids -static int tile_xmax; -static int tile_ymax; - -static int max_tcache; -// [max_tcache] -static tile_cache *tcache; -// [x*y] -static int *screen_tcache_idx; - -const int tcache_wx_normal = TILE_X; -const int tcache_wy_normal = TILE_Y; -const int tcache_ox_normal = 0; -const int tcache_oy_normal = 0; -const int tcache_nlayer_normal = 1; - -const int region_sx_normal = 0; -const int region_sy_normal = 0; -const int region_wx_normal = TILE_X; -const int region_wy_normal = TILE_Y; - -// ISO mode sink mask -static char *sink_mask; - -/********* Image manipulation subroutines ****************/ -img_type ImgLoadFileSimple(const char *name) -{ - char fname[512]; -#ifdef USE_X11 - sprintf(fname,"tiles/%s.png", name); - std::string path = datafile_path(fname, true, true); - return ImgLoadFile(path.c_str()); -#endif -#ifdef WIN32TILES - sprintf(fname,"tiles/%s.bmp", name); - std::string path = datafile_path(fname, true, true); - return ImgLoadFile(path.c_str()); -#endif -} - -// TileImg macro -void _ImgCopyFromTileImg(int idx, img_type dest, int dx, int dy, int copy, - char *mask = NULL, bool hilite = false) -{ - int sx = (idx % TILE_PER_ROW)*TILE_X; - int sy = (idx / TILE_PER_ROW)*TILE_Y; - if (hilite) - { - if (mask != NULL) - ImgCopyMaskedH(TileImg, sx, sy, TILE_X, TILE_Y, - dest, dx, dy, mask); - else - ImgCopyH(TileImg, sx, sy, TILE_X, TILE_Y, dest, dx, dy, copy); - } - else - { - if (mask != NULL) - ImgCopyMasked(TileImg, sx, sy, TILE_X, TILE_Y, - dest, dx, dy, mask); - else - ImgCopy(TileImg, sx, sy, TILE_X, TILE_Y, dest, dx, dy, copy); - } -} - -static void _ImgCopyToTileImg(int idx, img_type src, int sx, int sy, int copy, - char *mask = NULL, bool hilite = false) -{ - int dx = (idx % TILE_PER_ROW)*TILE_X; - int dy = (idx / TILE_PER_ROW)*TILE_Y; - if (hilite) - { - if (mask != NULL) - ImgCopyMaskedH(src, sx, sy, TILE_X, TILE_Y, - TileImg, dx, dy, mask); - else - ImgCopyH(src, sx, sy, TILE_X, TILE_Y, TileImg, dx, dy, copy); - } - else - { - if (mask != NULL) - ImgCopyMasked(src, sx, sy, TILE_X, TILE_Y, - TileImg, dx, dy, mask); - else - ImgCopy(src, sx, sy, TILE_X, TILE_Y, TileImg, dx, dy, copy); - } -} - -void TileInit() -{ - textcolor(WHITE); - - TileImg = ImgLoadFileSimple("tile"); - PlayerImg = ImgLoadFileSimple("player"); - WallImg = ImgLoadFileSimple("wall2d"); - - - if (!TileImg) - { - cprintf("Main tile not initialized\n"); - getch(); - end(-1); - } - - ImgSetTransparentPix(TileImg); - - if (ImgWidth(TileImg)!= TILE_X * TILE_PER_ROW - || ImgHeight(TileImg) < - TILE_Y * ((TILE_TOTAL + TILE_PER_ROW -1)/TILE_PER_ROW) ) - { - cprintf("Main tile size invalid\n"); - getch(); - end(-1); - } - - if (!PlayerImg) - { - cprintf("Player tile not initialized\n"); - getch(); - end(-1); - } - - if (ImgWidth(PlayerImg)!= TILE_X * TILEP_PER_ROW) - { - cprintf("Player tile size invalid\n"); - getch(); - end(-1); - } - - if (!WallImg) - { - cprintf("wall2d tile not initialized\n"); - getch(); - end(-1); - } - - tile_xmax = tile_dngn_x; - tile_ymax = tile_dngn_y; - - max_tcache = 4*tile_xmax*tile_ymax; - - screen_tcache_idx = (int *)malloc(sizeof(int)* tile_xmax * tile_ymax); - tcache = (tile_cache *)malloc(sizeof(tile_cache)*max_tcache); - for (int x = 0; x < tile_xmax * tile_ymax; x++) - screen_tcache_idx[x] = -1; - - sink_mask = (char *)malloc(TILE_X*TILE_Y); - - _init_tcache(); - - DollCacheImg = ImgCreateSimple(TILE_X, TILE_Y); - - for (int x = 0; x < TILE_DAT_XMAX + 2; x++) - { - for (int y = 0; y < TILE_DAT_YMAX + 2; y++) - { - t1buf[x][y] = 0; - t2buf[x][y] = TILE_DNGN_UNSEEN|TILE_FLAG_UNSEEN; - } - } - - force_redraw_tile = false; - - _mcache_init(); - - for (int x = 0; x < MAX_ITEMLIST; x++) - itemlist[x] = itemlist_num[x] = itemlist_key[x] = itemlist_idx[x] = 0; -} - -void TileResizeScreen(int x0, int y0) -{ - tile_xmax = x0; - tile_ymax = y0; - max_tcache = 4*tile_xmax*tile_ymax; - - free(screen_tcache_idx); - screen_tcache_idx = (int *)malloc(sizeof(int)* tile_xmax * tile_ymax); - - free(tcache); - tcache = (tile_cache *)malloc(sizeof(tile_cache)*max_tcache); - - for (int x = 0; x < tile_xmax * tile_ymax; x++) - screen_tcache_idx[x] = -1; - _init_tcache(); - - crawl_view.viewsz.x = tile_xmax; - crawl_view.viewsz.y = tile_ymax; - crawl_view.vbuf.size(crawl_view.viewsz); -} - -void _clear_tcache() -{ - tcache_head = 0; - - for (int i = 0; i < max_tcache; i++) - { - tcache[i].id[1] = tcache[i].id[0] = 0; - tcache[i].idx = i; - if (i == 0) - tcache[i].prev = NULL; - else - tcache[i].prev = &tcache[i-1]; - - if (i == max_tcache - 1) - tcache[i].next = NULL; - else - tcache[i].next = &tcache[i+1]; - } -} - -void _init_tcache() -{ - _clear_tcache(); - ImgDestroy(tcache_image); - tcache_image = ImgCreateSimple(tcache_wx_normal, - max_tcache*tcache_wy_normal); -} - -// Move a cache to the top of pointer string -// to shorten the search time -static void _lift_tcache(int ix) -{ - int head_old = tcache_head; - tile_cache *p = tcache[ix].prev; - tile_cache *n = tcache[ix].next; - - ASSERT(ix < max_tcache); - ASSERT(head_old < max_tcache); - - if (ix == head_old) - return; - if (p!=NULL) - p->next = n; - if (n!=NULL) - n->prev = p; - - tcache_head = ix; - tcache[head_old].prev = &tcache[ix]; - tcache[ix].next = &tcache[head_old]; -} - -// Find cached image of fg+bg -// If not found, compose and cache it -static int _tcache_find_id_normal(int *fg, int *bg, int *is_new) -{ - tile_cache *tc0 = &tcache[tcache_head]; - *is_new = 0; - - while (true) - { - tile_cache *next = tc0->next; - - if ((int)tc0->id[0] == fg[0] && (int)tc0->id[1] == bg[0]) - break; - - if (next == NULL) - { - //end of used cache - *is_new = 1; - _tcache_compose_normal(tc0->idx, fg, bg); - tc0->id[0] = fg[0]; - tc0->id[1] = bg[0]; - break; - } - tc0 = next; - } - _lift_tcache(tc0->idx); - - return (tc0->idx); -} - - -// Overlay a tile onto an existing image with transparency operation. -static void _tcache_overlay(img_type img, int idx, int tile, - int *copy, char *mask, unsigned int shift_left = 0) -{ - - int x0, y0; - int sx = region_sx_normal + shift_left; - int sy = region_sy_normal; - int wx = region_wx_normal - shift_left; - int wy = region_wy_normal; - int ox = 0; - int oy = 0; - img_type src = TileImg; - int uy = wy; - - tile &= TILE_FLAG_MASK; - - x0 = (tile % TILE_PER_ROW) * TILE_X; - y0 = (tile / TILE_PER_ROW) * TILE_Y; - - if (mask != NULL) - { - if (*copy == 2) - { - ImgCopyMaskedH(src, x0 + sx, y0 + sy, wx, wy, - img, ox, oy + idx*uy, mask); - } - else - { - ImgCopyMasked(src, x0 + sx, y0 + sy, wx, wy, - img, ox, oy + idx*uy, mask); - } - } - // Hack: hilite rim color - else if (*copy == 2) - { - ImgCopyH(src, x0 + sx, y0 + sy, wx, wy, - img, ox, oy + idx*uy, *copy); - } - else - { - ImgCopy(src, x0 + sx, y0 + sy, wx, wy, - img, ox, oy + idx*uy, *copy); - } - *copy = 0; -} - -void _tcache_overlay_player(img_type img, int dx, int dy, int part, int idx, - int ymax, int *copy) -{ - int xs, ys; - int tidx = tilep_parts_start[part]; - int nx = tilep_parts_nx[part]; - int ny = tilep_parts_ny[part]; - int ox = tilep_parts_ox[part]; - int oy = tilep_parts_oy[part]; - int wx = TILE_X/nx; - int wy = TILE_Y/ny; - - if (!idx) - return; - - idx--; - tidx += idx/(nx*ny); - - if (oy+wy > ymax) - wy -= oy + wy - ymax; - - if (wy <= 0) - return; - - xs = (tidx % TILEP_PER_ROW)*TILE_X; - ys = (tidx / TILEP_PER_ROW)*TILE_Y; - - xs += (idx % nx)*(TILE_X/nx); - ys += ((idx/nx) % ny)*(TILE_Y/ny); - - ImgCopy(PlayerImg, xs, ys, wx, wy, - img, dx+ox, dy+oy, *copy); - - *copy = 0; -} - -/* overlay a tile onto an exsisting image with transpalency operation */ -void _register_tile_mask(int tile, int *copy, - char *mask, bool smalltile) -{ - int x0, y0, x, y; - int sx = region_sx_normal; - int sy = region_sy_normal; - int wx = region_wx_normal; - int wy = region_wy_normal; - int ox = 0; - int oy = 0; - int ux = wx; - int uy = wy; - img_type src = TileImg; - - tile &= TILE_FLAG_MASK; - - x0 = (tile % TILE_PER_ROW) * TILE_X; - y0 = (tile / TILE_PER_ROW) * TILE_Y; - - if (*copy != 0) - memset(mask, 0, ux*uy); - - if (*copy == 2) - { - if (smalltile) - ux = wx; - - for (x = 0; x < wx; x++) - for (y = 0; y < wy; y++) - { - if (!ImgIsTransparentAt(src, x0+sx+x, y0+sy+y)) - mask[(y+oy) * ux + (x+ox)] = 1; - } - } - else - { - for (x = 0; x < wx; x += 2) - { - for (y = 0; y < wy; y += 2) - { - if (!ImgIsTransparentAt(src, x0+sx+x, y0+sy+y)) - mask[(y+oy) * ux + (x+ox)] = 1; - } - } - } - *copy = 0; -} - -void _tile_draw_grid(int xx, int yy) -{ - int fg[4],bg[4],ix, ix_old, is_new; - - if (xx < 0 || yy < 0 || xx >= tile_xmax || yy>= tile_ymax) - return; - - fg[0] = t1buf[xx+1][yy+1]; - bg[0] = t2buf[xx+1][yy+1]; - - ix_old = screen_tcache_idx[xx+yy*tile_xmax]; - - ix = _tcache_find_id_normal(fg, bg, &is_new); - - screen_tcache_idx[xx+yy*tile_xmax] = ix; - - if (is_new || ix!=ix_old || force_redraw_tile) - { - int x_dest = tcache_ox_normal+xx* TILE_UX_NORMAL; - int y_dest = tcache_oy_normal+yy* TILE_UY_NORMAL; - int wx = tcache_wx_normal; - int wy = tcache_wy_normal; - ImgCopy(tcache_image, 0, ix*wy, wx, wy, ScrBufImg, x_dest, y_dest, 1); - } -} - -static void _update_single_grid(int x, int y) -{ - _tile_draw_grid(x, y); - - int sx = x*TILE_UX_NORMAL; - int sy = y*TILE_UY_NORMAL; - int wx = TILE_UX_NORMAL; - int wy = TILE_UY_NORMAL; - - region_tile->redraw(sx, sy, sx+wx-1, sy+wy-1); -} - - -// Discard cache containing specific tile -static void _redraw_spx_tcache(int tile) -{ - for (int idx = 0; idx < max_tcache; idx++) - { - int fg = tcache[idx].id[0]; - int bg = tcache[idx].id[1]; - if ((fg & TILE_FLAG_MASK) == tile - || (bg & TILE_FLAG_MASK) == tile) - { - _tcache_compose_normal(idx, &fg, &bg); - } - } -} - -static void _get_bbg(int bg, int *new_bg, int *bbg) -{ - int bg0 = bg & TILE_FLAG_MASK; - *bbg = TILE_DNGN_FLOOR; - *new_bg = bg0; - - if (bg0 == TILE_DNGN_UNSEEN || bg0 == 0 - || (bg0 >= TILE_DNGN_ROCK_WALL_OFS && bg0 < TILE_DNGN_WAX_WALL)) - { - *bbg = 0; - } - else if (bg0 >= TILE_DNGN_FLOOR && bg0 <= TILE_DNGN_SHALLOW_WATER) - { - *bbg = bg; - *new_bg = 0; - } -} - -static int _sink_mask_tile(int bg, int fg) -{ - int bg0 = bg & TILE_FLAG_MASK; - - if (fg == 0 || (fg & TILE_FLAG_FLYING) != 0) - return 0; - - if ( bg0 >= TILE_DNGN_LAVA && - bg0 <= TILE_DNGN_SHALLOW_WATER + 3) - { - return TILE_SINK_MASK; - } - - return 0; -} - -//normal -void _tcache_compose_normal(int ix, int *fg, int *bg) -{ - int bbg; - int new_bg; - int c = 1; - int fg0 = fg[0]; - int bg0 = bg[0]; - int sink; - - _get_bbg(bg0, &new_bg, &bbg); - - if (bbg) - _tcache_overlay(tcache_image, ix, bbg, &c, NULL); - - if (bg0 & TILE_FLAG_BLOOD) - _tcache_overlay(tcache_image, ix, TILE_BLOOD0 + ix % 5, &c, NULL); - - if (new_bg) - _tcache_overlay(tcache_image, ix, new_bg, &c, NULL); - - else if (bg0 & TILE_FLAG_HALO) - _tcache_overlay(tcache_image, ix, TILE_HALO, &c, NULL); - - if ((bg0 & TILE_FLAG_SANCTUARY) && !(bg0 & TILE_FLAG_UNSEEN)) - _tcache_overlay(tcache_image, ix, TILE_SANCTUARY, &c, NULL); - - // Apply the travel exclusion under the foreground if the cell is - // visible. It will be applied later if the cell is unseen. - if ((bg0 & TILE_FLAG_TRAV_EXCL) && !(bg0 & TILE_FLAG_UNSEEN)) - _tcache_overlay(tcache_image, ix, TILE_TRAVEL_EXCLUSION, &c, NULL); - else if ((bg0 & TILE_FLAG_EXCL_CTR) && !(bg0 & TILE_FLAG_UNSEEN)) - _tcache_overlay(tcache_image, ix, TILE_TRAVEL_EXCL_CENTRE, &c, NULL); - - if (bg0 & TILE_FLAG_RAY) - _tcache_overlay(tcache_image, ix, TILE_RAY_MESH, &c, NULL); - - if (fg0) - { - sink = _sink_mask_tile(bg0, fg0); - if (sink) - { - int flag = 2; - _register_tile_mask(sink, &flag, sink_mask); - _tcache_overlay(tcache_image, ix, fg0, &c, sink_mask); - } - else - _tcache_overlay(tcache_image, ix, fg0, &c, NULL); - } - - if (fg0 & TILE_FLAG_NET) - _tcache_overlay(tcache_image, ix, TILE_TRAP_NET, &c, NULL); - - if (fg0 & TILE_FLAG_S_UNDER) - _tcache_overlay(tcache_image, ix, TILE_SOMETHING_UNDER, &c, NULL); - - // Pet mark - int status_shift = 0; - if (fg0 & TILE_FLAG_PET) - { - _tcache_overlay(tcache_image, ix, TILE_HEART, &c, NULL); - status_shift += 10; - } - else if ((fg0 & TILE_FLAG_MAY_STAB) == TILE_FLAG_NEUTRAL) - { - _tcache_overlay(tcache_image, ix, TILE_NEUTRAL, &c, NULL); - status_shift += 8; - } - else if ((fg0 & TILE_FLAG_MAY_STAB) == TILE_FLAG_STAB) - { - _tcache_overlay(tcache_image, ix, TILE_STAB_BRAND, &c, NULL); - status_shift += 8; - } - else if ((fg0 & TILE_FLAG_MAY_STAB) == TILE_FLAG_MAY_STAB) - { - _tcache_overlay(tcache_image, ix, TILE_MAY_STAB_BRAND, &c, - NULL); - status_shift += 5; - } - - if (fg0 & TILE_FLAG_POISON) - { - _tcache_overlay(tcache_image, ix, TILE_POISON, &c, NULL, - status_shift); - status_shift += 5; - } - - if (fg0 & TILE_FLAG_ANIM_WEP) - { - _tcache_overlay(tcache_image, ix, TILE_ANIMATED_WEAPON, &c, NULL); - } - - if (bg0 & TILE_FLAG_UNSEEN) - { - _tcache_overlay(tcache_image, ix, TILE_MESH, &c, NULL); - } - - if (bg0 & TILE_FLAG_MM_UNSEEN) - { - _tcache_overlay(tcache_image, ix, TILE_MAGIC_MAP_MESH, &c, - NULL); - } - - // Don't let the "new stair" icon cover up any existing icons, but - // draw it otherwise. - if (bg0 & TILE_FLAG_NEW_STAIR && status_shift == 0) - _tcache_overlay(tcache_image, ix, TILE_NEW_STAIR, &c, NULL); - - if ((bg0 & TILE_FLAG_TRAV_EXCL) && (bg0 & TILE_FLAG_UNSEEN)) - { - _tcache_overlay(tcache_image, ix, TILE_TRAVEL_EXCLUSION, &c, - NULL); - } - else if ((bg0 & TILE_FLAG_EXCL_CTR) && (bg0 & TILE_FLAG_UNSEEN)) - { - _tcache_overlay(tcache_image, ix, TILE_TRAVEL_EXCL_CENTRE, &c, - NULL); - } - - // Tile cursor - if (bg0 & TILE_FLAG_CURSOR) - { - int type = ((bg0 & TILE_FLAG_CURSOR) == TILE_FLAG_CURSOR1) ? - TILE_CURSOR : TILE_CURSOR2; - - if ((bg0 & TILE_FLAG_CURSOR) == TILE_FLAG_CURSOR3) - type = TILE_CURSOR3; - - _tcache_overlay(tcache_image, ix, type, &c, NULL); - - if (type != TILE_CURSOR3) - c = 2; - } - -} - -// Tile cursor -int TileDrawCursor(int x, int y, int cflag) -{ - int oldc = t2buf[x+1][y+1] & TILE_FLAG_CURSOR; - t2buf[x+1][y+1] &= ~TILE_FLAG_CURSOR; - t2buf[x+1][y+1] |= cflag; - _update_single_grid(x, y); - return oldc; -} - void TileDrawBolt(int x, int y, int fg) { - + // TODO enne +#if 0 t1buf[x+1][y+1] = fg | TILE_FLAG_FLYING; _update_single_grid(x, y); -} - -void StoreDungeonView(unsigned int *tileb) -{ - int x, y; - int count = 0; - - if (tileb == NULL) - tileb = tb_bk; - - for (y = 0; y < tile_dngn_y; y++) - { - for (x = 0; x < tile_dngn_x; x++) - { - tileb[count++] = t1buf[x+1][y+1]; - tileb[count++] = t2buf[x+1][y+1]; - } - } -} - -void LoadDungeonView(unsigned int *tileb) -{ - int x, y; - int count = 0; - - if (tileb == NULL) - tileb = tb_bk; - - for (y = 0; y < crawl_view.viewsz.y; y++) - { - for (x = 0; x < crawl_view.viewsz.x; x++) - { - if (tileb[count] == tileb[count+1]) - tileb[count] = 0; - - t1buf[x+1][y+1] = tileb[count++]; - t2buf[x+1][y+1] = tileb[count++]; - } - } -} - -//Draw the tile screen once and for all -void TileDrawDungeon(unsigned int *tileb) -{ - if (!TileImg) - return; - - ASSERT(tile_dngn_x == crawl_view.viewsz.x); - ASSERT(tile_dngn_y == crawl_view.viewsz.y); - ASSERT(tile_xmax = crawl_view.viewsz.x); - ASSERT(tile_ymax = crawl_view.viewsz.y); - - LoadDungeonView(tileb); - - extern int tile_cursor_x; - tile_cursor_x = -1; - - for (int x = 0; x < crawl_view.viewsz.x; x++) - for (int y = 0; y < crawl_view.viewsz.y; y++) - _tile_draw_grid(x, y); - - force_redraw_tile = false; - TileDrawDungeonAux(); - region_tile->redraw(); -} - -void TileDrawFarDungeon(int cx, int cy) -{ - unsigned int tb[TILE_DAT_YMAX*TILE_DAT_XMAX*2]; - - int count = 0; - for (int y = 0; y < tile_dngn_y; y++) - { - for (int x = 0; x < tile_dngn_x; x++) - { - int fg; - int bg; - - const coord_def gc(cx + x - tile_dngn_x/2, - cy + y - tile_dngn_y/2); - const coord_def ep = view2show(grid2view(gc)); - - // mini "viewwindow" routine - if (!map_bounds(gc)) - { - fg = 0; - bg = TILE_DNGN_UNSEEN; - } - else if (!crawl_view.in_grid_los(gc) || !env.show(ep)) - { - fg = env.tile_bk_fg[gc.x][gc.y]; - bg = env.tile_bk_bg[gc.x][gc.y]; - if (bg == 0) - bg |= TILE_DNGN_UNSEEN; - bg |= tile_unseen_flag(gc); - } - else - { - fg = env.tile_fg[ep.x-1][ep.y-1]; - bg = env.tile_bg[ep.x-1][ep.y-1]; - } - - if (gc.x == cx && gc.y == cy) - bg |= TILE_FLAG_CURSOR1; - - tb[count++] = fg; - tb[count++] = bg; - } - } - tile_finish_dngn(tb, cx, cy); - TileDrawDungeon(tb); - region_tile->redraw(); -} - -void TileDrawMap(int gx, int gy) -{ - TileDrawFarDungeon(gx, gy); -} - -// Load optional wall tile -static void _TileLoadWallAux(int idx_src, int idx_dst, img_type wall) -{ - int tile_per_row = ImgWidth(wall) / TILE_X; - - int sx = idx_src % tile_per_row; - int sy = idx_src / tile_per_row; - - sx *= TILE_X; - sy *= TILE_Y; - - _ImgCopyToTileImg(idx_dst, wall, sx, sy, 1); +#endif } void WallIdx(int &wall, int &floor, int &special) @@ -938,44 +88,44 @@ void WallIdx(int &wall, int &floor, int &special) case BLUE: case LIGHTBLUE: wall = IDX_WALL_ZOT_BLUE; - floor = IDX_FLOOR_ZOT_BLUE; + floor = IDX_FLOOR_TOMB; break; case RED: case LIGHTRED: wall = IDX_WALL_ZOT_RED; - floor = IDX_FLOOR_ZOT_RED; + floor = IDX_FLOOR_TOMB; break; case MAGENTA: case LIGHTMAGENTA: wall = IDX_WALL_ZOT_MAGENTA; - floor = IDX_FLOOR_ZOT_MAGENTA; + floor = IDX_FLOOR_TOMB; break; case GREEN: case LIGHTGREEN: wall = IDX_WALL_ZOT_GREEN; - floor = IDX_FLOOR_ZOT_GREEN; + floor = IDX_FLOOR_TOMB; break; case CYAN: case LIGHTCYAN: wall = IDX_WALL_ZOT_CYAN; - floor = IDX_FLOOR_ZOT_CYAN; + floor = IDX_FLOOR_TOMB; break; case BROWN: case YELLOW: wall = IDX_WALL_ZOT_YELLOW; - floor = IDX_FLOOR_ZOT_YELLOW; + floor = IDX_FLOOR_TOMB; break; case BLACK: case WHITE: default: wall = IDX_WALL_ZOT_GRAY; - floor = IDX_FLOOR_ZOT_GRAY; + floor = IDX_FLOOR_TOMB; break; } @@ -1021,7 +171,7 @@ void WallIdx(int &wall, int &floor, int &special) else if (you.level_type == LEVEL_LABYRINTH) { wall = IDX_WALL_UNDEAD; - floor = IDX_FLOOR_UNDEAD; + floor = IDX_FLOOR_TOMB; return; } else if (you.level_type == LEVEL_PORTAL_VAULT) @@ -1111,7 +261,7 @@ void WallIdx(int &wall, int &floor, int &special) case BRANCH_CRYPT: case BRANCH_VESTIBULE_OF_HELL: wall = IDX_WALL_UNDEAD; - floor = IDX_FLOOR_UNDEAD; + floor = IDX_FLOOR_TOMB; return; case BRANCH_TOMB: @@ -1121,7 +271,7 @@ void WallIdx(int &wall, int &floor, int &special) case BRANCH_DIS: wall = IDX_WALL_ZOT_CYAN; - floor = IDX_FLOOR_ZOT_CYAN; + floor = IDX_FLOOR_TOMB; return; case BRANCH_GEHENNA: @@ -1172,7 +322,7 @@ void WallIdx(int &wall, int &floor, int &special) if (you.your_level - you.branch_stairs[7] <= 1) { wall = IDX_WALL_ZOT_YELLOW; - floor = IDX_FLOOR_ZOT_YELLOW; + floor = IDX_FLOOR_TOMB; return; } @@ -1180,20 +330,20 @@ void WallIdx(int &wall, int &floor, int &special) { case 2: wall = IDX_WALL_ZOT_GREEN; - floor = IDX_FLOOR_ZOT_GREEN; + floor = IDX_FLOOR_TOMB; return; case 3: wall = IDX_WALL_ZOT_CYAN; - floor = IDX_WALL_ZOT_CYAN; + floor = IDX_FLOOR_TOMB; return; case 4: wall = IDX_WALL_ZOT_BLUE; - floor = IDX_FLOOR_ZOT_GREEN; + floor = IDX_FLOOR_TOMB; return; case 5: default: wall = IDX_WALL_ZOT_MAGENTA; - floor = IDX_FLOOR_ZOT_MAGENTA; + floor = IDX_FLOOR_TOMB; return; } @@ -1210,51 +360,32 @@ void WallIdx(int &wall, int &floor, int &special) wall = IDX_WALL_NORMAL; floor = IDX_FLOOR_NORMAL; } + void TileLoadWall(bool wizard) { - _clear_tcache(); - force_redraw_tile = true; - int wall_idx; int floor_idx; int special_idx; WallIdx(wall_idx, floor_idx, special_idx); // Number of flavors are generated automatically... + // TODO enne - link floor tile index to the right location rather than + // starting at floor normal + floor_tile_idx = tile_DNGN_start[floor_idx]; + floor_flavors = tile_DNGN_count[floor_idx]; - floor_tile_idx = TILE_DNGN_FLOOR; - floor_flavors = tile_W2D_count[floor_idx]; - int offset = floor_tile_idx; - - for (int i = 0; i < floor_flavors; i++) - { - int idx_src = tile_W2D_start[floor_idx] + i; - int idx_dst = offset++; - _TileLoadWallAux(idx_src, idx_dst, WallImg); - } - - wall_tile_idx = offset; - wall_flavors = tile_W2D_count[wall_idx]; - for (int i = 0; i < wall_flavors; i++) - { - int idx_src = tile_W2D_start[wall_idx] + i; - int idx_dst = offset++; - _TileLoadWallAux(idx_src, idx_dst, WallImg); - } + wall_tile_idx = tile_DNGN_start[wall_idx]; + wall_flavors = tile_DNGN_count[wall_idx]; if (special_idx != -1) { - special_tile_idx = offset; - special_flavors = tile_W2D_count[special_idx]; - for (int i = 0; i < special_flavors; i++) - { - int idx_src = tile_W2D_start[special_idx] + i; - int idx_dst = offset++; - _TileLoadWallAux(idx_src, idx_dst, WallImg); - } + special_tile_idx = tile_DNGN_start[special_idx]; + special_flavors = tile_DNGN_count[special_idx]; } else + { special_flavors = 0; + } } #define DOLLS_MAX 11 @@ -1262,227 +393,8 @@ void TileLoadWall(bool wizard) #define PARTS_ITEMS 12 #define TILEP_SELECT_DOLL 20 -typedef struct dolls_data -{ - int parts[TILEP_PARTS_TOTAL]; -} dolls_data; - static dolls_data current_doll; static int current_gender = 0; -static int current_parts[TILEP_PARTS_TOTAL]; - -static bool _draw_doll(img_type img, dolls_data *doll, bool force_redraw = false, - bool your_doll = true) -{ - const int p_order[TILEP_PARTS_TOTAL] = - { - TILEP_PART_SHADOW, - TILEP_PART_HALO, - TILEP_PART_DRCWING, - TILEP_PART_CLOAK, - TILEP_PART_BASE, - TILEP_PART_BOOTS, - TILEP_PART_LEG, - TILEP_PART_BODY, - TILEP_PART_ARM, - TILEP_PART_HAND1, - TILEP_PART_HAND2, - TILEP_PART_HAIR, - TILEP_PART_BEARD, - TILEP_PART_HELM, - TILEP_PART_DRCHEAD - }; - int p_order2[TILEP_PARTS_TOTAL]; - - int i; - int flags[TILEP_PARTS_TOTAL]; - int parts2[TILEP_PARTS_TOTAL]; - int *parts = doll->parts; - int c = 1; - bool changed = false; - - int default_parts[TILEP_PARTS_TOTAL]; - memset(default_parts, 0, sizeof(default_parts)); - - if (your_doll) - { - tilep_race_default(you.species, parts[TILEP_PART_BASE] % 2, - you.experience_level, default_parts); - - if (default_parts[TILEP_PART_BASE] != parts[TILEP_PART_BASE]) - force_redraw = true; - - parts[TILEP_PART_BASE] = default_parts[TILEP_PART_BASE]; - - // TODO enne - make these configurable. - parts[TILEP_PART_DRCHEAD] = default_parts[TILEP_PART_DRCHEAD]; - parts[TILEP_PART_DRCWING] = default_parts[TILEP_PART_DRCWING]; - - bool halo = inside_halo(you.x_pos, you.y_pos); - parts[TILEP_PART_HALO] = halo ? TILEP_HALO_TSO : 0; - } - - // convert TILEP_SHOW_EQUIP into real parts number - for (i = 0; i < TILEP_PARTS_TOTAL; i++) - { - parts2[i] = parts[i]; - if (parts2[i] == TILEP_SHOW_EQUIP) - { - int item = -1; - switch (i) - { - case TILEP_PART_HAND1: - item = you.equip[EQ_WEAPON]; - if (you.attribute[ATTR_TRANSFORMATION] == TRAN_BLADE_HANDS) - parts2[i] = TILEP_HAND1_BLADEHAND; - else if (item == -1) - parts2[i] = 0; - else - parts2[i] = tilep_equ_weapon(you.inv[item]); - break; - - case TILEP_PART_HAND2: - item = you.equip[EQ_SHIELD]; - if (you.attribute[ATTR_TRANSFORMATION] == TRAN_BLADE_HANDS) - parts2[i] = TILEP_HAND2_BLADEHAND; - else if (item == -1) - parts2[i] = 0; - else - parts2[i] = tilep_equ_shield(you.inv[item]); - break; - - case TILEP_PART_BODY: - item = you.equip[EQ_BODY_ARMOUR]; - if (item == -1) - parts2[i] = 0; - else - parts2[i] = tilep_equ_armour(you.inv[item]); - break; - - case TILEP_PART_CLOAK: - item = you.equip[EQ_CLOAK]; - if (item == -1) - parts2[i] = 0; - else - parts2[i] = tilep_equ_cloak(you.inv[item]); - break; - - case TILEP_PART_HELM: - item = you.equip[EQ_HELMET]; - if (item == -1) - parts2[i] = 0; - else - parts2[i] = tilep_equ_helm(you.inv[item]); - - if (parts2[i] == 0 && player_mutation_level(MUT_HORNS) > 0) - { - switch (player_mutation_level(MUT_HORNS)) - { - case 1: - parts2[i] = TILEP_HELM_HORNS1; - break; - case 2: - parts2[i] = TILEP_HELM_HORNS2; - break; - case 3: - parts2[i] = TILEP_HELM_HORNS3; - break; - } - } - - break; - - case TILEP_PART_BOOTS: - item = you.equip[EQ_BOOTS]; - if (item == -1) - parts2[i] = 0; - else - parts2[i] = tilep_equ_boots(you.inv[item]); - - if (parts2[i] == 0 && player_mutation_level(MUT_HOOVES)) - parts2[i] = TILEP_BOOTS_HOOVES; - break; - - case TILEP_PART_ARM: - item = you.equip[EQ_GLOVES]; - if (item == -1) - parts2[i] = 0; - else - parts2[i] = tilep_equ_gloves(you.inv[item]); - - // There is player_has_claws() but it is not equivalent. - // Claws appear if they're big enough to not wear gloves - // or on races that have claws. - if (parts2[i] == 0 && (player_mutation_level(MUT_CLAWS) >= 3 - || you.species == SP_TROLL || you.species == SP_GHOUL)) - { - parts2[i] = TILEP_ARM_CLAWS; - } - break; - - case TILEP_PART_HAIR: - case TILEP_PART_BEARD: - parts2[i] = default_parts[i]; - break; - - case TILEP_PART_LEG: - default: - parts2[i] = 0; - } - } - - if (parts2[i] != current_parts[i]) - changed = true; - current_parts[i] = parts2[i]; - } - - - if (!changed && !force_redraw) - return (false); - - tilep_calc_flags(parts2, flags); - ImgClear(img); - - // Hack: change overlay order of boots/skirts. - for (i = 0; i < TILEP_PARTS_TOTAL; i++) - p_order2[i] = p_order[i]; - - // Swap boot and leg-armour. - if (parts2[TILEP_PART_LEG] < TILEP_LEG_SKIRT_OFS) - { - p_order2[6] = TILEP_PART_LEG; - p_order2[5] = TILEP_PART_BOOTS; - } - - for (i = 0; i < TILEP_PARTS_TOTAL; i++) - { - int p = p_order2[i]; - int ymax = TILE_Y; - if (flags[p] == TILEP_FLAG_CUT_CENTAUR - || flags[p] == TILEP_FLAG_CUT_NAGA) - { - ymax=18; - } - - if (parts2[p] && p == TILEP_PART_BOOTS - && (parts2[p] == TILEP_BOOTS_NAGA_BARDING - || parts2[p] == TILEP_BOOTS_CENTAUR_BARDING)) - { - // Special case for barding. They should be in "boots" but because - // they're double-wide, they're stored in a different part. We just - // intercept it here before drawing. - char tile = (parts2[p] == TILEP_BOOTS_NAGA_BARDING) ? - TILEP_SHADOW_NAGA_BARDING : - TILEP_SHADOW_CENTAUR_BARDING; - - _tcache_overlay_player(img, 0, 0, TILEP_PART_SHADOW, - tile, TILE_Y, &c); - } - else if (parts2[p] && flags[p]) - _tcache_overlay_player(img, 0, 0, p, parts2[p], ymax, &c); - } - return (true); -} static void _load_doll_data(const char *fn, dolls_data *dolls, int max, int *mode, int *cur) @@ -1569,6 +481,7 @@ static void _load_doll_data(const char *fn, dolls_data *dolls, int max, void TilePlayerEdit() { +#if 0 const int p_lines[PARTS_ITEMS] = { TILEP_SELECT_DOLL, @@ -2036,7 +949,9 @@ void TilePlayerEdit() for (y = 0; y < TILE_DAT_YMAX + 2; y++) { t1buf[x][y] = 0; +#if 0 t2buf[x][y] = TILE_DNGN_UNSEEN | TILE_FLAG_UNSEEN; +#endif } } @@ -2045,45 +960,12 @@ void TilePlayerEdit() clrscr(); redraw_screen(); -} - -void TilePlayerRefresh() -{ - if (!_draw_doll(DollCacheImg, ¤t_doll)) - return; // Not changed - - _ImgCopyToTileImg(TILE_PLAYER, DollCacheImg, 0, 0, 1); - - _redraw_spx_tcache(TILE_PLAYER); - force_redraw_tile = true; - - const coord_def ep = grid2view(you.pos()); - _update_single_grid(ep.x-1, ep.y-1); -} - -void TilePlayerInit() -{ - int i; - int cur_doll = 0; - int mode = TILEP_M_DEFAULT; - dolls_data doll; - int gender = 0; - - for (i = 0; i < TILEP_PARTS_TOTAL; i++) - doll.parts[i] = 0; - - tilep_race_default(you.species, gender, you.experience_level, doll.parts); - tilep_job_default(you.char_class, gender, doll.parts); - - _load_doll_data("dolls.txt", &doll, 1, &mode, &cur_doll); - current_doll = doll; - _draw_doll(DollCacheImg, &doll); - - _ImgCopyToTileImg(TILE_PLAYER, DollCacheImg, 0, 0, 1); +#endif } void TileGhostInit(const struct ghost_demon &ghost) { +#if 0 dolls_data doll; int x, y; unsigned int pseudo_rand = ghost.max_hp * 54321 * 54321; @@ -2244,97 +1126,13 @@ void TileGhostInit(const struct ghost_demon &ghost) _draw_doll(DollCacheImg, &doll); _ImgCopyToTileImg(TILE_MONS_PLAYER_GHOST, DollCacheImg, 0, 0, 1, mask, false); _redraw_spx_tcache(TILE_MONS_PLAYER_GHOST); +#endif } -void TileInitItems() -{ - for (int i = 0; i < NUM_POTIONS; i++) - { - int special = you.item_description[IDESC_POTIONS][i]; - int tile0 = TILE_POTION_OFFSET + special % 14; - int tile1 = TILE_POT_HEALING + i; - - _ImgCopyFromTileImg(tile0, DollCacheImg, 0, 0, 1); - _ImgCopyFromTileImg(tile1, DollCacheImg, 0, 0, 0); - _ImgCopyToTileImg(tile1, DollCacheImg, 0, 0, 1); - } - - for (int i = 0; i < NUM_WANDS; i++) - { - int special = you.item_description[IDESC_WANDS][i]; - int tile0 = TILE_WAND_OFFSET + special % 12; - int tile1 = TILE_WAND_FLAME + i; - - _ImgCopyFromTileImg(tile0, DollCacheImg, 0, 0, 1); - _ImgCopyFromTileImg(tile1, DollCacheImg, 0, 0, 0); - _ImgCopyToTileImg(tile1, DollCacheImg, 0, 0, 1); - } - - for (int i = 0; i < STAFF_SMITING; i++) - { - int special = you.item_description[IDESC_STAVES][i]; - int tile0 = TILE_STAFF_OFFSET + (special / 4) % 10; - int tile1 = TILE_STAFF_WIZARDRY + i; - - _ImgCopyFromTileImg(tile0, DollCacheImg, 0, 0, 1); - _ImgCopyFromTileImg(tile1, DollCacheImg, 0, 0, 0); - _ImgCopyToTileImg(tile1, DollCacheImg, 0, 0, 1); - } - for (int i = STAFF_SMITING; i < NUM_STAVES; i++) - { - int special = you.item_description[IDESC_STAVES][i]; - int tile0 = TILE_ROD_OFFSET + (special / 4) % 10; - int tile1 = TILE_ROD_SMITING + i - STAFF_SMITING; - - _ImgCopyFromTileImg(tile0, DollCacheImg, 0, 0, 1); - _ImgCopyFromTileImg(tile1, DollCacheImg, 0, 0, 0); - _ImgCopyToTileImg(tile1, DollCacheImg, 0, 0, 1); - } -} - -// Monster weapon tile -#define N_MCACHE (TILE_MCACHE_END - TILE_MCACHE_START +1) - -typedef struct mcache mcache; -struct mcache -{ - bool lock_flag; - mcache *next; - int mon_tile; - int equ_tile; - int draco; - int idx; -}; - -mcache mc_data[N_MCACHE]; - -mcache *mc_head = NULL; - -static void _ImgCopyDoll(int equ_tile, int hand, int ofs_x, int ofs_y) -{ - int handidx = hand == 1 ? TILEP_PART_HAND1 : TILEP_PART_HAND2; - - int nx = tilep_parts_nx[handidx]; - int ny = tilep_parts_ny[handidx]; - int ox = tilep_parts_ox[handidx]; - int oy = tilep_parts_oy[handidx]; - int wx = std::min(TILE_X/nx + ofs_x, TILE_X/nx); - int wy = std::min(TILE_Y/ny + ofs_y, TILE_Y/ny); - int idx = equ_tile -1; - int tidx = tilep_parts_start[handidx] + idx/(nx*ny); - - //Source pos - int xs = (tidx % TILEP_PER_ROW)*TILE_X + (idx % nx) * (TILE_X/nx) - ofs_x; - int ys = (tidx / TILEP_PER_ROW)*TILE_Y - + ((idx/nx) % ny) * (TILE_Y/ny) - ofs_y; - - ImgCopy(PlayerImg, xs, ys, wx, wy, DollCacheImg, ox, oy, 0); -} - -static void _mcache_compose(int tile_idx, int mon_tile, int equ_tile) +void tile_get_monster_weapon_offset(int mon_tile, int &ofs_x, int &ofs_y) { - int ofs_x = 0; - int ofs_y = 0; + ofs_x = 0; + ofs_y = 0; switch (mon_tile) { @@ -2423,157 +1221,6 @@ static void _mcache_compose(int tile_idx, int mon_tile, int equ_tile) ofs_x = -1; break; } - - // Copy monster tile - _ImgCopyFromTileImg(mon_tile, DollCacheImg, 0, 0, 1); - - // Overlay weapon tile - _ImgCopyDoll(equ_tile, 1, ofs_x, ofs_y); - - // In some cases, overlay a second weapon tile... - if (mon_tile == TILE_MONS_DEEP_ELF_BLADEMASTER) - { - int eq2; - switch (equ_tile) - { - case TILEP_HAND1_DAGGER: - eq2 = TILEP_HAND2_DAGGER; - break; - case TILEP_HAND1_SABRE: - eq2 = TILEP_HAND2_SABRE; - break; - default: - case TILEP_HAND1_SHORT_SWORD_SLANT: - eq2 = TILEP_HAND2_SHORT_SWORD_SLANT; - break; - }; - _ImgCopyDoll(eq2, 2, -ofs_x, ofs_y); - } - - // Copy to the buffer - _ImgCopyToTileImg(tile_idx, DollCacheImg, 0, 0, 1); - - _redraw_spx_tcache(tile_idx); -} - -static void _mcache_compose_draco(int tile_idx, int race, int cls, int w) -{ - extern int draconian_color(int race, int level); - - dolls_data doll; - int x; - - int color = draconian_color(race, -1); - int armour = 0; - int armour2 = 0; - int weapon = 0; - int weapon2 = 0; - int arm = 0; - - for (x = 0; x < TILEP_PARTS_TOTAL; x++) - { - doll.parts[x] = 0; - current_parts[x] = 0; - } - doll.parts[TILEP_PART_SHADOW] = 1; - - doll.parts[TILEP_PART_BASE] = TILEP_BASE_DRACONIAN + color *2; - doll.parts[TILEP_PART_DRCWING] = 1 + color; - doll.parts[TILEP_PART_DRCHEAD] = 1 + color; - - switch(cls) - { - case MONS_DRACONIAN_CALLER: - weapon = TILEP_HAND1_STAFF_EVIL; - weapon2 = TILEP_HAND2_BOOK_YELLOW; - armour = TILEP_BODY_ROBE_BROWN; - break; - - case MONS_DRACONIAN_MONK: - arm = TILEP_ARM_GLOVE_SHORT_BLUE; - armour = TILEP_BODY_KARATE2; - break; - - case MONS_DRACONIAN_ZEALOT: - weapon = TILEP_HAND1_MACE; - weapon2 = TILEP_HAND2_BOOK_CYAN; - armour = TILEP_BODY_MONK_BLUE; - break; - - case MONS_DRACONIAN_SHIFTER: - weapon = TILEP_HAND1_STAFF_LARGE; - armour = TILEP_BODY_ROBE_CYAN; - weapon2 = TILEP_HAND2_BOOK_GREEN; - break; - - case MONS_DRACONIAN_ANNIHILATOR: - weapon = TILEP_HAND1_STAFF_RUBY; - weapon2 = TILEP_HAND2_FIRE_CYAN; - armour = TILEP_BODY_ROBE_GREEN_GOLD; - break; - - case MONS_DRACONIAN_KNIGHT: - weapon = w; - weapon2 = TILEP_HAND2_SHIELD_KNIGHT_GRAY; - armour = TILEP_BODY_BPLATE_METAL1; - armour2 = TILEP_LEG_BELT_GRAY; - break; - - case MONS_DRACONIAN_SCORCHER: - weapon = TILEP_HAND1_FIRE_RED; - weapon2 = TILEP_HAND2_BOOK_RED; - armour = TILEP_BODY_ROBE_RED; - break; - - default: - weapon = w; - armour = TILEP_BODY_BELT2; - armour2 = TILEP_LEG_LOINCLOTH_RED; - break; - } - - doll.parts[TILEP_PART_HAND1] = weapon; - doll.parts[TILEP_PART_HAND2] = weapon2; - doll.parts[TILEP_PART_BODY] = armour; - doll.parts[TILEP_PART_LEG] = armour2; - doll.parts[TILEP_PART_ARM] = arm; - - ImgClear(DollCacheImg); - _draw_doll(DollCacheImg, &doll, true, false); - // Copy to the buffer - _ImgCopyToTileImg(tile_idx, DollCacheImg, 0, 0, 1); - _redraw_spx_tcache(tile_idx); -} - -static void _mcache_init() -{ - int i; - - for (i = 0; i < N_MCACHE; i++) - { - mc_data[i].lock_flag = false; - mc_data[i].next = NULL; - - if (i != N_MCACHE - 1) - mc_data[i].next = &mc_data[i+1]; - - mc_data[i].idx = TILE_MCACHE_START + i; - mc_data[i].mon_tile = 0; - mc_data[i].equ_tile = 0; - mc_data[i].draco = 0; - } - mc_head = &mc_data[0]; -} - -int get_base_idx_from_mcache(int tile_idx) -{ - for (mcache *mc = mc_head; mc != NULL; mc = mc->next) - { - if (mc->idx == tile_idx) - return mc->mon_tile; - } - - return tile_idx; } int get_clean_map_idx(int tile_idx) @@ -2581,7 +1228,7 @@ int get_clean_map_idx(int tile_idx) int idx = tile_idx & TILE_FLAG_MASK; if (idx >= TILE_CLOUD_FIRE_0 && idx <= TILE_CLOUD_PURP_SMOKE || idx >= TILE_MONS_SHADOW && idx <= TILE_MONS_WATER_ELEMENTAL || - idx >= TILE_MCACHE_START && idx <= TILE_MCACHE_END) + idx >= TILE_MCACHE_START) { return 0; } @@ -2589,115 +1236,9 @@ int get_clean_map_idx(int tile_idx) return tile_idx; } -void TileMcacheUnlock() -{ - int i; - - for (i = 0; i < N_MCACHE; i++) - mc_data[i].lock_flag = false; -} - -int TileMcacheFind(int mon_tile, int equ_tile, int draco) -{ - mcache *mc = mc_head; - mcache *prev = NULL; - mcache *empty = NULL; -#ifdef DEBUG_DIAGNOSTICS - int count = 0; - char cache_info[40]; -#endif - int best2 = -1; - int best3 = -1; - - while (true) - { - if (mon_tile == mc->mon_tile && equ_tile == mc->equ_tile - && draco == mc->draco) - { - // match found - // move cache to the head to reduce future search time - if (prev != NULL) - prev->next = mc->next; - if (mc != mc_head) - mc->next = mc_head; - mc_head = mc; - - // lock it - mc->lock_flag=true; - // return cache index - return mc->idx; - } - else if (draco != 0 && mon_tile == mc->mon_tile && draco == mc->draco) - // second best for draconian: only weapon differ - best2 = mc->idx; - else if (draco != 0 && mon_tile == mc->mon_tile) - // third best for draconian: only class matches - best3 = mc->idx; - - if (!mc->lock_flag) - empty = mc; - if (mc->next == NULL) - break; - prev = mc; - mc = mc->next; - -#ifdef DEBUG_DIAGNOSTICS - count++; -#endif - } // while - - // cache image not found and no room do draw it - if (empty == NULL) - { -#ifdef DEBUG_DIAGNOSTICS - snprintf( cache_info, 39, "mcache (M %d, E %d) cache full", - mon_tile, equ_tile); - mpr(cache_info, MSGCH_DIAGNOSTICS ); -#endif - if (best2 != -1) - return best2; - - if (best3 != -1) - return best3; - - if (draco != 0) - return TILE_ERROR; - else - return mon_tile; - } - mc = empty; - -#ifdef DEBUG_DIAGNOSTICS - snprintf( cache_info, 39, "mcache (M %d, E %d) newly composed", - mon_tile, equ_tile); - mpr(cache_info, MSGCH_DIAGNOSTICS ); -#endif - - // compose new image - if (draco != 0) - // race, class, weapon - _mcache_compose_draco(mc->idx, draco, mon_tile, equ_tile); - else - _mcache_compose(mc->idx, mon_tile, equ_tile); - - mc->mon_tile = mon_tile; - mc->equ_tile = equ_tile; - mc->draco = draco; - - // move cache to the head to reduce future search time - if (prev) - prev->next = mc->next; - if (mc != mc_head) - mc->next = mc_head; - - mc_head = mc; - mc->lock_flag = true; - - return mc->idx; -} - void TileDrawTitle() { +#if 0 img_type TitleImg = ImgLoadFileSimple("title"); if (!TitleImg) return; @@ -2740,240 +1281,7 @@ void TileDrawTitle() clrscr(); win_main->removeRegion(&title); -} - -static void _TilePutch(int c, img_type Dest, int dx, int dy) -{ - int tidx = TILE_CHAR00 + (c-32)/8; - int tidx2 = c & 7; - - int sx = (tidx % TILE_PER_ROW)*TILE_X + (tidx2 % 4)*(TILE_X/4); - int sy = (tidx / TILE_PER_ROW)*TILE_Y + (tidx2 / 4)*(TILE_Y/2);; - - ImgCopy(TileImg, sx, sy, TILE_X/4, TILE_Y/2, - Dest, dx, dy, 0); -} - -void TileRedrawInv(int region) -{ - TileRegionClass *r = (region == REGION_INV1) ? region_item:region_item2; - r->flag = true; - r->make_active(); - r->redraw(); -} - -void TileClearInv(int region) -{ - TileRegionClass *r = (region == REGION_INV1) ? region_item - : region_item2; - - for (int i = 0; i < r->mx * r->my; i++) - { - TileDrawOneItem(region, i, 0, -1, -1, -1, - false, false, false, false, false); - } - - last_cursor = -1; - itemlist_n = 0; -} - -void TileDrawOneItem(int region, int i, char key, int idx, - int tile, int num, bool floor, - bool select, bool equip, bool tried, bool cursed) -{ - ASSERT(idx >= -1 && idx < MAX_ITEMS); - TileRegionClass *r = (region == REGION_INV1) ? region_item - : region_item2; - - int item_x = r->mx; - int dx = (i % item_x) * TILE_X; - int dy = (i / item_x) * TILE_Y; - - if (tile == -1) - { - _ImgCopyFromTileImg(TILE_DNGN_UNSEEN, r->backbuf, dx, dy, 1); - return; - } - - if (floor) - _ImgCopyFromTileImg(TILE_DNGN_FLOOR, r->backbuf, dx, dy, 1); - else - _ImgCopyFromTileImg(TILE_ITEM_SLOT, r->backbuf, dx, dy, 1); - - if (equip) - { - if (cursed) - _ImgCopyFromTileImg(TILE_ITEM_SLOT_EQUIP_CURSED, r->backbuf, - dx, dy, 0); - else - _ImgCopyFromTileImg(TILE_ITEM_SLOT_EQUIP, r->backbuf, dx, dy, 0); - } - else if (cursed) - _ImgCopyFromTileImg(TILE_ITEM_SLOT_CURSED, r->backbuf, dx, dy, 0); - - if (select) - _ImgCopyFromTileImg(TILE_RAY_MESH, r->backbuf, dx, dy, 0); - - if (itemlist_iflag[i] & TILEI_FLAG_CURSOR) - _ImgCopyFromTileImg(TILE_CURSOR, r->backbuf, dx, dy, 0); - - // Item tile - _ImgCopyFromTileImg(tile, r->backbuf, dx, dy, 0); - - // quantity/charge - if (num != -1) - { - // If you have that many, who cares. - if (num > 999) - num = 999; - - const int offset_amount = TILE_X/4; - int offset = 0; - - int help = num; - int c100 = help/100; - help -= c100*100; - - if (c100) - { - _TilePutch('0' + c100, r->backbuf, dx+offset, dy); - offset += offset_amount; - } - - int c10 = help/10; - if (c10 || c100) - { - _TilePutch('0' + c10, r->backbuf, dx+offset, dy); - offset += offset_amount; - } - - int c1 = help % 10; - _TilePutch('0' + c1, r->backbuf, dx+offset, dy); - } - - // '?' mark - if (tried) - _TilePutch('?', r->backbuf, dx, dy + TILE_Y/2); - - // record tile information as we draw it so that we can re-draw it at will - itemlist[i] = tile; - itemlist_num[i] = num; - itemlist_key[i] = key; - itemlist_idx[i] = idx; - itemlist_iflag[i] = 0; - - if (floor) - itemlist_iflag[i] |= TILEI_FLAG_FLOOR; - - if (tried) - itemlist_iflag[i] |= TILEI_FLAG_TRIED; - - if (equip) - itemlist_iflag[i] |= TILEI_FLAG_EQUIP; - - if (cursed) - itemlist_iflag[i] |= TILEI_FLAG_CURSE; - - if (select) - itemlist_iflag[i] |= TILEI_FLAG_SELECT; - - if (i >= itemlist_n) - itemlist_n = i+1; -} - -void TileDrawInvData(int n, int flag, int *tiles, int *num, int *idx, - int *iflags) -{ - int i; - TileRegionClass *r = (flag == REGION_INV1 ? region_item - : region_item2); - - r->flag = true; - - last_cursor = -1; - int old_itemlist_n = itemlist_n; - itemlist_n = n; - - int item_x = r->mx; - int item_y = r->my; - - for (i = 0; i < item_x * item_y; i++) - { - if (i == MAX_ITEMLIST) - break; - - int tile0 = (i >= n) ? -1 : tiles[i]; - int idx0 = (i >= n) ? -1 : idx[i]; - char key = (iflags[i] & TILEI_FLAG_FLOOR) ? 0 - : index_to_letter(idx[i]); - - if (flag == itemlist_flag - && tile0 == itemlist[i] - && num[i] == itemlist_num[i] - && key == itemlist_key[i] - && idx0 == itemlist_idx[i] - && iflags[i] == itemlist_iflag[i] - && !force_redraw_inv - && i < old_itemlist_n) - { - continue; - } - - TileDrawOneItem(flag, i, key, idx0, tile0, num[i], - ((iflags[i]&TILEI_FLAG_FLOOR) != 0), - ((iflags[i]&TILEI_FLAG_SELECT) != 0), - ((iflags[i]&TILEI_FLAG_EQUIP) != 0), - ((iflags[i]&TILEI_FLAG_TRIED) != 0), - ((iflags[i]&TILEI_FLAG_CURSE) != 0)); - } - - r->make_active(); - r->redraw(); - itemlist_flag = flag; - force_redraw_inv = false; -} - -void TileDrawInvCursor(int ix, bool flag) -{ - TileRegionClass *r = - (itemlist_flag == REGION_INV1) ? region_item - : region_item2; - - int tile0 = itemlist[ix]; - int num0 = itemlist_num[ix]; - - if (flag) - itemlist_iflag[ix] |= TILEI_FLAG_CURSOR; - else - itemlist_iflag[ix] &= ~TILEI_FLAG_CURSOR; - - TileDrawOneItem(itemlist_flag, ix, itemlist_key[ix], itemlist_idx[ix], tile0, num0, - ((itemlist_iflag[ix]&TILEI_FLAG_FLOOR) != 0), - ((itemlist_iflag[ix]&TILEI_FLAG_SELECT) != 0), - ((itemlist_iflag[ix]&TILEI_FLAG_EQUIP) != 0), - ((itemlist_iflag[ix]&TILEI_FLAG_TRIED) != 0), - ((itemlist_iflag[ix]&TILEI_FLAG_CURSE) != 0)); - - r->redraw(); -} - -void TileMoveInvCursor(int ix) -{ - if (last_cursor != -1) - TileDrawInvCursor(last_cursor, false); - - if (ix != -1) - TileDrawInvCursor(ix, true); - - last_cursor = ix; -} - -int TileInvIdx(int i) -{ - if (i >= itemlist_n) - return -1; - else - return itemlist_idx[i]; +#endif } #endif diff --git a/crawl-ref/source/tilefont.cc b/crawl-ref/source/tilefont.cc new file mode 100644 index 0000000000..8faf6051d8 --- /dev/null +++ b/crawl-ref/source/tilefont.cc @@ -0,0 +1,448 @@ +/* + * File: tilefont.cc + * Created by: ennewalker on Sat Apr 26 01:33:53 2008 UTC + * + * Modified for Crawl Reference by $Author: ennewalker $ on $Date: 2008-03-07 $ + */ + +#include "tilefont.h" +#include "defines.h" + +#include <SDL.h> +#include <SDL_opengl.h> +#include <ft2build.h> +#include FT_FREETYPE_H + +const unsigned char term_colours[MAX_TERM_COLOUR][3] = +{ + { 0, 0, 0}, // BLACK + { 0, 82, 255}, // BLUE + {100, 185, 70}, // GREEN + { 0, 180, 180}, // CYAN + {255, 48, 0}, // RED + {238, 92, 238}, // MAGENTA + {165, 91, 0}, // BROWN + {162, 162, 162}, // LIGHTGREY + { 82, 82, 82}, // DARKGREY + { 82, 102, 255}, // LIGHTBLUE + { 82, 255, 82}, // LIGHTGREEN + { 82, 255, 255}, // LIGHTCYAN + {255, 82, 82}, // LIGHTRED + {255, 82, 255}, // LIGHTMAGENTA + {255, 255, 82}, // YELLOW + {255, 255, 255} // WHITE +}; + +FTFont::FTFont() : + m_glyphs(NULL), + m_max_advance(0, 0), + m_min_offset(0) +{ +} + +FTFont::~FTFont() +{ + delete[] m_glyphs; +} + +bool FTFont::load_font(const char *font_name, unsigned int font_size) +{ + FT_Library library; + FT_Face face; + FT_Error error; + + error = FT_Init_FreeType(&library); + if (error) + { + fprintf(stderr, "Failed to initialize freetype library.\n"); + return false; + } + + error = FT_New_Face(library, font_name, 0, &face); + if (error == FT_Err_Unknown_File_Format) + { + fprintf(stderr, "Unknown font format for file '%s'\n", font_name); + return false; + } + else if (error) + { + fprintf(stderr, "Invalid font from file '%s'\n", font_name); + } + + error = FT_Set_Pixel_Sizes(face, font_size, font_size); + ASSERT(!error); + + // Get maximum advance + m_max_advance = coord_def(0,0); + int ascender = face->ascender >> 6; + int min_y = 100000; // TODO enne - fix me + int max_y = 0; + m_min_offset = 0; + m_glyphs = new GlyphInfo[256]; + for (unsigned int c = 0; c < 256; c++) + { + m_glyphs[c].offset = 0; + m_glyphs[c].advance = 0; + m_glyphs[c].renderable = false; + + FT_Int glyph_index = FT_Get_Char_Index(face, c); + if (!glyph_index) + { + continue; + } + + error = FT_Load_Glyph(face, glyph_index, FT_LOAD_RENDER); + ASSERT(!error); + + FT_Bitmap *bmp = &face->glyph->bitmap; + + int advance = face->glyph->advance.x >> 6; + + m_max_advance.x = std::max(m_max_advance.x, advance); + + min_y = std::min(min_y, ascender - face->glyph->bitmap_top); + max_y = std::max(max_y, ascender + bmp->rows - face->glyph->bitmap_top); + + m_glyphs[c].offset = face->glyph->bitmap_left; + m_glyphs[c].advance = advance; + + m_min_offset = std::min(m_min_offset, m_glyphs[c].offset); + } + + // TEMP enne - this seems to be broken on OSX - it returns 8, when it should be 2? + m_max_advance.x = 10; + + // The ascender and text height given by FreeType2 is ridiculously large + // (e.g. 37 pixels high for 14 pixel font). Use min and max bounding + // heights on the characters we care about to get better values for the + // text height and the ascender. + m_max_advance.y = max_y - min_y; + ascender -= min_y; + + // Grow character size to power of 2 + coord_def charsz(1,1); + while (charsz.x < m_max_advance.x) + charsz.x *= 2; + while (charsz.y < m_max_advance.y) + charsz.y *= 2; + + // Fill out texture to be (16*charsz.x) X (16*charsz.y) X (32-bit) + // Having to blow out 8-bit alpha values into full 32-bit textures is + // kind of frustrating, but not all OpenGL implementations support the + // "esoteric" ALPHA8 format and it's not like this texture is very large. + unsigned int width = 16 * charsz.x; + unsigned int height = 16 * charsz.y; + unsigned char *pixels = new unsigned char[4 * width * height]; + memset(pixels, 0, sizeof(unsigned char) * 4 * width * height); + + for (unsigned int c = 0; c < 256; c++) + { + FT_Int glyph_index = FT_Get_Char_Index(face, c); + if (!glyph_index) + { + // If no mapping for this character, leave blank. + continue; + } + + error = FT_Load_Glyph(face, glyph_index, FT_LOAD_RENDER); + ASSERT(!error); + + FT_Bitmap *bmp = &face->glyph->bitmap; + ASSERT(bmp); + // Some glyphs (e.g. " ") don't get a buffer. + if (!bmp->buffer) + continue; + + m_glyphs[c].renderable = true; + + int vert_offset = ascender - face->glyph->bitmap_top; + + ASSERT(bmp->pixel_mode == FT_PIXEL_MODE_GRAY); + ASSERT(bmp->num_grays == 256); + ASSERT(bmp->width + face->glyph->bitmap_left <= m_max_advance.x); + ASSERT(bmp->rows <= m_max_advance.y); + ASSERT(vert_offset >= 0); + ASSERT(vert_offset + bmp->rows <= m_max_advance.y); + + // Horizontal offset stored in m_glyphs and handled when drawing + unsigned int offset_x = (c % 16) * charsz.x; + unsigned int offset_y = (c / 16) * charsz.y + vert_offset; + + for (int x = 0; x < bmp->width; x++) + for (int y = 0; y < bmp->rows; y++) + { + unsigned int idx = offset_x + x + (offset_y + y) * width; + idx *= 4; + unsigned char alpha = bmp->buffer[x + bmp->width * y]; + pixels[idx] = 255; + pixels[idx + 1] = 255; + pixels[idx + 2] = 255; + pixels[idx + 3] = alpha; + } + } + + bool success = m_tex.load_texture(pixels, width, height, + GenericTexture::MIPMAP_NONE); + + delete[] pixels; + + return success; +} + +struct FontVertLayout +{ + float pos_x; + float pos_y; + float tex_x; + float tex_y; + unsigned char r; + unsigned char g; + unsigned char b; + unsigned char a; +}; + +void FTFont::render_textblock(unsigned int x_pos, unsigned int y_pos, + unsigned char *chars, unsigned char *colours, + unsigned int width, unsigned int height, + bool drop_shadow) +{ + if (!chars || !colours || !width || !height || !m_glyphs) + return; + + coord_def adv(std::max(-m_min_offset, 0), 0); + unsigned int i = 0; + + std::vector<FontVertLayout> verts; + // TODO enne - make this better + // This is bad for the CRT. Maybe we should just reserve some fixed limit? + // Maybe we should just cache this in FTFont? + verts.reserve(4 * width * height); + + float texcoord_dy = (float)m_max_advance.y / (float)m_tex.height(); + + for (unsigned int y = 0; y < height; y++) + { + for (unsigned int x = 0; x < width; x++) + { + unsigned char c = chars[i]; + unsigned int this_adv = m_glyphs[c].advance + 1; + adv.x += m_glyphs[c].offset; + + if (m_glyphs[c].renderable) + { + unsigned char col = colours[i]; + float tex_x = (float)(c % 16) / 16.0f; + float tex_y = (float)(c / 16) / 16.0f; + float tex_x2 = tex_x + (float)this_adv / (float)m_tex.width(); + float tex_y2 = tex_y + texcoord_dy; + FontVertLayout v; + + v.pos_x = adv.x; + v.pos_y = adv.y; + v.tex_x = tex_x; + v.tex_y = tex_y; + v.r = term_colours[col][0]; + v.g = term_colours[col][1]; + v.b = term_colours[col][2]; + v.a = 255; + verts.push_back(v); + + v.pos_x = adv.x; + v.pos_y = adv.y + m_max_advance.y; + v.tex_x = tex_x; + v.tex_y = tex_y2; + v.r = term_colours[col][0]; + v.g = term_colours[col][1]; + v.b = term_colours[col][2]; + v.a = 255; + verts.push_back(v); + + v.pos_x = adv.x + this_adv; + v.pos_y = adv.y + m_max_advance.y; + v.tex_x = tex_x2; + v.tex_y = tex_y2; + v.r = term_colours[col][0]; + v.g = term_colours[col][1]; + v.b = term_colours[col][2]; + v.a = 255; + verts.push_back(v); + + v.pos_x = adv.x + this_adv; + v.pos_y = adv.y; + v.tex_x = tex_x2; + v.tex_y = tex_y; + v.r = term_colours[col][0]; + v.g = term_colours[col][1]; + v.b = term_colours[col][2]; + v.a = 255; + verts.push_back(v); + } + + i++; + adv.x += this_adv - m_glyphs[c].offset - 1; + } + + adv.x = 0; + adv.y += m_max_advance.y; + } + + if (!verts.size()) + return; + + GLState state; + state.array_vertex = true; + state.array_texcoord = true; + state.blend = true; + state.texture = true; + GLStateManager::set(state); + + m_tex.bind(); + glVertexPointer(2, GL_FLOAT, sizeof(FontVertLayout), &verts[0].pos_x); + glTexCoordPointer(2, GL_FLOAT, sizeof(FontVertLayout), &verts[0].tex_x); + + if (drop_shadow) + { + glColor3f(0.0f, 0.0f, 0.0f); + + glLoadIdentity(); + glTranslatef(x_pos + 1, y_pos + 1, 0.0f); + glDrawArrays(GL_QUADS, 0, verts.size()); + + glColor3f(1.0f, 1.0f, 1.0f); + } + + glLoadIdentity(); + glTranslatef(x_pos, y_pos, 0.0f); + + glEnableClientState(GL_COLOR_ARRAY); + glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(FontVertLayout), &verts[0].r); + glDrawArrays(GL_QUADS, 0, verts.size()); + glDisableClientState(GL_COLOR_ARRAY); +} + +struct box_vert +{ + float x; + float y; + unsigned char r; + unsigned char g; + unsigned char b; + unsigned char a; +}; + +static void _draw_box(int x_pos, int y_pos, float width, float height, + float box_width, unsigned char box_colour, + unsigned char box_alpha) +{ + box_vert verts[4]; + for (unsigned int i = 0; i < 4; i++) + { + verts[i].r = term_colours[box_colour][0]; + verts[i].g = term_colours[box_colour][1]; + verts[i].b = term_colours[box_colour][2]; + verts[i].a = box_alpha; + } + verts[0].x = x_pos - box_width; + verts[0].y = y_pos - box_width; + verts[1].x = verts[0].x; + verts[1].y = y_pos + height + box_width; + verts[2].x = x_pos + width + box_width; + verts[2].y = verts[1].y; + verts[3].x = verts[2].x; + verts[3].y = verts[0].y; + + glLoadIdentity(); + + GLState state; + state.array_vertex = true; + state.array_colour = true; + state.blend = true; + GLStateManager::set(state); + + glVertexPointer(2, GL_FLOAT, sizeof(box_vert), &verts[0].x); + glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(box_vert), &verts[0].r); + glDrawArrays(GL_QUADS, 0, sizeof(verts) / sizeof(box_vert)); + +} + +void FTFont::render_string(unsigned int px, unsigned int py, + const char *text, + const coord_def &min_pos, const coord_def &max_pos, + unsigned char font_colour, bool drop_shadow, + unsigned char box_alpha, + unsigned char box_colour, + unsigned int outline) +{ + ASSERT(text); + + // Determine extent of this text + unsigned int max_rows = 1; + unsigned int cols = 0; + unsigned int max_cols = 0; + for (const char *itr = text; *itr; itr++) + { + cols++; + max_cols = std::max(cols, max_cols); + + // NOTE: only newlines should be used for tool tips. Don't use EOL. + ASSERT(*itr != '\r'); + + if (*itr == '\n') + { + cols = 0; + max_rows++; + } + } + + // Create the text block + unsigned char *chars = (unsigned char *)alloca(max_rows * max_cols); + unsigned char *colours = (unsigned char *)alloca(max_rows * max_cols); + memset(chars, ' ', max_rows * max_cols); + memset(colours, font_colour, max_rows * max_cols); + + // Fill the text block + cols = 0; + unsigned int rows = 0; + for (const char *itr = text; *itr; itr++) + { + chars[cols + rows * max_cols] = *itr; + cols++; + + if (*itr == '\n') + { + cols = 0; + rows++; + } + } + + // Find a suitable location on screen + const int buffer = 5; // additional buffer size from edges + + int wx = max_cols * char_width(); + int wy = max_rows * char_height(); + + // text starting location + int tx = px - wx / 2; + int ty = py - wy - outline; + + // box with extra buffer to test against min_pos/max_pos window size + int sx = tx - buffer; + int sy = ty - buffer; + int ex = sx + wx + buffer; + int ey = sy + wy + buffer; + + if (ex > max_pos.x) + tx += max_pos.x - ex; + else if (sx < min_pos.x) + tx -= sx; + + if (ey > max_pos.y) + ty += max_pos.y - ey; + else if (sy < min_pos.y) + ty -= sy; + + if (box_alpha != 0) + _draw_box(tx, ty, wx, wy, outline, box_colour, box_alpha); + + render_textblock(tx, ty, chars, colours, max_cols, max_rows, drop_shadow); +} diff --git a/crawl-ref/source/tilefont.h b/crawl-ref/source/tilefont.h new file mode 100644 index 0000000000..5d8939a9a9 --- /dev/null +++ b/crawl-ref/source/tilefont.h @@ -0,0 +1,71 @@ +/* + * File: tilefont.h + * Created by: ennewalker on Sat Jan 5 01:33:53 2008 UTC + * + * Modified for Crawl Reference by $Author: ennewalker $ on $Date: 2008-03-07 $ + */ + +#ifndef TILEFONT_H +#define TILEFONT_H + +#include "AppHdr.h" +#include "externs.h" +#include "tiletex.h" + +// This class handles loading FreeType2 fonts and rendering them via OpenGL. + +// TODO enne - Fonts could be made better by: +// +// * handling kerning +// +// * the possibility of streaming this class in and out so that Crawl doesn't +// have to link against FreeType2 or be forced do as much processing at +// load time. + +class FTFont +{ +public: + FTFont(); + virtual ~FTFont(); + + bool load_font(const char *font_name, unsigned int font_size); + + // render just text + void render_textblock(unsigned int x, unsigned int y, + unsigned char *chars, unsigned char *colours, + unsigned int width, unsigned int height, + bool drop_shadow = false); + + // render text + background box + void render_string(unsigned int x, unsigned int y, const char *text, + const coord_def &min_pos, const coord_def &max_pos, + unsigned char font_colour, bool drop_shadow = false, + unsigned char box_alpha = 0, + unsigned char box_colour = 0, unsigned int outline = 0); + + unsigned int char_width() const { return m_max_advance.x; } + unsigned int char_height() const { return m_max_advance.y; } + +protected: + struct GlyphInfo + { + // offset before drawing glyph; can be negative + int offset; + + // per-glyph horizontal advance + int advance; + + bool renderable; + }; + GlyphInfo *m_glyphs; + + // cached value of the maximum advance from m_advance + coord_def m_max_advance; + + // minimum offset (likely negative) + int m_min_offset; + + GenericTexture m_tex; +}; + +#endif diff --git a/crawl-ref/source/tile1.cc b/crawl-ref/source/tilepick.cc index 5dcea8891f..fa793fc57d 100644 --- a/crawl-ref/source/tile1.cc +++ b/crawl-ref/source/tilepick.cc @@ -1,5 +1,5 @@ /* - * File: tile1.cc + * File: tilepick.cc * Created by: ennewalker on Sat Jan 5 01:33:53 2008 UTC * * Modified for Crawl Reference by $Author: j-p-e-g $ on $Date: 2008-03-07 $ @@ -24,34 +24,87 @@ #include "stuff.h" #include "terrain.h" #include "tiles.h" -#include "tiledef-p.h" +#include "tiledef-dngn.h" #include "traps.h" #include "travel.h" #include "view.h" +struct mcache_entry +{ + int mon_tile; + int equ_tile; + int draco; +}; + +std::vector<mcache_entry> mcache; + +int get_base_idx_from_mcache(int tile_idx) +{ + int mcache_idx = tile_idx - TILE_MCACHE_START; + if (mcache_idx >= 0 && mcache_idx < (int)mcache.size()) + { + return mcache[mcache_idx].mon_tile; + } + + return tile_idx; +} + +bool get_mcache_entry(int tile_idx, int &mon_idx, int &equ_tile, int &draco) +{ + int mcache_idx = tile_idx - TILE_MCACHE_START; + if (mcache_idx >= 0 && (unsigned int)mcache_idx < mcache.size()) + { + mon_idx = mcache[mcache_idx].mon_tile; + equ_tile = mcache[mcache_idx].equ_tile; + draco = mcache[mcache_idx].draco; + + return true; + } + + return false; +} + +static int _mcache_register(int mon_tile, int equ_tile, int draco = 0) +{ + mcache_entry entry; + entry.mon_tile = mon_tile; + entry.equ_tile = equ_tile; + entry.draco = draco; + + mcache.push_back(entry); + + int idx = TILE_MCACHE_START + mcache.size() - 1; + return idx; +} + +void tile_mcache_unlock() +{ + mcache.clear(); +} + // tile index cache to reduce tileidx() calls static FixedArray < unsigned int, GXM, GYM > tile_dngn; -bool is_bazaar() +static inline bool _is_bazaar() { return (you.level_type == LEVEL_PORTAL_VAULT && you.level_type_name == "bazaar"); } -unsigned short get_bazaar_special_colour() +static inline unsigned short _get_bazaar_special_colour() { return YELLOW; } void TileNewLevel(bool first_time) { - GmapInit(false); + init_minimap(); TileLoadWall(false); tile_clear_buf(); if (first_time) tile_init_flavor(); - if (!player_in_mappable_area()) + if (!player_in_mappable_area() || first_time) { for (unsigned int x = 0; x < GXM; x++) for (unsigned int y = 0; y < GYM; y++) @@ -2013,9 +2066,10 @@ int tileidx_feature(int object, int gx, int gy) { case DNGN_UNSEEN: return TILE_DNGN_UNSEEN; + case DNGN_FLOOR_SPECIAL: case DNGN_ROCK_WALL: case DNGN_PERMAROCK_WALL: - return TILE_DNGN_ROCK_WALL_OFS; + return TILE_WALL_NORMAL; case DNGN_SECRET_DOOR: return (unsigned int)grid_secret_door_appearance(gx, gy); case DNGN_CLEAR_ROCK_WALL: @@ -2044,9 +2098,7 @@ int tileidx_feature(int object, int gx, int gy) return TILE_DNGN_SHALLOW_WATER; case DNGN_FLOOR: case DNGN_UNDISCOVERED_TRAP: - return TILE_DNGN_FLOOR; - case DNGN_FLOOR_SPECIAL: - return TILE_DNGN_FLOOR_SPECIAL; + return TILE_FLOOR_NORMAL; case DNGN_ENTER_HELL: return TILE_DNGN_ENTER_HELL; case DNGN_OPEN_DOOR: @@ -2268,13 +2320,13 @@ int tileidx_unseen(int ch, const coord_def& gc) case ' ': res = TILE_DNGN_UNSEEN; break; case 127: //old case 176: - case 177: res = TILE_DNGN_ROCK_WALL_OFS; break; + case 177: res = TILE_WALL_NORMAL; break; case 130: case ',': case '.': case 249: - case 250: res = TILE_DNGN_FLOOR; break; + case 250: res = TILE_FLOOR_NORMAL; break; case 137: res = TILE_DNGN_WAX_WALL; break; case 138: res = TILE_DNGN_STONE_WALL; break; @@ -2293,7 +2345,7 @@ int tileidx_unseen(int ch, const coord_def& gc) case 134: res = TILE_DNGN_OPEN_DOOR; break; case '(': case ')': res = TILE_UNSEEN_WEAPON; break; - case '*': res = TILE_DNGN_ROCK_WALL_OFS ; break; + case '*': res = TILE_WALL_NORMAL ; break; case '+': res = TILE_BOOK_PAPER_OFFSET + 15; break; case '/': res = TILE_WAND_OFFSET; break; @@ -2340,12 +2392,11 @@ int tileidx_zap(int colour) return (TILE_SYM_BOLT_OFS - 1 + col); } -// Convert normal tile to 3D tile if it exists -// Plus modify wall tile index depending on -// 1: floor/wall flavor in 2D mode -// 2: connectivity in 3D mode +// modify wall tile index depending on floor/wall flavor static void _finalize_tile(unsigned int *tile, bool is_special, - char wall_flv, char floor_flv, char special_flv) + unsigned char wall_flv, + unsigned char floor_flv, + unsigned char special_flv) { int orig = (*tile) & TILE_FLAG_MASK; int flag = (*tile) & (~TILE_FLAG_MASK); @@ -2355,26 +2406,25 @@ static void _finalize_tile(unsigned int *tile, bool is_special, if ((you.where_are_you == BRANCH_CRYPT || you.where_are_you == BRANCH_TOMB) && orig == TILE_DNGN_STONE_WALL) { - orig = TILE_DNGN_ROCK_WALL_OFS; + orig = TILE_WALL_NORMAL; } // If there are special tiles for this level, then use them. // Otherwise, we'll fall through to the next case and replace // special tiles with normal floor. - if (orig == TILE_DNGN_FLOOR && is_special + if (orig == TILE_FLOOR_NORMAL && is_special && get_num_floor_special_flavors() > 0) { (*tile) = get_floor_special_tile_idx() + special_flv; - ASSERT(special_flv >= 0 - && special_flv < get_num_floor_special_flavors()); + ASSERT(special_flv < get_num_floor_special_flavors()); } - else if (orig == TILE_DNGN_FLOOR || orig == TILE_DNGN_FLOOR_SPECIAL) + else if (orig == TILE_FLOOR_NORMAL) { - (*tile) = get_floor_tile_idx() + floor_flv; + (*tile) = floor_flv; } - else if (orig == TILE_DNGN_ROCK_WALL_OFS) + else if (orig == TILE_WALL_NORMAL) { - (*tile) = get_wall_tile_idx() + wall_flv; + (*tile) = wall_flv; } else if (orig == TILE_DNGN_SHALLOW_WATER || orig == TILE_DNGN_DEEP_WATER @@ -2382,11 +2432,11 @@ static void _finalize_tile(unsigned int *tile, bool is_special, || orig == TILE_DNGN_STONE_WALL) { // These types always have four flavors... - (*tile) = orig + (floor_flv % 4); + (*tile) = orig + (special_flv % 4); } else if (orig == TILE_DNGN_CLOSED_DOOR || orig == TILE_DNGN_OPEN_DOOR) { - ASSERT(special_flv >= 0 && special_flv <= 3); + ASSERT(special_flv <= 3); (*tile) = orig + special_flv; } @@ -3646,8 +3696,8 @@ int jitter(SpecialIdx i) void tile_init_flavor() { - const bool bazaar = is_bazaar(); - const unsigned short baz_col = get_bazaar_special_colour(); + const bool bazaar = _is_bazaar(); + const unsigned short baz_col = _get_bazaar_special_colour(); for (int x = 0; x < GXM; x++) for (int y = 0; y < GYM; y++) @@ -3657,8 +3707,8 @@ void tile_init_flavor() int wall_flavor = random_range(0, max_wall_flavor); int floor_flavor = random_range(0, max_floor_flavor); - env.tile_flavor[x][y].floor = floor_flavor; - env.tile_flavor[x][y].wall = wall_flavor; + env.tile_flv[x][y].floor = get_floor_tile_idx() + floor_flavor; + env.tile_flv[x][y].wall = get_wall_tile_idx() + wall_flavor; if (grd[x][y] == DNGN_CLOSED_DOOR || grd[x][y] == DNGN_OPEN_DOOR) { @@ -3680,12 +3730,12 @@ void tile_init_flavor() // NOTE: This requires that closed gates and open gates // are positioned in the tile set relative to their // door counterpart. - env.tile_flavor[x][y].special = + env.tile_flv[x][y].special = target - TILE_DNGN_CLOSED_DOOR; } else { - env.tile_flavor[x][y].special = 0; + env.tile_flv[x][y].special = 0; } } else if (bazaar && env.grid_colours[x][y] == baz_col @@ -3722,140 +3772,140 @@ void tile_init_flavor() if (l_nrm && r_nrm || u_nrm && d_nrm) { // Not much to do here... - env.tile_flavor[x][y].special = SPECIAL_FULL; + env.tile_flv[x][y].special = SPECIAL_FULL; } else if (l_nrm) { if (u_nrm) - env.tile_flavor[x][y].special = SPECIAL_NW; + env.tile_flv[x][y].special = SPECIAL_NW; else if (d_nrm) - env.tile_flavor[x][y].special = SPECIAL_SW; + env.tile_flv[x][y].special = SPECIAL_SW; else if (u_spc && d_spc) - env.tile_flavor[x][y].special = SPECIAL_W; + env.tile_flv[x][y].special = SPECIAL_W; else if (u_spc && r_spc) - env.tile_flavor[x][y].special = SPECIAL_SW; + env.tile_flv[x][y].special = SPECIAL_SW; else if (d_spc && r_spc) - env.tile_flavor[x][y].special = SPECIAL_NW; + env.tile_flv[x][y].special = SPECIAL_NW; else if (u_spc) - env.tile_flavor[x][y].special = coinflip() ? + env.tile_flv[x][y].special = coinflip() ? SPECIAL_W : SPECIAL_SW; else if (d_spc) - env.tile_flavor[x][y].special = coinflip() ? + env.tile_flv[x][y].special = coinflip() ? SPECIAL_W : SPECIAL_NW; else - env.tile_flavor[x][y].special = jitter(SPECIAL_W); + env.tile_flv[x][y].special = jitter(SPECIAL_W); } else if (r_nrm) { if (u_nrm) - env.tile_flavor[x][y].special = SPECIAL_NE; + env.tile_flv[x][y].special = SPECIAL_NE; else if (d_nrm) - env.tile_flavor[x][y].special = SPECIAL_SE; + env.tile_flv[x][y].special = SPECIAL_SE; else if (u_spc && d_spc) - env.tile_flavor[x][y].special = SPECIAL_E; + env.tile_flv[x][y].special = SPECIAL_E; else if (u_spc && l_spc) - env.tile_flavor[x][y].special = SPECIAL_SE; + env.tile_flv[x][y].special = SPECIAL_SE; else if (d_spc && l_spc) - env.tile_flavor[x][y].special = SPECIAL_NE; + env.tile_flv[x][y].special = SPECIAL_NE; else if (u_spc) - env.tile_flavor[x][y].special = coinflip() ? + env.tile_flv[x][y].special = coinflip() ? SPECIAL_E : SPECIAL_SE; else if (d_spc) - env.tile_flavor[x][y].special = coinflip() ? + env.tile_flv[x][y].special = coinflip() ? SPECIAL_E : SPECIAL_NE; else - env.tile_flavor[x][y].special = jitter(SPECIAL_E); + env.tile_flv[x][y].special = jitter(SPECIAL_E); } else if (u_nrm) { if (r_spc && l_spc) - env.tile_flavor[x][y].special = SPECIAL_N; + env.tile_flv[x][y].special = SPECIAL_N; else if (r_spc && d_spc) - env.tile_flavor[x][y].special = SPECIAL_NW; + env.tile_flv[x][y].special = SPECIAL_NW; else if (l_spc && d_spc) - env.tile_flavor[x][y].special = SPECIAL_NE; + env.tile_flv[x][y].special = SPECIAL_NE; else if (r_spc) { - env.tile_flavor[x][y].special = coinflip() ? + env.tile_flv[x][y].special = coinflip() ? SPECIAL_N : SPECIAL_NW; } else if (l_spc) { - env.tile_flavor[x][y].special = coinflip() ? + env.tile_flv[x][y].special = coinflip() ? SPECIAL_N : SPECIAL_NE; } else - env.tile_flavor[x][y].special = jitter(SPECIAL_N); + env.tile_flv[x][y].special = jitter(SPECIAL_N); } else if (d_nrm) { if (r_spc && l_spc) - env.tile_flavor[x][y].special = SPECIAL_S; + env.tile_flv[x][y].special = SPECIAL_S; else if (r_spc && u_spc) - env.tile_flavor[x][y].special = SPECIAL_SW; + env.tile_flv[x][y].special = SPECIAL_SW; else if (l_spc && u_spc) - env.tile_flavor[x][y].special = SPECIAL_SE; + env.tile_flv[x][y].special = SPECIAL_SE; else if (r_spc) { - env.tile_flavor[x][y].special = coinflip() ? + env.tile_flv[x][y].special = coinflip() ? SPECIAL_S : SPECIAL_SW; } else if (l_spc) { - env.tile_flavor[x][y].special = coinflip() ? + env.tile_flv[x][y].special = coinflip() ? SPECIAL_S : SPECIAL_SE; } else - env.tile_flavor[x][y].special = jitter(SPECIAL_S); + env.tile_flv[x][y].special = jitter(SPECIAL_S); } else if (u_spc && d_spc) { // We know this value is already initialized and // is necessarily in bounds. - char t = env.tile_flavor[x][y-1].special; + char t = env.tile_flv[x][y-1].special; if (t == SPECIAL_NE || t == SPECIAL_E) - env.tile_flavor[x][y].special = SPECIAL_E; + env.tile_flv[x][y].special = SPECIAL_E; else if (t == SPECIAL_NW || t == SPECIAL_W) - env.tile_flavor[x][y].special = SPECIAL_W; + env.tile_flv[x][y].special = SPECIAL_W; else - env.tile_flavor[x][y].special = SPECIAL_FULL; + env.tile_flv[x][y].special = SPECIAL_FULL; } else if (r_spc && l_spc) { // We know this value is already initialized and // is necessarily in bounds. - char t = env.tile_flavor[x-1][y].special; + char t = env.tile_flv[x-1][y].special; if (t == SPECIAL_NW || t == SPECIAL_N) - env.tile_flavor[x][y].special = SPECIAL_N; + env.tile_flv[x][y].special = SPECIAL_N; else if (t == SPECIAL_SW || t == SPECIAL_S) - env.tile_flavor[x][y].special = SPECIAL_S; + env.tile_flv[x][y].special = SPECIAL_S; else - env.tile_flavor[x][y].special = SPECIAL_FULL; + env.tile_flv[x][y].special = SPECIAL_FULL; } else if (u_spc && l_spc) { - env.tile_flavor[x][y].special = SPECIAL_SE; + env.tile_flv[x][y].special = SPECIAL_SE; } else if (u_spc && r_spc) { - env.tile_flavor[x][y].special = SPECIAL_SW; + env.tile_flv[x][y].special = SPECIAL_SW; } else if (d_spc && l_spc) { - env.tile_flavor[x][y].special = SPECIAL_NE; + env.tile_flv[x][y].special = SPECIAL_NE; } else if (d_spc && r_spc) { - env.tile_flavor[x][y].special = SPECIAL_NW; + env.tile_flv[x][y].special = SPECIAL_NW; } else { - env.tile_flavor[x][y].special = SPECIAL_FULL; + env.tile_flv[x][y].special = SPECIAL_FULL; } } else { - env.tile_flavor[x][y].special = 0; + env.tile_flv[x][y].special = 0; } } @@ -3886,39 +3936,39 @@ void tile_init_flavor() if (grd[x][y] != DNGN_FLOOR || env.grid_colours[x][y] != baz_col) continue; - if (env.tile_flavor[x][y].special != SPECIAL_N - && env.tile_flavor[x][y].special != SPECIAL_S - && env.tile_flavor[x][y].special != SPECIAL_E - && env.tile_flavor[x][y].special != SPECIAL_W) + if (env.tile_flv[x][y].special != SPECIAL_N + && env.tile_flv[x][y].special != SPECIAL_S + && env.tile_flv[x][y].special != SPECIAL_E + && env.tile_flv[x][y].special != SPECIAL_W) { continue; } - int right_flavor = x < GXM - 1 ? env.tile_flavor[x+1][y].special + int right_flavor = x < GXM - 1 ? env.tile_flv[x+1][y].special : SPECIAL_FULL; - int down_flavor = y < GYM - 1 ? env.tile_flavor[x][y+1].special + int down_flavor = y < GYM - 1 ? env.tile_flv[x][y+1].special : SPECIAL_FULL; - int this_flavor = env.tile_flavor[x][y].special; + int this_flavor = env.tile_flv[x][y].special; if (this_flavor == SPECIAL_N && right_flavor == SPECIAL_S) { - env.tile_flavor[x][y].special = SPECIAL_NE; - env.tile_flavor[x+1][y].special = SPECIAL_SW; + env.tile_flv[x][y].special = SPECIAL_NE; + env.tile_flv[x+1][y].special = SPECIAL_SW; } else if (this_flavor == SPECIAL_S && right_flavor == SPECIAL_N) { - env.tile_flavor[x][y].special = SPECIAL_SE; - env.tile_flavor[x+1][y].special = SPECIAL_NW; + env.tile_flv[x][y].special = SPECIAL_SE; + env.tile_flv[x+1][y].special = SPECIAL_NW; } else if (this_flavor == SPECIAL_E && down_flavor == SPECIAL_W) { - env.tile_flavor[x][y].special = SPECIAL_SE; - env.tile_flavor[x][y+1].special = SPECIAL_NW; + env.tile_flv[x][y].special = SPECIAL_SE; + env.tile_flv[x][y+1].special = SPECIAL_NW; } else if (this_flavor == SPECIAL_W && down_flavor == SPECIAL_E) { - env.tile_flavor[x][y].special = SPECIAL_NE; - env.tile_flavor[x][y+1].special = SPECIAL_SW; + env.tile_flv[x][y].special = SPECIAL_NE; + env.tile_flv[x][y+1].special = SPECIAL_SW; } } } @@ -4070,7 +4120,7 @@ void tile_place_monster(int gx, int gy, int idx, bool foreground, bool detected) { eq = tilep_equ_weapon(mitm[mon_wep]); } - t = flag | TileMcacheFind(cls, eq, race); + t = flag | _mcache_register(cls, eq, race); } else if (mon_wep != NON_ITEM) { @@ -4155,7 +4205,7 @@ void tile_place_monster(int gx, int gy, int idx, bool foreground, bool detected) case TILE_MONS_MERFOLK_FIGHTER_WATER: if (eq != 0 ) - t = flag | TileMcacheFind(t0, eq); + t = flag | _mcache_register(t0, eq); break; } @@ -4164,6 +4214,11 @@ void tile_place_monster(int gx, int gy, int idx, bool foreground, bool detected) if (foreground) { env.tile_fg[ep.x-1][ep.y-1] = t; + if (menv[idx].is_named()) + { + tiles.add_text_tag(TAG_NAMED_MONSTER, + menv[idx].name(DESC_CAP_A), gc); + } } else { @@ -4205,8 +4260,8 @@ void tile_finish_dngn(unsigned int *tileb, int cx, int cy) int x, y; int count = 0; - const bool bazaar = is_bazaar(); - const unsigned short baz_col = get_bazaar_special_colour(); + const bool bazaar = _is_bazaar(); + const unsigned short baz_col = _get_bazaar_special_colour(); for (y = 0; y < crawl_view.viewsz.y; y++) for (x = 0; x < crawl_view.viewsz.x; x++) @@ -4215,17 +4270,17 @@ void tile_finish_dngn(unsigned int *tileb, int cx, int cy) const int gx = view2gridX(x + 1) + cx - you.x_pos; const int gy = view2gridY(y + 1) + cy - you.y_pos; - char wall_flv = 0; - char floor_flv = 0; - char special_flv = 0; + unsigned char wall_flv = 0; + unsigned char floor_flv = 0; + unsigned char special_flv = 0; bool is_special = false; const bool in_bounds = (map_bounds(gx, gy)); if (in_bounds) { - wall_flv = env.tile_flavor[gx][gy].wall; - floor_flv = env.tile_flavor[gx][gy].floor; - special_flv = env.tile_flavor[gx][gy].special; + wall_flv = env.tile_flv[gx][gy].wall; + floor_flv = env.tile_flv[gx][gy].floor; + special_flv = env.tile_flv[gx][gy].special; is_special = (bazaar && env.grid_colours[gx][gy] == baz_col); } @@ -4273,414 +4328,4 @@ void tile_finish_dngn(unsigned int *tileb, int cx, int cy) } } -void tile_draw_dungeon(unsigned int *tileb) -{ - tile_finish_dngn(tileb, you.x_pos, you.y_pos); - TileDrawDungeon(tileb); -} - -#define swapint(a, b) {int tmp = a; a = b; b = tmp;} - -// Item is unided(1) or tried(2) or id'ed (0) -static int _item_unid_type(const item_def &item) -{ - if ((item.flags & ISFLAG_KNOW_TYPE) != 0) - return 0; - - const int s = item.sub_type; - const id_arr& id = get_typeid_array(); - int id0 = 0; - - switch (item.base_type) - { - case OBJ_STAVES: - id0 = id[ IDTYPE_STAVES ][s]; - if (id0 != ID_KNOWN_TYPE) - return 1; - else - return 0; - - case OBJ_SCROLLS: - id0 = id[ IDTYPE_SCROLLS ][s]; - break; - - case OBJ_WANDS: - id0 = id[ IDTYPE_WANDS ][s]; - break; - - case OBJ_POTIONS: - id0 = id[ IDTYPE_POTIONS ][s]; - break; - - case OBJ_JEWELLERY: - if (is_artefact(item)) - { - if (item.props.exists("jewellery_tried") - && item.props["jewellery_tried"].get_bool()) - { - return 2; - } - return 1; - } - id0 = id[ IDTYPE_JEWELLERY ][s]; - break; - - default: - return 0; - } - - if (id0 == ID_TRIED_TYPE) - return 2; - else if (id0 != ID_KNOWN_TYPE) - return 1; - - return 0; -} - -// Helper routine: sort floor item index and pack into idx. -static int _pack_floor_item(int *idx, int *flag, int *isort, int max) -{ - int n = 0; - static int isort_weapon2[NUM_WEAPONS]; - static int isort_armour2[NUM_ARMOURS]; - - static const int isort_weapon[NUM_WEAPONS] = - { - WPN_WHIP, WPN_CLUB, WPN_HAMMER, WPN_MACE, - WPN_FLAIL, WPN_DEMON_WHIP, - WPN_ANKUS, WPN_MORNINGSTAR, WPN_EVENINGSTAR, - WPN_SPIKED_FLAIL, WPN_GREAT_MACE, WPN_DIRE_FLAIL, - WPN_GIANT_CLUB, WPN_GIANT_SPIKED_CLUB, - - WPN_KNIFE, WPN_DAGGER, WPN_SHORT_SWORD, WPN_SABRE, WPN_QUICK_BLADE, - WPN_FALCHION, WPN_LONG_SWORD, WPN_SCIMITAR, WPN_KATANA, - WPN_DEMON_BLADE, WPN_DOUBLE_SWORD, WPN_GREAT_SWORD, WPN_TRIPLE_SWORD, - - WPN_HAND_AXE, WPN_WAR_AXE, WPN_BROAD_AXE, - WPN_BATTLEAXE, WPN_EXECUTIONERS_AXE, - - WPN_SPEAR, WPN_TRIDENT, WPN_HALBERD, WPN_SCYTHE, - WPN_GLAIVE, WPN_DEMON_TRIDENT, - - WPN_QUARTERSTAFF, - - WPN_SLING, WPN_BOW, WPN_CROSSBOW, WPN_HAND_CROSSBOW - }; - static const int isort_armour[NUM_ARMOURS] = - { - ARM_ROBE, - ARM_ANIMAL_SKIN, - ARM_LEATHER_ARMOUR, - ARM_TROLL_LEATHER_ARMOUR, - ARM_RING_MAIL, ARM_SCALE_MAIL, ARM_CHAIN_MAIL, - ARM_SPLINT_MAIL, ARM_BANDED_MAIL, ARM_PLATE_MAIL, - ARM_CRYSTAL_PLATE_MAIL, - ARM_SWAMP_DRAGON_ARMOUR, - ARM_MOTTLED_DRAGON_ARMOUR, - ARM_STEAM_DRAGON_ARMOUR, - ARM_DRAGON_ARMOUR, - ARM_ICE_DRAGON_ARMOUR, - ARM_STORM_DRAGON_ARMOUR, - ARM_GOLD_DRAGON_ARMOUR, - ARM_TROLL_HIDE, - ARM_SWAMP_DRAGON_HIDE, - ARM_MOTTLED_DRAGON_HIDE, - ARM_STEAM_DRAGON_HIDE, - ARM_DRAGON_HIDE, - ARM_ICE_DRAGON_HIDE, - ARM_STORM_DRAGON_HIDE, - ARM_GOLD_DRAGON_HIDE, - ARM_CLOAK, - ARM_BUCKLER, ARM_SHIELD, ARM_LARGE_SHIELD, - ARM_HELMET, ARM_GLOVES, ARM_BOOTS - }; - - for (int i = 0; i < NUM_WEAPONS; i++) - isort_weapon2[isort_weapon[i]] = i; - - for (int i = 0; i < NUM_ARMOURS; i++) - isort_armour2[isort_armour[i]] = i; - - int o = igrd[you.x_pos][you.y_pos]; - if (o == NON_ITEM) return 0; - - while (o != NON_ITEM) - { - int id0 = _item_unid_type(mitm[o]); - int next = mitm[o].link; - int typ = mitm[o].base_type; - - if (n >= max) break; - - idx[n] = o; - isort[n] = typ * 256 * 3; - if (typ == OBJ_WEAPONS) - { - isort[n] += 3 * isort_weapon2[ mitm[o].sub_type]; - } - if (typ == OBJ_ARMOUR) - { - isort[n] += 3 * isort_armour2[ mitm[o].sub_type ]; - } - flag[n] = 0; - - if (item_ident( mitm[o], ISFLAG_KNOW_CURSE ) && - item_cursed(mitm[o])) - { - flag[n] |= TILEI_FLAG_CURSE; - } - - if (id0 != 0) - { - isort[n] += id0; - if (id0 == 2) - flag[n] = TILEI_FLAG_TRIED; - } - flag[n] |= TILEI_FLAG_FLOOR; - - // Simple Bubble sort - int k = n; - while (k > 0 && isort[k-1] > isort[k]) - { - swapint(idx[k-1], idx[k]); - swapint(isort[k-1], isort[k]); - swapint(flag[k-1], flag[k]); - k--; - } - n++; - o = next; - } - return n; -} - -// Helper routine: Calculate tile index and quantity data to be displayed -static void _finish_inven_data(int n, int *tiles, int *num, int *idx, - int *iflag) -{ - int i; - - for (i = 0; i < n; i++) - { - int q = -1; - int j = idx[i]; - item_def *itm; - - if (j == -1) - { - num[i] = -1; - tiles[i] = 0; - continue; - } - - if (iflag[i] & TILEI_FLAG_FLOOR) - itm = &mitm[j]; - else - itm = &you.inv[j]; - - int type = itm->base_type; - - if (type == OBJ_FOOD || type == OBJ_SCROLLS - || type == OBJ_POTIONS || type == OBJ_MISSILES) - { - q = itm->quantity; - } - if (q == 1) - q = -1; - - if (type == OBJ_WANDS - && ((itm->flags & ISFLAG_KNOW_PLUSES) - || itm->plus2 == ZAPCOUNT_EMPTY)) - { - q = itm->plus; - } - - tiles[i] = tileidx_item(*itm); - num[i] = q; - } -} - -// Display Inventory/floor items -#include "guic.h" -extern TileRegionClass *region_item; -extern TileRegionClass *region_item2; -extern WinClass *win_main; - -void tile_draw_inv(int flag) -{ - // "inventory" including items on floor - #define MAXINV 200 - int tiles[MAXINV]; - int num[MAXINV]; - int idx[MAXINV]; - int iflag[MAXINV]; - int isort[MAXINV]; - - if (flag == -1) - { - flag = (win_main->active_layer == 0) ? REGION_INV1 - : REGION_INV2; - } - - TileRegionClass *r = (flag == REGION_INV1) ? region_item - : region_item2; - int numInvTiles = r->mx * r->my; - if (numInvTiles > MAXINV) - numInvTiles = MAXINV; - - // Show one row of ground tiles, no matter what. This may cause some - // items not to show up, but theoretically you've ordered tile_show_items - // to prioritize the important stuff. - int max_inventory_items = std::min(numInvTiles - r->mx, ENDOFPACK); - - // which items to show in inventory - const char *item_chars = Options.tile_show_items; - - // show no items, please - if (item_chars[0] == 0) - return; - - int eq_flag[ENDOFPACK]; - int empty = 0; // counts empty slots - - // first set eq_flag = 1 for all slots that actually hold valid items - // XXX: Why? --jpeg - for (int i = 0; i < max_inventory_items; i++) - { - eq_flag[i] = - (you.inv[i].quantity != 0 && is_valid_item( you.inv[i])) ? 1 : 0; - - if (!eq_flag[i]) - empty++; - } - - // next, increase eq_flag to 2 if it's actually equipped - // FIX ME: Doesn't check for sensible equipment, i.e. - // wielded armour counts, too - for (int eq = 0; eq < NUM_EQUIP; eq++) - { - int slot = you.equip[eq]; - if (slot >= 0 && slot < ENDOFPACK) - eq_flag[slot] = 2; - } - - int n = 0; - - // item.base_type <-> char conversion table - const static char *obj_syms = ")([/%#?=!#+\\0}x"; - - for (int i = 0; i < (int)strlen(item_chars); i++) - { - int top = n; - char ic = item_chars[i]; - - if (n >= numInvTiles) - break; - - // Items on the floor - if (ic == '.') - { - n += _pack_floor_item(&idx[n], &iflag[n], &isort[n], - numInvTiles - n); - continue; - } - - // empty slots - if (ic == '_') - { - for (int j = 0; j < empty && n < numInvTiles; j++) - { - idx[n] = -1; - iflag[n] = 0; - n++; - } - continue; - } - - // convert item char to item type - int type = -1; - for (int j = 0; j < (int)strlen(obj_syms); j++) - { - if (obj_syms[j] == ic) - { - type = j; - break; - } - } - - if (type == -1) - continue; - - for (int j = 0; j < max_inventory_items && n < numInvTiles; j++) - { - if (you.inv[j].base_type == type && eq_flag[j] != 0) - { - int sval = NUM_EQUIP + you.inv[j].sub_type; - int base = 0; - int id0 = _item_unid_type(you.inv[j]); - - idx[n] = j; - iflag[n] = 0; - - if (type == OBJ_JEWELLERY && sval >= AMU_RAGE) - { - base = 1000; - sval = base + sval; - } - - if (id0 == 2) - { - iflag[n] |= TILEI_FLAG_TRIED; - // To the tail - sval = base + 980; - } - else if (id0 == 1) - { - // To the tail - sval = base + 990; - } - - // Equipment first - if (eq_flag[j] == 2) - { - //sval = base; - iflag[n] |= TILEI_FLAG_EQUIP; - } - - if (item_cursed(you.inv[j]) - && item_ident( you.inv[j], ISFLAG_KNOW_CURSE )) - { - iflag[n] |= TILEI_FLAG_CURSE; - } - - if (flag == REGION_INV2) - sval = j; - - isort[n] = sval; - - int k = n; - while (k > top && isort[k-1] > isort[k]) - { - swapint(idx[k-1], idx[k]); - swapint(isort[k-1], isort[k]); - swapint(iflag[k-1], iflag[k]); - k--; - } - - n++; - } // type == base - } // j - } // i - - _finish_inven_data(n, tiles, num, idx, iflag); - - for (int i = n; i < numInvTiles; i++) - { - tiles[i] = 0; - num[i] = 0; - idx[i] = -1; - iflag[i] = 0; - } - TileDrawInvData(n, flag, tiles, num, idx, iflag); -} - #endif diff --git a/crawl-ref/source/tilereg.cc b/crawl-ref/source/tilereg.cc new file mode 100644 index 0000000000..4d9ff8645e --- /dev/null +++ b/crawl-ref/source/tilereg.cc @@ -0,0 +1,2553 @@ +/* + * File: tilereg.cc + * Summary: Region system implementaions + * + * Created by: ennewalker on Sat Jan 5 01:33:53 2008 UTC + * + * Modified for Crawl Reference by $Author: j-p-e-g $ on $Date: 2008-03-07 $ + */ + +#include "AppHdr.h" +#include "cio.h" +#include "debug.h" +#include "describe.h" +#include "food.h" +#include "itemname.h" +#include "it_use2.h" +#include "item_use.h" +#include "message.h" +#include "misc.h" +#include "newgame.h" +#include "mon-util.h" +#include "player.h" +#include "spells3.h" +#include "stuff.h" +#include "terrain.h" +#include "transfor.h" +#include "travel.h" + +#include "tilereg.h" +#include "tiles.h" +#include "tilefont.h" +#include "tilesdl.h" +#include "tiledef-dngn.h" + +#include <SDL_opengl.h> + +coord_def Region::NO_CURSOR(-1, -1); + +unsigned int TextRegion::print_x; +unsigned int TextRegion::print_y; +TextRegion *TextRegion::text_mode = NULL; +int TextRegion::text_col = 0; + +TextRegion *TextRegion::cursor_region= NULL; +int TextRegion::cursor_flag = 0; +unsigned int TextRegion::cursor_x; +unsigned int TextRegion::cursor_y; + +const int map_colours[MAX_MAP_COL][3] = +{ + { 0, 0, 0}, // BLACK + {128, 128, 128}, // DKGREY + {160, 160, 160}, // MDGREY + {192, 192, 192}, // LTGREY + {255, 255, 255}, // WHITE + + { 0, 64, 255}, // BLUE (actually cyan-blue) + {128, 128, 255}, // LTBLUE + { 0, 32, 128}, // DKBLUE (maybe too dark) + + { 0, 255, 0}, // GREEN + {128, 255, 128}, // LTGREEN + { 0, 128, 0}, // DKGREEN + + { 0, 255, 255}, // CYAN + { 64, 255, 255}, // LTCYAN (maybe too pale) + { 0, 128, 128}, // DKCYAN + + {255, 0, 0}, // RED + {255, 128, 128}, // LTRED (actually pink) + {128, 0, 0}, // DKRED + + {192, 0, 255}, // MAGENTA (actually blue-magenta) + {255, 128, 255}, // LTMAGENTA + { 96, 0, 128}, // DKMAGENTA + + {255, 255, 0}, // YELLOW + {255, 255, 64}, // LTYELLOW (maybe too pale) + {128, 128, 0}, // DKYELLOW + + {165, 91, 0}, // BROWN +}; + +const int dir_dx[9] = {-1, 0, 1, -1, 0, 1, -1, 0, 1}; +const int dir_dy[9] = {1, 1, 1, 0, 0, 0, -1, -1, -1}; + +const int cmd_normal[9] = {'b', 'j', 'n', 'h', '.', 'l', 'y', 'k', 'u'}; +const int cmd_shift[9] = {'B', 'J', 'N', 'H', '5', 'L', 'Y', 'K', 'U'}; +const int cmd_ctrl[9] = {CONTROL('B'), CONTROL('J'), CONTROL('N'), + CONTROL('H'), 'X', CONTROL('L'), + CONTROL('Y'), CONTROL('K'), CONTROL('U')}; +const int cmd_dir[9] = {'1', '2', '3', '4', '5', '6', '7', '8', '9'}; + +Region::Region() : + ox(0), + oy(0), + dx(0), + dy(0), + mx(0), + my(0), + wx(0), + wy(0), + sx(0), + sy(0), + ex(0), + ey(0) +{ +} + +void Region::resize(unsigned int _mx, unsigned int _my) +{ + mx = _mx; + my = _my; + + recalculate(); +} + +void Region::place(unsigned int _sx, unsigned int _sy, unsigned int margin) +{ + sx = _sx; + sy = _sy; + ox = margin; + oy = margin; + + recalculate(); +} + +void Region::resize_to_fit(int _wx, int _wy) +{ + if (_wx < 0 || _wy < 0) + { + mx = wx = my = wy = 0; + ey = sy; + ex = sy; + return; + } + + unsigned int inner_x = _wx - 2 * ox; + unsigned int inner_y = _wy - 2 * oy; + + mx = dx ? inner_x / dx : 0; + my = dy ? inner_y / dy : 0; + + recalculate(); +} + +void Region::recalculate() +{ + wx = ox * 2 + mx * dx; + wy = oy * 2 + my * dy; + ex = sx + wx; + ey = sy + wy; + + on_resize(); +} + +Region::~Region() +{ +} + +bool Region::inside(unsigned int x, unsigned int y) +{ + // TODO enne - need to handle invalid/unintialised regions? + return (x >= sx && y >= sy && x <= ex && y <= ey); +} + +bool Region::mouse_pos(int mouse_x, int mouse_y, int &cx, int &cy) +{ + int x = mouse_x - ox - sx; + int y = mouse_y - oy - sy; + bool valid = (x >= 0 && y >= 0); + + x /= dx; + y /= dy; + valid &= ((unsigned int)x < mx && (unsigned int)y < my); + + cx = x; + cy = y; + + return valid; +} + +TileRegion::TileRegion(ImageManager* im, unsigned int tile_x, unsigned int tile_y) +{ + ASSERT(im); + m_image = im; + dx = tile_x; + dy = tile_y; +} + +TileRegion::~TileRegion() +{ +} + +DungeonRegion::DungeonRegion(ImageManager* im, FTFont *tag_font, + unsigned int tile_x, unsigned int tile_y) : + TileRegion(im, tile_x, tile_y), + m_cx_to_gx(0), + m_cy_to_gy(0), + m_tag_font(tag_font) +{ + ASSERT(tag_font); + for (unsigned int i = 0; i < CURSOR_MAX; i++) + m_cursor[i] = NO_CURSOR; +} + +DungeonRegion::~DungeonRegion() +{ +} + +void DungeonRegion::load_dungeon(unsigned int* tileb, int cx_to_gx, int cy_to_gy) +{ + m_tileb.clear(); + + if (!tileb) + return; + + unsigned int len = 2 * crawl_view.viewsz.x * crawl_view.viewsz.y; + m_tileb.resize(len); + // TODO enne - move this function into dungeonregion + tile_finish_dngn(tileb, you.pos().x, you.pos().y); + memcpy(&m_tileb[0], tileb, sizeof(unsigned int) * len); + + m_cx_to_gx = cx_to_gx; + m_cy_to_gy = cy_to_gy; + + place_cursor(CURSOR_TUTORIAL, m_cursor[CURSOR_TUTORIAL]); +} + +void DungeonRegion::add_quad_doll(unsigned int part, unsigned int idx, int ymax, unsigned int x, unsigned int y, int ox_spec, int oy_spec) +{ + float tex_sx, tex_sy, tex_wx, tex_wy; + int ox_extra, oy_extra, wx_pix, wy_pix; + m_image->m_textures[TEX_DOLL].get_texcoord_doll(part, idx, ymax, tex_sx, tex_sy, tex_wx, tex_wy, wx_pix, wy_pix, ox_extra, oy_extra); + + if (wx_pix <= 0 || wy_pix <= 0) + return; + + float pos_ox = (ox_spec + ox_extra) / (float)TILE_X; + float pos_oy = (oy_spec + oy_extra) / (float)TILE_Y; + + float tex_ex = tex_sx + tex_wx; + float tex_ey = tex_sy + tex_wy; + + float pos_sx = x + pos_ox; + float pos_sy = y + pos_oy; + float pos_ex = pos_sx + wx_pix / (float)TILE_X; + float pos_ey = pos_sy + wy_pix / (float)TILE_Y; + + tile_vert v; + v.pos_x = pos_sx; + v.pos_y = pos_sy; + v.tex_x = tex_sx; + v.tex_y = tex_sy; + m_verts.push_back(v); + + v.pos_y = pos_ey; + v.tex_y = tex_ey; + m_verts.push_back(v); + + v.pos_x = pos_ex; + v.tex_x = tex_ex; + m_verts.push_back(v); + + v.pos_y = pos_sy; + v.tex_y = tex_sy; + m_verts.push_back(v); +} + +void TileRegion::add_quad(TextureID tex, unsigned int idx, unsigned int x, unsigned int y, int ofs_x, int ofs_y) +{ + // Generate quad + // + // 0 - 3 + // | | + // 1 - 2 + // + // Data Layout: + // float2 (position) + // float2 (texcoord) + + float tex_sx, tex_sy, tex_wx, tex_wy; + m_image->m_textures[tex].get_texcoord(idx, tex_sx, tex_sy, tex_wx, tex_wy); + float tex_ex = tex_sx + tex_wx; + float tex_ey = tex_sy + tex_wy; + + float pos_sx = x + ofs_x / (float)TILE_X; + float pos_sy = y + ofs_y / (float)TILE_Y; + float pos_ex = pos_sx + 1; + float pos_ey = pos_sy + 1; + + // TODO enne - handle wx/wy non-standard sizes + tile_vert v; + v.pos_x = pos_sx; + v.pos_y = pos_sy; + v.tex_x = tex_sx; + v.tex_y = tex_sy; + m_verts.push_back(v); + + v.pos_y = pos_ey; + v.tex_y = tex_ey; + m_verts.push_back(v); + + v.pos_x = pos_ex; + v.tex_x = tex_ex; + m_verts.push_back(v); + + v.pos_y = pos_sy; + v.tex_y = tex_sy; + m_verts.push_back(v); +} + +void DungeonRegion::draw_background(unsigned int bg, unsigned int x, unsigned int y) +{ + unsigned int bg_idx = bg & TILE_FLAG_MASK; + if (bg_idx >= TILE_DNGN_WAX_WALL) + { + tile_flavour &flv = env.tile_flv[x + m_cx_to_gx][y + m_cy_to_gy]; + add_quad(TEX_DUNGEON, flv.floor, x, y); + } + + if (bg & TILE_FLAG_BLOOD) + { + tile_flavour &flv = env.tile_flv[x + m_cx_to_gx][y + m_cy_to_gy]; + unsigned int offset = flv.special % tile_DNGN_count[IDX_BLOOD]; + add_quad(TEX_DUNGEON, TILE_BLOOD + offset, x, y); + } + + add_quad(TEX_DUNGEON, bg_idx, x, y); + + if (bg & TILE_FLAG_HALO) + add_quad(TEX_DUNGEON, TILE_HALO, x, y); + + if (bg & TILE_FLAG_SANCTUARY && !(bg & TILE_FLAG_UNSEEN)) + add_quad(TEX_DUNGEON, TILE_SANCTUARY, x, y); + + // Apply the travel exclusion under the foreground if the cell is + // visible. It will be applied later if the cell is unseen. + if (bg & TILE_FLAG_EXCL_CTR && !(bg & TILE_FLAG_UNSEEN)) + add_quad(TEX_DUNGEON, TILE_TRAVEL_EXCLUSION_CENTRE_BG, x, y); + else if (bg & TILE_FLAG_TRAV_EXCL && !(bg & TILE_FLAG_UNSEEN)) + add_quad(TEX_DUNGEON, TILE_TRAVEL_EXCLUSION_BG, x, y); + + if (bg & TILE_FLAG_RAY) + add_quad(TEX_DUNGEON, TILE_RAY_MESH, x, y); +} + +void DungeonRegion::draw_player(unsigned int x, unsigned int y) +{ + dolls_data default_doll; + dolls_data player_doll; + dolls_data result; + + // TODO enne - store character doll here and get gender + for (int i = 0; i < TILEP_PARTS_TOTAL; i++) + player_doll.parts[i] = TILEP_SHOW_EQUIP; + int gender = 0; + + tilep_race_default(you.species, gender, you.experience_level, + default_doll.parts); + + result = player_doll; + + // TODO enne - make these configurable + result.parts[TILEP_PART_BASE] = default_doll.parts[TILEP_PART_BASE]; + result.parts[TILEP_PART_DRCHEAD] = default_doll.parts[TILEP_PART_DRCHEAD]; + result.parts[TILEP_PART_DRCWING] = default_doll.parts[TILEP_PART_DRCWING]; + bool halo = inside_halo(you.x_pos, you.y_pos); + result.parts[TILEP_PART_HALO] = halo ? TILEP_HALO_TSO : 0; + + if (result.parts[TILEP_PART_HAND1] == TILEP_SHOW_EQUIP) + { + int item = you.equip[EQ_WEAPON]; + if (you.attribute[ATTR_TRANSFORMATION] == TRAN_BLADE_HANDS) + result.parts[TILEP_PART_HAND1] = TILEP_HAND1_BLADEHAND; + else if (item == -1) + result.parts[TILEP_PART_HAND1] = 0; + else + result.parts[TILEP_PART_HAND1] = tilep_equ_weapon(you.inv[item]); + } + if (result.parts[TILEP_PART_HAND2] == TILEP_SHOW_EQUIP) + { + int item = you.equip[EQ_SHIELD]; + if (you.attribute[ATTR_TRANSFORMATION] == TRAN_BLADE_HANDS) + result.parts[TILEP_PART_HAND2] = TILEP_HAND2_BLADEHAND; + else if (item == -1) + result.parts[TILEP_PART_HAND2] = 0; + else + result.parts[TILEP_PART_HAND2] = tilep_equ_shield(you.inv[item]); + } + if (result.parts[TILEP_PART_BODY] == TILEP_SHOW_EQUIP) + { + int item = you.equip[EQ_BODY_ARMOUR]; + if (item == -1) + result.parts[TILEP_PART_BODY] = 0; + else + result.parts[TILEP_PART_BODY] = tilep_equ_armour(you.inv[item]); + } + if (result.parts[TILEP_PART_CLOAK] == TILEP_SHOW_EQUIP) + { + int item = you.equip[EQ_CLOAK]; + if (item == -1) + result.parts[TILEP_PART_CLOAK] = 0; + else + result.parts[TILEP_PART_CLOAK] = tilep_equ_cloak(you.inv[item]); + } + if (result.parts[TILEP_PART_HELM] == TILEP_SHOW_EQUIP) + { + int item = you.equip[EQ_HELMET]; + if (item != -1) + { + result.parts[TILEP_PART_HELM] = tilep_equ_helm(you.inv[item]); + } + else if (player_mutation_level(MUT_HORNS) > 0) + { + switch (player_mutation_level(MUT_HORNS)) + { + case 1: + result.parts[TILEP_PART_HELM] = TILEP_HELM_HORNS1; + break; + case 2: + result.parts[TILEP_PART_HELM] = TILEP_HELM_HORNS2; + break; + case 3: + result.parts[TILEP_PART_HELM] = TILEP_HELM_HORNS3; + break; + } + } + else + { + result.parts[TILEP_PART_HELM] = 0; + } + } + if (result.parts[TILEP_PART_BOOTS] == TILEP_SHOW_EQUIP) + { + int item = you.equip[EQ_BOOTS]; + if (item != -1) + result.parts[TILEP_PART_BOOTS] = tilep_equ_boots(you.inv[item]); + else if (player_mutation_level(MUT_HOOVES)) + result.parts[TILEP_PART_BOOTS] = TILEP_BOOTS_HOOVES; + else + result.parts[TILEP_PART_BOOTS] = 0; + } + if (result.parts[TILEP_PART_ARM] == TILEP_SHOW_EQUIP) + { + int item = you.equip[EQ_GLOVES]; + if (item != -1) + result.parts[TILEP_PART_ARM] = tilep_equ_gloves(you.inv[item]); + else if (player_mutation_level(MUT_CLAWS) >= 3 + || you.species == SP_TROLL || you.species == SP_GHOUL) + { + // There is player_has_claws() but it is not equivalent. + // Claws appear if they're big enough to not wear gloves + // or on races that have claws. + result.parts[TILEP_PART_ARM] = TILEP_ARM_CLAWS; + } + else + result.parts[TILEP_PART_ARM] = 0; + } + + draw_doll(result, x, y); +} + +bool DungeonRegion::draw_objects(unsigned int fg, unsigned int x, unsigned int y) +{ + unsigned int fg_idx = fg & TILE_FLAG_MASK; + + // handled elsewhere + if (fg_idx == TILE_PLAYER) + return false; + + int equ_tile; + int draco; + int mon_tile; + if (get_mcache_entry(fg_idx, mon_tile, equ_tile, draco)) + { + if (!draco) + add_quad(TEX_DEFAULT, get_base_idx_from_mcache(fg_idx), x, y); + return true; + } + else if (fg_idx) + { + add_quad(TEX_DEFAULT, fg_idx, x, y); + } + return false; +} + +void DungeonRegion::draw_doll(dolls_data &doll, unsigned int x, unsigned int y) +{ + int p_order[TILEP_PARTS_TOTAL] = + { + TILEP_PART_SHADOW, + TILEP_PART_HALO, + TILEP_PART_DRCWING, + TILEP_PART_CLOAK, + TILEP_PART_BASE, + TILEP_PART_BOOTS, + TILEP_PART_LEG, + TILEP_PART_BODY, + TILEP_PART_ARM, + TILEP_PART_HAND1, + TILEP_PART_HAND2, + TILEP_PART_HAIR, + TILEP_PART_BEARD, + TILEP_PART_HELM, + TILEP_PART_DRCHEAD + }; + + int flags[TILEP_PARTS_TOTAL]; + tilep_calc_flags(doll.parts, flags); + + // For skirts, boots go under the leg armour. For pants, they go over. + if (doll.parts[TILEP_PART_LEG] < TILEP_LEG_SKIRT_OFS) + { + p_order[5] = TILEP_PART_BOOTS; + p_order[6] = TILEP_PART_LEG; + } + + for (int i = 0; i < TILEP_PARTS_TOTAL; i++) + { + int p = p_order[i]; + if (!doll.parts[p]) + continue; + + int ymax = TILE_Y; + + if (flags[p] == TILEP_FLAG_CUT_CENTAUR + || flags[p] == TILEP_FLAG_CUT_NAGA) + { + ymax = 18; + } + + if (doll.parts[p] && p == TILEP_PART_BOOTS + && (doll.parts[p] == TILEP_BOOTS_NAGA_BARDING + || doll.parts[p] == TILEP_BOOTS_CENTAUR_BARDING)) + { + // Special case for barding. They should be in "boots" but because + // they're double-wide, they're stored in a different part. We just + // intercept it here before drawing. + char tile = (doll.parts[p] == TILEP_BOOTS_NAGA_BARDING) ? + TILEP_SHADOW_NAGA_BARDING : + TILEP_SHADOW_CENTAUR_BARDING; + + add_quad_doll(TILEP_PART_SHADOW, tile, TILE_Y, x, y, 0, 0); + } + else + { + add_quad_doll(p, doll.parts[p], ymax, x, y, 0, 0); + } + } +} + +void DungeonRegion::draw_draco(int colour, int mon_idx, int equ_tile, unsigned int x, unsigned int y) +{ + dolls_data doll; + + int armour = 0; + int armour2 = 0; + int weapon = 0; + int weapon2 = 0; + int arm = 0; + + for (int i = 0; i < TILEP_PARTS_TOTAL; i++) + doll.parts[i] = 0; + + doll.parts[TILEP_PART_SHADOW] = 1; + doll.parts[TILEP_PART_BASE] = TILEP_BASE_DRACONIAN + colour * 2; + doll.parts[TILEP_PART_DRCWING] = 1 + colour; + doll.parts[TILEP_PART_DRCHEAD] = 1 + colour; + + switch (mon_idx) + { + case MONS_DRACONIAN_CALLER: + weapon = TILEP_HAND1_STAFF_EVIL; + weapon2 = TILEP_HAND2_BOOK_YELLOW; + armour = TILEP_BODY_ROBE_BROWN; + break; + + case MONS_DRACONIAN_MONK: + arm = TILEP_ARM_GLOVE_SHORT_BLUE; + armour = TILEP_BODY_KARATE2; + break; + + case MONS_DRACONIAN_ZEALOT: + weapon = TILEP_HAND1_MACE; + weapon2 = TILEP_HAND2_BOOK_CYAN; + armour = TILEP_BODY_MONK_BLUE; + break; + + case MONS_DRACONIAN_SHIFTER: + weapon = TILEP_HAND1_STAFF_LARGE; + armour = TILEP_BODY_ROBE_CYAN; + weapon2 = TILEP_HAND2_BOOK_GREEN; + break; + + case MONS_DRACONIAN_ANNIHILATOR: + weapon = TILEP_HAND1_STAFF_RUBY; + weapon2 = TILEP_HAND2_FIRE_CYAN; + armour = TILEP_BODY_ROBE_GREEN_GOLD; + break; + + case MONS_DRACONIAN_KNIGHT: + weapon = equ_tile; + weapon2 = TILEP_HAND2_SHIELD_KNIGHT_GRAY; + armour = TILEP_BODY_BPLATE_METAL1; + armour2 = TILEP_LEG_BELT_GRAY; + break; + + case MONS_DRACONIAN_SCORCHER: + weapon = TILEP_HAND1_FIRE_RED; + weapon2 = TILEP_HAND2_BOOK_RED; + armour = TILEP_BODY_ROBE_RED; + break; + + default: + weapon = equ_tile; + armour = TILEP_BODY_BELT2; + armour2 = TILEP_LEG_LOINCLOTH_RED; + break; + } + + doll.parts[TILEP_PART_HAND1] = weapon; + doll.parts[TILEP_PART_HAND2] = weapon2; + doll.parts[TILEP_PART_BODY] = armour; + doll.parts[TILEP_PART_LEG] = armour2; + doll.parts[TILEP_PART_ARM] = arm; + + draw_doll(doll, x, y); +} + +void DungeonRegion::draw_monster(unsigned int fg, unsigned int x, unsigned int y) +{ + // Currently, monsters only get displayed weapons (no armour) + unsigned int fg_idx = fg & TILE_FLAG_MASK; + if (fg_idx < TILE_MCACHE_START) + return; + + int equ_tile; + int draco; + int mon_tile; + + if (!get_mcache_entry(fg_idx, mon_tile, equ_tile, draco)) + return; + + if (draco == 0) + { + int ofs_x, ofs_y; + tile_get_monster_weapon_offset(mon_tile, ofs_x, ofs_y); + + add_quad_doll(TILEP_PART_HAND1, equ_tile, TILE_Y, x, y, ofs_x, ofs_y); + + // In some cases, overlay a second weapon tile... + if (mon_tile == TILE_MONS_DEEP_ELF_BLADEMASTER) + { + int eq2; + switch (equ_tile) + { + case TILEP_HAND1_DAGGER: + eq2 = TILEP_HAND2_DAGGER; + break; + case TILEP_HAND1_SABRE: + eq2 = TILEP_HAND2_SABRE; + break; + default: + case TILEP_HAND1_SHORT_SWORD_SLANT: + eq2 = TILEP_HAND2_SHORT_SWORD_SLANT; + break; + }; + add_quad_doll(TILEP_PART_HAND2, eq2, TILE_Y, x, y, -ofs_x, ofs_y); + } + } + else + { + int colour; + switch (draco) + { + default: + case MONS_DRACONIAN: colour = 0; break; + case MONS_BLACK_DRACONIAN: colour = 1; break; + case MONS_YELLOW_DRACONIAN: colour = 2; break; + case MONS_GREEN_DRACONIAN: colour = 4; break; + case MONS_MOTTLED_DRACONIAN:colour = 5; break; + case MONS_PALE_DRACONIAN: colour = 6; break; + case MONS_PURPLE_DRACONIAN: colour = 7; break; + case MONS_RED_DRACONIAN: colour = 8; break; + case MONS_WHITE_DRACONIAN: colour = 9; break; + } + + draw_draco(colour, mon_tile, equ_tile, x, y); + } +} + +void DungeonRegion::draw_foreground(unsigned int bg, unsigned int fg, unsigned int x, unsigned int y) +{ + unsigned int fg_idx = fg & TILE_FLAG_MASK; + unsigned int bg_idx = bg & TILE_FLAG_MASK; + + if (fg_idx && !(fg & TILE_FLAG_FLYING)) + { + if (bg_idx >= TILE_DNGN_LAVA && bg_idx <= TILE_DNGN_LAVA + 3) + { + add_quad(TEX_DEFAULT, TILE_MASK_LAVA, x, y); + } + else if (bg_idx >= TILE_DNGN_SHALLOW_WATER + && bg_idx <= TILE_DNGN_SHALLOW_WATER + 3) + { + add_quad(TEX_DEFAULT, TILE_MASK_SHALLOW_WATER, x, y); + } + else if (bg_idx >= TILE_DNGN_DEEP_WATER + && bg_idx <= TILE_DNGN_DEEP_WATER + 3) + { + add_quad(TEX_DEFAULT, TILE_MASK_DEEP_WATER, x, y); + } + } + + if (fg & TILE_FLAG_NET) + add_quad(TEX_DEFAULT, TILE_TRAP_NET, x, y); + + if (fg & TILE_FLAG_S_UNDER) + add_quad(TEX_DEFAULT, TILE_SOMETHING_UNDER, x, y); + + // Pet mark + int status_shift = 0; + if (fg & TILE_FLAG_PET) + { + add_quad(TEX_DEFAULT, TILE_HEART, x, y); + status_shift += 10; + } + else if ((fg & TILE_FLAG_MAY_STAB) == TILE_FLAG_NEUTRAL) + { + add_quad(TEX_DEFAULT, TILE_NEUTRAL, x, y); + status_shift += 8; + } + else if ((fg & TILE_FLAG_MAY_STAB) == TILE_FLAG_STAB) + { + add_quad(TEX_DEFAULT, TILE_STAB_BRAND, x, y); + status_shift += 8; + } + else if ((fg & TILE_FLAG_MAY_STAB) == TILE_FLAG_MAY_STAB) + { + add_quad(TEX_DEFAULT, TILE_MAY_STAB_BRAND, x, y); + status_shift += 5; + } + + if (fg & TILE_FLAG_POISON) + { + add_quad(TEX_DEFAULT, TILE_POISON, x, y, -status_shift, 0); + status_shift += 5; + } + + if (fg & TILE_FLAG_ANIM_WEP) + { + add_quad(TEX_DEFAULT, TILE_ANIMATED_WEAPON, x, y); + } + + if (bg & TILE_FLAG_UNSEEN) + add_quad(TEX_DEFAULT, TILE_MESH, x, y); + + if (bg & TILE_FLAG_MM_UNSEEN) + add_quad(TEX_DEFAULT, TILE_MAGIC_MAP_MESH, x, y); + + // Don't let the "new stair" icon cover up any existing icons, but + // draw it otherwise. + if (bg & TILE_FLAG_NEW_STAIR && status_shift == 0) + add_quad(TEX_DEFAULT, TILE_NEW_STAIR, x, y); + + if (bg & TILE_FLAG_EXCL_CTR && (bg & TILE_FLAG_UNSEEN)) + add_quad(TEX_DUNGEON, TILE_TRAVEL_EXCLUSION_CENTRE_FG, x, y); + else if (bg & TILE_FLAG_TRAV_EXCL && (bg & TILE_FLAG_UNSEEN)) + add_quad(TEX_DUNGEON, TILE_TRAVEL_EXCLUSION_FG, x, y); + + // Tutorial cursor takes precedence over other cursors. + if (bg & TILE_FLAG_TUT_CURSOR) + { + add_quad(TEX_DEFAULT, TILE_TUTORIAL_CURSOR, x, y); + } + else if (bg & TILE_FLAG_CURSOR) + { + int type = ((bg & TILE_FLAG_CURSOR) == TILE_FLAG_CURSOR1) ? + TILE_CURSOR : TILE_CURSOR2; + + if ((bg & TILE_FLAG_CURSOR) == TILE_FLAG_CURSOR3) + type = TILE_CURSOR3; + + add_quad(TEX_DEFAULT, type, x, y); + } +} + +void DungeonRegion::render() +{ + if (m_tileb.size() == 0) + return; + + glLoadIdentity(); + glTranslatef(sx + ox, sy + oy, 0); + glScalef(dx, dy, 1); + + m_verts.clear(); + m_verts.reserve(4 * crawl_view.viewsz.x * crawl_view.viewsz.y); + + GLState state; + state.array_vertex = true; + state.array_texcoord = true; + state.blend = true; + state.texture = true; + GLStateManager::set(state); + + int tile = 0; + for (int y = 0; y < crawl_view.viewsz.y; y++) + for (int x = 0; x < crawl_view.viewsz.x; x++) + { + unsigned int bg = m_tileb[tile + 1]; + draw_background(bg, x, y); + + tile += 2; + } + + ASSERT(m_verts.size() > 0); + + if (m_verts.size() > 0) + { + m_image->m_textures[TEX_DUNGEON].bind(); + glVertexPointer(2, GL_FLOAT, sizeof(tile_vert), &m_verts[0].pos_x); + glTexCoordPointer(2, GL_FLOAT, sizeof(tile_vert), &m_verts[0].tex_x); + glDrawArrays(GL_QUADS, 0, m_verts.size()); + } + + + tile = 0; + m_verts.clear(); + + int player_x = -1; + int player_y = -1; + bool need_doll = false; + for (int y = 0; y < crawl_view.viewsz.y; y++) + for (int x = 0; x < crawl_view.viewsz.x; x++) + { + unsigned int fg = m_tileb[tile]; + need_doll |= draw_objects(fg, x, y); + + if ((fg & TILE_FLAG_MASK) == TILE_PLAYER) + { + player_x = x; + player_y = y; + } + + tile += 2; + } + + if (m_verts.size() > 0) + { + m_image->m_textures[TEX_DEFAULT].bind(); + glVertexPointer(2, GL_FLOAT, sizeof(tile_vert), &m_verts[0].pos_x); + glTexCoordPointer(2, GL_FLOAT, sizeof(tile_vert), &m_verts[0].tex_x); + glDrawArrays(GL_QUADS, 0, m_verts.size()); + } + + tile = 0; + m_verts.clear(); + if (player_x != -1) + draw_player(player_x, player_y); + + if (need_doll) + { + for (int y = 0; y < crawl_view.viewsz.y; y++) + for (int x = 0; x < crawl_view.viewsz.x; x++) + { + unsigned int fg = m_tileb[tile]; + draw_monster(fg, x, y); + + tile += 2; + } + } + + if (m_verts.size() > 0) + { + m_image->m_textures[TEX_DOLL].bind(); + glVertexPointer(2, GL_FLOAT, sizeof(tile_vert), &m_verts[0].pos_x); + glTexCoordPointer(2, GL_FLOAT, sizeof(tile_vert), &m_verts[0].tex_x); + glDrawArrays(GL_QUADS, 0, m_verts.size()); + } + + tile = 0; + m_verts.clear(); + for (int y = 0; y < crawl_view.viewsz.y; y++) + for (int x = 0; x < crawl_view.viewsz.x; x++) + { + unsigned int fg = m_tileb[tile]; + unsigned int bg = m_tileb[tile + 1]; + draw_foreground(bg, fg, x, y); + tile += 2; + } + + if (m_verts.size() > 0) + { + m_image->m_textures[TEX_DEFAULT].bind(); + glVertexPointer(2, GL_FLOAT, sizeof(tile_vert), &m_verts[0].pos_x); + glTexCoordPointer(2, GL_FLOAT, sizeof(tile_vert), &m_verts[0].tex_x); + glDrawArrays(GL_QUADS, 0, m_verts.size()); + } + + // Draw text labels + // TODO enne - add an option for this + // TODO enne - be more intelligent about not covering stuff up + for (unsigned int t = 0; t < TAG_MAX; t++) + { + for (unsigned int i = 0; i < m_tags[t].size(); i++) + { + if (!on_screen(m_tags[t][i].gc)) + continue; + + coord_def pc; + to_screen_coords(m_tags[t][i].gc, pc); + // center this coord, which is at the top left of gc's cell + pc.x += dx / 2; + + const coord_def min_pos(sx, sy); + const coord_def max_pos(ex, ey); + m_tag_font->render_string(pc.x, pc.y, m_tags[t][i].tag.c_str(), + min_pos, max_pos, WHITE, true); + } + } +} + +void DungeonRegion::clear() +{ + m_tileb.clear(); +} + +void DungeonRegion::on_resize() +{ + // TODO enne +} + +int DungeonRegion::handle_mouse(MouseEvent &event) +{ + if (mouse_control::current_mode() == MOUSE_MODE_NORMAL + || mouse_control::current_mode() == MOUSE_MODE_MACRO + || mouse_control::current_mode() == MOUSE_MODE_MORE) + { + return 0; + } + + int cx; + int cy; + + if (!inside(event.px, event.py)) + return 0; + + bool on_map = mouse_pos(event.px, event.py, cx, cy); + + const coord_def gc(cx + m_cx_to_gx, cy + m_cy_to_gy); + tiles.place_cursor(CURSOR_MOUSE, gc); + + // TODO enne - can we handle this through tooltips + // Destroying the message area is such bad behaviour. + // mesclr(); + // terse_describe_square(gc); + + if (!on_map) + return 0; + + if (mouse_control::current_mode() == MOUSE_MODE_TARGET + || mouse_control::current_mode() == MOUSE_MODE_TARGET_DIR) + { + if (event.event == MouseEvent::MOVE) + { + return CK_MOUSE_MOVE; + } + else if (event.event == MouseEvent::PRESS + && event.button == MouseEvent::LEFT && on_screen(gc)) + { + return CK_MOUSE_CLICK; + } + + return 0; + } + + if (event.event != MouseEvent::PRESS) + return 0; + + if (you.pos() == gc) + { + switch (event.button) + { + case MouseEvent::LEFT: + if (!(event.mod & MOD_SHIFT)) + return 'g'; + + switch (grid_stair_direction(grd(gc))) + { + case CMD_GO_DOWNSTAIRS: + return ('>'); + case CMD_GO_UPSTAIRS: + return ('<'); + default: + return 0; + } + + case MouseEvent::RIGHT: + if (!(event.mod & MOD_SHIFT)) + return '%'; // Character overview. + if (you.religion != GOD_NO_GOD) + return '^'; // Religion screen. + + // fall through... + default: + return 0; + } + + } + // else not on player... + if (event.button == MouseEvent::RIGHT) + { + full_describe_square(gc); + return CK_MOUSE_CMD; + } + + if (event.button != MouseEvent::LEFT) + return 0; + + // If adjacent, return that key (modified by shift or ctrl, etc...) + coord_def dir = gc - you.pos(); + for (unsigned int i = 0; i < 9; i++) + { + if (dir_dx[i] == dir.x && dir_dy[i] == dir.y) + { + if (event.mod & MOD_SHIFT) + return cmd_shift[i]; + else if (event.mod & MOD_CTRL) + return cmd_ctrl[i]; + else + return cmd_normal[i]; + } + } + + // Otherwise, travel to that grid. + if (!in_bounds(gc)) + return 0; + + // Activate travel. + start_travel(gc.x, gc.y); + + return CK_MOUSE_CMD; +} + +void DungeonRegion::to_screen_coords(const coord_def &gc, coord_def &pc) const +{ + int cx = gc.x - m_cx_to_gx; + int cy = gc.y - m_cy_to_gy; + + pc.x = sx + ox + cx * dx; + pc.y = sy + oy + cy * dy; +} + +bool DungeonRegion::on_screen(const coord_def &gc) const +{ + int x = gc.x - m_cx_to_gx; + int y = gc.y - m_cy_to_gy; + + return (x >= 0 && (unsigned int)x < mx && y >= 0 && (unsigned int)y < my); +} + +// Returns the index into m_tileb for the foreground tile. +// This value may not be valid. Check on_screen() first. +// Add one to the return value to get the background tile idx. +int DungeonRegion::get_buffer_index(const coord_def &gc) +{ + int x = gc.x - m_cx_to_gx; + int y = gc.y - m_cy_to_gy; + return 2 * (x + y * mx); +} + +void DungeonRegion::place_cursor(cursor_type type, const coord_def &gc) +{ + unsigned int unmask = ~((type == CURSOR_MOUSE) ? TILE_FLAG_CURSOR : + TILE_FLAG_TUT_CURSOR); + unsigned int mask = (type == CURSOR_MOUSE) ? TILE_FLAG_CURSOR1 : + TILE_FLAG_TUT_CURSOR; + + // Remove cursor from previous location + if (on_screen(m_cursor[type])) + { + unsigned int idx = get_buffer_index(m_cursor[type]) + 1; + m_tileb[idx] &= unmask; + } + + // If we're only looking for a direction, put the mouse + // cursor next to the player to let them know that their + // spell/wand will only go one square. + if (mouse_control::current_mode() == MOUSE_MODE_TARGET_DIR + && type == CURSOR_MOUSE) + { + coord_def delta = gc - you.pos(); + + int ax = abs(delta.x); + int ay = abs(delta.y); + + coord_def result = you.pos(); + + if (1000 * ay < 414 * ax) + result += (delta.x > 0) ? coord_def(1, 0) : coord_def(-1, 0); + else if (1000 * ax < 414 * ay) + result += (delta.y > 0) ? coord_def(0, 1) : coord_def(0, -1); + else if (delta.x > 0) + result += (delta.y > 0) ? coord_def(1, 1) : coord_def(1, -1); + else if (delta.x < 0) + result += (delta.y > 0) ? coord_def(-1, 1) : coord_def(-1, -1); + + m_cursor[type] = result; + } + else + { + m_cursor[type] = gc; + } + + // Add cursor to new location + if ((m_cursor[type] != NO_CURSOR) && on_screen(m_cursor[type])) + { + unsigned int idx = get_buffer_index(m_cursor[type]) + 1; + m_tileb[idx] &= unmask; + + // TODO enne - specify type of cursor in place_cursor? or determine type based on grd? + m_tileb[idx] |= mask; + } +} + +bool DungeonRegion::update_tip_text(std::string& tip) +{ + // TODO enne - it would be really nice to use the tutorial + // descriptions here for features, monsters, etc... + // Unfortunately, that would require quite a bit of rewriting + // and some parsing of formatting to get that to work. + + if (mouse_control::current_mode() != MOUSE_MODE_COMMAND) + return false; + + if (m_cursor[CURSOR_MOUSE] == you.pos()) + { + tip = you.your_name; + tip += " ("; + tip += get_species_abbrev(you.species); + tip += get_class_abbrev(you.char_class); + tip += ")"; + + if (igrd(m_cursor[CURSOR_MOUSE]) != NON_ITEM) + tip += "\n[L-Click] Pick up items (g)"; + + if (grid_stair_direction(grd(m_cursor[CURSOR_MOUSE])) != CMD_NO_CMD) + tip += "\n[Shift-L-Click] use stairs (</>)"; + + // Character overview. + tip += "\n[R-Click] Overview (%)"; + + // Religion. + if (you.religion != GOD_NO_GOD) + tip += "\n[Shift-R-Click] Religion (^)"; + } + else if (abs(m_cursor[CURSOR_MOUSE].x - you.pos().x) <= 1 + && abs(m_cursor[CURSOR_MOUSE].y - you.pos().y) <= 1) + { + tip = ""; + + if (!grid_is_solid(m_cursor[CURSOR_MOUSE])) + { + int mon_num = mgrd(m_cursor[CURSOR_MOUSE]); + const monsters *mons = &menv[mon_num]; + if (mon_num == NON_MONSTER || mons_friendly(mons)) + { + tip = "[L-Click] Move\n"; + } + else if (mon_num != NON_MONSTER) + { + tip = mons->name(DESC_CAP_A); + tip += "\n[L-Click] Attack\n"; + } + } + + tip += "[R-Click] Describe"; + } + else + { + if (i_feel_safe() && !grid_is_solid(m_cursor[CURSOR_MOUSE])) + { + tip = "[L-Click] Travel\n"; + } + + tip += "[R-Click] Describe"; + } + + return true; +} + +void DungeonRegion::clear_text_tags(text_tag_type type) +{ + m_tags[type].clear(); +} + +void DungeonRegion::add_text_tag(text_tag_type type, const std::string &tag, + const coord_def &gc) +{ + TextTag t; + t.tag = tag; + t.gc = gc; + + m_tags[type].push_back(t); +} + + +InventoryTile::InventoryTile() +{ + tile = 0; + idx = -1; + quantity = -1; + key = 0; + flag = 0; +} + +bool InventoryTile::empty() const +{ + return (idx == -1); +} + +InventoryRegion::InventoryRegion(ImageManager* im, unsigned tile_x, unsigned int tile_y) : + TileRegion(im, tile_x, tile_y), + m_flavour(NULL), m_cursor(NO_CURSOR), m_need_to_pack(false) +{ +} + +InventoryRegion::~InventoryRegion() +{ + delete[] m_flavour; +} + +void InventoryRegion::clear() +{ + m_items.clear(); + m_verts.clear(); +} + +void InventoryRegion::on_resize() +{ + delete[] m_flavour; + if (mx * my <= 0) + return; + + m_flavour = new unsigned char[mx * my]; + for (unsigned int i = 0; i < mx * my; i++) + { + m_flavour[i] = random2((unsigned char)~0); + } +} + +void InventoryRegion::update(unsigned int num, InventoryTile *items) +{ + m_items.clear(); + for (unsigned int i = 0; i < num; i++) + { + m_items.push_back(items[i]); + } + + m_need_to_pack = true; +} + +void InventoryRegion::update_slot(unsigned int slot, InventoryTile &desc) +{ + while (m_items.size() <= slot) + { + InventoryTile temp; + m_items.push_back(temp); + } + + m_items[slot] = desc; + + m_need_to_pack = true; +} + +void InventoryRegion::render() +{ + if (m_need_to_pack) + pack_verts(); + + if (m_verts.size() == 0) + return; + + glLoadIdentity(); + glTranslatef(sx + ox, sy + oy, 0); + glScalef(dx, dy, 1); + + GLState state; + state.array_vertex = true; + state.array_texcoord = true; + state.blend = true; + state.texture = true; + GLStateManager::set(state); + + m_image->m_textures[TEX_DUNGEON].bind(); + glVertexPointer(2, GL_FLOAT, sizeof(tile_vert), &m_verts[0].pos_x); + glTexCoordPointer(2, GL_FLOAT, sizeof(tile_vert), &m_verts[0].tex_x); + glDrawArrays(GL_QUADS, 0, m_base_verts); + + m_image->m_textures[TEX_DEFAULT].bind(); + glDrawArrays(GL_QUADS, m_base_verts, m_verts.size() - m_base_verts); +} + +void InventoryRegion::add_quad_char(char c, unsigned int x, unsigned int y, int ofs_x, int ofs_y) +{ + int idx = TILE_CHAR00 + (c - 32) / 8; + int subidx = c & 7; + + float tex_sx, tex_sy, tex_wx, tex_wy; + m_image->m_textures[TEX_DEFAULT].get_texcoord(idx, tex_sx, tex_sy, tex_wx, tex_wy); + tex_wx /= 4.0f; + tex_wy /= 2.0f; + tex_sx += (subidx % 4) * tex_wx; + tex_sy += (subidx / 4) * tex_wy; + float tex_ex = tex_sx + tex_wx; + float tex_ey = tex_sy + tex_wy; + + float pos_sx = x + ofs_x / (float)TILE_X; + float pos_sy = y + ofs_y / (float)TILE_Y; + float pos_ex = pos_sx + 0.25f; + float pos_ey = pos_sy + 0.5f; + + tile_vert v; + v.pos_x = pos_sx; + v.pos_y = pos_sy; + v.tex_x = tex_sx; + v.tex_y = tex_sy; + m_verts.push_back(v); + + v.pos_y = pos_ey; + v.tex_y = tex_ey; + m_verts.push_back(v); + + v.pos_x = pos_ex; + v.tex_x = tex_ex; + m_verts.push_back(v); + + v.pos_y = pos_sy; + v.tex_y = tex_sy; + m_verts.push_back(v); +} + +void InventoryRegion::pack_verts() +{ + m_need_to_pack = false; + m_verts.clear(); + + // ensure the cursor has been placed + place_cursor(m_cursor); + + // Pack base separately, as it comes from a different texture... + unsigned int i = 0; + for (unsigned int y = 0; y < my; y++) + { + if (i >= m_items.size()) + break; + + for (unsigned int x = 0; x < mx; x++) + { + if (i >= m_items.size()) + break; + + InventoryTile &item = m_items[i++]; + + if (item.flag & TILEI_FLAG_FLOOR) + add_quad(TEX_DUNGEON, get_floor_tile_idx() + + m_flavour[i] % get_num_floor_flavors(), x, y); + else + add_quad(TEX_DUNGEON, TILE_ITEM_SLOT, x, y); + } + } + + // Make note of how many verts are used by the base + m_base_verts = m_verts.size(); + + i = 0; + for (unsigned int y = 0; y < my; y++) + { + if (i >= m_items.size()) + break; + + for (unsigned int x = 0; x < mx; x++) + { + if (i >= m_items.size()) + break; + + InventoryTile &item = m_items[i++]; + + if (item.flag & TILEI_FLAG_EQUIP) + { + if (item.flag & TILEI_FLAG_CURSE) + add_quad(TEX_DEFAULT, TILE_ITEM_SLOT_EQUIP_CURSED, x, y); + else + add_quad(TEX_DEFAULT, TILE_ITEM_SLOT_EQUIP, x, y); + } + else if (item.flag & TILEI_FLAG_CURSE) + add_quad(TEX_DEFAULT, TILE_ITEM_SLOT_CURSED, x, y); + + // TODO enne - need better graphic here + if (item.flag & TILEI_FLAG_SELECT) + add_quad(TEX_DEFAULT, TILE_ITEM_SLOT_SELECTED, x, y); + + if (item.flag & TILEI_FLAG_CURSOR) + add_quad(TEX_DEFAULT, TILE_CURSOR, x, y); + + if (item.tile) + add_quad(TEX_DEFAULT, item.tile, x, y); + + if (item.quantity != -1) + { + unsigned int num = item.quantity; + // If you have that many, who cares. + if (num > 999) + num = 999; + + const int offset_amount = TILE_X/4; + int offset = 0; + + int help = num; + int c100 = help/100; + help -= c100*100; + + if (c100) + { + add_quad_char('0' + c100, x, y, offset, 0); + offset += offset_amount; + } + + int c10 = help/10; + if (c10 || c100) + { + add_quad_char('0' + c10, x, y, offset, 0); + offset += offset_amount; + } + + int c1 = help % 10; + add_quad_char('0' + c1, x, y, offset, 0); + } + + + if (item.flag & TILEI_FLAG_TRIED) + add_quad_char('?', x, y, 0, TILE_Y / 2); + } + } +} + +unsigned int InventoryRegion::cursor_index() const +{ + ASSERT(m_cursor != NO_CURSOR); + return m_cursor.x + m_cursor.y * mx; +} + +void InventoryRegion::place_cursor(const coord_def &cursor) +{ + if (m_cursor != NO_CURSOR) + { + m_items[cursor_index()].flag &= ~TILEI_FLAG_CURSOR; + m_need_to_pack = true; + } + + m_cursor = cursor; + + if (m_cursor == NO_CURSOR || cursor_index() >= m_items.size()) + return; + + // Add cursor to new location + m_items[cursor_index()].flag |= TILEI_FLAG_CURSOR; + m_need_to_pack = true; +} + +int InventoryRegion::handle_mouse(MouseEvent &event) +{ + int cx, cy; + if (!mouse_pos(event.px, event.py, cx, cy)) + { + place_cursor(NO_CURSOR); + return 0; + } + + const coord_def cursor(cx, cy); + place_cursor(cursor); + + if (mouse_control::current_mode() != MOUSE_MODE_COMMAND) + return 0; + + if (event.event != MouseEvent::PRESS) + return 0; + + // TODO enne - if mouse_mode is command, then: + + unsigned int item_idx = cursor_index(); + if (item_idx >= m_items.size() || m_items[item_idx].empty()) + return 0; + + int idx = m_items[item_idx].idx; + bool on_floor = m_items[item_idx].flag & TILEI_FLAG_FLOOR; + + ASSERT(idx >= 0); + + // TODO enne - this is all really only valid for the on-screen inventory + // Do we subclass inventoryregion for the onscreen and offscreen versions? + char key = m_items[item_idx].key; + if (key) + return key; + + if (event.button == MouseEvent::LEFT) + { + if (on_floor) + { + if (event.mod & MOD_SHIFT) + tile_item_use_floor(idx); + else + tile_item_pickup(idx); + } + else + { + if (event.mod & MOD_SHIFT) + tile_item_drop(idx); + else if (event.mod & MOD_CTRL) + tile_item_use_secondary(idx); + else + tile_item_use(idx); + } + // TODO enne - need to redraw inventory here? + return CK_MOUSE_CMD; + } + else if (event.button == MouseEvent::RIGHT) + { + if (on_floor) + { + if (event.mod & MOD_SHIFT) + tile_item_eat_floor(idx); + else + describe_item(mitm[idx]); + } + else + { + describe_item(you.inv[idx]); + } + return CK_MOUSE_CMD; + } + + return 0; +} + +// NOTE: Assumes the item is equipped in the first place! +static bool _is_true_equipped_item(item_def item) +{ + // Weapons and staves are only truly equipped if wielded. + if (item.link == you.equip[EQ_WEAPON]) + return (item.base_type == OBJ_WEAPONS || item.base_type == OBJ_STAVES); + + // Cursed armour and rings are only truly equipped if *not* wielded. + return (item.link != you.equip[EQ_WEAPON]); +} + +// Returns whether there's any action you can take with an item in inventory +// apart from dropping it. +static bool _can_use_item(const item_def &item, bool equipped) +{ + // Vampires can drain corpses. + if (item.base_type == OBJ_CORPSES) + { + return (you.species == SP_VAMPIRE + && item.sub_type != CORPSE_SKELETON + && !food_is_rotten(item) + && mons_has_blood(item.plus)); + } + + if (equipped && item_cursed(item)) + { + // Misc. items/rods can always be evoked, cursed or not. + if (item.base_type == OBJ_MISCELLANY || item_is_rod(item)) + return true; + + // You can't unwield/fire a wielded cursed weapon/staff + // but cursed armour and rings can be unwielded without problems. + return (!_is_true_equipped_item(item)); + } + + // Mummies can't do anything with food or potions. + if (you.species == SP_MUMMY) + return (item.base_type != OBJ_POTIONS && item.base_type != OBJ_FOOD); + + // In all other cases you can use the item in some way. + return true; +} + +bool InventoryRegion::update_tip_text(std::string& tip) +{ + unsigned int item_idx = cursor_index(); + if (item_idx >= m_items.size() || m_items[item_idx].empty()) + return false; + + int idx = m_items[item_idx].idx; + + // TODO enne - consider subclassing this class, rather than depending + // on "key" to determine if this is the crt inventory or the on screen one. + bool display_actions = (m_items[item_idx].key == 0 + && mouse_control::current_mode() == MOUSE_MODE_COMMAND); + + // TODO enne - should the command keys here respect keymaps? + + if (m_items[item_idx].flag & TILEI_FLAG_FLOOR) + { + const item_def &item = mitm[idx]; + + tip = ""; + if (m_items[item_idx].key) + { + tip = m_items[item_idx].key; + tip += " - "; + } + + tip += item.name(DESC_NOCAP_A); + + if (!display_actions) + return true; + + tip += "\n[L-Click] Pick up (g)"; + if (item.base_type == OBJ_CORPSES + && item.sub_type != CORPSE_SKELETON + && !food_is_rotten(item)) + { + tip += "\n[Shift-L-Click] "; + if (can_bottle_blood_from_corpse(item.plus)) + tip += "Bottle blood"; + else + tip += "Chop up"; + tip += " (c)"; + + if (you.species == SP_VAMPIRE) + tip += "\n\n[Shift-R-Click] Drink blood (e)"; + } + else if (item.base_type == OBJ_FOOD + && you.is_undead != US_UNDEAD + && you.species != SP_VAMPIRE) + { + tip += "\n[Shift-R-Click] Eat (e)"; + } + } + else + { + const item_def &item = you.inv[idx]; + tip = item.name(DESC_INVENTORY_EQUIP); + + if (!display_actions) + return true; + + int type = item.base_type; + const bool equipped = m_items[item_idx].flag & TILEI_FLAG_EQUIP; + bool wielded = (you.equip[EQ_WEAPON] == idx); + + const int EQUIP_OFFSET = NUM_OBJECT_CLASSES; + + if (_can_use_item(item, equipped)) + { + tip += "\n[L-Click] "; + if (equipped) + { + if (wielded && type != OBJ_MISCELLANY && !item_is_rod(item)) + { + if (type == OBJ_JEWELLERY || type == OBJ_ARMOUR + || type == OBJ_WEAPONS || type == OBJ_STAVES) + { + type = OBJ_WEAPONS + EQUIP_OFFSET; + } + } + else + type += EQUIP_OFFSET; + } + + switch (type) + { + // first equipable categories + case OBJ_WEAPONS: + case OBJ_STAVES: + case OBJ_MISCELLANY: + tip += "Wield (w)"; + if (is_throwable(item, player_size(PSIZE_BODY))) + tip += "\n[Ctrl-L-Click] Fire (f)"; + break; + case OBJ_WEAPONS + EQUIP_OFFSET: + tip += "Unwield"; + if (is_throwable(item, player_size(PSIZE_BODY))) + tip += "\n[Ctrl-L-Click] Fire (f)"; + break; + case OBJ_MISCELLANY + EQUIP_OFFSET: + if (item.sub_type >= MISC_DECK_OF_ESCAPE + && item.sub_type <= MISC_DECK_OF_DEFENCE) + { + tip += "Draw a card (v)"; + tip += "\n[Ctrl-L-Click] Unwield"; + break; + } + // else fall-through + case OBJ_STAVES + EQUIP_OFFSET: // rods - other staves handled above + tip += "Evoke (v)"; + tip += "\n[Ctrl-L-Click] Unwield"; + break; + case OBJ_ARMOUR: + tip += "Wear (W)"; + break; + case OBJ_ARMOUR + EQUIP_OFFSET: + tip += "Take off (T)"; + break; + case OBJ_JEWELLERY: + tip += "Put on (P)"; + break; + case OBJ_JEWELLERY + EQUIP_OFFSET: + tip += "Remove (R)"; + break; + case OBJ_MISSILES: + tip += "Fire (f)"; + + if (wielded) + tip += "\n[Ctrl-L-Click] Unwield"; + else if ( item.sub_type == MI_STONE + && player_knows_spell(SPELL_SANDBLAST) + || item.sub_type == MI_ARROW + && player_knows_spell( + SPELL_STICKS_TO_SNAKES) ) + { + // For Sandblast and Sticks to Snakes, + // respectively. + tip += "\n[Ctrl-L-Click] Wield (w)"; + } + break; + case OBJ_WANDS: + tip += "Zap (Z)"; + if (wielded) + tip += "\n[Ctrl-L-Click] Unwield"; + break; + case OBJ_BOOKS: + if (item_type_known(item) + && item.sub_type != BOOK_MANUAL + && item.sub_type != BOOK_DESTRUCTION) + { + tip += "Memorise (M)"; + if (wielded) + tip += "\n[Ctrl-L-Click] Unwield"; + break; + } + // else fall-through + case OBJ_SCROLLS: + tip += "Read (r)"; + if (wielded) + tip += "\n[Ctrl-L-Click] Unwield"; + break; + case OBJ_POTIONS: + tip += "Quaff (q)"; + // For Sublimation of Blood. + if (wielded) + tip += "\n[Ctrl-L-Click] Unwield"; + else if ( item_type_known(item) + && is_blood_potion(item) + && player_knows_spell( + SPELL_SUBLIMATION_OF_BLOOD) ) + { + tip += "\n[Ctrl-L-Click] Wield (w)"; + } + break; + case OBJ_FOOD: + tip += "Eat (e)"; + // For Sublimation of Blood. + if (wielded) + tip += "\n[Ctrl-L-Click] Unwield"; + else if (item.sub_type == FOOD_CHUNK + && player_knows_spell( + SPELL_SUBLIMATION_OF_BLOOD)) + { + tip += "\n[Ctrl-L-Click] Wield (w)"; + } + break; + case OBJ_CORPSES: + if (you.species == SP_VAMPIRE) + tip += "Drink blood (e)"; + + if (wielded) + { + if (you.species == SP_VAMPIRE) + tip += EOL; + tip += "[Ctrl-L-Click] Unwield"; + } + break; + default: + tip += "Use"; + } + } + + // For Boneshards. + // Special handling since skeletons have no primary action. + if (item.base_type == OBJ_CORPSES + && item.sub_type == CORPSE_SKELETON) + { + if (wielded) + tip += "\n[Ctrl-L-Click] Unwield"; + else if (player_knows_spell(SPELL_BONE_SHARDS)) + tip += "\n[Ctrl-L-Click] Wield (w)"; + } + + tip += "\n[R-Click] Info"; + // Has to be non-equipped or non-cursed to drop. + if (!equipped || !_is_true_equipped_item(you.inv[idx]) + || !item_cursed(you.inv[idx])) + { + tip += "\n[Shift-L-Click] Drop (d)"; + } + + } + + return true; +} + +MapRegion::MapRegion(unsigned int pixsz) : + m_buf(NULL), + m_far_view(false) +{ + dx = pixsz; + dy = pixsz; + clear(); + init_colours(); +} + +void MapRegion::on_resize() +{ + delete[] m_buf; + + int size = mx * my; + m_buf = new unsigned char[size]; + memset(m_buf, 0, sizeof(unsigned char) * size); +} + +void MapRegion::init_colours() +{ + // TODO enne - the options array for colours should be + // tied to the map feature enumeration to avoid this function. + m_colours[MF_UNSEEN] = (map_colour)Options.tile_unseen_col; + m_colours[MF_FLOOR] = (map_colour)Options.tile_floor_col; + m_colours[MF_WALL] = (map_colour)Options.tile_wall_col; + m_colours[MF_MAP_FLOOR] = (map_colour)Options.tile_floor_col; // TODO enne + m_colours[MF_MAP_WALL] = (map_colour)Options.tile_mapped_wall_col; + m_colours[MF_DOOR] = (map_colour)Options.tile_door_col; + m_colours[MF_ITEM] = (map_colour)Options.tile_item_col; + m_colours[MF_MONS_HOSTILE] = (map_colour)Options.tile_monster_col; + m_colours[MF_MONS_FRIENDLY] = (map_colour)Options.tile_friendly_col; + m_colours[MF_MONS_NEUTRAL] = (map_colour)Options.tile_neutral_col; + m_colours[MF_MONS_NO_EXP] = (map_colour)Options.tile_plant_col; + m_colours[MF_STAIR_UP] = (map_colour)Options.tile_upstairs_col; + m_colours[MF_STAIR_DOWN] = (map_colour)Options.tile_downstairs_col; + m_colours[MF_STAIR_BRANCH] = (map_colour)Options.tile_feature_col; + m_colours[MF_FEATURE] = (map_colour)Options.tile_feature_col; + m_colours[MF_WATER] = (map_colour)Options.tile_water_col; + m_colours[MF_LAVA] = (map_colour)Options.tile_lava_col; + m_colours[MF_TRAP] = (map_colour)Options.tile_trap_col; + m_colours[MF_EXCL_ROOT] = (map_colour)Options.tile_excl_centre_col; + m_colours[MF_EXCL] = (map_colour)Options.tile_excluded_col; + m_colours[MF_PLAYER] = (map_colour)Options.tile_player_col; +} + +MapRegion::~MapRegion() +{ + delete[] m_buf; +} + +struct map_vertex +{ + float x; + float y; + unsigned char r; + unsigned char g; + unsigned char b; + unsigned char a; +}; + +void MapRegion::render() +{ + if (m_min_gx > m_max_gx || m_min_gy > m_max_gy) + return; + + // [enne] - GL_POINTS should probably be used here, but there's (apparently) + // a bug in the OpenGL driver that I'm using and it doesn't respect + // glPointSize unless GL_SMOOTH_POINTS is on. GL_SMOOTH_POINTS is + // *terrible* for performance if it has to fall back on software rendering, + // so instead we'll just make quads. + + glLoadIdentity(); + glTranslatef(sx + ox, sy + oy, 0); + glScalef(dx, dx, 1); + + std::vector<map_vertex> verts; + verts.reserve(4 * (m_max_gx - m_min_gx + 1) * (m_max_gy - m_min_gy + 1)); + + for (unsigned int x = m_min_gx; x <= m_max_gx; x++) + { + for (unsigned int y = m_min_gy; y <= m_max_gy; y++) + { + map_feature f = (map_feature)m_buf[x + y * mx]; + map_colour c = m_colours[f]; + + unsigned int pos_x = x - m_min_gx; + unsigned int pos_y = y - m_min_gy; + + map_vertex v; + v.r = map_colours[c][0]; + v.g = map_colours[c][1]; + v.b = map_colours[c][2]; + v.a = 255; + + v.x = pos_x; + v.y = pos_y; + verts.push_back(v); + + v.x = pos_x; + v.y = pos_y + 1; + verts.push_back(v); + + v.x = pos_x + 1; + v.y = pos_y + 1; + verts.push_back(v); + + v.x = pos_x + 1; + v.y = pos_y; + verts.push_back(v); + } + } + + GLState state; + state.array_vertex = true; + state.array_colour = true; + GLStateManager::set(state); + + glVertexPointer(2, GL_FLOAT, sizeof(map_vertex), &verts[0].x); + glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(map_vertex), &verts[0].r); + glDrawArrays(GL_QUADS, 0, verts.size()); + + // TODO enne - make sure we're drawing within the map square here... + + // Draw window box. + if (m_win_start.x == -1 && m_win_end.x == -1) + return; + + verts.clear(); + glLoadIdentity(); + glTranslatef(sx + ox, sy + oy, 0); + + map_vertex v; + int c = (int)Options.tile_window_col; + v.r = map_colours[c][0]; + v.g = map_colours[c][1]; + v.b = map_colours[c][2]; + v.a = 255; + + v.x = (int)dx * (m_win_start.x - (int)m_min_gx); + v.y = (int)dy * (m_win_start.y - (int)m_min_gy); + verts.push_back(v); + + v.y = (int)dy * (m_win_end.y - (int)m_min_gy) + 1; + verts.push_back(v); + + v.x = (int)dx * (m_win_end.x - (int)m_min_gx) + 1; + verts.push_back(v); + + v.y = (int)dy * (m_win_start.y - (int)m_min_gy); + verts.push_back(v); + + glVertexPointer(2, GL_FLOAT, sizeof(map_vertex), &verts[0].x); + glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(map_vertex), &verts[0].r); + glDrawArrays(GL_LINE_LOOP, 0, verts.size()); +} + +void MapRegion::update_offsets() +{ + // adjust offsets to center map + ox = (wx - dx * (m_max_gx - m_min_gx)) / 2; + oy = (wy - dy * (m_max_gy - m_min_gy)) / 2; +} + +void MapRegion::set(unsigned int gx, unsigned int gy, map_feature f) +{ + ASSERT((unsigned int)f <= (unsigned char)~0); + m_buf[gx + gy * mx] = f; + + if (f == MF_UNSEEN) + return; + + // Get map extents + m_min_gx = std::min(m_min_gx, gx); + m_max_gx = std::max(m_max_gx, gx); + m_min_gy = std::min(m_min_gy, gy); + m_max_gy = std::max(m_max_gy, gy); + + update_offsets(); +} + +void MapRegion::set_window(const coord_def &start, const coord_def &end) +{ + m_win_start = start; + m_win_end = end; +} + +void MapRegion::clear() +{ + m_min_gx = GXM; + m_max_gx = 0; + m_min_gy = GYM; + m_max_gy = 0; + + m_win_start.x = -1; + m_win_start.y = -1; + m_win_end.x = -1; + m_win_end.y = -1; + + update_offsets(); + + if (m_buf) + memset(m_buf, 0, sizeof(*m_buf) * mx * my); +} + +int MapRegion::handle_mouse(MouseEvent &event) +{ + if (mouse_control::current_mode() != MOUSE_MODE_COMMAND) + return 0; + + int cx; + int cy; + if (!mouse_pos(event.px, event.py, cx, cy)) + { + if (m_far_view) + { + m_far_view = false; + tiles.load_dungeon(you.pos().x, you.pos().y); + return 0; + } + return 0; + } + + const coord_def gc(m_min_gx + cx, m_min_gy + cy); + + tiles.place_cursor(CURSOR_MOUSE, gc); + + switch (event.event) + { + case MouseEvent::MOVE: + if (m_far_view) + tiles.load_dungeon(gc.x, gc.y); + return 0; + case MouseEvent::PRESS: + if (event.button == MouseEvent::LEFT) + { + if (!in_bounds(gc)) + return 0; + + start_travel(gc.x, gc.y); + } + else if (event.button == MouseEvent::RIGHT) + { + m_far_view = true; + tiles.load_dungeon(gc.x, gc.y); + } + return CK_MOUSE_CMD; + case MouseEvent::RELEASE: + if ((event.button == MouseEvent::RIGHT) && m_far_view) + { + tiles.load_dungeon(you.pos().x, you.pos().y); + } + return 0; + default: + return 0; + } +} + +bool MapRegion::update_tip_text(std::string& tip) +{ + if (mouse_control::current_mode() != MOUSE_MODE_COMMAND) + return false; + + tip = "[L-Click] Travel / [R-Click] View"; + return true; +} + +void TextRegion::scroll() +{ + for (unsigned int idx = 0; idx < mx*(my-1); idx++) + { + cbuf[idx] = cbuf[idx + mx]; + abuf[idx] = abuf[idx + mx]; + } + + for (unsigned int idx = mx*(my-1); idx < mx*my; idx++) + { + cbuf[idx] = ' '; + abuf[idx] = 0; + } + + if (print_y > 0) + print_y -= 1; + if (cursor_y > 0) + cursor_y -= 1; +} + +TextRegion::TextRegion(FTFont *font) : + cbuf(NULL), + abuf(NULL), + cx_ofs(0), + cy_ofs(0), + m_font(font) +{ + ASSERT(font); + + dx = m_font->char_width(); + dy = m_font->char_height(); + + // TODO enne - gah! + dx = 8; +} + +void TextRegion::on_resize() +{ + delete cbuf; + delete abuf; + + unsigned int size = mx * my; + cbuf = new unsigned char[size]; + abuf = new unsigned char[size]; + + for (unsigned int i = 0; i < size; i++) + { + cbuf[i] = ' '; + abuf[i] = 0; + } +} + +TextRegion::~TextRegion() +{ + delete[] cbuf; + delete[] abuf; +} + +void TextRegion::adjust_region(int *x1, int *x2, int y) +{ + *x2 = *x2 + 1; +} + +void TextRegion::addstr(char *buffer) +{ + char buf2[1024]; + int len = strlen(buffer); + + int j = 0; + + for (int i = 0; i < len + 1; i++) + { + char c = buffer[i]; + bool newline = false; + if (c == '\n' || c == '\r') + { + c = 0; + newline = true; + if (buffer[i+1] == '\n' || buffer[i+1] == '\r') + i++; + } + buf2[j] = c; + j++; + + if (c == 0) + { + if (j-1 != 0) + addstr_aux(buf2, j - 1); // draw it + if (newline) + { + print_x = cx_ofs; + print_y++; + j = 0; + + if (print_y - cy_ofs == my) + scroll(); + } + } + } + if (cursor_flag) + cgotoxy(print_x+1, print_y+1); +} + +void TextRegion::addstr_aux(char *buffer, unsigned int len) +{ + int x = print_x - cx_ofs; + int y = print_y - cy_ofs; + int adrs = y * mx; + int head = x; + int tail = x + len - 1; + + adjust_region(&head, &tail, y); + + for (unsigned int i = 0; i < len && x + i < mx; i++) + { + cbuf[adrs+x+i] = buffer[i]; + abuf[adrs+x+i] = text_col; + } + print_x += len; +} + +void TextRegion::clear_to_end_of_line() +{ + int cx = print_x - cx_ofs; + int cy = print_y - cy_ofs; + int col = text_col; + int adrs = cy * mx; + + ASSERT(adrs + mx - 1 < mx * my); + for (unsigned int i = cx; i < mx; i++) + { + cbuf[adrs+i] = ' '; + abuf[adrs+i] = col; + } +} + +void TextRegion::putch(unsigned char ch) +{ + if (ch == 0) + ch=32; + addstr_aux((char *)&ch, 1); +} + +void TextRegion::writeWChar(unsigned char *ch) +{ + addstr_aux((char *)ch, 2); +} + +void TextRegion::textcolor(int color) +{ + text_col = color; +} + +void TextRegion::textbackground(int col) +{ + textcolor(col*16 + (text_col & 0xf)); +} + +void TextRegion::cgotoxy(int x, int y) +{ + ASSERT(x >= 1); + ASSERT(y >= 1); + print_x = x-1; + print_y = y-1; + + if (cursor_region != NULL && cursor_flag) + { + cursor_region ->erase_cursor(); + cursor_region = NULL; + } + + if (cursor_flag) + { + text_mode->draw_cursor(print_x, print_y); + cursor_x = print_x; + cursor_y = print_y; + cursor_region = text_mode; + } +} + +int TextRegion::wherex() +{ + return print_x + 1; +} + +int TextRegion::wherey() +{ + return print_y + 1; +} + +void TextRegion::_setcursortype(int curstype) +{ + cursor_flag = curstype; + if (cursor_region != NULL) + cursor_region->erase_cursor(); + + if (curstype) + { + text_mode->draw_cursor(print_x, print_y); + cursor_x = print_x; + cursor_y = print_y; + cursor_region = text_mode; + } +} + +void TextRegion::draw_cursor(int x, int y) +{ + // TODO enne +} + +void TextRegion::erase_cursor() +{ + // TODO enne +} + +void TextRegion::render() +{ + m_font->render_textblock(sx + ox, sy + oy, cbuf, abuf, mx, my); +} + +void TextRegion::clear() +{ + for (unsigned int i = 0; i < mx * my; i++) + { + cbuf[i] = ' '; + abuf[i] = 0; + } +} + +StatRegion::StatRegion(FTFont *font) : TextRegion(font) +{ +} + +int StatRegion::handle_mouse(MouseEvent &event) +{ + if (mouse_control::current_mode() != MOUSE_MODE_COMMAND) + return 0; + + if (!inside(event.px, event.py)) + return 0; + + if (event.event != MouseEvent::PRESS || event.button != MouseEvent::LEFT) + return 0; + + // Resting + return '5'; +} + +bool StatRegion::update_tip_text(std::string& tip) +{ + if (mouse_control::current_mode() != MOUSE_MODE_COMMAND) + return false; + + tip = "[L-Click] Rest / Search for a while"; + return true; +} + +MessageRegion::MessageRegion(FTFont *font) : TextRegion(font) +{ +} + +int MessageRegion::handle_mouse(MouseEvent &event) +{ + // TODO enne - mouse scrolling here should mouse scroll up through + // the message history in the message pane, without going to the CRT. + + if (mouse_control::current_mode() != MOUSE_MODE_COMMAND) + return 0; + + if (!inside(event.px, event.py)) + return 0; + + if (event.event != MouseEvent::PRESS || event.button != MouseEvent::LEFT) + return 0; + + + return CONTROL('P'); +} + +bool MessageRegion::update_tip_text(std::string& tip) +{ + if (mouse_control::current_mode() != MOUSE_MODE_COMMAND) + return false; + + tip = "[L-Click] Browse message history"; + return true; +} + +CRTRegion::CRTRegion(FTFont *font) : TextRegion(font) +{ +} + +int CRTRegion::handle_mouse(MouseEvent &event) +{ + // TODO enne - clicking on menu items? We could probably + // determine which items were clicked based on text size. + return 0; +} + +ImageManager::ImageManager() +{ +} + +ImageManager::~ImageManager() +{ + unload_textures(); +} + +bool ImageManager::load_textures() +{ + GenericTexture::MipMapOptions mip = GenericTexture::MIPMAP_CREATE; + if (!m_textures[TEX_DUNGEON].load_texture("dngn.png", mip)) + return false; + + if (!m_textures[TEX_DOLL].load_texture("player.png", mip)) + return false; + + if (!m_textures[TEX_TITLE].load_texture("title.png", mip)) + return false; + + return true; +} + +static void _copy_onto(unsigned char *pixels, unsigned int width, + unsigned int height, unsigned char *src, + int idx, bool blend) +{ + const unsigned int tile_size = 32; + const unsigned int tiles_per_row = width / tile_size; + + unsigned int row = idx / tiles_per_row; + unsigned int col = idx % tiles_per_row; + + unsigned char *dest = &pixels[4 * 32 * (row * width + col)]; + + size_t dest_row_size = width * 4; + size_t src_row_size = 32 * 4; + + if (blend) + { + for (unsigned int r = 0; r < 32; r++) + { + for (unsigned int c = 0; c < 32; c++) + { + unsigned char a = src[3]; + unsigned char inv_a = 255 - src[3]; + dest[0] = (src[0] * a + dest[0] * inv_a) / 255; + dest[1] = (src[1] * a + dest[1] * inv_a) / 255; + dest[2] = (src[2] * a + dest[2] * inv_a) / 255; + dest[3] = (src[3] * a + dest[3] * inv_a) / 255; + + dest += 4; + src += 4; + } + dest += dest_row_size - src_row_size; + } + } + else + { + for (unsigned int r = 0; r < 32; r++) + { + memcpy(dest, src, src_row_size); + + dest += dest_row_size; + src += src_row_size; + } + } +} + +// Copy a 32x32 image at index idx from pixels into dest. +static void _copy_into(unsigned char *dest, unsigned char *pixels, + unsigned int width, + unsigned int height, int idx) +{ + const unsigned int tile_size = 32; + const unsigned int tiles_per_row = width / tile_size; + + unsigned int row = idx / tiles_per_row; + unsigned int col = idx % tiles_per_row; + + unsigned char *src = &pixels[4 * 32 * (row * width + col)]; + + size_t src_row_size = width * 4; + size_t dest_row_size = 32 * 4; + + for (unsigned int r = 0; r < 32; r++) + { + memcpy(dest, src, dest_row_size); + + dest += dest_row_size; + src += src_row_size; + } +} + +// Stores "over" on top of "under" in the location of "over". +static void _copy_under(unsigned char *pixels, unsigned int width, + unsigned int height, int idx_under, int idx_over) +{ + size_t image_size = 32 * 32 * 4; + + // Make a copy of the original images on the stack. + unsigned char *under = new unsigned char[image_size]; + _copy_into(under, pixels, width, height, idx_under); + unsigned char *over = new unsigned char[image_size]; + _copy_into(over, pixels, width, height, idx_over); + + // Replace the over image with the under image + _copy_onto(pixels, width, height, under, idx_over, false); + // Blend the over image over top. + _copy_onto(pixels, width, height, over, idx_over, true); + + delete[] under; + delete[] over; +} + +static bool _process_item_image(unsigned char *pixels, + unsigned int width, unsigned int height) +{ + for (int i = 0; i < NUM_POTIONS; i++) + { + int special = you.item_description[IDESC_POTIONS][i]; + int tile0 = TILE_POTION_OFFSET + special % 14; + int tile1 = TILE_POT_HEALING + i; + _copy_under(pixels, width, height, tile0, tile1); + } + + for (int i = 0; i < NUM_WANDS; i++) + { + int special = you.item_description[IDESC_WANDS][i]; + int tile0 = TILE_WAND_OFFSET + special % 12; + int tile1 = TILE_WAND_FLAME + i; + _copy_under(pixels, width, height, tile0, tile1); + } + + for (int i = 0; i < STAFF_SMITING; i++) + { + int special = you.item_description[IDESC_STAVES][i]; + int tile0 = TILE_STAFF_OFFSET + (special / 4) % 10; + int tile1 = TILE_STAFF_WIZARDRY + i; + _copy_under(pixels, width, height, tile0, tile1); + } + for (int i = STAFF_SMITING; i < NUM_STAVES; i++) + { + int special = you.item_description[IDESC_STAVES][i]; + int tile0 = TILE_ROD_OFFSET + (special / 4) % 10; + int tile1 = TILE_ROD_SMITING + i - STAFF_SMITING; + _copy_under(pixels, width, height, tile0, tile1); + } + + return true; +} + +bool ImageManager::load_item_texture() +{ + // We need to load images in two passes: one for the title and one + // for the items. To handle identifiable items, the texture itself + // is modified. So, it cannot be loaded until after the item + // description table has been initialised. + GenericTexture::MipMapOptions mip = GenericTexture::MIPMAP_CREATE; + return m_textures[TEX_DEFAULT].load_texture("tile.png", mip, + &_process_item_image); +} + +void ImageManager::unload_textures() +{ + for (unsigned int i = 0; i < TEX_MAX; i++) + { + m_textures[i].unload_texture(); + } +} diff --git a/crawl-ref/source/tilereg.h b/crawl-ref/source/tilereg.h new file mode 100644 index 0000000000..dcc8b92606 --- /dev/null +++ b/crawl-ref/source/tilereg.h @@ -0,0 +1,371 @@ +/* + * File: tilereg.h + * Created by: ennewalker on Sat Jan 5 01:33:53 2008 UTC + * + * Modified for Crawl Reference by $Author: j-p-e-g $ on $Date: 2008-03-07 $ + */ + +#ifdef USE_TILE +#ifndef TILEREG_H +#define TILEREG_H + +#include "tiletex.h" +#include "tiles.h" +#include <vector> + +class ImageManager +{ +public: + ImageManager(); + virtual ~ImageManager(); + + bool load_textures(); + bool load_item_texture(); + void unload_textures(); + + FixedVector<TilesTexture, TEX_MAX> m_textures; +}; + +// Windows and internal regions (text, dungeon, map, etc) +class MouseEvent; + +class Region +{ +public: + Region(); + virtual ~Region(); + + void resize(unsigned int mx, unsigned int my); + void place(unsigned int sx, unsigned int sy, unsigned int margin); + void resize_to_fit(int wx, int wy); + + // Returns true if the mouse position is over the region + // If true, then cx and cy are set in the range [0..mx-1], [0..my-1] + virtual bool mouse_pos(int mouse_x, int mouse_y, int &cx, int &cy); + + bool inside(unsigned int px, unsigned int py); + virtual bool update_tip_text(std::string &tip) { return false; } + virtual int handle_mouse(MouseEvent &event) = 0; + + virtual void render() = 0; + virtual void clear() = 0; + + // Geometry + // <-----------------wx-----------------------> + // sx ox ex + // |margin| text/tile area |margin| + + // Offset in pixels + unsigned int ox; + unsigned int oy; + + // Unit size + unsigned int dx; + unsigned int dy; + + // Region size in dx/dy + unsigned int mx; + unsigned int my; + + // Width of the region in pixels + unsigned int wx; + unsigned int wy; + + // Start position in pixels (top left) + unsigned int sx; + unsigned int sy; + + // End position in pixels (bottom right) + unsigned int ex; + unsigned int ey; + + static coord_def NO_CURSOR; + +protected: + void recalculate(); + virtual void on_resize() = 0; +}; + +class FTFont; + +class TextRegion : public Region +{ +public: + TextRegion(FTFont *font); + ~TextRegion(); + + virtual void render(); + virtual void clear(); + + // STATIC - + // TODO enne - move these to TilesFramework? + + // where now printing? what color? + static unsigned int print_x; + static unsigned int print_y; + static int text_col; + // which region now printing? + static class TextRegion *text_mode; + // display cursor? where is the cursor now? + static int cursor_flag; + static class TextRegion *cursor_region; + static unsigned int cursor_x; + static unsigned int cursor_y; + + // class methods + static void cgotoxy(int x, int y); + static int wherex(); + static int wherey(); + //static int get_number_of_lines(void); + static void _setcursortype(int curstype); + static void textbackground(int bg); + static void textcolor(int col); + + // Object's method + void clear_to_end_of_line(void); + void putch(unsigned char chr); + void writeWChar(unsigned char *ch); + + unsigned char *cbuf; //text backup + unsigned char *abuf; //textcolor backup + + int cx_ofs; //cursor x offset + int cy_ofs; //cursor y offset + + void addstr(char *buffer); + void addstr_aux(char *buffer, unsigned int len); + void adjust_region(int *x1, int *x2, int y); + void scroll(); + + //Sys dep + void draw_cursor(int x, int y, int width); + void draw_cursor(int x, int y); + void erase_cursor(); + +protected: + virtual void on_resize(); + FTFont *m_font; +}; + +class StatRegion : public TextRegion +{ +public: + StatRegion(FTFont *font); + + virtual int handle_mouse(MouseEvent &event); + virtual bool update_tip_text(std::string &tip); +}; + +class MessageRegion : public TextRegion +{ +public: + MessageRegion(FTFont *font); + + virtual int handle_mouse(MouseEvent &event); + virtual bool update_tip_text(std::string &tip); +}; + +class CRTRegion : public TextRegion +{ +public: + CRTRegion(FTFont *font); + + virtual int handle_mouse(MouseEvent &event); +}; + +class TileRegion : public Region +{ +public: + TileRegion(ImageManager *im, unsigned int tile_x, unsigned int tile_y); + ~TileRegion(); + +protected: + void add_quad(TextureID tex, unsigned int idx, unsigned int x, unsigned int y, int ofs_x = 0, int ofs_y = 0); + + ImageManager *m_image; + + struct tile_vert + { + float pos_x; + float pos_y; + float tex_x; + float tex_y; + }; + + std::vector<tile_vert> m_verts; +}; + +struct TextTag +{ + std::string tag; + coord_def gc; +}; + +enum cursor_type +{ + CURSOR_MOUSE, + CURSOR_TUTORIAL, + CURSOR_MAX +}; + +enum text_tag_type +{ + TAG_NAMED_MONSTER, + TAG_TUTORIAL, + TAG_MAX +}; + +class DungeonRegion : public TileRegion +{ +public: + DungeonRegion(ImageManager *im, FTFont *tag_font, + unsigned int tile_x, unsigned int tile_y); + virtual ~DungeonRegion(); + + virtual void render(); + virtual void clear(); + virtual int handle_mouse(MouseEvent &event); + virtual bool update_tip_text(std::string &tip); + virtual void on_resize(); + + void load_dungeon(unsigned int* tileb, int cx_to_gx, int cy_to_gy); + void place_cursor(cursor_type type, const coord_def &gc); + bool on_screen(const coord_def &gc) const; + + void clear_text_tags(text_tag_type type); + void add_text_tag(text_tag_type type, const std::string &tag, + const coord_def &gc); + + const coord_def &get_cursor() const { return m_cursor[CURSOR_MOUSE]; } + +protected: + void draw_background(unsigned int bg, unsigned int x, unsigned int y); + bool draw_objects(unsigned int fg, unsigned int x, unsigned int y); + void draw_player(unsigned int x, unsigned int y); + void draw_monster(unsigned int fg, unsigned int x, unsigned int y); + void draw_foreground(unsigned int bg, unsigned int fg, unsigned int x, unsigned int y); + void draw_doll(dolls_data &doll, unsigned int x, unsigned int y); + void draw_draco(int colour, int mon_idx, int equ_tile, unsigned int x, unsigned int y); + + void add_quad_doll(unsigned int part, unsigned int idx, int ymax, unsigned int x, unsigned int y, int ox, int oy); + + int get_buffer_index(const coord_def &gc); + void to_screen_coords(const coord_def &gc, coord_def& pc) const; + + std::vector<unsigned int> m_tileb; + int m_cx_to_gx; + int m_cy_to_gy; + coord_def m_cursor[CURSOR_MAX]; + std::vector<TextTag> m_tags[TAG_MAX]; + FTFont *m_tag_font; +}; + +class InventoryTile +{ +public: + InventoryTile(); + + // tile index + int tile; + // mitm/you.inv idx (depends on flag & TILEI_FLAG_FLOOR) + int idx; + // quantity of this item (0-999 valid, >999 shows as 999, <0 shows nothing) + short quantity; + // bitwise-or of TILEI_FLAG enumeration + unsigned short flag; + // for inventory items, the slot + char key; + + bool empty() const; +}; + +class InventoryRegion : public TileRegion +{ +public: + InventoryRegion(ImageManager *im, unsigned int tile_x, unsigned int tile_y); + virtual ~InventoryRegion(); + + virtual void clear(); + virtual void render(); + virtual void on_resize(); + virtual int handle_mouse(MouseEvent &event); + + void update(unsigned int num, InventoryTile *items); + void update_slot(unsigned int slot, InventoryTile &item); + virtual bool update_tip_text(std::string &tip); + +protected: + void pack_tile(unsigned int x, unsigned int y, unsigned int idx); + void pack_verts(); + void add_quad_char(char c, unsigned int x, unsigned int y, int ox, int oy); + void place_cursor(const coord_def &cursor); + unsigned int cursor_index() const; + + unsigned int m_base_verts; + std::vector<InventoryTile> m_items; + unsigned char *m_flavour; + + coord_def m_cursor; + + bool m_need_to_pack; +}; + +enum map_colour +{ + MAP_BLACK, + MAP_DKGREY, + MAP_MDGREY, + MAP_LTGREY, + MAP_WHITE, + MAP_BLUE, + MAP_LTBLUE, + MAP_DKBLUE, + MAP_GREEN, + MAP_LTGREEN, + MAP_DKGREEN, + MAP_CYAN, + MAP_LTCYAN, + MAP_DKCYAN, + MAP_RED, + MAP_LTRED, + MAP_DKRED, + MAP_MAGENTA, + MAP_LTMAGENTA, + MAP_DKMAGENTA, + MAP_YELLOW, + MAP_LTYELLOW, + MAP_DKYELLOW, + MAP_BROWN, + MAX_MAP_COL +}; + +class MapRegion : public Region +{ +public: + MapRegion(unsigned int pixsz); + ~MapRegion(); + + virtual void render(); + virtual void clear(); + virtual int handle_mouse(MouseEvent &event); + virtual bool update_tip_text(std::string &tip); + + void init_colours(); + void set(unsigned int gx, unsigned int gy, map_feature f); + void set_window(const coord_def &start, const coord_def &end); + +protected: + virtual void on_resize(); + void update_offsets(); + + map_colour m_colours[MF_MAX]; + unsigned int m_min_gx, m_max_gx, m_min_gy, m_max_gy; + coord_def m_win_start; + coord_def m_win_end; + unsigned char *m_buf; + bool m_far_view; +}; + + +#endif +#endif diff --git a/crawl-ref/source/tiles.h b/crawl-ref/source/tiles.h index f15faade53..1245633b57 100644 --- a/crawl-ref/source/tiles.h +++ b/crawl-ref/source/tiles.h @@ -5,11 +5,23 @@ * Modified for Crawl Reference by $Author: j-p-e-g $ on $Date: 2008-03-07 $ */ +#ifndef TILES_H +#define TILES_H + #ifdef USE_TILE #include "tiledef.h" #include "beam.h" +#include "tiledef-p.h" + +struct dolls_data +{ + dolls_data() { memset(parts, 0, sizeof(parts)); } + + int parts[TILEP_PARTS_TOTAL]; +}; + //*tile1.cc: get data from core part and drives tile drawing codes //**convert in-game data to tile index @@ -57,9 +69,8 @@ void tile_draw_rays(bool resetCount); void tile_clear_buf(); void tile_finish_dngn(unsigned int *tileb, int cx, int cy); -void tile_draw_dungeon(unsigned int *tileb); -// Tile Inventry display +// Tile Inventory display void tile_draw_inv(int flag = -1); // Multiple pickup void tile_pick_menu(); @@ -87,43 +98,18 @@ void TileResizeScreen(int x, int y); int TileDrawCursor(int x, int y, int flag); // display bolts void TileDrawBolt(int x, int y, int fg); -// display dungeon: tileb = { fg(0,0),bg(0,0),fg(1,0),bg(1,0), .. -void TileDrawDungeon(unsigned int *tileb); -// display memorised dungeon -void TileDrawFarDungeon(int cx, int cy); -// display map centered on grid coords -void TileDrawMap(int gx, int gy); -void LoadDungeonView(unsigned int *tileb); -void StoreDungeonView(unsigned int *tileb); - void TileNewLevel(bool first_time); - -// display inventry -void TileDrawInvData(int n, int flag, int *tiles, int *num, - int *idx, int *iflags); -void TileDrawOneItem(int region, int i, char key, int idx, - int tile, int num, bool floor, - bool select, bool equip, bool tried, bool cursed); -void TileRedrawInv(int region); -void TileClearInv(int region); -void TileMoveInvCursor(int ix); -int TileInvIdx(int i); - -// refresh player tile -void TilePlayerRefresh(); // edit player tile void TilePlayerEdit(); -// init player tile -void TilePlayerInit(); // init ghost tile void TileGhostInit(const struct ghost_demon &gs); // init pandem demon tile (only in iso mode) void TilePandemInit(struct ghost_demon &gs); // edit pandem tile (debug) void TileEditPandem(); -// init id-ed item tiles -void TileInitItems(); + +int item_unid_type(const item_def &item); // load wall tiles void TileLoadWall(bool wizard); @@ -131,9 +117,10 @@ void TileLoadWall(bool wizard); void TileDrawTitle(); // monster+weapon tile -void TileMcacheUnlock(); -int TileMcacheFind(int mon_tile, int eq_tile, int draco = 0); +void tile_mcache_unlock(); int get_base_idx_from_mcache(int tile_idx); +void tile_get_monster_weapon_offset(int mon_tile, int &ofs_x, int &ofs_y); +bool get_mcache_entry(int tile_idx, int &mon_idx, int &equ_tile, int &draco); int get_clean_map_idx(int tile_idx); /* Flags for drawing routines */ @@ -164,18 +151,21 @@ enum tile_flags TILE_FLAG_TRAV_EXCL = 0x00080000, TILE_FLAG_EXCL_CTR = 0x00100000, TILE_FLAG_SANCTUARY = 0x00200000, + TILE_FLAG_TUT_CURSOR= 0x00400000, // General TILE_FLAG_MASK = 0x000007FF }; - -#define TILEI_FLAG_SELECT 0x100 -#define TILEI_FLAG_TRIED 0x200 -#define TILEI_FLAG_EQUIP 0x400 -#define TILEI_FLAG_FLOOR 0x800 -#define TILEI_FLAG_CURSE 0x1000 -#define TILEI_FLAG_CURSOR 0x2000 +enum +{ + TILEI_FLAG_SELECT = 0x0100, + TILEI_FLAG_TRIED = 0x0200, + TILEI_FLAG_EQUIP = 0x0400, + TILEI_FLAG_FLOOR = 0x0800, + TILEI_FLAG_CURSE = 0x1000, + TILEI_FLAG_CURSOR = 0x2000 +}; #define TILEP_SHOW_EQUIP 0x1000 @@ -230,3 +220,4 @@ int get_parts_idx(int part, char *name); #define TILEP_BOOTS_CENTAUR_BARDING (N_PART_BOOTS + 2) #endif // USE_TILES +#endif diff --git a/crawl-ref/source/tilesdl.cc b/crawl-ref/source/tilesdl.cc new file mode 100644 index 0000000000..7a375ea046 --- /dev/null +++ b/crawl-ref/source/tilesdl.cc @@ -0,0 +1,937 @@ +#include "cio.h" +#include "itemname.h" +#include "items.h" +#include "itemprop.h" +#include "mon-util.h" +#include "player.h" +#include "stuff.h" +#include "tiles.h" +#include "tilesdl.h" +#include "travel.h" +#include "version.h" + +#include "tiledef-dngn.h" +#include "tilefont.h" + +#include <SDL.h> +#include <SDL_opengl.h> +#include <SDL_image.h> + +// Note: these defaults should match the OpenGL defaults +GLState::GLState() : + array_vertex(false), + array_texcoord(false), + array_colour(false), + blend(false), + texture(false) +{ +} + +void GLStateManager::init() +{ + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glClearColor(0.0, 0.0, 0.0, 1.0f); +} + +void GLStateManager::set(const GLState& state) +{ + if (state.array_vertex) + glEnableClientState(GL_VERTEX_ARRAY); + else + glDisableClientState(GL_VERTEX_ARRAY); + + if (state.array_texcoord) + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + else + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + + if (state.array_colour) + { + glEnableClientState(GL_COLOR_ARRAY); + } + else + { + glDisableClientState(GL_COLOR_ARRAY); + + // [enne] This should *not* be necessary, but the Linux OpenGL + // drive that I'm using sets this to the last colour of the + // colour array. So, we need to unset it here. + glColor3f(1.0f, 1.0f, 1.0f); + } + + if (state.texture) + glEnable(GL_TEXTURE_2D); + else + glDisable(GL_TEXTURE_2D); + + if (state.blend) + glEnable(GL_BLEND); + else + glDisable(GL_BLEND); +} + +TilesFramework tiles; + +TilesFramework::TilesFramework() : + m_windowsz(1024, 768), + m_viewsc(0, 0), + m_context(NULL), + m_fullscreen(false), + m_active_layer(LAYER_CRT), + m_font(NULL), + m_buttons_held(0), + m_key_mod(0), + m_mouse(-1, -1), + m_last_tick_moved(0) +{ +} + +TilesFramework::~TilesFramework() +{ +} + +void TilesFramework::shutdown() +{ + delete m_region_tile; + delete m_region_stat; + delete m_region_msg; + delete m_region_map; + delete m_region_self_inv; + delete m_region_crt; + delete m_region_menu_inv; + + m_region_tile = NULL; + m_region_stat = NULL; + m_region_msg = NULL; + m_region_map = NULL; + m_region_self_inv = NULL; + m_region_crt = NULL; + m_region_menu_inv = NULL; + + for (unsigned int i = 0; i < LAYER_MAX; i++) + { + m_layers[i].m_regions.clear(); + } + + SDL_Quit(); +} + +bool TilesFramework::initialise() +{ + if (SDL_Init(SDL_INIT_VIDEO) != 0) + { + printf ("Failed to initialise SDL: %s\n", SDL_GetError()); + return false; + } + + SDL_EnableUNICODE(true); + + SDL_WM_SetCaption(CRAWL " " VERSION, CRAWL); + SDL_Surface *icon = IMG_Load("dat/tiles/stone_soup_icon-32x32.png"); + if (!icon) + { + printf ("Failed to load icon: %s\n", SDL_GetError()); + return false; + } + SDL_WM_SetIcon(icon, NULL); + + SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); + SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 8); + SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8); + SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8); + SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8); + SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8); + + unsigned int flags = SDL_OPENGL; + if (m_fullscreen) + flags |= SDL_FULLSCREEN; + + // TODO enne - add options for screen size and fullscreen + m_context = SDL_SetVideoMode(m_windowsz.x, m_windowsz.y, 0, flags); + if (!m_context) + { + printf ("Failed to set video mode: %s\n", SDL_GetError()); + return false; + } + + if (!m_image.load_textures()) + return false; + + // TODO enne - make this configurable (and fall back on default if fails) + // TODO enne - use Crawl's dat file loading utilities + const char *font_file = "dat/tiles/VeraMono.ttf"; + const int font_size = 14; + if (!load_font(font_file, font_size)) + return false; + + ASSERT(m_font); + + // TODO enne - grab these from options + unsigned int map_pixsz = 4; + + // TODO enne - different font for tooltip and for dungeon tags + m_region_tile = new DungeonRegion(&m_image, m_font, TILE_X, TILE_Y); + m_region_map = new MapRegion(map_pixsz); + m_region_self_inv = new InventoryRegion(&m_image, TILE_X, TILE_Y); + m_region_msg = new MessageRegion(m_font); + m_region_stat = new StatRegion(m_font); + m_region_crt = new CRTRegion(m_font); + m_region_menu_inv = new InventoryRegion(&m_image, TILE_X, TILE_Y); + + m_layers[LAYER_NORMAL].m_regions.push_back(m_region_tile); + m_layers[LAYER_NORMAL].m_regions.push_back(m_region_map); + m_layers[LAYER_NORMAL].m_regions.push_back(m_region_self_inv); + m_layers[LAYER_NORMAL].m_regions.push_back(m_region_msg); + m_layers[LAYER_NORMAL].m_regions.push_back(m_region_stat); + + m_layers[LAYER_CRT].m_regions.push_back(m_region_crt); + m_layers[LAYER_CRT].m_regions.push_back(m_region_menu_inv); + + cgotoxy(1, 1, GOTO_CRT); + + GLStateManager::init(); + + resize(); + + return true; +} + +bool TilesFramework::load_font(const char *font_file, int font_size) +{ + m_font = new FTFont(); + + if (!m_font->load_font(font_file, font_size)) + { + delete m_font; + m_font = NULL; + + printf("Failed to open font '%s'\n", font_file); + return false; + } + + return true; +} + +void TilesFramework::load_dungeon(unsigned int *tileb, int gx, int gy) +{ + unsigned int ox = m_region_tile->mx/2; + unsigned int oy = m_region_tile->my/2; + m_region_tile->load_dungeon(tileb, gx - ox, gy - oy); + + coord_def win_start(gx - ox, gy - oy); + coord_def win_end(gx + ox + 1, gy + oy + 1); + + m_region_map->set_window(win_start, win_end); +} + +void TilesFramework::load_dungeon(int cx, int cy) +{ + int wx = m_region_tile->mx; + int wy = m_region_tile->my; + unsigned int *tb = (unsigned int*)alloca(sizeof(unsigned int) * + wy * wx * 2); + + int count = 0; + for (int y = 0; y < wy; y++) + { + for (int x = 0; x < wx; x++) + { + int fg; + int bg; + + const coord_def gc(cx + x - wx/2, + cy + y - wy/2); + const coord_def ep = view2show(grid2view(gc)); + + // mini "viewwindow" routine + if (!map_bounds(gc)) + { + fg = 0; + bg = TILE_DNGN_UNSEEN; + } + else if (!crawl_view.in_grid_los(gc) || !env.show(ep)) + { + fg = env.tile_bk_fg[gc.x][gc.y]; + bg = env.tile_bk_bg[gc.x][gc.y]; + if (bg == 0) + bg |= TILE_DNGN_UNSEEN; + bg |= tile_unseen_flag(gc); + } + else + { + fg = env.tile_fg[ep.x-1][ep.y-1]; + bg = env.tile_bg[ep.x-1][ep.y-1]; + } + + if (gc.x == cx && gc.y == cy) + bg |= TILE_FLAG_CURSOR1; + + tb[count++] = fg; + tb[count++] = bg; + } + } + + load_dungeon(tb, cx, cy); + tiles.redraw(); +} + +void TilesFramework::resize() +{ + do_layout(); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + + // TODO enne - need better resizing + // View size in pixels is (m_viewsc * crawl_view.viewsz) + m_viewsc.x = 32; + m_viewsc.y = 32; + + // For ease, vertex positions are pixel positions. + glOrtho(0, m_windowsz.x, m_windowsz.y, 0, 0, 100); +} + +static unsigned char _get_modifiers(SDL_keysym &keysym) +{ + // keysym.mod can't be used to keep track of the modifier state. + // If shift is hit by itself, this will not include KMOD_SHIFT. + // Instead, look for the key itself as a separate event. + switch (keysym.sym) + { + case SDLK_LSHIFT: + case SDLK_RSHIFT: + return MOD_SHIFT; + case SDLK_LCTRL: + case SDLK_RCTRL: + return MOD_CTRL; + case SDLK_LALT: + case SDLK_RALT: + return MOD_ALT; + default: + return 0; + } +} + +static int _translate_keysym(SDL_keysym &keysym) +{ + // This function returns the key that was hit. Returning zero implies that + // the keypress (e.g. hitting shift on its own) should be eaten and not + // handled. + + const int shift_offset = CK_SHIFT_UP - CK_UP; + const int ctrl_offset = CK_CTRL_UP - CK_UP; + + int offset = 0; + if (keysym.mod & KMOD_CTRL) + offset = ctrl_offset; + else if (keysym.mod & KMOD_SHIFT) + offset = shift_offset; + + switch (keysym.sym) + { + case SDLK_RETURN: + return CK_ENTER; + case SDLK_BACKSPACE: + return CK_BKSP; + case SDLK_ESCAPE: + return CK_ESCAPE; + case SDLK_DELETE: + return CK_DELETE; + + case SDLK_UP: + return CK_UP + offset; + case SDLK_DOWN: + return CK_DOWN + offset; + case SDLK_LEFT: + return CK_LEFT + offset; + case SDLK_RIGHT: + return CK_RIGHT + offset; + case SDLK_INSERT: + return CK_INSERT + offset; + case SDLK_HOME: + return CK_HOME + offset; + case SDLK_END: + return CK_END + offset; + case SDLK_CLEAR: + return CK_CLEAR + offset; + case SDLK_PAGEUP: + return CK_PGUP + offset; + case SDLK_PAGEDOWN: + return CK_PGDN + offset; + default: + break; + } + + bool is_ascii = ((keysym.unicode & 0xFF80) == 0); + return is_ascii ? keysym.unicode & 0x7F : 0; +} + +int TilesFramework::getch() +{ + // TODO enne - is there really a difference between these two functions?? + return getch_ck(); +} + +int TilesFramework::handle_mouse(MouseEvent &event) +{ + m_region_tile->place_cursor(CURSOR_MOUSE, Region::NO_CURSOR); + + // Note: the mouse event goes to all regions in the active layer because + // we want to be able to start some GUI event (e.g. far viewing) and + // stop if it moves to another region. + int return_key = 0; + for (unsigned int i = 0; i < m_layers[m_active_layer].m_regions.size(); i++) + { + // TODO enne - what if two regions give a key? + int key = 0; + key = m_layers[m_active_layer].m_regions[i]->handle_mouse(event); + if (key) + return_key = key; + } + + // Let regions take priority in any mouse mode. + if (return_key) + return return_key; + + // Handle "more" mode globally here, rather than duplicate across regions. + if (mouse_control::current_mode() == MOUSE_MODE_MORE + && event.button == MouseEvent::LEFT + && event.event == MouseEvent::PRESS) + { + return '\r'; + } + + // TODO enne - in what cases should the buttons be returned? +#if 0 + // If nothing else, return the mouse button that was pressed. + switch (event.button) + { + case MouseEvent::LEFT: + return CK_MOUSE_B1; + case MouseEvent::RIGHT: + return CK_MOUSE_B2; + case MouseEvent::MIDDLE: + return CK_MOUSE_B3; + case MouseEvent::SCROLL_UP: + return CK_MOUSE_B4; + case MouseEvent::SCROLL_DOWN: + return CK_MOUSE_B5; + default: + case MouseEvent::NONE: + return 0; + } +#endif + + return 0; +} + +static void _translate_event(const SDL_MouseMotionEvent &sdl_event, + MouseEvent &tile_event) +{ + tile_event.held = MouseEvent::NONE; + tile_event.event = MouseEvent::MOVE; + tile_event.button = MouseEvent::NONE; + tile_event.px = sdl_event.x; + tile_event.py = sdl_event.y; + + // TODO enne - do we want the relative motion? +} + +static void _translate_event(const SDL_MouseButtonEvent &sdl_event, + MouseEvent &tile_event) +{ + tile_event.held = MouseEvent::NONE; + tile_event.event = (sdl_event.type == SDL_MOUSEBUTTONDOWN) ? + MouseEvent::PRESS : MouseEvent::RELEASE; + switch (sdl_event.button) + { + case SDL_BUTTON_LEFT: + tile_event.button = MouseEvent::LEFT; + break; + case SDL_BUTTON_RIGHT: + tile_event.button = MouseEvent::RIGHT; + break; + case SDL_BUTTON_MIDDLE: + tile_event.button = MouseEvent::MIDDLE; + break; + case SDL_BUTTON_WHEELUP: + tile_event.button = MouseEvent::SCROLL_UP; + break; + case SDL_BUTTON_WHEELDOWN: + tile_event.button = MouseEvent::SCROLL_DOWN; + break; + default: + ASSERT(!"Unhandled button"); + tile_event.button = MouseEvent::NONE; + break; + } + tile_event.px = sdl_event.x; + tile_event.py = sdl_event.y; +} + +int TilesFramework::getch_ck() +{ + SDL_Event event; + + int key = 0; + + while (!key) + { + unsigned int ticks = SDL_GetTicks(); + + if (SDL_PollEvent(&event)) + { + switch(event.type) + { + case SDL_KEYDOWN: + m_key_mod |= _get_modifiers(event.key.keysym); + key = _translate_keysym(event.key.keysym); + + // If you hit a key, disable tooltips until the mouse + // is moved again. + m_last_tick_moved = ~0; + break; + + case SDL_KEYUP: + m_key_mod &= ~_get_modifiers(event.key.keysym); + m_last_tick_moved = ~0; + break; + + case SDL_MOUSEMOTION: + { + // Record mouse pos for tooltip timer + if (m_mouse.x != event.motion.x + || m_mouse.y != event.motion.y) + { + m_last_tick_moved = ticks; + } + m_mouse.x = event.motion.x; + m_mouse.y = event.motion.y; + + MouseEvent mouse_event; + _translate_event(event.motion, mouse_event); + mouse_event.held = m_buttons_held; + mouse_event.mod = m_key_mod; + key = handle_mouse(mouse_event); + } + break; + + case SDL_MOUSEBUTTONUP: + { + MouseEvent mouse_event; + _translate_event(event.button, mouse_event); + m_buttons_held &= ~(mouse_event.button); + mouse_event.held = m_buttons_held; + mouse_event.mod = m_key_mod; + key = handle_mouse(mouse_event); + m_last_tick_moved = ticks; + } + break; + + case SDL_MOUSEBUTTONDOWN: + { + MouseEvent mouse_event; + _translate_event(event.button, mouse_event); + m_buttons_held |= mouse_event.button; + mouse_event.held = m_buttons_held; + mouse_event.mod = m_key_mod; + key = handle_mouse(mouse_event); + m_last_tick_moved = ticks; + } + break; + + case SDL_QUIT: + // TODO enne + exit(0); + + case SDL_USEREVENT: + default: + break; + } + } + + // TODO enne - outsource this value + unsigned int tooltip_ticks = 1000; + bool show_tooltip = ((ticks - m_last_tick_moved > tooltip_ticks) + && ticks > m_last_tick_moved); + + if (show_tooltip) + { + if (m_tooltip.empty()) + { + for (unsigned int i = 0; + i < m_layers[m_active_layer].m_regions.size(); i++) + { + Region *reg = m_layers[m_active_layer].m_regions[i]; + if (!reg->inside(m_mouse.x, m_mouse.y)) + continue; + if (reg->update_tip_text(m_tooltip)) + break; + } + } + } + else + { + m_tooltip.clear(); + } + + redraw(); + } + + return key; +} + +void TilesFramework::do_layout() +{ + const int map_stat_buffer = 5; + + // TODO enne - use options + const int crt_width = 80; + const int crt_height = 30; + const int map_margin = 2; + + // Size regions that we know about + m_region_tile->resize(crawl_view.viewsz.x, crawl_view.viewsz.y); + m_region_crt->resize(crt_width, crt_height); + m_region_stat->resize(crawl_view.hudsz.x, crawl_view.hudsz.y); + m_region_msg->resize(crawl_view.msgsz.x, crawl_view.msgsz.y); + m_region_map->resize(GXM, GYM); + + + // Place regions for normal layer + const int margin = 4; + m_region_tile->place(0, 0, margin); + m_region_msg->place(0, m_region_tile->ey, margin); + + int stat_col = m_region_tile->ex + map_stat_buffer; + + m_region_stat->place(stat_col, 0, 0); + m_region_map->place(stat_col, m_region_stat->ey, map_margin); + + int inv_col = std::max(m_region_tile->ex, m_region_msg->ex); + + m_region_self_inv->place(inv_col, m_region_map->ey, 0); + m_region_self_inv->resize_to_fit(m_windowsz.x - + m_region_self_inv->sx, + m_windowsz.y - + m_region_self_inv->sy); + + // Place regions for crt layer + m_region_crt->place(0, 0, margin); + m_region_menu_inv->place(0, m_region_crt->ey, margin); + m_region_menu_inv->resize_to_fit(m_windowsz.x, m_windowsz.y - + m_region_menu_inv->sy); +} + +void TilesFramework::clrscr() +{ + TextRegion::cursor_region = NULL; + + if (m_region_stat) + m_region_stat->clear(); + if (m_region_msg) + m_region_msg->clear(); + if (m_region_crt) + m_region_crt->clear(); + if (m_region_menu_inv) + m_region_menu_inv->clear(); + + cgotoxy(1,1); +} + +void TilesFramework::message_out(int which_line, int colour, const char *s, int firstcol, bool newline) +{ + if (!firstcol) + firstcol = Options.delay_message_clear ? 2 : 1; + + cgotoxy(firstcol, which_line + 1, GOTO_MSG); + textcolor(colour); + + cprintf("%s", s); + + if (newline && which_line == crawl_view.msgsz.y - 1) + m_region_msg->scroll(); +} + +void TilesFramework::clear_message_window() +{ + m_region_msg->clear(); + m_active_layer = LAYER_NORMAL; +} + +void TilesFramework::cgotoxy(int x, int y, int region) +{ + if (region == GOTO_LAST) + { + // nothing + } + else if (region == GOTO_CRT) + { + m_active_layer = LAYER_CRT; + TextRegion::text_mode = m_region_crt; + } + else if (region == GOTO_MSG) + { + m_active_layer = LAYER_NORMAL; + TextRegion::text_mode = m_region_msg; + } + else if (region == GOTO_STAT) + { + m_active_layer = LAYER_NORMAL; + TextRegion::text_mode = m_region_stat; + } + + TextRegion::cgotoxy(x, y); +} + +void TilesFramework::redraw() +{ + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glScalef(m_viewsc.x, m_viewsc.y, 1.0f); + + for (unsigned int i = 0; i < m_layers[m_active_layer].m_regions.size(); i++) + { + m_layers[m_active_layer].m_regions[i]->render(); + } + + // Draw tooltip + if (!m_tooltip.empty()) + { + const coord_def min_pos(0, 0); + m_font->render_string(m_mouse.x, m_mouse.y - 2, m_tooltip.c_str(), + min_pos, m_windowsz, WHITE, false, 150, + BLUE, 5); + } + + SDL_GL_SwapBuffers(); +} + +void TilesFramework::update_minimap(int gx, int gy, map_feature f) +{ + if (!player_in_mappable_area()) + return; + + coord_def gc(gx, gy); + + if (you.pos() == gc) + { + f = MF_PLAYER; + } + else if (f == MF_MONS_HOSTILE && mgrd[gx][gy] != NON_MONSTER) + { + const int grid = mgrd[gx][gy]; + if (mons_friendly(&menv[grid])) + f = MF_MONS_FRIENDLY; + else if (mons_neutral(&menv[grid])) + f = MF_MONS_NEUTRAL; + else if (mons_class_flag(menv[grid].type, M_NO_EXP_GAIN)) + f = MF_MONS_NO_EXP; + } + else if (f == MF_FLOOR || f == MF_MAP_FLOOR) + { + if (is_exclude_root(gc)) + f = MF_EXCL_ROOT; + else if (is_excluded(gc)) + f = MF_EXCL; + } + + m_region_map->set(gx, gy, f); +} + +void TilesFramework::clear_minimap() +{ + m_region_map->clear(); +} + +static void _fill_item_info(InventoryTile &desc, const item_def &item) +{ + desc.tile = tileidx_item(item); + + int type = item.base_type; + if (type == OBJ_FOOD || type == OBJ_SCROLLS + || type == OBJ_POTIONS || type == OBJ_MISSILES) + { + // -1 specifies don't display anything + desc.quantity = item.quantity == 1 ? -1 : item.quantity; + } + else if (type == OBJ_WANDS + && ((item.flags & ISFLAG_KNOW_PLUSES) + || item.plus2 == ZAPCOUNT_EMPTY)) + { + desc.quantity = item.plus; + } + else + { + desc.quantity = -1; + } + + desc.flag = 0; + if (item_cursed(item) && item_ident(item, ISFLAG_KNOW_CURSE)) + desc.flag |= TILEI_FLAG_CURSE; + if (item_type_tried(item)) + desc.flag |= TILEI_FLAG_TRIED; + if (item.x != -1) + desc.flag |= TILEI_FLAG_FLOOR; +} + +void TilesFramework::update_inventory() +{ + std::vector<InventoryTile> inv; + + if (!Options.tile_show_items) + return; + + unsigned int max_pack_row = (ENDOFPACK-1) / m_region_self_inv->mx + 1; + max_pack_row = std::min(m_region_self_inv->my - 1, max_pack_row); + unsigned int max_pack_items = max_pack_row * m_region_self_inv->mx; + + // TODO enne - document that '.' and '_' no longer work + + // TODO enne - if all inventory and ground can't fit, allow ground + // and inventory items on the same row. + + // item.base_type <-> char conversion table + const static char *obj_syms = ")([/%#?=!#+\\0}x"; + + for (unsigned int c = 0; c < strlen(Options.tile_show_items); c++) + { + if (inv.size() >= max_pack_items) + break; + + const char *find = strchr(obj_syms, Options.tile_show_items[c]); + if (!find) + continue; + object_class_type type = (object_class_type)(find - obj_syms); + + // First, normal inventory + for (int i = 0; i < ENDOFPACK; i++) + { + if (!is_valid_item(you.inv[i]) || you.inv[i].quantity == 0) + continue; + + if (you.inv[i].base_type != type) + continue; + + InventoryTile desc; + _fill_item_info(desc, you.inv[i]); + desc.idx = i; + + for (int eq = 0; eq < NUM_EQUIP; eq++) + { + if (you.equip[eq] == i) + { + desc.flag |= TILEI_FLAG_EQUIP; + break; + } + } + + inv.push_back(desc); + } + } + + // Finish out this row + while (inv.size() % m_region_self_inv->mx != 0) + { + InventoryTile desc; + inv.push_back(desc); + } + + // How many ground items do we have? + unsigned int num_ground = 0; + for (int i = igrd[you.x_pos][you.y_pos]; i != NON_ITEM; i = mitm[i].link) + num_ground++; + + // Add extra rows, if needed. + unsigned int ground_rows = + std::max(((int)num_ground-1) / (int)m_region_self_inv->mx + 1, 1); + + while (inv.size() / m_region_self_inv->mx + ground_rows < m_region_self_inv->my) + { + for (unsigned int i = 0; i < m_region_self_inv->mx; i++) + { + InventoryTile desc; + inv.push_back(desc); + } + } + + // Then, ground items... + for (unsigned int c = 0; c < strlen(Options.tile_show_items); c++) + { + if (inv.size() >= m_region_self_inv->mx * m_region_self_inv->my) + break; + + const char *find = strchr(obj_syms, Options.tile_show_items[c]); + if (!find) + continue; + object_class_type type = (object_class_type)(find - obj_syms); + + for (int i = igrd[you.x_pos][you.y_pos]; i != NON_ITEM; i = mitm[i].link) + { + if (inv.size() >= m_region_self_inv->mx * m_region_self_inv->my) + break; + + if (mitm[i].base_type != type) + continue; + + InventoryTile desc; + _fill_item_info(desc, mitm[i]); + desc.idx = i; + + inv.push_back(desc); + } + } + + // Finish out ground inventory + while (inv.size() < m_region_self_inv->mx * m_region_self_inv->my) + { + InventoryTile desc; + desc.flag = TILEI_FLAG_FLOOR; + inv.push_back(desc); + } + + m_region_self_inv->update(inv.size(), &inv[0]); +} + +void TilesFramework::update_menu_inventory(unsigned int slot, + const item_def &item, + bool selected, char key) +{ + InventoryTile desc; + _fill_item_info(desc, item); + desc.key = key; + desc.idx = (desc.flag & TILEI_FLAG_FLOOR) ? item.index() : + letter_to_index(key); + if (selected) + desc.flag |= TILEI_FLAG_SELECT; + + m_region_menu_inv->update_slot(slot, desc); +} + +void TilesFramework::place_cursor(cursor_type type, const coord_def &gc) +{ + m_region_tile->place_cursor(type, gc); +} + +void TilesFramework::clear_text_tags(text_tag_type type) +{ + m_region_tile->clear_text_tags(type); +} + +void TilesFramework::add_text_tag(text_tag_type type, const std::string &tag, + const coord_def &gc) +{ + m_region_tile->add_text_tag(type, tag, gc); +} + +bool TilesFramework::initialise_items() +{ + return (m_image.load_item_texture()); +} + +const coord_def &TilesFramework::get_cursor() const +{ + return (m_region_tile->get_cursor()); +} diff --git a/crawl-ref/source/tilesdl.h b/crawl-ref/source/tilesdl.h new file mode 100644 index 0000000000..5f0032ebec --- /dev/null +++ b/crawl-ref/source/tilesdl.h @@ -0,0 +1,186 @@ +/* + * File: tilesdl.h + * Summary: SDL-related functionality for the tiles port + * Written by: Enne Walker + */ + +#ifdef USE_TILE +#ifndef TILESDL_H +#define TILESDL_H + +#include "debug.h" +#include "externs.h" +#include "FixVec.h" +#include "tilereg.h" + +// This struct defines all of the state that any particular rendering needs. +// If other rendering states are needed, they should be added here so that +// they do not introduce unneeded side effects for other parts of the code +// that have not thought about turning that new state off. +struct GLState +{ + GLState(); + + // vertex arrays + bool array_vertex; + bool array_texcoord; + bool array_colour; + + // render state + bool blend; + bool texture; +}; + +enum key_mod +{ + MOD_SHIFT = 0x1, + MOD_CTRL = 0x2, + MOD_ALT = 0x4 +}; + +struct MouseEvent +{ + enum mouse_event_type + { + PRESS, + RELEASE, + MOVE + }; + + enum mouse_event_button + { + NONE = 0x00, + LEFT = 0x01, + MIDDLE = 0x02, + RIGHT = 0x04, + SCROLL_UP = 0x08, + SCROLL_DOWN = 0x10 + }; + + // kind of event + mouse_event_type event; + // if PRESS or RELEASE, the button pressed + mouse_event_button button; + // bitwise-or of buttons currently pressed + unsigned short held; + // bitwise-or of key mods currently pressed + unsigned char mod; + // location of events in pixels and in window coordinate space + unsigned int px; + unsigned int py; +}; + +class GLStateManager +{ +public: + static void init(); + static void set(const GLState& state); +}; + +class SDL_Surface; +class FTFont; + +class TilesFramework +{ +public: + TilesFramework(); + virtual ~TilesFramework(); + + bool initialise(); + void shutdown(); + void load_dungeon(unsigned int *tileb, int gx, int gy); + void load_dungeon(int gx, int gy); + int getch(); + int getch_ck(); + void resize(); + void clrscr(); + + void message_out(int which_line, int colour, const char *s, int firstcol, bool newline); + + void cgotoxy(int x, int y, int region = GOTO_CRT); + void clear_message_window(); + + void update_minimap(int gx, int gy, map_feature f); + void clear_minimap(); + void update_inventory(); + + void update_menu_inventory(unsigned int slot, const item_def &item, bool selected, char key); + + void redraw(); + + void place_cursor(cursor_type type, const coord_def &gc); + void clear_text_tags(text_tag_type type); + void add_text_tag(text_tag_type type, const std::string &tag, + const coord_def &gc); + + bool initialise_items(); + + const coord_def &get_cursor() const; +protected: + + bool load_font(const char *font_file, int font_size); + int handle_mouse(MouseEvent &event); + + // screen pixel dimensions + coord_def m_windowsz; + // screen pixels per view cell + coord_def m_viewsc; + + SDL_Surface* m_context; + bool m_fullscreen; + + enum LayerID + { + LAYER_NORMAL, + LAYER_CRT, + LAYER_TITLE, + LAYER_MAX + }; + + class Layer + { + public: + // Layers don't own these regions + std::vector<Region*> m_regions; + }; + Layer m_layers[LAYER_MAX]; + LayerID m_active_layer; + + // Normal layer + DungeonRegion *m_region_tile; + StatRegion *m_region_stat; + MessageRegion *m_region_msg; + MapRegion *m_region_map; + InventoryRegion *m_region_self_inv; + + // Full-screen CRT layer + CRTRegion *m_region_crt; + InventoryRegion *m_region_menu_inv; + + FTFont *m_font; + + void do_layout(); + + ImageManager m_image; + + // Mouse state. + unsigned short m_buttons_held; + unsigned char m_key_mod; + coord_def m_mouse; + unsigned int m_last_tick_moved; + + std::string m_tooltip; +}; + +// Main interface for tiles functions +extern TilesFramework tiles; + +#ifdef __MINGW32__ +#ifndef alloca +// Srsly, MinGW, wtf? +void *alloca(size_t); +#endif +#endif + +#endif +#endif diff --git a/crawl-ref/source/tiletex.cc b/crawl-ref/source/tiletex.cc new file mode 100644 index 0000000000..38c2aa729a --- /dev/null +++ b/crawl-ref/source/tiletex.cc @@ -0,0 +1,262 @@ +#include "AppHdr.h" + +#include "tiles.h" +#include "tiletex.h" + +#include <SDL.h> +#include <SDL_opengl.h> +#include <SDL_image.h> + +GenericTexture::GenericTexture() : + m_handle(0), + m_width(0), + m_height(0) +{ +} + +GenericTexture::~GenericTexture() +{ + unload_texture(); +} + +void GenericTexture::unload_texture() +{ + glDeleteTextures(1, (GLuint*)&m_handle); +} + +bool GenericTexture::load_texture(const char *filename, + GenericTexture::MipMapOptions mip_opt, + tex_proc_func proc) +{ + char acBuffer[512]; + // TODO enne - use Crawl's helper functions to find images... + strcpy(acBuffer, "dat/tiles/"); + strcat(acBuffer, filename); + SDL_Surface *img = IMG_Load(acBuffer); + + if (!img) + { + printf("Warning: couldn't load file '%s'.\n", acBuffer); + return false; + } + + unsigned int bpp = img->format->BytesPerPixel; + glPixelStorei(GL_UNPACK_ALIGNMENT, bpp); + + // Determine texture format + unsigned char *pixels = (unsigned char*)img->pixels; + int new_width = img->w; + int new_height = img->h; + GLenum texture_format; + if (bpp == 4) + { + if (img->format->Rmask == 0x000000ff) + texture_format = GL_RGBA; + else + texture_format = GL_BGRA; + } + else if (bpp == 3) + { + if (img->format->Rmask == 0x000000ff) + texture_format = GL_RGB; + else + texture_format = GL_BGR; + } + else if (bpp == 1) + { + // need to depalettize + SDL_LockSurface(img); + + // Prefer power-of-two textures to avoid texture bleeding from + // floating point error. + // TODO enne - convert non-palettized to power-of-2 as well? + new_width = 1; + while (new_width < img->w) + new_width *= 2; + new_height = 1; + while (new_height < img->h) + new_height *= 2; + + pixels = new unsigned char[4 * new_width * new_height]; + + SDL_Palette* pal = img->format->palette; + ASSERT(pal); + ASSERT(pal->colors); + + // Find transparent colour + // TODO enne - this should probably be removed from rltiles + // TODO enne - is there more than one transparent color?? + int trans_index = -1; + for (int p = 0; p < pal->ncolors ; p++) + { + if (pal->colors[p].r == 71 && + pal->colors[p].g == 108 && + pal->colors[p].b == 108) + { + trans_index = p; + break; + } + } + + int src = 0; + int dest = 0; + for (int y = 0; y < img->h; y++) + { + int x; + for (x = 0; x < img->w; x++) + { + int index = ((unsigned char*)img->pixels)[src++]; + pixels[dest*4 ] = pal->colors[index].r; + pixels[dest*4 + 1] = pal->colors[index].g; + pixels[dest*4 + 2] = pal->colors[index].b; + pixels[dest*4 + 3] = (index == trans_index) ? 0 : 255; + dest++; + } + while (x++ < new_width) + { + // Extend to the right with transparent pixels + pixels[dest*4 ] = 0; + pixels[dest*4 + 1] = 0; + pixels[dest*4 + 2] = 0; + pixels[dest*4 + 3] = 0; + dest++; + } + } + while (dest < new_width * new_height) + { + // Extend down with transparent pixels + pixels[dest*4 ] = 0; + pixels[dest*4 + 1] = 0; + pixels[dest*4 + 2] = 0; + pixels[dest*4 + 3] = 0; + dest++; + } + + SDL_UnlockSurface(img); + + bpp = 4; + texture_format = GL_RGBA; + } + else + { + printf("Warning: unsupported format, bpp = %d for '%s'\n", + bpp, acBuffer); + return false; + } + + bool success = false; + if (!proc || proc(pixels, new_width, new_height)) + { + success |= load_texture(pixels, new_width, new_height, mip_opt); + } + + // If conversion has occurred, delete converted data. + if (pixels != img->pixels) + delete pixels; + + SDL_FreeSurface(img); + + return success; +} + +bool GenericTexture::load_texture(unsigned char *pixels, unsigned int new_width, + unsigned int new_height, + GenericTexture::MipMapOptions mip_opt) +{ + if (!pixels || !new_width || !new_height) + return false; + + // Assumptions... + const unsigned int bpp = 4; + const GLenum texture_format = GL_RGBA; + const GLenum format = GL_UNSIGNED_BYTE; + + m_width = new_width; + m_height = new_height; + + glGenTextures(1, (GLuint*)&m_handle); + glBindTexture(GL_TEXTURE_2D, m_handle); + + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); + + if (mip_opt == MIPMAP_CREATE) + { + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, + GL_LINEAR_MIPMAP_NEAREST); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + gluBuild2DMipmaps(GL_TEXTURE_2D, bpp, m_width, m_height, + texture_format, format, pixels); + } + else + { + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexImage2D(GL_TEXTURE_2D, 0, bpp, m_width, m_height, 0, + texture_format, format, pixels); + } + + return true; +} + +void GenericTexture::bind() +{ + ASSERT(m_handle); + glBindTexture(GL_TEXTURE_2D, m_handle); +} + +void TilesTexture::get_texcoord_doll(int part, int idx, int ymax, float &x, float &y, float &wx, float &wy, int &wx_pix, int &wy_pix, int &ox, int &oy) +{ + int tile_idx = tilep_parts_start[part]; + int nx = tilep_parts_nx[part]; + int ny = tilep_parts_ny[part]; + ox = tilep_parts_ox[part]; + oy = tilep_parts_oy[part]; + wx_pix = TILE_X / nx; + wy_pix = TILE_Y / ny; + + if (!idx) + { + wy = -1; + return; + } + + idx--; + tile_idx += idx / (nx * ny); + + if (oy + wy_pix > ymax) + wy_pix -= oy + wy_pix - ymax; + + int xs = (tile_idx % TILEP_PER_ROW) * TILE_X; + int ys = (tile_idx / TILEP_PER_ROW) * TILE_Y; + xs += (idx % nx) * TILE_X / nx; + ys += ((idx / nx) % ny) * TILE_Y / ny; + + x = xs / (float)m_width; + y = ys / (float)m_height; + wx = wx_pix / (float)m_width; + wy = wy_pix / (float)m_height; +} + +void TilesTexture::get_texcoord(int idx, float &x, float &y, + float &wx, float &wy) +{ + const unsigned int tile_size = 32; + unsigned int tiles_per_row = m_width / tile_size; + + wx = tile_size / (float)m_width; + wy = tile_size / (float)m_height; + + unsigned int row = idx / tiles_per_row; + unsigned int col = idx % tiles_per_row; + + x = tile_size * col / (float)m_width; + y = tile_size * row / (float)m_height; + + ASSERT(row >= 0); + ASSERT(col >= 0); + ASSERT(x + wx <= m_width); + ASSERT(y + wy <= m_height); +} + diff --git a/crawl-ref/source/tiletex.h b/crawl-ref/source/tiletex.h new file mode 100644 index 0000000000..9a8f78ccd7 --- /dev/null +++ b/crawl-ref/source/tiletex.h @@ -0,0 +1,60 @@ +/* + * File: tiletex.h + * Summary: PNG and texture loading functionality + * Written by: Enne Walker + */ + +#ifndef TILETEX_H +#define TILETEX_H + +enum TextureID +{ + TEX_DUNGEON, + TEX_DEFAULT, + TEX_DOLL, + TEX_TITLE, + TEX_MAX +}; + +class GenericTexture +{ +public: + GenericTexture(); + virtual ~GenericTexture(); + + enum MipMapOptions + { + MIPMAP_CREATE, + MIPMAP_NONE, + MIPMAP_MAX + }; + + // Arbitrary post-load texture processing + typedef bool(*tex_proc_func)(unsigned char *pixels, unsigned int w, + unsigned int h); + + bool load_texture(const char *filename, MipMapOptions mip_opt, + tex_proc_func proc = NULL); + bool load_texture(unsigned char *pixels, unsigned int w, unsigned int h, + MipMapOptions mip_opt); + void unload_texture(); + + unsigned int width() const { return m_width; } + unsigned int height() const { return m_height; } + void bind(); + +protected: + unsigned int m_handle; + unsigned int m_width; + unsigned int m_height; +}; + +class TilesTexture : public GenericTexture +{ +public: + void get_texcoord(int idx, float &x, float &y, float &wx, float &wy); + + void get_texcoord_doll(int part, int idx, int ymax, float &x, float &y, float &wx, float &wy, int &wx_pix, int &wy_pix, int &ox, int &oy); +}; + +#endif diff --git a/crawl-ref/source/travel.cc b/crawl-ref/source/travel.cc index 680c66f191..39674e8660 100644 --- a/crawl-ref/source/travel.cc +++ b/crawl-ref/source/travel.cc @@ -255,10 +255,10 @@ static void _tile_exclude_gmap_update(const coord_def p) { int px = p.x+x, py = p.y+y; if (in_bounds(coord_def(px,py))) - GmapUpdate(px, py, env.map[px][py].glyph(), true); + { + tiles.update_minimap(px, py, MF_EXCL); + } } - - GmapDisplay(p.x,p.y); } #endif diff --git a/crawl-ref/source/tutorial.cc b/crawl-ref/source/tutorial.cc index 52404c0875..0da644b00b 100644 --- a/crawl-ref/source/tutorial.cc +++ b/crawl-ref/source/tutorial.cc @@ -38,6 +38,7 @@ #include "player.h" #include "randart.h" #include "religion.h" +#include "shopping.h" #include "skills2.h" #include "spl-book.h" #include "spl-util.h" @@ -1182,9 +1183,9 @@ void tutorial_first_monster(const monsters &mon) if (!Options.tutorial_events[TUT_SEEN_MONSTER]) { if (get_mons_colour(&mon) != mon.colour) - learned_something_new(TUT_MONSTER_BRAND); + learned_something_new(TUT_MONSTER_BRAND, mon.x, mon.y); if (mons_friendly(&mon)) - learned_something_new(TUT_MONSTER_FRIENDLY); + learned_something_new(TUT_MONSTER_FRIENDLY, mon.x, mon.y); if (!Options.tut_just_triggered && one_chance_in(4) @@ -1215,8 +1216,9 @@ void tutorial_first_monster(const monsters &mon) std::string text = "That "; #ifdef USE_TILE // need to highlight monster - const coord_def ep = grid2view(coord_def(mon.x, mon.y)); - tile_place_cursor(ep.x-1,ep.y-1,true); + const coord_def gc(mon.x, mon.y); + tiles.place_cursor(CURSOR_TUTORIAL, gc); + tiles.add_text_tag(TAG_TUTORIAL, mon.name(DESC_CAP_A), gc); text += "monster is a "; text += mon.name(DESC_PLAIN).c_str(); @@ -1341,9 +1343,9 @@ void tutorial_first_item(const item_def &item) text += _colourize_glyph(col, ch); text += " "; #else - // Highlight item. XXX: Doesn't work, unfortunately. - const coord_def ep = grid2view(coord_def(item.x, item.y)); - tile_place_cursor(ep.x-1,ep.y-1,true); + const coord_def gc = coord_def(item.x, item.y); + tiles.place_cursor(CURSOR_TUTORIAL, gc); + tiles.add_text_tag(TAG_TUTORIAL, item.name(DESC_CAP_A), gc); #endif text += "is an item. If you move there and press <w>g</w> or " "<w>,</w> you will pick it up. " @@ -1369,10 +1371,6 @@ void tutorial_first_item(const item_def &item) ", you can read about its properties and its description."; formatted_message_history(text, MSGCH_TUTORIAL, 0, _get_tutorial_cols()); -#ifdef USE_TILE - // Force more() to highlight this item. - more(); -#endif } static void _new_god_conduct() @@ -1460,7 +1458,7 @@ void learned_something_new(tutorial_event_type seen_what, int x, int y) unsigned short colour; int object; #else - const coord_def ep = grid2view(coord_def(x,y)); + const coord_def gc(x, y); #endif Options.tut_just_triggered = true; @@ -1671,8 +1669,8 @@ void learned_something_new(tutorial_event_type seen_what, int x, int y) text << _colourize_glyph(col, ch); text << " "; #else - // Highlight item (if it works). - tile_place_cursor(ep.x-1,ep.y-1,true); + tiles.place_cursor(CURSOR_TUTORIAL, gc); + tiles.add_text_tag(TAG_TUTORIAL, mitm[i].name(DESC_CAP_A), gc); #endif text << "is a corpse."; @@ -1795,7 +1793,8 @@ void learned_something_new(tutorial_event_type seen_what, int x, int y) text << _colourize_glyph(colour, ch) << " "; #else - tile_place_cursor(ep.x-1,ep.y-1,true); + tiles.place_cursor(CURSOR_TUTORIAL, gc); + tiles.add_text_tag(TAG_TUTORIAL, "Stairs", gc); #endif text << "are some downstairs. You can enter the next (deeper) " "level by following them down (<w>></w>). To get back to " @@ -1825,7 +1824,8 @@ void learned_something_new(tutorial_event_type seen_what, int x, int y) text << _colourize_glyph(colour, ch); text << " "; #else - tile_place_cursor(ep.x-1,ep.y-1,true); + tiles.place_cursor(CURSOR_TUTORIAL, gc); + tiles.add_text_tag(TAG_TUTORIAL, "Escape hatch", gc); #endif text << "are some kind of escape hatch. You can use them to " "quickly leave a level with <w><<</w> and <w>></w>, " @@ -1851,7 +1851,8 @@ void learned_something_new(tutorial_event_type seen_what, int x, int y) text << _colourize_glyph(colour, ch) << " "; #else - tile_place_cursor(ep.x-1,ep.y-1,true); + tiles.place_cursor(CURSOR_TUTORIAL, gc); + tiles.add_text_tag(TAG_TUTORIAL, "Branch stairs", gc); #endif text << "is the entrance to a different branch of the dungeon, " "which might have different terrain, level layout and " @@ -1914,7 +1915,12 @@ void learned_something_new(tutorial_event_type seen_what, int x, int y) get_item_symbol( object, &ch, &colour ); text << _colourize_glyph(colour, ch) << " "; #else - tile_place_cursor(ep.x-1,ep.y-1,true); + { + tiles.place_cursor(CURSOR_TUTORIAL, gc); + std::string altar = "An altar to "; + altar += god_name(grid_altar_god(grd(gc))); + tiles.add_text_tag(TAG_TUTORIAL, altar, gc); + } #endif text << "is an altar. You can get information about it by pressing " "<w>p</w> while standing on the square. Before taking up " @@ -1930,8 +1936,9 @@ void learned_something_new(tutorial_event_type seen_what, int x, int y) break; case TUT_SEEN_SHOP: -#ifdef USE_TILES - tile_place_cursor(ep.x-1,ep.y-1,true); +#ifdef USE_TILE + tiles.place_cursor(CURSOR_TUTORIAL, gc); + tiles.add_text_tag(TAG_TUTORIAL, shop_name(gc.x, gc.y), gc); #endif text << "That " #ifndef USE_TILE @@ -1946,12 +1953,13 @@ void learned_something_new(tutorial_event_type seen_what, int x, int y) break; case TUT_SEEN_DOOR: +#ifdef USE_TILE + tiles.place_cursor(CURSOR_TUTORIAL, gc); + tiles.add_text_tag(TAG_TUTORIAL, "Closed door", gc); +#endif if (you.num_turns < 1) DELAY_EVENT; -#ifdef USE_TILES - tile_place_cursor(ep.x-1,ep.y-1,true); -#endif text << "That " #ifndef USE_TILE << _colourize_glyph(WHITE, get_screen_glyph(x,y)) << " " @@ -1967,8 +1975,9 @@ void learned_something_new(tutorial_event_type seen_what, int x, int y) break; case TUT_SEEN_SECRET_DOOR: -#ifdef USE_TILES - tile_place_cursor(ep.x-1,ep.y-1,true); +#ifdef USE_TILE + tiles.place_cursor(CURSOR_TUTORIAL, gc); + tiles.add_text_tag(TAG_TUTORIAL, "Secret door", gc); #endif text << "That " #ifndef USE_TILE @@ -2633,7 +2642,12 @@ void learned_something_new(tutorial_event_type seen_what, int x, int y) case TUT_MONSTER_BRAND: #ifdef USE_TILE - tile_place_cursor(ep.x-1,ep.y-1,true); + tiles.place_cursor(CURSOR_TUTORIAL, gc); + if (mgrd(gc) != NON_MONSTER) + { + tiles.add_text_tag(TAG_TUTORIAL, menv[mgrd(gc)].name(DESC_CAP_A), + gc); + } #endif text << "That monster looks a bit unusual. You might wish to examine " "it a bit more closely by " @@ -2646,7 +2660,12 @@ void learned_something_new(tutorial_event_type seen_what, int x, int y) case TUT_MONSTER_FRIENDLY: #ifdef USE_TILE - tile_place_cursor(ep.x-1,ep.y-1,true); + tiles.place_cursor(CURSOR_TUTORIAL, gc); + if (mgrd(gc) != NON_MONSTER) + { + tiles.add_text_tag(TAG_TUTORIAL, menv[mgrd(gc)].name(DESC_CAP_A), + gc); + } #endif text << "That monster is friendly to you and will attack your " "enemies, though you'll get only half the experience for " diff --git a/crawl-ref/source/view.cc b/crawl-ref/source/view.cc index 67ded0088c..e291205544 100644 --- a/crawl-ref/source/view.cc +++ b/crawl-ref/source/view.cc @@ -73,6 +73,7 @@ #include "tiles.h" #include "state.h" #include "terrain.h" +#include "tilesdl.h" #include "travel.h" #include "tutorial.h" #include "xom.h" @@ -192,14 +193,36 @@ bool is_envmap_detected_mons(int x, int y) return (env.map[x][y].flags & MAP_DETECTED_MONSTER); } +#ifdef USE_TILE +static void _update_minimap(int x, int y) +{ + int object = env.map[x][y].object; + map_feature f = (object >= DNGN_START_OF_MONSTERS) ? MF_MONS_HOSTILE : + Feature[object].minimap; + + if (f == MF_SKIP) + f = Feature[grd[x][y]].minimap; + ASSERT(f < MF_MAX); + + tiles.update_minimap(x, y, f); +} + +void init_minimap() +{ + tiles.clear_minimap(); + for (int y = 0; y < GYM; y++) + for (int x = 0; x < GXM; x++) + _update_minimap(x, y); +} +#endif + void set_envmap_glyph(int x, int y, int object, int col) { map_cell &c = env.map[x][y]; c.object = object; c.colour = col; #ifdef USE_TILE - int glyph = env.map[x][y].glyph(); - GmapUpdate(x,y,glyph); + _update_minimap(x, y); #endif } @@ -207,9 +230,7 @@ void set_envmap_obj( int x, int y, int obj ) { env.map[x][y].object = obj; #ifdef USE_TILE - int glyph = env.map[x][y].glyph(); - if (glyph) - GmapUpdate(x,y,glyph); + _update_minimap(x, y); #endif } @@ -3200,8 +3221,7 @@ void show_map( coord_def &spec_place, bool travel_mode ) // on in this function. --Enne unsigned int cx = start_x + curs_x - 1; unsigned int cy = start_y + curs_y - 1; - TileDrawMap(cx, cy); - GmapDisplay(cx, cy); + tiles.load_dungeon(cx, cy); #else _draw_level_map(start_x, start_y, travel_mode); #endif @@ -3669,7 +3689,6 @@ bool magic_mapping(int map_radius, int proportion, bool suppress_msg, } #ifdef USE_TILE - GmapInit(true); // Re-draw tile backup. tile_clear_buf(); #endif @@ -3902,6 +3921,7 @@ void init_feature_table( void ) Feature[i].seen_colour = BLACK; // -> no special seen map handling Feature[i].seen_em_colour = BLACK; Feature[i].em_colour = BLACK; + Feature[i].minimap = MF_UNSEEN; switch (i) { @@ -3914,12 +3934,14 @@ void init_feature_table( void ) Feature[i].dchar = DCHAR_WALL; Feature[i].colour = EC_ROCK; Feature[i].magic_symbol = Options.char_table[ DCHAR_WALL_MAGIC ]; + Feature[i].minimap = MF_WALL; break; case DNGN_STONE_WALL: Feature[i].dchar = DCHAR_WALL; Feature[i].colour = EC_STONE; Feature[i].magic_symbol = Options.char_table[ DCHAR_WALL_MAGIC ]; + Feature[i].minimap = MF_WALL; break; case DNGN_CLEAR_ROCK_WALL: @@ -3928,23 +3950,27 @@ void init_feature_table( void ) Feature[i].dchar = DCHAR_WALL; Feature[i].magic_symbol = Options.char_table[ DCHAR_WALL_MAGIC ]; Feature[i].colour = LIGHTCYAN; + Feature[i].minimap = MF_WALL; break; case DNGN_OPEN_DOOR: Feature[i].dchar = DCHAR_DOOR_OPEN; Feature[i].colour = LIGHTGREY; + Feature[i].minimap = MF_DOOR; break; case DNGN_CLOSED_DOOR: Feature[i].dchar = DCHAR_DOOR_CLOSED; Feature[i].colour = LIGHTGREY; + Feature[i].minimap = MF_DOOR; break; case DNGN_METAL_WALL: Feature[i].dchar = DCHAR_WALL; Feature[i].colour = CYAN; Feature[i].magic_symbol = Options.char_table[ DCHAR_WALL_MAGIC ]; + Feature[i].minimap = MF_WALL; break; case DNGN_SECRET_DOOR: @@ -3952,55 +3978,65 @@ void init_feature_table( void ) Feature[i].dchar = DCHAR_WALL; Feature[i].colour = EC_ROCK; Feature[i].magic_symbol = Options.char_table[ DCHAR_WALL_MAGIC ]; + Feature[i].minimap = MF_WALL; break; case DNGN_GREEN_CRYSTAL_WALL: Feature[i].dchar = DCHAR_WALL; Feature[i].colour = GREEN; Feature[i].magic_symbol = Options.char_table[ DCHAR_WALL_MAGIC ]; + Feature[i].minimap = MF_WALL; break; case DNGN_ORCISH_IDOL: Feature[i].dchar = DCHAR_STATUE; Feature[i].colour = BROWN; // same as clay golem, I hope that's okay + Feature[i].minimap = MF_WALL; break; case DNGN_WAX_WALL: Feature[i].dchar = DCHAR_WALL; Feature[i].colour = YELLOW; Feature[i].magic_symbol = Options.char_table[ DCHAR_WALL_MAGIC ]; - break; // wax wall + Feature[i].minimap = MF_WALL; + break; case DNGN_GRANITE_STATUE: Feature[i].dchar = DCHAR_STATUE; Feature[i].colour = DARKGREY; + Feature[i].minimap = MF_WALL; break; case DNGN_LAVA: Feature[i].dchar = DCHAR_WAVY; Feature[i].colour = RED; + Feature[i].minimap = MF_LAVA; break; case DNGN_DEEP_WATER: Feature[i].dchar = DCHAR_WAVY; Feature[i].colour = BLUE; + Feature[i].minimap = MF_WATER; break; case DNGN_SHALLOW_WATER: Feature[i].dchar = DCHAR_WAVY; Feature[i].colour = CYAN; + Feature[i].minimap = MF_WATER; break; case DNGN_FLOOR: Feature[i].dchar = DCHAR_FLOOR; Feature[i].colour = EC_FLOOR; Feature[i].magic_symbol = Options.char_table[ DCHAR_FLOOR_MAGIC ]; + Feature[i].minimap = MF_FLOOR; break; case DNGN_FLOOR_SPECIAL: Feature[i].dchar = DCHAR_FLOOR; Feature[i].colour = YELLOW; Feature[i].magic_symbol = Options.char_table[ DCHAR_FLOOR_MAGIC ]; + Feature[i].minimap = MF_FLOOR; break; case DNGN_EXIT_HELL: @@ -4008,6 +4044,7 @@ void init_feature_table( void ) Feature[i].colour = LIGHTRED; Feature[i].map_colour = LIGHTGREY; Feature[i].seen_colour = LIGHTRED; + Feature[i].minimap = MF_STAIR_UP; break; case DNGN_ENTER_HELL: @@ -4016,30 +4053,35 @@ void init_feature_table( void ) Feature[i].flags |= FFT_NOTABLE; Feature[i].map_colour = LIGHTGREY; Feature[i].seen_colour = RED; + Feature[i].minimap = MF_STAIR_BRANCH; break; case DNGN_TRAP_MECHANICAL: Feature[i].colour = LIGHTCYAN; Feature[i].dchar = DCHAR_TRAP; Feature[i].map_colour = LIGHTCYAN; + Feature[i].minimap = MF_TRAP; break; case DNGN_TRAP_MAGICAL: Feature[i].colour = MAGENTA; Feature[i].dchar = DCHAR_TRAP; Feature[i].map_colour = MAGENTA; + Feature[i].minimap = MF_TRAP; break; case DNGN_TRAP_NATURAL: Feature[i].colour = BROWN; Feature[i].dchar = DCHAR_TRAP; Feature[i].map_colour = BROWN; + Feature[i].minimap = MF_TRAP; break; case DNGN_UNDISCOVERED_TRAP: Feature[i].dchar = DCHAR_FLOOR; Feature[i].colour = EC_FLOOR; Feature[i].magic_symbol = Options.char_table[ DCHAR_FLOOR_MAGIC ]; + Feature[i].minimap = MF_FLOOR; break; case DNGN_ENTER_SHOP: @@ -4048,6 +4090,7 @@ void init_feature_table( void ) Feature[i].flags |= FFT_NOTABLE; Feature[i].map_colour = LIGHTGREY; Feature[i].seen_colour = YELLOW; + Feature[i].minimap = MF_FEATURE; break; case DNGN_ENTER_LABYRINTH: @@ -4056,6 +4099,7 @@ void init_feature_table( void ) Feature[i].flags |= FFT_NOTABLE; Feature[i].map_colour = LIGHTGREY; Feature[i].seen_colour = CYAN; + Feature[i].minimap = MF_STAIR_BRANCH; break; case DNGN_ENTER_PORTAL_VAULT: @@ -4067,12 +4111,14 @@ void init_feature_table( void ) Feature[i].colour = EC_SHIMMER_BLUE; Feature[i].map_colour = LIGHTGREY; Feature[i].seen_colour = EC_SHIMMER_BLUE; + Feature[i].minimap = MF_STAIR_BRANCH; break; case DNGN_ESCAPE_HATCH_DOWN: Feature[i].dchar = DCHAR_STAIRS_DOWN; Feature[i].colour = BROWN; Feature[i].map_colour = BROWN; + Feature[i].minimap = MF_STAIR_DOWN; break; case DNGN_STONE_STAIRS_DOWN_I: @@ -4083,12 +4129,14 @@ void init_feature_table( void ) Feature[i].em_colour = WHITE; Feature[i].map_colour = RED; Feature[i].seen_em_colour = WHITE; + Feature[i].minimap = MF_STAIR_DOWN; break; case DNGN_ESCAPE_HATCH_UP: Feature[i].dchar = DCHAR_STAIRS_UP; Feature[i].colour = BROWN; Feature[i].map_colour = BROWN; + Feature[i].minimap = MF_STAIR_UP; break; case DNGN_STONE_STAIRS_UP_I: @@ -4099,6 +4147,7 @@ void init_feature_table( void ) Feature[i].map_colour = GREEN; Feature[i].em_colour = WHITE; Feature[i].seen_em_colour = WHITE; + Feature[i].minimap = MF_STAIR_UP; break; case DNGN_ENTER_DIS: @@ -4107,6 +4156,7 @@ void init_feature_table( void ) Feature[i].flags |= FFT_NOTABLE; Feature[i].map_colour = LIGHTGREY; Feature[i].seen_colour = CYAN; + Feature[i].minimap = MF_STAIR_BRANCH; break; case DNGN_ENTER_GEHENNA: @@ -4115,6 +4165,7 @@ void init_feature_table( void ) Feature[i].flags |= FFT_NOTABLE; Feature[i].map_colour = LIGHTGREY; Feature[i].seen_colour = RED; + Feature[i].minimap = MF_STAIR_BRANCH; break; case DNGN_ENTER_COCYTUS: @@ -4123,6 +4174,7 @@ void init_feature_table( void ) Feature[i].flags |= FFT_NOTABLE; Feature[i].map_colour = LIGHTGREY; Feature[i].seen_colour = LIGHTCYAN; + Feature[i].minimap = MF_STAIR_BRANCH; break; case DNGN_ENTER_TARTARUS: @@ -4131,6 +4183,7 @@ void init_feature_table( void ) Feature[i].flags |= FFT_NOTABLE; Feature[i].map_colour = LIGHTGREY; Feature[i].seen_colour = DARKGREY; + Feature[i].minimap = MF_STAIR_BRANCH; break; case DNGN_ENTER_ABYSS: @@ -4139,18 +4192,21 @@ void init_feature_table( void ) Feature[i].flags |= FFT_NOTABLE; Feature[i].map_colour = LIGHTGREY; Feature[i].seen_colour = EC_RANDOM; + Feature[i].minimap = MF_STAIR_BRANCH; break; case DNGN_EXIT_ABYSS: Feature[i].colour = EC_RANDOM; Feature[i].dchar = DCHAR_ARCH; Feature[i].map_colour = EC_RANDOM; + Feature[i].minimap = MF_STAIR_BRANCH; break; case DNGN_STONE_ARCH: Feature[i].colour = LIGHTGREY; Feature[i].dchar = DCHAR_ARCH; Feature[i].map_colour = LIGHTGREY; + Feature[i].minimap = MF_FLOOR; break; case DNGN_ENTER_PANDEMONIUM: @@ -4159,6 +4215,7 @@ void init_feature_table( void ) Feature[i].flags |= FFT_NOTABLE; Feature[i].map_colour = LIGHTGREY; Feature[i].seen_colour = LIGHTBLUE; + Feature[i].minimap = MF_STAIR_BRANCH; break; case DNGN_EXIT_PANDEMONIUM: @@ -4167,6 +4224,7 @@ void init_feature_table( void ) Feature[i].dchar = DCHAR_ARCH; Feature[i].map_colour = LIGHTGREY; Feature[i].seen_colour = LIGHTBLUE; + Feature[i].minimap = MF_STAIR_BRANCH; break; case DNGN_TRANSIT_PANDEMONIUM: @@ -4174,6 +4232,7 @@ void init_feature_table( void ) Feature[i].dchar = DCHAR_ARCH; Feature[i].map_colour = LIGHTGREY; Feature[i].seen_colour = LIGHTGREEN; + Feature[i].minimap = MF_STAIR_BRANCH; break; case DNGN_ENTER_ORCISH_MINES: @@ -4197,6 +4256,7 @@ void init_feature_table( void ) Feature[i].flags |= FFT_NOTABLE; Feature[i].map_colour = RED; Feature[i].seen_colour = YELLOW; + Feature[i].minimap = MF_STAIR_BRANCH; break; case DNGN_ENTER_ZOT: @@ -4205,6 +4265,7 @@ void init_feature_table( void ) Feature[i].flags |= FFT_NOTABLE; Feature[i].map_colour = LIGHTGREY; Feature[i].seen_colour = MAGENTA; + Feature[i].minimap = MF_STAIR_BRANCH; break; case DNGN_RETURN_FROM_ORCISH_MINES: @@ -4227,6 +4288,7 @@ void init_feature_table( void ) Feature[i].dchar = DCHAR_STAIRS_UP; Feature[i].map_colour = GREEN; Feature[i].seen_colour = YELLOW; + Feature[i].minimap = MF_STAIR_BRANCH; break; case DNGN_RETURN_FROM_ZOT: @@ -4234,6 +4296,7 @@ void init_feature_table( void ) Feature[i].dchar = DCHAR_ARCH; Feature[i].map_colour = LIGHTGREY; Feature[i].seen_colour = MAGENTA; + Feature[i].minimap = MF_STAIR_BRANCH; break; case DNGN_ALTAR_ZIN: @@ -4242,6 +4305,7 @@ void init_feature_table( void ) Feature[i].flags |= FFT_NOTABLE; Feature[i].map_colour = DARKGREY; Feature[i].seen_colour = WHITE; + Feature[i].minimap = MF_FEATURE; break; case DNGN_ALTAR_SHINING_ONE: @@ -4250,6 +4314,7 @@ void init_feature_table( void ) Feature[i].flags |= FFT_NOTABLE; Feature[i].map_colour = DARKGREY; Feature[i].seen_colour = YELLOW; + Feature[i].minimap = MF_FEATURE; break; case DNGN_ALTAR_KIKUBAAQUDGHA: @@ -4258,6 +4323,7 @@ void init_feature_table( void ) Feature[i].flags |= FFT_NOTABLE; Feature[i].map_colour = DARKGREY; Feature[i].seen_colour = DARKGREY; + Feature[i].minimap = MF_FEATURE; break; case DNGN_ALTAR_YREDELEMNUL: @@ -4266,6 +4332,7 @@ void init_feature_table( void ) Feature[i].flags |= FFT_NOTABLE; Feature[i].map_colour = DARKGREY; Feature[i].seen_colour = EC_UNHOLY; + Feature[i].minimap = MF_FEATURE; break; case DNGN_ALTAR_XOM: @@ -4274,6 +4341,7 @@ void init_feature_table( void ) Feature[i].flags |= FFT_NOTABLE; Feature[i].map_colour = DARKGREY; Feature[i].seen_colour = EC_RANDOM; + Feature[i].minimap = MF_FEATURE; break; case DNGN_ALTAR_VEHUMET: @@ -4282,6 +4350,7 @@ void init_feature_table( void ) Feature[i].flags |= FFT_NOTABLE; Feature[i].map_colour = DARKGREY; Feature[i].seen_colour = EC_VEHUMET; + Feature[i].minimap = MF_FEATURE; break; case DNGN_ALTAR_OKAWARU: @@ -4290,6 +4359,7 @@ void init_feature_table( void ) Feature[i].flags |= FFT_NOTABLE; Feature[i].map_colour = DARKGREY; Feature[i].seen_colour = CYAN; + Feature[i].minimap = MF_FEATURE; break; case DNGN_ALTAR_MAKHLEB: @@ -4298,6 +4368,7 @@ void init_feature_table( void ) Feature[i].flags |= FFT_NOTABLE; Feature[i].map_colour = DARKGREY; Feature[i].seen_colour = EC_FIRE; + Feature[i].minimap = MF_FEATURE; break; case DNGN_ALTAR_SIF_MUNA: @@ -4306,6 +4377,7 @@ void init_feature_table( void ) Feature[i].flags |= FFT_NOTABLE; Feature[i].map_colour = DARKGREY; Feature[i].seen_colour = BLUE; + Feature[i].minimap = MF_FEATURE; break; case DNGN_ALTAR_TROG: @@ -4314,6 +4386,7 @@ void init_feature_table( void ) Feature[i].flags |= FFT_NOTABLE; Feature[i].map_colour = DARKGREY; Feature[i].seen_colour = RED; + Feature[i].minimap = MF_FEATURE; break; case DNGN_ALTAR_NEMELEX_XOBEH: @@ -4322,6 +4395,7 @@ void init_feature_table( void ) Feature[i].flags |= FFT_NOTABLE; Feature[i].map_colour = DARKGREY; Feature[i].seen_colour = LIGHTMAGENTA; + Feature[i].minimap = MF_FEATURE; break; case DNGN_ALTAR_ELYVILON: @@ -4330,6 +4404,7 @@ void init_feature_table( void ) Feature[i].flags |= FFT_NOTABLE; Feature[i].map_colour = DARKGREY; Feature[i].seen_colour = LIGHTGREY; + Feature[i].minimap = MF_FEATURE; break; case DNGN_ALTAR_LUGONU: @@ -4338,6 +4413,7 @@ void init_feature_table( void ) Feature[i].flags |= FFT_NOTABLE; Feature[i].map_colour = DARKGREY; Feature[i].seen_colour = GREEN; + Feature[i].minimap = MF_FEATURE; break; case DNGN_ALTAR_BEOGH: @@ -4346,21 +4422,25 @@ void init_feature_table( void ) Feature[i].flags |= FFT_NOTABLE; Feature[i].map_colour = DARKGREY; Feature[i].seen_colour = EC_BEOGH; + Feature[i].minimap = MF_FEATURE; break; case DNGN_FOUNTAIN_BLUE: Feature[i].colour = BLUE; Feature[i].dchar = DCHAR_FOUNTAIN; + Feature[i].minimap = MF_FEATURE; break; case DNGN_FOUNTAIN_SPARKLING: Feature[i].colour = LIGHTBLUE; Feature[i].dchar = DCHAR_FOUNTAIN; + Feature[i].minimap = MF_FEATURE; break; case DNGN_FOUNTAIN_BLOOD: Feature[i].colour = RED; Feature[i].dchar = DCHAR_FOUNTAIN; + Feature[i].minimap = MF_FEATURE; break; case DNGN_DRY_FOUNTAIN_BLUE: @@ -4369,78 +4449,97 @@ void init_feature_table( void ) case DNGN_PERMADRY_FOUNTAIN: Feature[i].colour = LIGHTGREY; Feature[i].dchar = DCHAR_FOUNTAIN; + Feature[i].minimap = MF_FEATURE; break; case DNGN_INVIS_EXPOSED: Feature[i].dchar = DCHAR_INVIS_EXPOSED; + Feature[i].minimap = MF_MONS_HOSTILE; break; case DNGN_ITEM_DETECTED: Feature[i].dchar = DCHAR_ITEM_DETECTED; + Feature[i].minimap = MF_ITEM; break; case DNGN_ITEM_ORB: Feature[i].dchar = DCHAR_ITEM_ORB; + Feature[i].minimap = MF_ITEM; break; case DNGN_ITEM_WEAPON: Feature[i].dchar = DCHAR_ITEM_WEAPON; + Feature[i].minimap = MF_ITEM; break; case DNGN_ITEM_ARMOUR: Feature[i].dchar = DCHAR_ITEM_ARMOUR; + Feature[i].minimap = MF_ITEM; break; case DNGN_ITEM_WAND: Feature[i].dchar = DCHAR_ITEM_WAND; + Feature[i].minimap = MF_ITEM; break; case DNGN_ITEM_FOOD: Feature[i].dchar = DCHAR_ITEM_FOOD; + Feature[i].minimap = MF_ITEM; break; case DNGN_ITEM_SCROLL: Feature[i].dchar = DCHAR_ITEM_SCROLL; + Feature[i].minimap = MF_ITEM; break; case DNGN_ITEM_RING: Feature[i].dchar = DCHAR_ITEM_RING; + Feature[i].minimap = MF_ITEM; break; case DNGN_ITEM_POTION: Feature[i].dchar = DCHAR_ITEM_POTION; + Feature[i].minimap = MF_ITEM; break; case DNGN_ITEM_MISSILE: Feature[i].dchar = DCHAR_ITEM_MISSILE; + Feature[i].minimap = MF_ITEM; break; case DNGN_ITEM_BOOK: Feature[i].dchar = DCHAR_ITEM_BOOK; + Feature[i].minimap = MF_ITEM; break; case DNGN_ITEM_STAVE: Feature[i].dchar = DCHAR_ITEM_STAVE; + Feature[i].minimap = MF_ITEM; break; case DNGN_ITEM_MISCELLANY: Feature[i].dchar = DCHAR_ITEM_MISCELLANY; + Feature[i].minimap = MF_ITEM; break; case DNGN_ITEM_CORPSE: Feature[i].dchar = DCHAR_ITEM_CORPSE; + Feature[i].minimap = MF_ITEM; break; case DNGN_ITEM_GOLD: Feature[i].dchar = DCHAR_ITEM_GOLD; + Feature[i].minimap = MF_ITEM; break; case DNGN_ITEM_AMULET: Feature[i].dchar = DCHAR_ITEM_AMULET; + Feature[i].minimap = MF_ITEM; break; case DNGN_CLOUD: Feature[i].dchar = DCHAR_CLOUD; + Feature[i].minimap = MF_SKIP; break; } @@ -4735,6 +4834,7 @@ void viewwindow(bool draw_it, bool do_updates) #ifdef USE_TILE std::vector<unsigned int> tileb( crawl_view.viewsz.y * crawl_view.viewsz.x * 2); + tiles.clear_text_tags(TAG_NAMED_MONSTER); #endif screen_buffer_t *buffy(crawl_view.vbuf); @@ -4748,7 +4848,7 @@ void viewwindow(bool draw_it, bool do_updates) #ifdef USE_TILE tile_draw_floor(); - TileMcacheUnlock(); + tile_mcache_unlock(); #endif env.show_col.init(LIGHTGREY); @@ -5033,8 +5133,8 @@ void viewwindow(bool draw_it, bool do_updates) if (draw) { #ifdef USE_TILE - tile_draw_dungeon(&tileb[0]); - GmapDisplay(you.x_pos, you.y_pos); + tiles.load_dungeon(&tileb[0], you.pos().x, you.pos().y); + tiles.update_inventory(); #else you.last_view_update = you.num_turns; puttext(crawl_view.viewp.x, crawl_view.viewp.y, diff --git a/crawl-ref/source/view.h b/crawl-ref/source/view.h index e154b6f854..08b8c7b5f9 100644 --- a/crawl-ref/source/view.h +++ b/crawl-ref/source/view.h @@ -227,6 +227,10 @@ void view_update_at(const coord_def &pos); void viewwindow(bool draw_it, bool do_updates); void fire_monster_alerts(); +#ifdef USE_TILE +void init_minimap(); +#endif + struct ray_def; bool find_ray( int sourcex, int sourcey, int targetx, int targety, bool allow_fallback, ray_def& ray, int cycle_dir = 0, |