summaryrefslogtreecommitdiffstats
path: root/crawl-ref/source/libgui.cc
diff options
context:
space:
mode:
authorennewalker <ennewalker@c06c8d41-db1a-0410-9941-cceddc491573>2008-01-05 01:33:53 +0000
committerennewalker <ennewalker@c06c8d41-db1a-0410-9941-cceddc491573>2008-01-05 01:33:53 +0000
commit62f7040f14b39e67042be98f951575fbc819e84e (patch)
treed4fa0598a1bee1d34fff81e2c150de08c2256753 /crawl-ref/source/libgui.cc
parent19155f1f85058ef9d65d11e60c63cc69c36d4e8a (diff)
downloadcrawl-ref-62f7040f14b39e67042be98f951575fbc819e84e.tar.gz
crawl-ref-62f7040f14b39e67042be98f951575fbc819e84e.zip
Tiles!
git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@3194 c06c8d41-db1a-0410-9941-cceddc491573
Diffstat (limited to 'crawl-ref/source/libgui.cc')
-rw-r--r--crawl-ref/source/libgui.cc2172
1 files changed, 2172 insertions, 0 deletions
diff --git a/crawl-ref/source/libgui.cc b/crawl-ref/source/libgui.cc
new file mode 100644
index 0000000000..08e00b2a5d
--- /dev/null
+++ b/crawl-ref/source/libgui.cc
@@ -0,0 +1,2172 @@
+/*
+ * File: libx11.cc
+ * Summary: Functions for x11
+ * Written by: M.Itakura
+ *
+ * Change History (most recent first):
+ *
+ * <1> 03/08/11 Ita copied from liblinux.cc and modified
+ *
+ */
+
+#define deblog(x) {FILE *ddfp=fopen("log.txt","a");fprintf(ddfp,x);fprintf(ddfp,"\n");fclose(ddfp);}
+#define deblog2(x,y) {FILE *ddfp=fopen("log.txt","a");fprintf(ddfp,"%s %d\n",x,y);fclose(ddfp);}
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "AppHdr.h"
+#include "cio.h"
+#include "defines.h"
+#include "describe.h"
+#include "direct.h"
+#include "files.h"
+#include "itemname.h"
+#include "items.h"
+#include "externs.h"
+#include "guic.h"
+#include "message.h"
+#include "player.h"
+#include "stash.h"
+#include "state.h"
+#include "stuff.h"
+#include "terrain.h"
+#include "tiles.h"
+#include "travel.h"
+#include "version.h"
+#include "view.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, TileIsoImg;
+img_type PlayerImg;
+img_type WallImg;
+
+extern bool force_redraw_tile;
+extern bool force_redraw_inv;
+
+// 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 = 3;
+static int msg_x = 80, msg_y = 8;
+static int dngn_x = 17, 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] = "8x16";
+#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_TEXT 0
+#define PREF_MODE_TILE 1
+#define PREF_MODE_ISO 2
+#define PREF_MODE_NUM 3
+static const char *pref_mode_name[PREF_MODE_NUM]
+ ={ "Text", "Tile", "Iso"};
+
+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;
+
+#define char_is_wall(ch) (ch == 127 || (ch >= 137 && ch <= 140) \
+ || ch == 177 || ch == 176 || ch == '#')
+
+#define char_is_item(ch) ( (ch == 33)||(ch == 34)||(ch == 36)||(ch == 37) \
+ ||(ch == 40) ||(ch == 41)||(ch == 43)||(ch == 47)||(ch == 48) \
+ ||(ch == 58) ||(ch == 61)||(ch == 63)||(ch == 88)||(ch == 91) \
+ ||(ch == 92) ||(ch == 93)||(ch == 125) || (ch == '~'))
+
+#define char_is_monster(ch) ( (ch>='@' && ch<='Z') || (ch>='a' && ch<='z') \
+ || ch=='&' || (ch>='1' && ch<='5') || ch == ';')
+
+/***********************************************************/
+//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 name to save space
+#define PX_0 MAP_BLACK //unseen
+#define PX_F MAP_LTGREY //floor
+#define PX_W MAP_DKGREY //walls
+#define PX_D MAP_BROWN //doors
+#define PX_WB MAP_LTBLUE //blue wall
+#define PX_I MAP_GREEN //items
+#define PX_M MAP_RED //monsters
+#define PX_US MAP_BLUE //upstair
+#define PX_DS MAP_MAGENTA //downstair
+#define PX_SS MAP_CYAN //special stair
+#define PX_WT MAP_MDGREY //water
+#define PX_LV MAP_MDGREY //lava
+#define PX_T MAP_YELLOW //trap
+#define PX_MS MAP_CYAN //misc
+
+ 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;
+
+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;
+
+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)
+{
+ 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);
+
+ if (feature == DNGN_SECRET_DOOR)
+ feature = (unsigned int)grid_secret_door_appearance(x, y);
+
+ int t = tileidx_feature(feature);
+ if (t == TILE_ERROR || what == ' ')
+ t = tileidx_unseen(what, gc);
+
+ t |= tile_unseen_flag(gc);
+
+ return t;
+}
+
+void GmapUpdate(int x, int y, int what, bool upd_tile)
+{
+ int c;
+ 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_col[grid_symbol & 0xff];
+ break;
+ default:
+ c = gmap_col[what & 0xff];
+ break;
+ }
+
+ 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_fg[x][y]= t;
+ if (env.tile_bk_bg[x][y] == 0)
+ env.tile_bk_bg[x][y] = tileidx_feature(DNGN_UNSEEN);
+ }
+ 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)
+{
+ 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 x,y;
+ int count=0;
+ int ox, oy;
+
+ for (x = 0; x < GXM*GYM; x++)
+ {
+ buf2[x] = 0;
+ }
+
+ ox = ( gmap_min_x + (GXM -1 - gmap_max_x) ) / 2;
+ oy = ( gmap_min_y + (GYM -1 - gmap_max_y) ) / 2;
+ count = ox + oy * GXM;
+ gmap_ox = ox - gmap_min_x;
+ gmap_oy = oy - gmap_min_y;
+
+ for (y = gmap_min_y; y <= gmap_max_y; y++)
+ {
+ for (x = gmap_min_x; x <= gmap_max_x; x++)
+ {
+ if ( (count>=0)&&(count<GXM*GYM) )
+ buf2[count] = gmap_data[x][y];
+ count += 1;
+ }
+ count += GXM - (gmap_max_x - gmap_min_x + 1);
+ }
+
+ if ( (you.level_type != LEVEL_LABYRINTH)&&(you.level_type != LEVEL_ABYSS) )
+ {
+ ox += linex - gmap_min_x;
+ oy += liney - gmap_min_y;
+ buf2[ ox + oy * GXM] = MAP_WHITE;
+ }
+
+ region_map->flag = true;
+ region_map->draw_data(buf2);
+}
+
+/* initialize routines */
+static void do_layout()
+{
+#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);
+ 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.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*2,
+ MAP_YMAX-map_margin*2,
+ map_margin, map_margin,
+ false);
+ region_map->id = REGION_MAP;
+ region_map->dx = map_px;
+ region_map->dy = map_px;
+
+ TileInit();
+
+#ifdef WIN32TILES
+ TileInitWin();
+#endif
+
+ if (Options.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(40, 17, 0, 0);
+#else
+ region_stat = new TextRegionClass(40, 16, 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)
+ region_tip = new TextRegionClass(region_stat->mx, 1, 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
+
+ do_layout();
+
+ win_main->create((char*)(CRAWL " " VERSION));
+
+ region_map->init_backbuf();
+
+ region_tile -> init_backbuf();
+ region_item2->init_backbuf();
+ if (region_item) region_item->init_backbuf();
+}
+
+void libgui_shutdown()
+{
+
+ if(TileImg) ImgDestroy(TileImg);
+ if(PlayerImg) ImgDestroy(PlayerImg);
+ if(WallImg) ImgDestroy(WallImg);
+ if(TileIsoImg) ImgDestroy(TileIsoImg);
+
+ // 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, true, 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;
+ }
+ 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;
+ }// tag match
+ } //mode
+ }//i
+ }// while
+ }
+}
+
+static void libgui_save_prefs()
+{
+ int i, mode;
+ FILE *fp;
+
+ 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);
+ }
+
+ 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, "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]);
+ 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;
+ gotoxy(x, y, region);
+ textcolor(col);
+ for (i=0; i < len; i++)
+ {
+ switch((i+ ofs) % 10)
+ {
+ case 0: cprintf("%c",'+');break;
+ case 4: cprintf("%c",'0' + (1+(i+ofs)/10)%10);break;
+ case 5: cprintf("%c",'0');break;
+ default: cprintf("%c",'-');
+ }
+ }
+}
+
+static void draw_vgauge(int x, int y, int ofs, int region, int len, int col)
+{
+ int i;
+ textcolor(col);
+ for (i=0; i < len; i++)
+ {
+ gotoxy(x, y+i, region);
+ cprintf("%02d", ofs+i);
+ }
+}
+
+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(1)
+ {
+ 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);
+ gotoxy (4, 4, GOTO_MSG);
+ cprintf("j, k, up, down : Select pref");
+ gotoxy (4, 5, GOTO_MSG);
+ cprintf("h, l, left, right : Decrease/Increase");
+ gotoxy (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];
+ gotoxy(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
+ gotoxy(4, MAX_EDIT_PREFS+3, GOTO_STAT);
+ cprintf("FONT: %s %d",font_name, font_size);
+ if (UseDosChar)
+ {
+ gotoxy(4, MAX_EDIT_PREFS+4, GOTO_STAT);
+ cprintf("DOSFONT: %s %d", dos_font_name, dos_font_size);
+ }
+#else
+ gotoxy(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=2;
+ if (inc==-1) inc=-2;
+ }
+ 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;
+ }// changed
+
+ 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();
+ force_redraw_tile = true;
+ TileResizeScreen(dngn_x, dngn_y);
+ }
+ if (region_item)
+ region_item->resize_backbuf();
+ if (region_item2)
+ region_item2->resize_backbuf();
+ force_redraw_inv = true;
+ tile_draw_inv(-1, REGION_INV1);
+
+ region_map->force_redraw = true;
+ viewwindow(true, true);
+ region_tile->redraw();
+ region_item->redraw();
+ }// need resize
+ }//while
+ 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;
+
+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 gc = view2grid(coord_def(x+1, y+1));
+ if (gc.x < 0 || gc.y < 0 || gc.x >= GXM || gc.y >= GYM)
+ {
+ // off the dungeon...
+ tile_cursor_x = -1;
+ return;
+ }
+ else if (!map_bounds(gc))
+ {
+ new_flag = TILE_FLAG_CURSOR2;
+ }
+ else
+ {
+ unsigned char ch = env.map[gc.x][gc.y].glyph() & 0xff;
+ if (ch==0 || ch==' ' || char_is_wall(ch))
+ 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 = x - gmap_ox + region_map->x_margin + 1;
+ y = y - gmap_oy + region_map->y_margin + 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;
+}
+
+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);
+
+ 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)
+ {
+ if (itemlist_key[cx])
+ {
+ desc = itemlist_key[cx];
+ desc += " - ";
+ }
+ desc += mitm[ix].name(DESC_NOCAP_A);
+ if (display_actions)
+ desc += EOL "[L-Click] *Pickup(g)";
+ }
+ else
+ {
+ desc = you.inv[ix].name(DESC_INVENTORY_EQUIP);
+
+ if (display_actions)
+ {
+ desc += EOL "[L-Click] ";
+ int type = you.inv[ix].base_type;
+
+ if (itemlist_iflag[cx] & TILEI_FLAG_EQUIP)
+ type += 18;
+
+ switch (type)
+ {
+ case OBJ_JEWELLERY + 18:
+ desc += "*(R)emove";
+ break;
+ case OBJ_WEAPONS:
+ case OBJ_STAVES:
+ desc += "*(w)ield";
+ break;
+ case OBJ_MISSILES:
+ desc += "*(t)hrow";
+ break;
+ case OBJ_WANDS:
+ desc += "*(z)ap";
+ break;
+ case OBJ_SCROLLS:
+ case OBJ_BOOKS:
+ desc += "*(r)ead";
+ break;
+ case OBJ_JEWELLERY:
+ desc += "*(P)ut on";
+ break;
+ case OBJ_POTIONS:
+ desc += "*(q)uaff";
+ break;
+ default:
+ desc += "*Use it";
+ }
+
+ desc += EOL "[R-Click] Info";
+ desc += EOL "[Shift-L-Click] *(d)rop";
+ }
+ }
+ 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)
+ {
+ oldcx = cx;
+ oldcy = cy;
+ oldmode = mode;
+
+ if(mode==REGION_DNGN)
+ tile_place_cursor(cx, cy, true);
+
+ if(mode==REGION_TDNGN)
+ {
+ gotoxy(cx+2, cy+1, GOTO_DNGN);
+ }
+
+ int gx = view2gridX(cx) + 1;
+ int gy = view2gridY(cy) + 1;
+ tip_grid(gx, gy);
+
+ 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 0
+ if (mode == REGION_STAT && mouse_mode == MOUSE_MODE_COMMAND)
+ {
+ oldcx = cx;
+ oldcy = cy;
+ oldmode = mode;
+
+ int i = 0;
+ while( Tips[i].tiptext != NULL)
+ {
+ if (cx >= Tips[i].sx && cx <= Tips[i].ex &&
+ cy >= Tips[i].sy && cy <= Tips[i].ey)
+ break;
+ i++;
+ }
+ if (Tips[i].tiptext == NULL) i = -1;
+
+ if (i == old_tip_idx) return 0;
+
+ if (old_tip_idx != -1)
+ hilite_tip_text(old_tip_idx, false);
+
+ old_tip_idx = i;
+ if (i != -1)
+ {
+ hilite_tip_text(i, true);
+ update_tip_text((char *)Tips[i].tiptext);
+ }
+ else
+ update_tip_text("");
+ return 0;
+ }
+#endif
+ 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;
+ if (button == 2) trig = CK_MOUSE_B2;
+ if (button == 3) trig = CK_MOUSE_B3;
+ if (button == 4) trig = CK_MOUSE_B4;
+ if (button == 5) trig = CK_MOUSE_B5;
+ if (shift) trig |= 512;
+ if (ctrl) trig |= 1024;
+
+ switch(mouse_mode)
+ {
+ case MOUSE_MODE_NORMAL:
+ return trig;
+ break;
+ case MOUSE_MODE_MORE:
+ return '\r';
+ break;
+ }
+
+ 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;
+ }
+
+ // item clicked
+ if (mode == REGION_INV1 || mode == REGION_INV2)
+ {
+ int ix = TileInvIdx(cx);
+
+ if (ix != -1)
+ {
+ if (button == 2)
+ {
+ // describe item
+ if (itemlist_iflag[cx] & TILEI_FLAG_FLOOR)
+ 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 pick up one item
+ if (button != 1) return 0;
+ gui_set_mouse_inv(ix, INV_PICKUP);
+ return CK_MOUSE_B1ITEM;
+ }
+ // use item
+ if (shift)
+ gui_set_mouse_inv(ix, INV_DROP);
+ 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 0
+ if (mode == REGION_STAT && mouse_mode == MOUSE_MODE_COMMAND)
+ {
+ int i = 0;
+ while( Tips[i].tiptext != NULL)
+ {
+ if (cx >= Tips[i].sx && cx <= Tips[i].ex &&
+ cy >= Tips[i].sy && cy <= Tips[i].ey)
+ break;
+ i++;
+ }
+
+ if (Tips[i].tipfilename)
+ {
+ char fname[256];
+ snprintf(fname, 250, "tips_e/%s.txt", Tips[i].tipfilename);
+ ViewTextFile(fname);
+ redraw_screen();
+ return CK_MOUSE_DONE;
+ }
+ return 0;
+ }
+#endif
+
+ if((mouse_mode==MOUSE_MODE_COMMAND || mouse_mode == MOUSE_MODE_MACRO) &&
+ (mode == REGION_DNGN || mode == REGION_TDNGN))
+ {
+ if (button == 2)
+ {
+ // describe yourself (char info)
+ if (cx == DCX && cy == DCY) return '%';
+
+ // trigger
+ if (mouse_mode == MOUSE_MODE_MACRO)
+ return trig;
+
+ // Right Click: try to describe grid
+ // otherwise return trigger key
+ if (!in_los_bounds(cx+1,cy+1))
+ return CK_MOUSE_B2;
+ const coord_def ep = view2show(coord_def(cx, cy));
+ if (env.show(ep) == 0)
+ return trig;
+
+ int mid = mgrd[cx][cy];
+ if (mid == NON_MONSTER || !player_monster_visible( &menv[mid] ))
+ {
+ return trig;
+ }
+
+ describe_monsters( menv[ mid ] );
+ redraw_screen();
+ mesclr( true );
+ 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(1)
+ {
+ 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;
+ } // switch
+
+ if (k != 0) break;
+ }/*while*/
+
+ 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();
+}
+
+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;
+}
+
+void gui_init_view_params(coord_def &termsz, coord_def &viewsz,
+ coord_def &msgp, coord_def &msgsz, coord_def &hudp, coord_def &hudsz)
+{
+ // TODO enne - set these other params too?
+ msgsz.x = msg_x;
+ msgsz.y = msg_y;
+}
+
+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;
+ }
+ }
+
+ gotoxy(1, 1);
+}
+
+void putch(unsigned char chr)
+{
+ // object's method
+ TextRegionClass::text_mode->putch(chr);
+}
+
+void putwch(unsigned chr)
+{
+ // No unicode support.
+ putch(static_cast<unsigned char>(chr));
+}
+
+void writeWChar(unsigned char *ch)
+{
+ // object's method
+ TextRegionClass::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();
+}
+
+void get_input_line_gui(char *const buff, int len)
+{
+ int y, x;
+ int k = 0;
+ int prev = 0;
+ int done = 0;
+ int kin;
+ TextRegionClass *r = TextRegionClass::text_mode;
+
+ static char last[128];
+ static int lastk = 0;
+
+ if(!r->flag)return;
+
+ /* Locate the cursor */
+ x = wherex();
+ y = wherey();
+
+ /* Paranoia -- check len */
+ if (len < 1) len = 1;
+
+ /* Restrict the length */
+ if (x + len > r->mx) len = r->mx - x;
+ if (len > 40) len = 40;
+
+ /* Paranoia -- Clip the default entry */
+ buff[len] = '\0';
+ buff[0] = '\0';
+
+ r->gotoxy(x, y);
+ putch('_');
+
+ /* Process input */
+ while (!done)
+ {
+ /* Get a key */
+ kin = getch_ck();
+
+ /* Analyze the key */
+ switch (kin)
+ {
+ case 0x1B:
+ k = 0;
+ done = 1;
+ break;
+
+ case '\n':
+ case '\r':
+ k = strlen(buff);
+ done = 1;
+ lastk = k;
+ strncpy(last, buff, k);
+ break;
+
+ case CK_UP: // history
+ if (lastk != 0)
+ {
+ k = lastk;
+ strncpy(buff, last, k);
+ }
+ break;
+
+ case 0x7F:
+ case '\010':
+ k = prev;
+ break;
+
+ // Escape conversion. (for ^H, etc)
+ case CONTROL('V'):
+ kin = getch();
+ // fallthrough
+
+ default:
+ {
+ if (k < len &&
+ (
+ isprint(kin)
+ || (kin >= CONTROL('A') && kin <= CONTROL('Z'))
+ || (kin >= 0x80 && kin <=0xff)
+ )
+ )
+ buff[k++] = kin;
+ break;
+ }
+
+ }
+ /* Terminate */
+ buff[k] = '\0';
+
+ /* Update the entry */
+ r->gotoxy(x, y);
+ int i;
+
+ //addstr(buff);
+ for(i=0;i<k;i++)
+ {
+ prev = i;
+ int c = (unsigned char)buff[i];
+ if (c>=0x80)
+ {
+ if (buff[i+1]==0) break;
+ writeWChar((unsigned char *)&buff[i]);
+ i++;
+ }
+ else
+ if (c >= CONTROL('A') && c<= CONTROL('Z'))
+ {
+ putch('^');
+ putch(c + 'A' - 1);
+ }
+ else
+ putch(c);
+ }
+ r->addstr((char *)"_ ");
+ r->gotoxy(x+k, y);
+ }/* while */
+}
+
+void cprintf(const char *format,...)
+{
+ char buffer[2048]; // One full screen if no control seq...
+ va_list argp;
+ va_start(argp, format);
+ vsprintf(buffer, format, argp);
+ va_end(argp);
+ // object's method
+ TextRegionClass::text_mode->addstr(buffer);
+ TextRegionClass::text_mode->make_active();
+}
+
+void textcolor(int color)
+{
+ TextRegionClass::textcolor(color);
+}
+
+void textbackground(int bg)
+{
+ TextRegionClass::textbackground(bg);
+}
+
+void gotoxy(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::gotoxy(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);
+}
+
+void set_cursor_enabled(bool enabled)
+{
+ if (gui_smart_cursor) return;
+ if (enabled) TextRegionClass::_setcursortype(1);
+ else TextRegionClass::_setcursortype(0);
+}
+
+bool is_cursor_enabled()
+{
+ if (TextRegionClass::cursor_flag) return true;
+ return false;
+}
+
+int wherex()
+{
+ return TextRegionClass::wherex();
+}
+
+int wherey()
+{
+ return TextRegionClass::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
+}
+
+int get_number_of_cols()
+{
+ return std::min(region_crt->mx, region_msg->mx);
+}
+
+void message_out(int which_line, int colour, const char *s, int firstcol,
+ bool newline)
+{
+ if (!firstcol)
+ firstcol = Options.delay_message_clear ? 2 : 1;
+
+ gotoxy(firstcol, which_line + 1, GOTO_MSG);
+ textcolor(colour);
+
+ cprintf("%s", s);
+
+ if (newline && which_line == crawl_view.msgsz.y - 1)
+ region_msg->scroll();
+}
+
+void clear_message_window()
+{
+ region_msg->clear();
+}
+
+void put_colour_ch(int colour, unsigned ch)
+{
+ textcolor(colour);
+ putwch(ch);
+}
+
+void puttext(int sx, int sy, int ex, int ey, unsigned char *buf, bool mono,
+ int where)
+{
+ TextRegionClass *r = (where == 1) ?region_crt:region_dngn;
+
+ if (where==1 && UseDosChar) r=region_xmap;
+
+ int xx, yy;
+ unsigned char *ptr = buf;
+ //gotoxy(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;
+ if (*c==0) *c=32;
+#if 0 //deb
+ if (*c==177) *c=2;
+ if (*c==176) *c=2;
+ if (*c==249) *c=31;
+#endif
+ 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 ViewTextFile(const char *name)
+{
+ FILE *fp = fopen(name, "r");
+ int max = get_number_of_lines();
+
+ // Hack
+#define MAXTEXTLINES 100
+
+#define DELIMITER_END "-------------------------------------------------------------------------------"
+#define DELIMITER_MORE "...(more)... "
+ unsigned char buf[80*MAXTEXTLINES], buf2[84];
+ int nlines = 0;
+ int cline = 0;
+ int i;
+
+ if (!fp)
+ {
+ mpr("Couldn't open file.");
+ return;
+ }
+
+ for (i=0; i<80*MAXTEXTLINES; i++) buf[i] = ' ';
+
+ while(nlines<MAXTEXTLINES)
+ {
+ fgets((char *)buf2, 82, fp);
+ if (feof(fp)) break;
+ i = 0;
+ while(i<79 && buf2[i] !=13 && buf2[i] != 10) i++;
+ memcpy(&buf[nlines*80], buf2, i);
+ nlines++;
+ }
+ fclose(fp);
+ clrscr();
+
+ while(1)
+ {
+ gotoxy(1, 1);
+ if (cline == 0)
+ cprintf(DELIMITER_END);
+ else
+ cprintf(DELIMITER_MORE);
+
+ puttext(1, 2, 80, max, &buf[cline*80], true, 1);
+
+ gotoxy(1, max);
+
+ if (cline + max-2 >= nlines)
+ cprintf(DELIMITER_END);
+ else
+ cprintf(DELIMITER_MORE);
+
+ gotoxy(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;
+ if (key == '-' || key == 'b') cline -= max-2;
+ if (key == 'k') cline --;
+ if (key == '+' || key == ' ') cline += max-2;
+ if (key == 'j') cline ++;
+ if (key == CK_MOUSE_B4) cline--;
+ if (key == CK_MOUSE_B5) cline++;
+
+ if (cline + max-2 > nlines) cline = nlines-max + 2;
+ if (cline < 0) cline = 0;
+ }
+}
+
+void window(int x1, int y1, int x2, int y2)
+{
+}