diff --git a/doomsday/build/codeblocks/jdoom64.cbp b/doomsday/build/codeblocks/jdoom64.cbp
index b88527ae6d..977668deea 100644
--- a/doomsday/build/codeblocks/jdoom64.cbp
+++ b/doomsday/build/codeblocks/jdoom64.cbp
@@ -101,6 +101,7 @@
+
@@ -111,7 +112,6 @@
-
@@ -134,7 +134,6 @@
-
@@ -163,6 +162,7 @@
+
@@ -188,7 +188,6 @@
-
@@ -256,7 +255,6 @@
-
diff --git a/doomsday/build/win32/jdoom64_cl.rsp b/doomsday/build/win32/jdoom64_cl.rsp
index e4fa85eb89..fa3e73fc3e 100644
--- a/doomsday/build/win32/jdoom64_cl.rsp
+++ b/doomsday/build/win32/jdoom64_cl.rsp
@@ -20,7 +20,6 @@
.\..\..\plugins\common\src\m_ctrl.c
.\..\..\plugins\common\src\m_fixed.c
.\..\..\plugins\common\src\p_actor.c
- .\..\..\plugins\common\src\p_automap.c
.\..\..\plugins\common\src\p_ceiling.c
.\..\..\plugins\common\src\p_door.c
.\..\..\plugins\common\src\p_floor.c
@@ -44,7 +43,7 @@
.\..\..\plugins\common\src\p_xgsave.c
.\..\..\plugins\common\src\p_xgsec.c
.\..\..\plugins\common\src\r_common.c
- .\..\..\plugins\common\src\rend_automap.c
+ .\..\..\plugins\common\src\hu_automap.c
.\..\..\plugins\common\src\x_hair.c
.\..\..\plugins\jdoom64\src\acfnlink.c
.\..\..\plugins\jdoom64\src\d_api.c
diff --git a/doomsday/build/win32/vs8/jdoom64.vcproj b/doomsday/build/win32/vs8/jdoom64.vcproj
index 8277eaacb7..95d04661b6 100644
--- a/doomsday/build/win32/vs8/jdoom64.vcproj
+++ b/doomsday/build/win32/vs8/jdoom64.vcproj
@@ -852,6 +852,10 @@
RelativePath="..\..\..\plugins\common\include\gl_drawpatch.h"
>
+
+
@@ -892,10 +896,6 @@
RelativePath="..\..\..\plugins\common\include\p_actor.h"
>
-
-
@@ -984,10 +984,6 @@
RelativePath="..\..\..\plugins\common\include\r_common.h"
>
-
-
@@ -1048,6 +1044,10 @@
RelativePath="..\..\..\plugins\common\src\gl_drawpatch.c"
>
+
+
@@ -1088,10 +1088,6 @@
RelativePath="..\..\..\plugins\common\src\p_actor.c"
>
-
-
@@ -1184,10 +1180,6 @@
RelativePath="..\..\..\plugins\common\src\r_common.c"
>
-
-
diff --git a/doomsday/plugins/jdoom64/include/r_defs.h b/doomsday/plugins/jdoom64/include/r_defs.h
index 979e24c2ac..7391e14e91 100644
--- a/doomsday/plugins/jdoom64/include/r_defs.h
+++ b/doomsday/plugins/jdoom64/include/r_defs.h
@@ -124,6 +124,15 @@ xline_t* P_ToXLine(linedef_t* line);
xsector_t* P_ToXSector(sector_t* sector);
xsector_t* P_ToXSectorOfSubsector(subsector_t* sub);
+/**
+ * Update the specified player's automap.
+ *
+ * @param player Local player number whose map is to change.
+ * @param line Line to change.
+ * @param visible @c true= mark the line as visible.
+ */
+void P_SetLinedefAutomapVisibility(int player, uint line, boolean visible);
+
xline_t* P_GetXLine(uint index);
xsector_t* P_GetXSector(uint index);
#endif
diff --git a/doomsday/plugins/jdoom64/include/st_stuff.h b/doomsday/plugins/jdoom64/include/st_stuff.h
index 3b52e81564..50b8656512 100644
--- a/doomsday/plugins/jdoom64/include/st_stuff.h
+++ b/doomsday/plugins/jdoom64/include/st_stuff.h
@@ -36,17 +36,20 @@
# error "Using jDoom64 headers without __JDOOM64__"
#endif
-#include "hu_chat.h"
+#include "hu_lib.h"
+#include "d_config.h"
// Palette indices.
// For damage/bonus red-/gold-shifts
-#define STARTREDPALS (1)
-#define STARTBONUSPALS (9)
-#define NUMREDPALS (8)
-#define NUMBONUSPALS (4)
+#define STARTREDPALS (1)
+#define STARTBONUSPALS (9)
+#define NUMREDPALS (8)
+#define NUMBONUSPALS (4)
-#define HUDBORDERX (14)
-#define HUDBORDERY (18)
+#define HUDBORDERX (14)
+#define HUDBORDERY (18)
+
+#define ST_AUTOMAP_OBSCURE_TOLERANCE (.9999f)
void ST_Register(void);
void ST_Init(void);
@@ -59,6 +62,10 @@ void ST_Drawer(int player);
void ST_Start(int player);
void ST_Stop(int player);
+uiwidget_t* ST_UIChatForPlayer(int player);
+uiwidget_t* ST_UILogForPlayer(int player);
+uiwidget_t* ST_UIAutomapForPlayer(int player);
+
boolean ST_ChatIsActive(int player);
/**
@@ -92,6 +99,46 @@ void ST_LogStart(int player);
void ST_LogUpdateAlignment(void);
void ST_LogPostVisibilityChangeNotification(void);
+/**
+ * Start the automap.
+ */
+void ST_AutomapOpen(int player, boolean yes, boolean fast);
+
+boolean ST_AutomapIsActive(int player);
+
+void ST_ToggleAutomapPanMode(int player);
+
+void ST_ToggleAutomapMaxZoom(int player);
+
+float ST_AutomapOpacity(int player);
+
+/**
+ * Does the player's automap obscure this region completely?
+ * \assume: Window dimensions use the fixed coordinate space {x} 0 - 320, {y} 0 - 200.
+ *
+ * @param player Local player number whose automap to check.
+ * @param region Window region.
+ *
+ * @return @true= there is no point even partially visible.
+ */
+boolean ST_AutomapWindowObscures2(int player, const rectanglei_t* region);
+boolean ST_AutomapWindowObscures(int player, int x, int y, int width, int height);
+
+int ST_AutomapAddPoint(int player, float x, float y, float z);
+void ST_AutomapClearPoints(int player);
+boolean ST_AutomapPointOrigin(int player, int point, float* x, float* y, float* z);
+
+void ST_SetAutomapCameraRotation(int player, boolean on);
+
+int ST_AutomapCheatLevel(int player);
+void ST_SetAutomapCheatLevel(int player, int level);
+void ST_CycleAutomapCheatLevel(int player);
+
+void ST_RevealAutomap(int player, boolean on);
+boolean ST_AutomapHasReveal(int player);
+
+void ST_RebuildAutomap(int player);
+
/// Call when it might be neccessary for the hud to unhide.
void ST_HUDUnHide(int player, hueevent_t event);
diff --git a/doomsday/plugins/jdoom64/src/d_refresh.c b/doomsday/plugins/jdoom64/src/d_refresh.c
index b5f4f2ab68..f3c5f5b939 100644
--- a/doomsday/plugins/jdoom64/src/d_refresh.c
+++ b/doomsday/plugins/jdoom64/src/d_refresh.c
@@ -38,7 +38,7 @@
#include "hu_pspr.h"
#include "hu_msg.h"
#include "hu_log.h"
-#include "am_map.h"
+#include "hu_automap.h"
#include "g_common.h"
#include "r_common.h"
#include "d_net.h"
@@ -47,7 +47,6 @@
#include "p_mapsetup.h"
#include "p_tick.h"
#include "p_actor.h"
-#include "rend_automap.h"
// MACROS ------------------------------------------------------------------
@@ -101,7 +100,7 @@ static void drawSpecialFilter(int pnum, int x, int y, int w, int h)
g = MINMAX_OF(0.f, str * 2 - .4, 1.f);
b = MINMAX_OF(0.f, str * 2 - .8, 1.f);
- DGL_DrawRect(x, y, w, h, r, g, b, 1);
+ DGL_DrawRectColor(x, y, w, h, r, g, b, 1);
// Restore the normal rendering state.
DGL_BlendMode(BM_NORMAL);
@@ -207,7 +206,6 @@ static void rendHUD(int player, int viewW, int viewH)
if(!DD_GetInteger(DD_GAME_DRAW_HUD_HINT))
return; // The engine advises not to draw any HUD displays.
- AM_Drawer(player);
ST_Drawer(player);
HU_DrawScoreBoard(player);
@@ -262,7 +260,7 @@ void D_Display(int layer)
if(G_GetGameState() == GS_MAP && cfg.screenBlocks <= 10 &&
!(P_MobjIsCamera(plr->plr->mo) && Get(DD_PLAYBACK))) // $democam: can be set on every frame.
{
- R_GetViewWindow(&winX, &winY, &winW, &winH);
+ R_GetSmoothedViewWindow(&winX, &winY, &winW, &winH);
}
else
{ // Full screen.
@@ -279,12 +277,12 @@ void D_Display(int layer)
vY = ROUND(winY * yScale);
vW = ROUND(winW * xScale);
vH = ROUND(winH * yScale);
- R_SetViewWindow(vX, vY, vW, vH);
+ R_SetViewWindow(player, vX, vY, vW, vH);
switch(G_GetGameState())
{
case GS_MAP:
- if(!R_MapObscures(player, winX, winY, winW, winH))
+ if(!ST_AutomapWindowObscures(player, winX, winY, winW, winH))
{
if(IS_CLIENT && (!Get(DD_GAME_READY) || !Get(DD_GOTFRAME)))
return;
@@ -299,7 +297,7 @@ void D_Display(int layer)
}
break;
case GS_STARTUP:
- DGL_DrawRect(0, 0, vpWidth, vpHeight, 0, 0, 0, 1);
+ DGL_DrawRectColor(0, 0, vpWidth, vpHeight, 0, 0, 0, 1);
break;
default:
break;
@@ -318,7 +316,7 @@ void D_Display2(void)
if(G_GetGameAction() == GA_QUIT)
{
- DGL_DrawRect(0, 0, 320, 200, 0, 0, 0, quitDarkenOpacity);
+ DGL_DrawRectColor(0, 0, 320, 200, 0, 0, 0, quitDarkenOpacity);
}
}
diff --git a/doomsday/plugins/jdoom64/src/m_cheat.c b/doomsday/plugins/jdoom64/src/m_cheat.c
index 36cac9d5ad..fe835b8fb0 100644
--- a/doomsday/plugins/jdoom64/src/m_cheat.c
+++ b/doomsday/plugins/jdoom64/src/m_cheat.c
@@ -405,24 +405,24 @@ D_CMD(CheatWarp)
D_CMD(CheatReveal)
{
- int option;
- automapid_t map;
+ int option, i;
if(!cheatsEnabled())
return false;
- map = AM_MapForPlayer(CONSOLEPLAYER);
- AM_SetCheatLevel(map, 0);
- AM_RevealMap(map, false);
-
option = atoi(argv[1]);
if(option < 0 || option > 3)
return false;
- if(option == 1)
- AM_RevealMap(map, true);
- else if(option != 0)
- AM_SetCheatLevel(map, option -1);
+ for(i = 0; i < MAXPLAYERS; ++i)
+ {
+ ST_SetAutomapCheatLevel(i, 0);
+ ST_RevealAutomap(i, false);
+ if(option == 1)
+ ST_RevealAutomap(i, true);
+ else if(option != 0)
+ ST_SetAutomapCheatLevel(i, option -1);
+ }
return true;
}
diff --git a/doomsday/plugins/jdoom64/src/p_inter.c b/doomsday/plugins/jdoom64/src/p_inter.c
index d1c1baad58..7835b2521c 100644
--- a/doomsday/plugins/jdoom64/src/p_inter.c
+++ b/doomsday/plugins/jdoom64/src/p_inter.c
@@ -330,7 +330,7 @@ boolean P_GivePower(player_t* player, int power)
}
if(power == PT_ALLMAP)
- AM_RevealMap(AM_MapForPlayer(player - players), true);
+ ST_RevealAutomap(player - players, true);
// Maybe unhide the HUD?
ST_HUDUnHide(player - players, HUE_ON_PICKUP_POWER);
@@ -946,7 +946,7 @@ void P_KillMobj(mobj_t *source, mobj_t *target, boolean stomping)
P_DropWeapon(target->player);
// Don't die with the automap open.
- AM_Open(AM_MapForPlayer(target->player - players), false, false);
+ ST_AutomapOpen(target->player - players, false, false);
#if __JHERETIC__ || __JHEXEN__
Hu_InventoryOpen(target->player - players, false);
#endif
diff --git a/doomsday/plugins/jdoom64/src/p_setup.c b/doomsday/plugins/jdoom64/src/p_setup.c
index 952fdd2d36..808fb4bf59 100644
--- a/doomsday/plugins/jdoom64/src/p_setup.c
+++ b/doomsday/plugins/jdoom64/src/p_setup.c
@@ -165,7 +165,7 @@ int P_HandleMapObjectStatusReport(int code, uint id, int dtype, void *data)
* *data is a pointer to int, giving the player id which has seen it.
* We'll utilize this to mark it as being visible in the automap.
*/
- AM_UpdateLinedef(AM_MapForPlayer(*(int *) data), id, true);
+ P_SetLinedefAutomapVisibility(*(int*)data, id, true);
break;
default:
diff --git a/doomsday/plugins/jdoom64/src/st_stuff.c b/doomsday/plugins/jdoom64/src/st_stuff.c
index 3fe7610e97..0e4bae16b4 100644
--- a/doomsday/plugins/jdoom64/src/st_stuff.c
+++ b/doomsday/plugins/jdoom64/src/st_stuff.c
@@ -44,9 +44,13 @@
#include "hu_lib.h"
#include "hu_chat.h"
#include "hu_log.h"
-#include "am_map.h"
+#include "hu_automap.h"
+#include "p_mapsetup.h"
#include "p_tick.h" // for P_IsPaused
#include "p_inventory.h"
+#include "p_player.h"
+#include "am_map.h"
+#include "r_common.h"
// MACROS ------------------------------------------------------------------
@@ -60,20 +64,36 @@
// TYPES -------------------------------------------------------------------
-typedef struct {
- boolean inited;
- boolean stopped;
- int hideTics;
- float hideAmount;
- float alpha; // Fullscreen hud alpha value.
+enum {
+ UWG_MAPNAME = 0,
+ UWG_BOTTOMLEFT,
+ UWG_BOTTOMRIGHT,
+ UWG_BOTTOM,
+ UWG_TOP,
+ UWG_COUNTERS,
+ UWG_AUTOMAP,
+ NUM_UIWIDGET_GROUPS
+};
+typedef struct {
+ boolean inited;
+ boolean stopped;
+ int hideTics;
+ float hideAmount;
+ float alpha; // Fullscreen hud alpha value.
+ boolean statusbarActive; // Whether the HUD is on.
+ int automapCheatLevel; /// \todo Belongs in player state?
+
+ int widgetGroupIds[NUM_UIWIDGET_GROUPS];
+ int automapWidgetId;
int chatWidgetId;
int logWidgetId;
- boolean firstTime; // ST_Start() has just been called.
- boolean statusbarActive; // Whether the HUD is on.
- int currentFragsCount; // Number of frags so far in deathmatch.
+ boolean firstTime; // ST_Start() has just been called.
+ int currentFragsCount; // Number of frags so far in deathmatch.
+ // Other:
+ guidata_automap_t automap;
guidata_chat_t chat;
guidata_log_t log;
} hudstate_t;
@@ -91,9 +111,6 @@ typedef enum hotloc_e {
// PRIVATE FUNCTION PROTOTYPES ---------------------------------------------
-uiwidget_t* ST_UIChatForPlayer(int player);
-uiwidget_t* ST_UILogForPlayer(int player);
-
int ST_ChatResponder(int player, event_t* ev);
void unhideHUD(void);
@@ -217,17 +234,16 @@ int ST_Responder(event_t* ev)
void ST_Ticker(timespan_t ticLength)
{
- static trigger_t fixed = {1.0 / TICSPERSEC};
-
- boolean runFixedTic = M_RunTrigger(&fixed, ticLength);
+ /// \kludge
+ boolean runGameTic = GUI_RunGameTicTrigger(ticLength);
+ /// kludge end.
int i;
-
for(i = 0; i < MAXPLAYERS; ++i)
{
player_t* plr = &players[i];
hudstate_t* hud = &hudStates[i];
- if(!(plr->plr->inGame && (plr->plr->flags & DDPF_LOCAL)))
+ if(!plr->plr->inGame)
continue;
// Fade in/out the fullscreen HUD.
@@ -256,23 +272,30 @@ void ST_Ticker(timespan_t ticLength)
}
// The following is restricted to fixed 35 Hz ticks.
- if(runFixedTic)
+ if(runGameTic && !P_IsPaused())
{
- if(!P_IsPaused())
+ if(cfg.hudTimer == 0)
{
- if(cfg.hudTimer == 0)
- {
- hud->hideTics = hud->hideAmount = 0;
- }
- else
- {
- if(hud->hideTics > 0)
- hud->hideTics--;
- if(hud->hideTics == 0 && cfg.hudTimer > 0 && hud->hideAmount < 1)
- hud->hideAmount += 0.1f;
- }
+ hud->hideTics = hud->hideAmount = 0;
+ }
+ else
+ {
+ if(hud->hideTics > 0)
+ hud->hideTics--;
+ if(hud->hideTics == 0 && cfg.hudTimer > 0 && hud->hideAmount < 1)
+ hud->hideAmount += 0.1f;
+ }
+
+ /// \todo Refactor me away.
+ ST_updateWidgets(i);
+ }
- ST_updateWidgets(i);
+ if(hud->inited)
+ {
+ int j;
+ for(j = 0; j < NUM_UIWIDGET_GROUPS; ++j)
+ {
+ UIWidget_RunTic(GUI_MustFindObjectById(hud->widgetGroupIds[j]), ticLength);
}
}
}
@@ -587,6 +610,78 @@ Draw_EndZoom();
DGL_PopMatrix();
}
+void MapName_Drawer(uiwidget_t* obj, int x, int y)
+{
+ assert(NULL != obj && obj->type == GUI_MAPNAME);
+ {
+ const float scale = .75f;
+ const float textAlpha = uiRendState->pageAlpha;
+ const patchid_t patch = P_FindMapTitlePatch(gameEpisode, gameMap);
+ const char* text = Hu_ChoosePatchReplacement2(patch, P_GetMapNiceName(), false);
+
+ if(NULL == text && 0 == patch)
+ return;
+
+ DGL_MatrixMode(DGL_MODELVIEW);
+ DGL_PushMatrix();
+ DGL_Translatef(x, y, 0);
+ DGL_Scalef(scale, scale, 1);
+
+ DGL_Enable(DGL_TEXTURE_2D);
+ WI_DrawPatch4(patch, text, 0, 0, DPF_ALIGN_BOTTOMLEFT, obj->fontId, cfg.hudColor[0], cfg.hudColor[1], cfg.hudColor[2], textAlpha);
+ DGL_Disable(DGL_TEXTURE_2D);
+
+ DGL_MatrixMode(DGL_MODELVIEW);
+ DGL_PopMatrix();
+ }
+}
+
+void MapName_Dimensions(uiwidget_t* obj, int* width, int *height)
+{
+ assert(NULL != obj && obj->type == GUI_MAPNAME);
+ {
+ const patchid_t patch = P_FindMapTitlePatch(gameEpisode, gameMap);
+ const char* text = Hu_ChoosePatchReplacement2(patch, P_GetMapNiceName(), false);
+ const float scale = .75f;
+ patchinfo_t info;
+
+ if(NULL != width) *width = 0;
+ if(NULL != height) *height = 0;
+
+ if(NULL == text && 0 == patch)
+ return;
+
+ if(NULL != text)
+ {
+ FR_TextDimensions(width, height, text, obj->fontId);
+ if(NULL != width) *width = *width * scale;
+ if(NULL != height) *height = *height * scale;
+ return;
+ }
+
+ R_GetPatchInfo(patch, &info);
+ if(NULL != width) *width = info.width * scale;
+ if(NULL != height) *height = info.height * scale;
+ }
+}
+
+typedef struct {
+ guiwidgettype_t type;
+ int group;
+ gamefontid_t fontIdx;
+ void (*updateDimensions) (uiwidget_t* obj);
+ void (*drawer) (uiwidget_t* obj, int x, int y);
+ void (*ticker) (uiwidget_t* obj, timespan_t ticLength);
+ void* typedata;
+} uiwidgetdef_t;
+
+typedef struct {
+ int group;
+ int alignFlags;
+ int groupFlags;
+ int padding; // In fixed 320x200 pixels.
+} uiwidgetgroupdef_t;
+
void ST_Drawer(int player)
{
hudstate_t* hud;
@@ -603,9 +698,7 @@ void ST_Drawer(int player)
hud = &hudStates[player];
hud->firstTime = hud->firstTime;
- hud->statusbarActive = (fullscreenMode < 2) || (AM_IsActive(AM_MapForPlayer(player)) && (cfg.automapHudDisplay == 0 || cfg.automapHudDisplay == 2));
- if(!hud->inited)
- hud->inited = true;
+ hud->statusbarActive = (fullscreenMode < 2) || (ST_AutomapIsActive(player) && (cfg.automapHudDisplay == 0 || cfg.automapHudDisplay == 2));
// Do palette shifts.
ST_doPaletteStuff(player);
@@ -635,19 +728,150 @@ static void initData(hudstate_t* hud)
ST_HUDUnHide(player, HUE_FORCE);
}
+static void findMapBounds(float* lowX, float* hiX, float* lowY, float* hiY)
+{
+ assert(NULL != lowX && NULL != hiX && NULL != lowY && NULL != hiY);
+ {
+ float pos[2];
+ uint i;
+
+ *lowX = *lowY = DDMAXFLOAT;
+ *hiX = *hiY = -DDMAXFLOAT;
+
+ for(i = 0; i < numvertexes; ++i)
+ {
+ P_GetFloatv(DMU_VERTEX, i, DMU_XY, pos);
+
+ if(pos[VX] < *lowX)
+ *lowX = pos[VX];
+ if(pos[VX] > *hiX)
+ *hiX = pos[VX];
+
+ if(pos[VY] < *lowY)
+ *lowY = pos[VY];
+ if(pos[VY] > *hiY)
+ *hiY = pos[VY];
+ }
+ }
+}
+
+static void setAutomapCheatLevel(uiwidget_t* obj, int level)
+{
+ assert(NULL != obj);
+ {
+ hudstate_t* hud = &hudStates[UIWidget_Player(obj)];
+ int flags;
+
+ hud->automapCheatLevel = level;
+
+ flags = UIAutomap_Flags(obj) & ~(AMF_REND_ALLLINES|AMF_REND_THINGS|AMF_REND_SPECIALLINES|AMF_REND_VERTEXES|AMF_REND_LINE_NORMALS);
+ if(hud->automapCheatLevel >= 1)
+ flags |= AMF_REND_ALLLINES;
+ if(hud->automapCheatLevel == 2)
+ flags |= AMF_REND_THINGS | AMF_REND_SPECIALLINES;
+ if(hud->automapCheatLevel > 2)
+ flags |= (AMF_REND_VERTEXES | AMF_REND_LINE_NORMALS);
+ UIAutomap_SetFlags(obj, flags);
+ }
+}
+
+static void initAutomapForCurrentMap(uiwidget_t* obj)
+{
+ assert(NULL != obj);
+ {
+ hudstate_t* hud = &hudStates[UIWidget_Player(obj)];
+ float lowX, hiX, lowY, hiY;
+ automapcfg_t* mcfg;
+
+ UIAutomap_Reset(obj);
+
+ findMapBounds(&lowX, &hiX, &lowY, &hiY);
+ UIAutomap_SetMinScale(obj, 2 * PLAYERRADIUS);
+ UIAutomap_SetWorldBounds(obj, lowX, hiX, lowY, hiY);
+
+ mcfg = UIAutomap_Config(obj);
+
+ // Determine the obj view scale factors.
+ UIAutomap_SetScale(obj, UIAutomap_ZoomMax(obj)? 0 : .45f);
+ UIAutomap_ClearPoints(obj);
+
+#if !__JHEXEN__
+ if(gameSkill == SM_BABY && cfg.automapBabyKeys)
+ {
+ int flags = UIAutomap_Flags(obj);
+ UIAutomap_SetFlags(obj, flags|AMF_REND_KEYS);
+ }
+
+ if(!IS_NETGAME && hud->automapCheatLevel)
+ AM_SetVectorGraphic(mcfg, AMO_THINGPLAYER, VG_CHEATARROW);
+#endif
+
+ // Are we re-centering on a followed mobj?
+ { mobj_t* mo = UIAutomap_FollowMobj(obj);
+ if(NULL != mo)
+ {
+ UIAutomap_SetCameraOrigin(obj, mo->pos[VX], mo->pos[VY]);
+ }}
+
+ if(IS_NETGAME)
+ {
+ setAutomapCheatLevel(obj, 0);
+ }
+
+ UIAutomap_SetReveal(obj, false);
+
+ // Add all immediately visible lines.
+ { uint i;
+ for(i = 0; i < numlines; ++i)
+ {
+ xline_t* xline = &xlines[i];
+ if(!(xline->flags & ML_MAPPED)) continue;
+ P_SetLinedefAutomapVisibility(UIWidget_Player(obj), i, true);
+ }}
+ }
+}
+
void ST_Start(int player)
{
+ const int winWidth = Get(DD_WINDOW_WIDTH);
+ const int winHeight = Get(DD_WINDOW_HEIGHT);
+ uiwidget_t* obj;
hudstate_t* hud;
+ int flags;
if(player < 0 || player >= MAXPLAYERS)
- return;
-
+ {
+ Con_Error("ST_Start: Invalid player #%i.", player);
+ exit(1); // Unreachable.
+ }
hud = &hudStates[player];
if(!hud->stopped)
ST_Stop(player);
initData(hud);
+ // If the automap has been left open; close it.
+ ST_AutomapOpen(player, false, true);
+
+ /**
+ * Initialize widgets according to player preferences.
+ */
+
+ obj = GUI_MustFindObjectById(hud->widgetGroupIds[UWG_TOP]);
+ flags = UIWidget_Alignment(obj);
+ flags &= ~(ALIGN_LEFT|ALIGN_RIGHT);
+ if(cfg.msgAlign == 0)
+ flags |= ALIGN_LEFT;
+ else if(cfg.msgAlign == 2)
+ flags |= ALIGN_RIGHT;
+ UIWidget_SetAlignment(obj, flags);
+
+ obj = GUI_MustFindObjectById(hud->automapWidgetId);
+ initAutomapForCurrentMap(obj);
+ UIAutomap_SetScale(obj, 1);
+ UIAutomap_SetCameraRotation(obj, cfg.automapRotate);
+ UIAutomap_SetOrigin(obj, 0, 0);
+ UIAutomap_SetDimensions(obj, winWidth, winHeight);
hud->stopped = false;
}
@@ -666,17 +890,42 @@ void ST_Stop(int player)
hud->stopped = true;
}
+void ST_BuildWidgets(int player)
+{
+ assert(player >= 0 && player < MAXPLAYERS);
+ {
+#define PADDING 2 // In fixed 320x200 units.
+
+ hudstate_t* hud = &hudStates[player];
+ const uiwidgetgroupdef_t widgetGroupDefs[] = {
+ { UWG_MAPNAME, ALIGN_BOTTOMLEFT },
+ { UWG_AUTOMAP, ALIGN_TOPLEFT }
+ };
+ size_t i;
+
+ for(i = 0; i < sizeof(widgetGroupDefs)/sizeof(widgetGroupDefs[0]); ++i)
+ {
+ const uiwidgetgroupdef_t* def = &widgetGroupDefs[i];
+ hud->widgetGroupIds[def->group] = GUI_CreateGroup(player, def->groupFlags, def->alignFlags, def->padding);
+ }
+
+ hud->automapWidgetId = GUI_CreateWidget(GUI_AUTOMAP, player, FID(GF_FONTB), UIAutomap_UpdateDimensions, UIAutomap_Drawer, UIAutomap_Ticker, &hud->automap);
+ UIGroup_AddWidget(GUI_MustFindObjectById(hud->widgetGroupIds[UWG_AUTOMAP]), GUI_FindObjectById(hud->automapWidgetId));
+
+#undef PADDING
+ }
+}
+
void ST_Init(void)
{
int i;
+ ST_InitAutomapConfig();
for(i = 0; i < MAXPLAYERS; ++i)
{
hudstate_t* hud = &hudStates[i];
- //memset(hud->widgetGroupIds, -1, sizeof(hud->widgetGroupIds));
- hud->chatWidgetId = -1;
- hud->logWidgetId = -1;
+ ST_BuildWidgets(i);
+ hud->inited = true;
}
-
ST_loadData();
}
@@ -712,14 +961,15 @@ uiwidget_t* ST_UILogForPlayer(int player)
exit(1); // Unreachable.
}
-boolean ST_ChatIsActive(int player)
-{
- uiwidget_t* obj = ST_UIChatForPlayer(player);
- if(NULL != obj)
+uiwidget_t* ST_UIAutomapForPlayer(int player)
+{
+ if(player >= 0 && player < MAXPLAYERS)
{
- return UIChat_IsActive(obj);
+ hudstate_t* hud = &hudStates[player];
+ return GUI_FindObjectById(hud->automapWidgetId);
}
- return false;
+ Con_Error("ST_UIAutomapForPlayer: Invalid player #%i.", player);
+ exit(1); // Unreachable.
}
int ST_ChatResponder(int player, event_t* ev)
@@ -732,6 +982,16 @@ int ST_ChatResponder(int player, event_t* ev)
return false;
}
+boolean ST_ChatIsActive(int player)
+{
+ uiwidget_t* obj = ST_UIChatForPlayer(player);
+ if(NULL != obj)
+ {
+ return UIChat_IsActive(obj);
+ }
+ return false;
+}
+
void ST_LogPost(int player, byte flags, const char* msg)
{
uiwidget_t* obj = ST_UILogForPlayer(player);
@@ -785,6 +1045,173 @@ void ST_LogUpdateAlignment(void)
#endif
}
+void ST_AutomapOpen(int player, boolean yes, boolean fast)
+{
+ uiwidget_t* obj = ST_UIAutomapForPlayer(player);
+ if(NULL == obj) return;
+ UIAutomap_Open(obj, yes, fast);
+}
+
+boolean ST_AutomapIsActive(int player)
+{
+ uiwidget_t* obj = ST_UIAutomapForPlayer(player);
+ if(NULL == obj) return false;
+ return UIAutomap_Active(obj);
+}
+
+boolean ST_AutomapWindowObscures2(int player, const rectanglei_t* region)
+{
+ uiwidget_t* obj = ST_UIAutomapForPlayer(player);
+ if(NULL == obj) return false;
+ if(UIAutomap_Active(obj))
+ {
+ if(cfg.automapOpacity * ST_AutomapOpacity(player) >= ST_AUTOMAP_OBSCURE_TOLERANCE)
+ {
+ /*if(UIAutomap_Fullscreen(obj))
+ {*/
+ return true;
+ /*}
+ else
+ {
+ // We'll have to compare the dimensions.
+ const int scrwidth = Get(DD_WINDOW_WIDTH);
+ const int scrheight = Get(DD_WINDOW_HEIGHT);
+ const rectanglei_t* dims = UIWidget_Dimensions(obj);
+ float fx = FIXXTOSCREENX(region->x);
+ float fy = FIXYTOSCREENY(region->y);
+ float fw = FIXXTOSCREENX(region->width);
+ float fh = FIXYTOSCREENY(region->height);
+
+ if(dims->x >= fx && dims->y >= fy && dims->width >= fw && dims->height >= fh)
+ return true;
+ }*/
+ }
+ }
+ return false;
+}
+
+boolean ST_AutomapWindowObscures(int player, int x, int y, int width, int height)
+{
+ rectanglei_t rect;
+ rect.x = x;
+ rect.y = y;
+ rect.width = width;
+ rect.height = height;
+ return ST_AutomapWindowObscures2(player, &rect);
+}
+
+void ST_AutomapClearPoints(int player)
+{
+ uiwidget_t* obj = ST_UIAutomapForPlayer(player);
+ if(NULL == obj) return;
+ UIAutomap_ClearPoints(obj);
+}
+
+/**
+ * Adds a marker at the specified X/Y location.
+ */
+int ST_AutomapAddPoint(int player, float x, float y, float z)
+{
+ static char buffer[20];
+ uiwidget_t* obj = ST_UIAutomapForPlayer(player);
+ int newPoint;
+ if(NULL == obj) return - 1;
+
+ if(UIAutomap_PointCount(obj) == MAX_MAP_POINTS)
+ return -1;
+
+ newPoint = UIAutomap_AddPoint(obj, x, y, z);
+ sprintf(buffer, "%s %d", AMSTR_MARKEDSPOT, newPoint);
+ P_SetMessage(&players[player], buffer, false);
+
+ return newPoint;
+}
+
+boolean ST_AutomapPointOrigin(int player, int point, float* x, float* y, float* z)
+{
+ uiwidget_t* obj = ST_UIAutomapForPlayer(player);
+ if(NULL == obj) return false;
+ return UIAutomap_PointOrigin(obj, point, x, y, z);
+}
+
+void ST_ToggleAutomapMaxZoom(int player)
+{
+ uiwidget_t* obj = ST_UIAutomapForPlayer(player);
+ if(NULL == obj) return;
+ if(UIAutomap_SetZoomMax(obj, !UIAutomap_ZoomMax(obj)))
+ {
+ Con_Printf("Maximum zoom %s in automap.\n", UIAutomap_ZoomMax(obj)? "ON":"OFF");
+ }
+}
+
+float ST_AutomapOpacity(int player)
+{
+ uiwidget_t* obj = ST_UIAutomapForPlayer(player);
+ if(NULL == obj) return 0;
+ return UIAutomap_Opacity(obj);
+}
+
+void ST_SetAutomapCameraRotation(int player, boolean on)
+{
+ uiwidget_t* obj = ST_UIAutomapForPlayer(player);
+ if(NULL == obj) return;
+ UIAutomap_SetCameraRotation(obj, on);
+}
+
+void ST_ToggleAutomapPanMode(int player)
+{
+ uiwidget_t* obj = ST_UIAutomapForPlayer(player);
+ if(NULL == obj) return;
+ if(UIAutomap_SetPanMode(obj, !UIAutomap_PanMode(obj)))
+ {
+ P_SetMessage(&players[player], (UIAutomap_PanMode(obj)? AMSTR_FOLLOWON : AMSTR_FOLLOWOFF), true);
+ }
+}
+
+void ST_CycleAutomapCheatLevel(int player)
+{
+ if(player >= 0 && player < MAXPLAYERS)
+ {
+ hudstate_t* hud = &hudStates[player];
+ ST_SetAutomapCheatLevel(player, (hud->automapCheatLevel + 1) % 3);
+ }
+}
+
+void ST_SetAutomapCheatLevel(int player, int level)
+{
+ uiwidget_t* obj = ST_UIAutomapForPlayer(player);
+ if(NULL == obj) return;
+ setAutomapCheatLevel(obj, level);
+}
+
+void ST_RevealAutomap(int player, boolean on)
+{
+ uiwidget_t* obj = ST_UIAutomapForPlayer(player);
+ if(NULL == obj) return;
+ UIAutomap_SetReveal(obj, on);
+}
+
+boolean ST_AutomapHasReveal(int player)
+{
+ uiwidget_t* obj = ST_UIAutomapForPlayer(player);
+ if(NULL == obj) return false;
+ return UIAutomap_Reveal(obj);
+}
+
+void ST_RebuildAutomap(int player)
+{
+ uiwidget_t* obj = ST_UIAutomapForPlayer(player);
+ if(NULL == obj) return;
+ UIAutomap_Rebuild(obj);
+}
+
+int ST_AutomapCheatLevel(int player)
+{
+ if(player >=0 && player < MAXPLAYERS)
+ return hudStates[player].automapCheatLevel;
+ return 0;
+}
+
/**
* Called when a cvar changes that affects the look/behavior of the HUD in order to unhide it.
*/