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