This commit is contained in:
oy 2018-11-23 19:33:00 +01:00
commit 43b8bac9ac
9 changed files with 218 additions and 18 deletions

View file

@ -44,12 +44,23 @@ void CMapLayers::LoadBackgroundMap()
int HourOfTheDay = time_houroftheday();
char aBuf[128];
str_format(aBuf, sizeof(aBuf), "ui/%s_%s.map", g_Config.m_ClMenuMap, (HourOfTheDay >= 6 && HourOfTheDay < 18) ? "day" : "night");
// check for the appropriate day/night map
str_format(aBuf, sizeof(aBuf), "ui/themes/%s_%s.map", g_Config.m_ClMenuMap, (HourOfTheDay >= 6 && HourOfTheDay < 18) ? "day" : "night");
if(!m_pMenuMap->Load(aBuf, m_pClient->Storage()))
{
str_format(aBuf, sizeof(aBuf), "map '%s' not found", g_Config.m_ClMenuMap);
Console()->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "client", aBuf);
return;
// fall back on generic map
str_format(aBuf, sizeof(aBuf), "ui/themes/%s.map", g_Config.m_ClMenuMap);
if(!m_pMenuMap->Load(aBuf, m_pClient->Storage()))
{
// fall back on day/night alternative map
str_format(aBuf, sizeof(aBuf), "ui/themes/%s_%s.map", g_Config.m_ClMenuMap, (HourOfTheDay >= 6 && HourOfTheDay < 18) ? "night" : "day");
if(!m_pMenuMap->Load(aBuf, m_pClient->Storage()))
{
str_format(aBuf, sizeof(aBuf), "map '%s' not found", g_Config.m_ClMenuMap);
Console()->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "client", aBuf);
return;
}
}
}
str_format(aBuf, sizeof(aBuf), "loaded map '%s'", g_Config.m_ClMenuMap);

View file

@ -21,8 +21,8 @@ class CMapLayers : public CComponent
static void EnvelopeEval(float TimeOffset, int Env, float *pChannels, void *pUser);
void LoadBackgroundMap();
void LoadEnvPoints(const CLayers *pLayers, array<CEnvPoint>& lEnvPoints);
void LoadBackgroundMap();
public:
enum

View file

@ -202,6 +202,24 @@ private:
const CMenuImage *FindMenuImage(const char* pName);
// themes
class CTheme
{
public:
CTheme() {}
CTheme(const char *n, bool HasDay, bool HasNight) : m_Name(n), m_HasDay(HasDay), m_HasNight(HasNight) {}
string m_Name;
bool m_HasDay;
bool m_HasNight;
IGraphics::CTextureHandle m_IconTexture;
bool operator<(const CTheme &Other) { return m_Name < Other.m_Name; }
};
sorted_array<CTheme> m_lThemes;
static int ThemeScan(const char *pName, int IsDir, int DirType, void *pUser);
static int ThemeIconScan(const char *pName, int IsDir, int DirType, void *pUser);
int64 m_LastInput;
// loading
@ -511,6 +529,7 @@ private:
// found in menus_settings.cpp
void RenderLanguageSelection(CUIRect MainView, bool Header=true);
void RenderThemeSelection(CUIRect MainView, bool Header=true);
void RenderHSLPicker(CUIRect Picker);
void RenderSkinSelection(CUIRect MainView);
void RenderSkinPartSelection(CUIRect MainView);

View file

@ -566,6 +566,90 @@ public:
bool operator<(const CLanguage &Other) { return m_Name < Other.m_Name; }
};
int CMenus::ThemeScan(const char *pName, int IsDir, int DirType, void *pUser)
{
CMenus *pSelf = (CMenus *)pUser;
int l = str_length(pName);
if(l < 5 || IsDir || str_comp(pName+l-4, ".map") != 0)
return 0;
char aFullName[128];
char aThemeName[128];
str_copy(aFullName, pName, min((int)sizeof(aFullName),l-3));
l = str_length(aFullName);
bool isDay = false;
bool isNight = false;
if(l > 4 && str_comp(aFullName+l-4, "_day") == 0)
{
str_copy(aThemeName, pName, min((int)sizeof(aThemeName),l-3));
isDay = true;
}
else if(l > 6 && str_comp(aFullName+l-6, "_night") == 0)
{
str_copy(aThemeName, pName, min((int)sizeof(aThemeName),l-5));
isNight = true;
}
else
str_copy(aThemeName, aFullName, sizeof(aThemeName));
// try to edit an existing theme
for(int i = 0; i < pSelf->m_lThemes.size(); i++)
{
if(str_comp(pSelf->m_lThemes[i].m_Name, aThemeName) == 0)
{
if(isDay)
pSelf->m_lThemes[i].m_HasDay = true;
if(isNight)
pSelf->m_lThemes[i].m_HasNight = true;
return 0;
}
}
// make new theme
CTheme Theme(aThemeName, isDay, isNight);
char aBuf[512];
str_format(aBuf, sizeof(aBuf), "added theme %s from ui/themes/%s", aThemeName, pName);
pSelf->Console()->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "game", aBuf);
pSelf->m_lThemes.add(Theme);
return 0;
}
int CMenus::ThemeIconScan(const char *pName, int IsDir, int DirType, void *pUser)
{
CMenus *pSelf = (CMenus *)pUser;
int l = str_length(pName);
if(l < 4 || IsDir || str_comp(pName+l-4, ".png") != 0)
return 0;
char aThemeName[128];
str_copy(aThemeName, pName, min((int)sizeof(aThemeName),l-3));
// save icon for an existing theme
for(sorted_array<CTheme>::range r = pSelf->m_lThemes.all(); !r.empty(); r.pop_front()) // bit slow but whatever
{
if(str_comp(r.front().m_Name, aThemeName) == 0)
{
char aBuf[512];
str_format(aBuf, sizeof(aBuf), "ui/themes/%s", pName);
CImageInfo Info;
if(!pSelf->Graphics()->LoadPNG(&Info, aBuf, DirType))
{
str_format(aBuf, sizeof(aBuf), "failed to load theme icon from %s", pName);
pSelf->Console()->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "game", aBuf);
return 0;
}
str_format(aBuf, sizeof(aBuf), "loaded theme icon %s", pName);
pSelf->Console()->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "game", aBuf);
r.front().m_IconTexture = pSelf->Graphics()->LoadTextureRaw(Info.m_Width, Info.m_Height, Info.m_Format, Info.m_pData, Info.m_Format, 0);
return 0;
}
}
return 0; // no existing theme
}
void LoadLanguageIndexfile(IStorage *pStorage, IConsole *pConsole, sorted_array<CLanguage> *pLanguages)
{
// read file data into buffer
@ -670,6 +754,96 @@ void CMenus::RenderLanguageSelection(CUIRect MainView, bool Header)
}
}
void CMenus::RenderThemeSelection(CUIRect MainView, bool Header)
{
static int s_ThemeList = 0;
static int s_SelectedTheme = 0;
static CListBoxState s_ListBoxState_Theme;
if(m_lThemes.size() == 0) // not loaded yet
{
m_lThemes.add(CTheme("", false, false)); // no theme
Storage()->ListDirectory(IStorage::TYPE_ALL, "ui/themes", ThemeScan, (CMenus*)this);
Storage()->ListDirectory(IStorage::TYPE_ALL, "ui/themes", ThemeIconScan, (CMenus*)this);
for(int i = 0; i < m_lThemes.size(); i++)
if(str_comp(m_lThemes[i].m_Name, g_Config.m_ClMenuMap) == 0)
{
s_SelectedTheme = i;
break;
}
}
int OldSelected = s_SelectedTheme;
if(Header)
UiDoListboxHeader(&s_ListBoxState_Theme, &MainView, Localize("Theme"), 20.0f, 2.0f);
UiDoListboxStart(&s_ListBoxState_Theme, &s_ThemeList, 20.0f, 0, m_lThemes.size(), 1, s_SelectedTheme, Header?0:&MainView, Header?true:false);
for(sorted_array<CTheme>::range r = m_lThemes.all(); !r.empty(); r.pop_front())
{
CListboxItem Item = UiDoListboxNextItem(&s_ListBoxState_Theme, &r.front());
if(Item.m_Visible)
{
CUIRect Rect;
Item.m_Rect.VSplitLeft(Item.m_Rect.h*2.0f, &Rect, &Item.m_Rect);
Rect.VMargin(6.0f, &Rect);
Rect.HMargin(3.0f, &Rect);
vec4 Color(1.0f, 1.0f, 1.0f, 1.0f);
// draw icon if it exists
if(r.front().m_IconTexture.IsValid())
{
Graphics()->TextureSet(r.front().m_IconTexture);
Graphics()->QuadsBegin();
Graphics()->SetColor(1.0f, 1.0f, 1.0f, 1.0f);
IGraphics::CQuadItem QuadItem(Rect.x, Rect.y, Rect.w, Rect.h);
Graphics()->QuadsDrawTL(&QuadItem, 1);
Graphics()->QuadsEnd();
}
Item.m_Rect.y += 2.0f;
char aName[128];
if(r.front().m_Name[0])
{
if(r.front().m_HasDay && r.front().m_HasNight)
str_format(aName, sizeof(aName), "%s", r.front().m_Name.cstr());
else if(r.front().m_HasDay && !r.front().m_HasNight)
str_format(aName, sizeof(aName), "%s (day)", r.front().m_Name.cstr());
else if(!r.front().m_HasDay && r.front().m_HasNight)
str_format(aName, sizeof(aName), "%s (night)", r.front().m_Name.cstr());
else // generic
str_format(aName, sizeof(aName), "%s", r.front().m_Name.cstr());
}
else
str_copy(aName, "(none)", sizeof(aName));
if(!str_comp(m_lThemes[s_SelectedTheme].m_Name, r.front().m_Name))
{
TextRender()->TextColor(0.0f, 0.0f, 0.0f, 1.0f);
TextRender()->TextOutlineColor(1.0f, 1.0f, 1.0f, 0.25f);
UI()->DoLabelScaled(&Item.m_Rect, aName, Item.m_Rect.h*ms_FontmodHeight*0.8f, CUI::ALIGN_LEFT);
TextRender()->TextColor(1.0f, 1.0f, 1.0f, 1.0f);
TextRender()->TextOutlineColor(0.0f, 0.0f, 0.0f, 0.3f);
}
else
UI()->DoLabelScaled(&Item.m_Rect, aName, Item.m_Rect.h*ms_FontmodHeight*0.8f, CUI::ALIGN_LEFT);
}
}
s_SelectedTheme = UiDoListboxEnd(&s_ListBoxState_Theme, 0);
if(OldSelected != s_SelectedTheme)
{
str_copy(g_Config.m_ClMenuMap, m_lThemes[s_SelectedTheme].m_Name, sizeof(g_Config.m_ClMenuMap));
if(m_lThemes[s_SelectedTheme].m_Name[0])
g_Config.m_ClShowMenuMap = 1;
else
g_Config.m_ClShowMenuMap = 0;
m_pClient->m_pMapLayersBackGround->BackgroundMapUpdate();
}
}
void CMenus::RenderSettingsGeneral(CUIRect MainView)
{
CUIRect Label, Button, Game, Client, BottomView;
@ -690,7 +864,7 @@ void CMenus::RenderSettingsGeneral(CUIRect MainView)
RenderTools()->DrawUIRect(&Game, vec4(0.0f, 0.0f, 0.0f, 0.25f), CUI::CORNER_ALL, 5.0f);
// render client menu background
NumOptions = 4;
NumOptions = 3;
if(g_Config.m_ClAutoDemoRecord) NumOptions += 1;
if(g_Config.m_ClAutoScreenshot) NumOptions += 1;
BackgroundHeight = (float)(NumOptions+1)*ButtonHeight+(float)NumOptions*Spacing;
@ -819,15 +993,6 @@ void CMenus::RenderSettingsGeneral(CUIRect MainView)
if(DoButton_CheckBox(&s_SkipMainMenu, Localize("Skip the main menu"), g_Config.m_ClSkipStartMenu, &Button))
g_Config.m_ClSkipStartMenu ^= 1;
Client.HSplitTop(Spacing, 0, &Client);
Client.HSplitTop(ButtonHeight, &Button, &Client);
static int s_DisplayAnimatedBackgrounds = 0;
if(DoButton_CheckBox(&s_DisplayAnimatedBackgrounds, Localize("Display animated backgrounds"), g_Config.m_ClShowMenuMap, &Button))
{
g_Config.m_ClShowMenuMap ^= 1;
m_pClient->m_pMapLayersBackGround->BackgroundMapUpdate();
}
Client.HSplitTop(Spacing, 0, &Client);
Client.HSplitTop(ButtonHeight, &Button, &Client);
static int s_AutoDemoRecord = 0;
@ -858,8 +1023,13 @@ void CMenus::RenderSettingsGeneral(CUIRect MainView)
MainView.HSplitTop(10.0f, 0, &MainView);
// render language selection
RenderLanguageSelection(MainView);
// render language and theme selection
CUIRect LanguageView, ThemeView;
MainView.VSplitMid(&LanguageView, &ThemeView);
LanguageView.VSplitRight(1, &LanguageView, 0);
ThemeView.VSplitLeft(1, 0, &ThemeView);
RenderLanguageSelection(LanguageView);
RenderThemeSelection(ThemeView);
// reset button
Spacing = 3.0f;

View file

@ -84,7 +84,7 @@ MACRO_CONFIG_INT(UiAutoswitchInfotab, ui_autoswitch_infotab, 1, 0, 1, CFGFLAG_SA
MACRO_CONFIG_INT(GfxNoclip, gfx_noclip, 0, 0, 1, CFGFLAG_CLIENT|CFGFLAG_SAVE, "Disable clipping")
MACRO_CONFIG_STR(ClMenuMap, cl_menu_map, 64, "menu", CFGFLAG_CLIENT|CFGFLAG_SAVE, "Background map in the menu")
MACRO_CONFIG_STR(ClMenuMap, cl_menu_map, 64, "jungle", CFGFLAG_CLIENT|CFGFLAG_SAVE, "Background map in the menu")
MACRO_CONFIG_INT(ClShowMenuMap, cl_show_menu_map, 1, 0, 1, CFGFLAG_CLIENT|CFGFLAG_SAVE, "Display background map in the menu")
MACRO_CONFIG_INT(ClRotationRadius, cl_rotation_radius, 30, 1, 500, CFGFLAG_CLIENT|CFGFLAG_SAVE, "Camera rotation radius")
MACRO_CONFIG_INT(ClRotationSpeed, cl_rotation_speed, 40, 1, 120, CFGFLAG_CLIENT|CFGFLAG_SAVE, "Camera rotations in seconds")