1 /* GemRB - Infinity Engine Emulator
2 * Copyright (C) 2003 The GemRB Project
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 #include "GUI/WorldMapControl.h"
26 #include "Interface.h"
30 #define MAP_TO_SCREENX(x) XWin + XPos - ScrollX + (x)
31 #define MAP_TO_SCREENY(y) YWin + YPos - ScrollY + (y)
33 WorldMapControl::WorldMapControl(const char *font
, int direction
)
41 Game
* game
= core
->GetGame();
42 WorldMap
* worldmap
= core
->GetWorldMap();
43 strncpy(currentArea
, game
->CurrentArea
, 8);
44 int entry
= core
->GetAreaAlias(currentArea
);
46 WMPAreaEntry
*m
= worldmap
->GetEntry(entry
);
47 strncpy(currentArea
, m
->AreaResRef
, 8);
50 //if there is no trivial area, look harder
51 if (!worldmap
->GetArea(currentArea
, (unsigned int &) entry
) &&
52 core
->HasFeature(GF_FLEXIBLE_WMAP
) ) {
53 WMPAreaEntry
*m
= worldmap
->FindNearestEntry(currentArea
, (unsigned int &) entry
);
55 strncpy(currentArea
, m
->AreaResRef
, 8);
59 //this also updates visible locations
60 worldmap
->CalculateDistances(currentArea
, Value
);
62 // alpha bit is unfortunately ignored
64 ftext
= core
->GetFont(font
);
69 // initialize label colors
70 Color normal
= { 0xf0, 0xf0, 0xf0, 0xff };
71 Color selected
= { 0xf0, 0x80, 0x80, 0xff };
72 Color notvisited
= { 0x80, 0x80, 0xf0, 0xff };
73 Color black
= { 0x00, 0x00, 0x00, 0x00 };
75 pal_normal
= core
->CreatePalette ( normal
, black
);
76 pal_selected
= core
->CreatePalette ( selected
, black
);
77 pal_notvisited
= core
->CreatePalette ( notvisited
, black
);
80 ResetEventHandler( WorldMapControlOnPress
);
81 ResetEventHandler( WorldMapControlOnEnter
);
84 WorldMapControl::~WorldMapControl(void)
86 //Video *video = core->GetVideoDriver();
88 gamedata
->FreePalette( pal_normal
);
89 gamedata
->FreePalette( pal_selected
);
90 gamedata
->FreePalette( pal_notvisited
);
93 /** Draws the Control on the Output Display */
94 void WorldMapControl::Draw(unsigned short XWin
, unsigned short YWin
)
96 WorldMap
* worldmap
= core
->GetWorldMap();
97 if (!Width
|| !Height
) {
103 Video
* video
= core
->GetVideoDriver();
104 Region
r( XWin
+XPos
, YWin
+YPos
, Width
, Height
);
106 video
->GetClipRect(clipbackup
);
107 video
->SetClipRect(&r
);
108 video
->BlitSprite( worldmap
->GetMapMOS(), MAP_TO_SCREENX(0), MAP_TO_SCREENY(0), true, &r
);
111 unsigned int ec
= worldmap
->GetEntryCount();
113 WMPAreaEntry
*m
= worldmap
->GetEntry(i
);
114 if (! (m
->GetAreaStatus() & WMP_ENTRY_VISIBLE
)) continue;
116 int xOffs
= MAP_TO_SCREENX(m
->X
);
117 int yOffs
= MAP_TO_SCREENY(m
->Y
);
118 Sprite2D
* icon
= m
->GetMapIcon(worldmap
->bam
);
120 video
->BlitSprite( icon
, xOffs
, yOffs
, true, &r
);
121 video
->FreeSprite( icon
);
124 if (AnimPicture
&& !strnicmp(m
->AreaResRef
, currentArea
, 8) ) {
125 core
->GetVideoDriver()->BlitSprite( AnimPicture
, xOffs
, yOffs
, true, &r
);
129 // Draw WMP entry labels
131 video
->SetClipRect(&clipbackup
);
135 WMPAreaEntry
*m
= worldmap
->GetEntry(i
);
136 if (! (m
->GetAreaStatus() & WMP_ENTRY_VISIBLE
)) continue;
137 Sprite2D
*icon
=m
->GetMapIcon(worldmap
->bam
);
138 int h
=0,w
=0,xpos
=0,ypos
=0;
144 video
->FreeSprite( icon
);
147 Region r2
= Region( MAP_TO_SCREENX(m
->X
-xpos
), MAP_TO_SCREENY(m
->Y
-ypos
), w
, h
);
148 if (!m
->GetCaption())
151 int tw
= ftext
->CalcStringWidth( m
->GetCaption() ) + 5;
152 int th
= ftext
->maxHeight
;
154 Palette
* text_pal
= pal_normal
;
157 text_pal
= pal_selected
;
159 if (! (m
->GetAreaStatus() & WMP_ENTRY_VISITED
)) {
160 text_pal
= pal_notvisited
;
164 ftext
->Print( Region( r2
.x
+ (r2
.w
- tw
)/2, r2
.y
+ r2
.h
, tw
, th
),
165 ( const unsigned char * ) m
->GetCaption(), text_pal
, 0, true );
167 video
->SetClipRect(&clipbackup
);
170 /** Key Release Event */
171 void WorldMapControl::OnKeyRelease(unsigned char Key
, unsigned short Mod
)
175 if (Mod
& GEM_MOD_CTRL
)
176 core
->GetVideoDriver()->ToggleFullscreenMode();
182 void WorldMapControl::AdjustScrolling(short x
, short y
)
184 WorldMap
* worldmap
= core
->GetWorldMap();
189 //center worldmap on current area
192 WMPAreaEntry
*m
= worldmap
->GetArea(currentArea
,entry
);
194 ScrollX
= m
->X
- Width
/2;
195 ScrollY
= m
->Y
- Height
/2;
198 Sprite2D
*MapMOS
= worldmap
->GetMapMOS();
199 if (ScrollX
> MapMOS
->Width
- Width
)
200 ScrollX
= MapMOS
->Width
- Width
;
201 if (ScrollY
> MapMOS
->Height
- Height
)
202 ScrollY
= MapMOS
->Height
- Height
;
211 /** Mouse Over Event */
212 void WorldMapControl::OnMouseOver(unsigned short x
, unsigned short y
)
214 WorldMap
* worldmap
= core
->GetWorldMap();
215 lastCursor
= IE_CURSOR_GRAB
;
218 AdjustScrolling(lastMouseX
-x
, lastMouseY
-y
);
224 if (Value
!=(ieDword
) -1) {
225 x
=(ieWord
) (x
+ ScrollX
);
226 y
=(ieWord
) (y
+ ScrollY
);
228 WMPAreaEntry
*oldArea
= Area
;
232 unsigned int ec
= worldmap
->GetEntryCount();
234 WMPAreaEntry
*ae
= worldmap
->GetEntry(i
);
236 if ( (ae
->GetAreaStatus() & WMP_ENTRY_WALKABLE
)!=WMP_ENTRY_WALKABLE
) {
237 continue; //invisible or inaccessible
239 if (!strnicmp(ae
->AreaResRef
, currentArea
, 8) ) {
240 continue; //current area
243 Sprite2D
*icon
=ae
->GetMapIcon(worldmap
->bam
);
248 core
->GetVideoDriver()->FreeSprite( icon
);
250 if (ftext
&& ae
->GetCaption()) {
251 int tw
= ftext
->CalcStringWidth( ae
->GetCaption() ) + 5;
252 int th
= ftext
->maxHeight
;
258 if (ae
->X
> x
) continue;
259 if (ae
->X
+ w
< x
) continue;
260 if (ae
->Y
> y
) continue;
261 if (ae
->Y
+ h
< y
) continue;
262 lastCursor
= IE_CURSOR_NORMAL
;
265 RunEventHandler(WorldMapControlOnEnter
);
271 Owner
->Cursor
= lastCursor
;
274 /** Sets the tooltip to be displayed on the screen now */
275 void WorldMapControl::DisplayTooltip()
278 int x
= Owner
->XPos
+XPos
+lastMouseX
;
279 int y
= Owner
->YPos
+YPos
+lastMouseY
-50;
280 core
->DisplayTooltip( x
, y
, this );
282 core
->DisplayTooltip( 0, 0, NULL
);
286 /** Mouse Leave Event */
287 void WorldMapControl::OnMouseLeave(unsigned short /*x*/, unsigned short /*y*/)
289 Owner
->Cursor
= IE_CURSOR_NORMAL
;
293 /** Mouse Button Down */
294 void WorldMapControl::OnMouseDown(unsigned short x
, unsigned short y
,
295 unsigned short Button
, unsigned short /*Mod*/)
304 OnSpecialKeyPress(GEM_UP
);
306 case GEM_MB_SCRLDOWN
:
307 OnSpecialKeyPress(GEM_DOWN
);
311 /** Mouse Button Up */
312 void WorldMapControl::OnMouseUp(unsigned short /*x*/, unsigned short /*y*/,
313 unsigned short Button
, unsigned short /*Mod*/)
315 if (Button
!= GEM_MB_ACTION
) {
318 if (lastCursor
==IE_CURSOR_NORMAL
) {
319 RunEventHandler( WorldMapControlOnPress
);
324 /** Special Key Press */
325 void WorldMapControl::OnSpecialKeyPress(unsigned char Key
)
327 WorldMap
* worldmap
= core
->GetWorldMap();
342 printf( "ALT pressed\n" );
345 printf( "TAB pressed\n" );
349 Sprite2D
*MapMOS
= worldmap
->GetMapMOS();
350 if (ScrollX
> MapMOS
->Width
- Width
)
351 ScrollX
= MapMOS
->Width
- Width
;
352 if (ScrollY
> MapMOS
->Height
- Height
)
353 ScrollY
= MapMOS
->Height
- Height
;
360 bool WorldMapControl::SetEvent(int eventType
, EventHandler handler
)
365 case IE_GUI_WORLDMAP_ON_PRESS
:
366 WorldMapControlOnPress
= handler
;
368 case IE_GUI_MOUSE_ENTER_WORLDMAP
:
369 WorldMapControlOnEnter
= handler
;
378 void WorldMapControl::SetColor(int which
, Color color
)
380 Color black
= { 0x00, 0x00, 0x00, 0x00 };
382 case IE_GUI_WMAP_COLOR_NORMAL
:
383 gamedata
->FreePalette( pal_normal
);
384 pal_normal
= core
->CreatePalette( color
, black
);
386 case IE_GUI_WMAP_COLOR_SELECTED
:
387 gamedata
->FreePalette( pal_selected
);
388 pal_selected
= core
->CreatePalette( color
, black
);
390 case IE_GUI_WMAP_COLOR_NOTVISITED
:
391 gamedata
->FreePalette( pal_notvisited
);
392 pal_notvisited
= core
->CreatePalette( color
, black
);