1 /* NetHack may be freely redistributed. See license for details. */
2
3 #include "vulture_sdl.h" /* XXX this must be the first include,
4 no idea why but it won't compile otherwise */
5
6 extern "C" {
7 #include "hack.h"
8 }
9
10 #include "vulture_main.h"
11 #include "vulture_win.h"
12 #include "vulture_opt.h"
13 #include "vulture_gfl.h"
14 #include "vulture_gra.h"
15 #include "vulture_mou.h"
16 #include "vulture_tile.h"
17
18 #include "minimap.h"
19 #include "levelwin.h"
20
21 minimap *minimapwin = NULL;
22
minimap(levelwin * p,mapdata * data)23 minimap::minimap(levelwin *p, mapdata *data) : window(p), level(p), map_data(data)
24 {
25 minimapbg = vulture_load_graphic(V_FILENAME_MINIMAPBG);
26 w = minimapbg->w;
27 h = minimapbg->h;
28 x = parent->w - (w + 6);
29 y = 6;
30 visible = vulture_opts.show_minimap;
31 menu_id = V_WIN_MINIMAP;
32 autobg = 1;
33
34 minimapwin = this;
35 }
36
37
~minimap()38 minimap::~minimap()
39 {
40 SDL_FreeSurface(minimapbg);
41 minimapwin = NULL;
42 }
43
44
draw()45 bool minimap::draw()
46 {
47 int map_x, map_y, sym;
48 Uint32 *pixels;
49 SDL_Rect destrect = {0, 0, 3, 2};
50
51 Uint32 minimap_colors[V_MMTILE_MAX] =
52 {CLR32_BLACK, V_COLOR_MINI_FLOOR, V_COLOR_MINI_STAIRS,
53 V_COLOR_MINI_DOOR, V_COLOR_MINI_YOU, CLR32_GREEN, CLR32_RED};
54
55 if (!minimapbg)
56 return false;
57
58 if (this->background)
59 vulture_put_img(abs_x, abs_y, background);
60
61
62 for (map_y = 0; map_y < ROWNO; map_y++)
63 {
64 for (map_x = 1; map_x < COLNO; map_x++)
65 {
66 /* translate the contents of the map into a minimap symbol color */
67 switch(map_data->get_glyph(MAP_BACK, map_x, map_y))
68 {
69 case V_TILE_WALL_GENERIC:
70 case V_MISC_UNMAPPED_AREA:
71 sym = V_MMTILE_NONE; break;
72
73 default:
74 sym = V_MMTILE_FLOOR; break;
75 }
76
77 switch(map_data->get_glyph(MAP_FURNITURE, map_x, map_y))
78 {
79 case V_MISC_STAIRS_UP:
80 case V_MISC_STAIRS_DOWN:
81 sym = V_MMTILE_STAIRS; break;
82
83 case V_MISC_VDOOR_WOOD_OPEN:
84 case V_MISC_VDOOR_WOOD_CLOSED:
85 case V_MISC_HDOOR_WOOD_OPEN:
86 case V_MISC_HDOOR_WOOD_CLOSED:
87 case V_MISC_VODBRIDGE:
88 case V_MISC_HODBRIDGE:
89 case V_MISC_VCDBRIDGE:
90 case V_MISC_HCDBRIDGE:
91 sym = V_MMTILE_DOOR; break;
92 }
93
94 if (map_data->get_glyph(MAP_TRAP, map_x, map_y) == V_MISC_MAGIC_PORTAL)
95 sym = V_MMTILE_STAIRS;
96
97 if (map_data->get_glyph(MAP_MON, map_x, map_y) != V_TILE_NONE)
98 {
99 if (map_data->get_glyph(MAP_PET, map_x, map_y))
100 sym = V_MMTILE_PET;
101 else
102 sym = V_MMTILE_MONSTER;
103 }
104
105 if ((map_y == u.uy) && (map_x == u.ux))
106 sym = V_MMTILE_YOU;
107
108 /* draw symbols that changed onto the "minimap surface" */
109 if (sym != vulture_minimap_syms[map_y][map_x])
110 {
111 vulture_minimap_syms[map_y][map_x] = sym;
112
113 destrect.x = 40 + 2*map_x - 2*map_y;
114 destrect.y = map_x + map_y;
115
116 pixels = (Uint32 *)((char*)minimapbg->pixels +
117 minimapbg->pitch * (destrect.y+6) + (destrect.x+6) * 4);
118
119 /* A minimap symbol has this shape: _ C _
120 * C C C
121 * where "_" is transparent and "C" is a colored pixel */
122
123 /* row 1: */
124 /* pixels[0] = transparent -> dont write */
125 pixels[1] = minimap_colors[sym];
126 /* pixels[2] = transparent -> dont write */
127
128 /* row 2 */
129 pixels = (Uint32 *)((char*)minimapbg->pixels +
130 minimapbg->pitch * (destrect.y+7) + (destrect.x+6) * 4);
131 pixels[0] = minimap_colors[sym];
132 pixels[1] = minimap_colors[sym];
133 pixels[2] = minimap_colors[sym];
134 }
135
136 }
137 }
138
139 vulture_put_img(abs_x, abs_y, minimapbg);
140
141 vulture_invalidate_region(abs_x, abs_y, w, h);
142
143 return false;
144 }
145
146
handle_mousemotion_event(window * target,void * result,int xrel,int yrel,int state)147 eventresult minimap::handle_mousemotion_event(window* target, void* result, int xrel,
148 int yrel, int state)
149 {
150 vulture_set_mcursor(V_CURSOR_NORMAL);
151 return V_EVENT_HANDLED_NOREDRAW;
152 }
153
154
handle_mousebuttonup_event(window * target,void * result,int mouse_x,int mouse_y,int button,int state)155 eventresult minimap::handle_mousebuttonup_event(window* target, void* result,
156 int mouse_x, int mouse_y, int button, int state)
157 {
158 point mouse, mappos;
159 int offs_x, offs_y;
160
161 /* translate the mouse position to a map coordinate */
162 mouse = vulture_get_mouse_pos();
163
164 offs_x = mouse.x - abs_x - 6 - 40;
165 offs_y = mouse.y - abs_y - 6;
166 mappos.x = ( offs_x + 2*offs_y)/4;
167 mappos.y = (-offs_x + 2*offs_y)/4;
168
169 if (mappos.x < 1 || mappos.x > COLNO ||
170 mappos.y < 0 || mappos.y > ROWNO)
171 return V_EVENT_UNHANDLED;
172
173 /* limited mouse event handling, due to the fact that the minimap
174 * is too small for precise targeting */
175 /* left button: direct selection of a location (for very imprecise teleport) */
176 if (button == SDL_BUTTON_LEFT) {
177 if (vulture_whatis_active) {
178 ((vulture_event*)result)->num = 0;
179 ((vulture_event*)result)->x = mappos.x;
180 ((vulture_event*)result)->y = mappos.y;
181 return V_EVENT_HANDLED_FINAL;
182 }
183
184 ((vulture_event*)result)->num = map_data->perform_map_action(V_ACTION_TRAVEL, mappos);
185 return V_EVENT_HANDLED_FINAL;
186 }
187 /* right button: travel to location */
188 else if(button == SDL_BUTTON_RIGHT) {
189 levwin->set_view(mappos.x, mappos.y);
190 levwin->need_redraw = 1;
191 return V_EVENT_HANDLED_REDRAW;
192 }
193
194 return V_EVENT_HANDLED_NOREDRAW;
195 }
196
197
handle_resize_event(window * target,void * result,int res_w,int res_h)198 eventresult minimap::handle_resize_event(window* target, void* result, int res_w, int res_h)
199 {
200 x = parent->w - (w + 6);
201 return V_EVENT_HANDLED_NOREDRAW;
202 }
203