diff --git a/src/engine/shared/config_variables.h b/src/engine/shared/config_variables.h index e5a13a3f9..61c566805 100644 --- a/src/engine/shared/config_variables.h +++ b/src/engine/shared/config_variables.h @@ -322,7 +322,6 @@ MACRO_CONFIG_INT(ClShowOthers, cl_show_others, 0, 0, 2, CFGFLAG_CLIENT | CFGFLAG MACRO_CONFIG_INT(ClShowOthersAlpha, cl_show_others_alpha, 40, 0, 100, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Show players in other teams (alpha value, 0 invisible, 100 fully visible)") MACRO_CONFIG_INT(ClOverlayEntities, cl_overlay_entities, 0, 0, 100, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Overlay game tiles with a percentage of opacity") MACRO_CONFIG_INT(ClShowQuads, cl_showquads, 1, 0, 1, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Show quads (only interesting for mappers, or if your system has extremely bad performance)") -MACRO_CONFIG_INT(ClZoomBackgroundLayers, cl_zoom_background_layers, 0, 0, 1, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Zoom background layers") MACRO_CONFIG_COL(ClBackgroundColor, cl_background_color, 128, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Background color") // 0 0 128 MACRO_CONFIG_COL(ClBackgroundEntitiesColor, cl_background_entities_color, 128, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Background (entities) color") // 0 0 128 MACRO_CONFIG_STR(ClBackgroundEntities, cl_background_entities, 100, "", CFGFLAG_CLIENT | CFGFLAG_SAVE, "Background (entities)") diff --git a/src/game/client/components/hud.cpp b/src/game/client/components/hud.cpp index 7dcbf7e95..a02e11365 100644 --- a/src/game/client/components/hud.cpp +++ b/src/game/client/components/hud.cpp @@ -621,7 +621,7 @@ void CHud::RenderCursor() if(!m_pClient->m_Snap.m_pLocalCharacter || Client()->State() == IClient::STATE_DEMOPLAYBACK) return; - RenderTools()->MapScreenToGroup(m_pClient->m_Camera.m_Center.x, m_pClient->m_Camera.m_Center.y, Layers()->GameGroup()); + RenderTools()->MapScreenToInterface(m_pClient->m_Camera.m_Center.x, m_pClient->m_Camera.m_Center.y); // render cursor int CurWeapon = m_pClient->m_Snap.m_pLocalCharacter->m_Weapon % NUM_WEAPONS; diff --git a/src/game/client/components/maplayers.cpp b/src/game/client/components/maplayers.cpp index 6c21603af..f54834742 100644 --- a/src/game/client/components/maplayers.cpp +++ b/src/game/client/components/maplayers.cpp @@ -1592,12 +1592,7 @@ void CMapLayers::OnRender() (int)((x1 - x0) * Graphics()->ScreenWidth()), (int)((y1 - y0) * Graphics()->ScreenHeight())); } - if((!g_Config.m_ClZoomBackgroundLayers || m_Type == TYPE_FULL_DESIGN) && !pGroup->m_ParallaxX && !pGroup->m_ParallaxY) - { - RenderTools()->MapScreenToGroup(Center.x, Center.y, pGroup, 1.0f); - } - else - RenderTools()->MapScreenToGroup(Center.x, Center.y, pGroup, GetCurCamera()->m_Zoom); + RenderTools()->MapScreenToGroup(Center.x, Center.y, pGroup, GetCurCamera()->m_Zoom); for(int l = 0; l < pGroup->m_NumLayers; l++) { diff --git a/src/game/client/components/nameplates.cpp b/src/game/client/components/nameplates.cpp index 60c42a642..0519ab641 100644 --- a/src/game/client/components/nameplates.cpp +++ b/src/game/client/components/nameplates.cpp @@ -101,7 +101,7 @@ void CNamePlates::RenderNameplatePos(vec2 Position, const CNetObj_PlayerInfo *pP // create nameplates at standard zoom float ScreenX0, ScreenY0, ScreenX1, ScreenY1; Graphics()->GetScreen(&ScreenX0, &ScreenY0, &ScreenX1, &ScreenY1); - RenderTools()->MapScreenToGroup(m_pClient->m_Camera.m_Center.x, m_pClient->m_Camera.m_Center.y, Layers()->GameGroup()); + RenderTools()->MapScreenToInterface(m_pClient->m_Camera.m_Center.x, m_pClient->m_Camera.m_Center.y); m_aNamePlates[ClientID].m_NameTextWidth = TextRender()->TextWidth(0, FontSize, pName, -1, -1.0f); @@ -126,7 +126,7 @@ void CNamePlates::RenderNameplatePos(vec2 Position, const CNetObj_PlayerInfo *pP // create nameplates at standard zoom float ScreenX0, ScreenY0, ScreenX1, ScreenY1; Graphics()->GetScreen(&ScreenX0, &ScreenY0, &ScreenX1, &ScreenY1); - RenderTools()->MapScreenToGroup(m_pClient->m_Camera.m_Center.x, m_pClient->m_Camera.m_Center.y, Layers()->GameGroup()); + RenderTools()->MapScreenToInterface(m_pClient->m_Camera.m_Center.x, m_pClient->m_Camera.m_Center.y); m_aNamePlates[ClientID].m_ClanNameTextWidth = TextRender()->TextWidth(0, FontSizeClan, pClan, -1, -1.0f); diff --git a/src/game/client/render.cpp b/src/game/client/render.cpp index 825e7bbc0..6d0a1deeb 100644 --- a/src/game/client/render.cpp +++ b/src/game/client/render.cpp @@ -783,10 +783,15 @@ void CRenderTools::CalcScreenParams(float Aspect, float Zoom, float *pWidth, flo } void CRenderTools::MapScreenToWorld(float CenterX, float CenterY, float ParallaxX, float ParallaxY, - float OffsetX, float OffsetY, float Aspect, float Zoom, float *pPoints) + float ParallaxZoom, float OffsetX, float OffsetY, float Aspect, float Zoom, float *pPoints) { float Width, Height; CalcScreenParams(Aspect, Zoom, &Width, &Height); + + float Scale = (ParallaxZoom * (Zoom - 1.0f) + 100.0f) / 100.0f / Zoom; + Width *= Scale; + Height *= Scale; + CenterX *= ParallaxX / 100.0f; CenterY *= ParallaxY / 100.0f; pPoints[0] = OffsetX + CenterX - Width / 2; @@ -798,7 +803,15 @@ void CRenderTools::MapScreenToWorld(float CenterX, float CenterY, float Parallax void CRenderTools::MapScreenToGroup(float CenterX, float CenterY, CMapItemGroup *pGroup, float Zoom) { float aPoints[4]; - MapScreenToWorld(CenterX, CenterY, pGroup->m_ParallaxX, pGroup->m_ParallaxY, + MapScreenToWorld(CenterX, CenterY, pGroup->m_ParallaxX, pGroup->m_ParallaxY, pGroup->GetParallaxZoom(), pGroup->m_OffsetX, pGroup->m_OffsetY, Graphics()->ScreenAspect(), Zoom, aPoints); Graphics()->MapScreen(aPoints[0], aPoints[1], aPoints[2], aPoints[3]); } + +void CRenderTools::MapScreenToInterface(float CenterX, float CenterY) +{ + float aPoints[4]; + MapScreenToWorld(CenterX, CenterY, 100.0f, 100.0f, 100.0f, + 0, 0, Graphics()->ScreenAspect(), 1.0f, aPoints); + Graphics()->MapScreen(aPoints[0], aPoints[1], aPoints[2], aPoints[3]); +} diff --git a/src/game/client/render.h b/src/game/client/render.h index bc63d031b..2675a4187 100644 --- a/src/game/client/render.h +++ b/src/game/client/render.h @@ -142,8 +142,9 @@ public: // helpers void CalcScreenParams(float Aspect, float Zoom, float *pWidth, float *pHeight); void MapScreenToWorld(float CenterX, float CenterY, float ParallaxX, float ParallaxY, - float OffsetX, float OffsetY, float Aspect, float Zoom, float *pPoints); - void MapScreenToGroup(float CenterX, float CenterY, CMapItemGroup *pGroup, float Zoom = 1.0f); + float ParallaxZoom, float OffsetX, float OffsetY, float Aspect, float Zoom, float *pPoints); + void MapScreenToGroup(float CenterX, float CenterY, CMapItemGroup *pGroup, float Zoom); + void MapScreenToInterface(float CenterX, float CenterY); // DDRace diff --git a/src/game/editor/editor.cpp b/src/game/editor/editor.cpp index ac556a6ab..cf0bf744b 100644 --- a/src/game/editor/editor.cpp +++ b/src/game/editor/editor.cpp @@ -102,6 +102,7 @@ CLayerGroup::CLayerGroup() m_OffsetY = 0; m_ParallaxX = 100; m_ParallaxY = 100; + m_ParallaxZoom = 100; m_UseClipping = 0; m_ClipX = 0; @@ -133,7 +134,7 @@ void CLayerGroup::Mapping(float *pPoints) { m_pMap->m_pEditor->RenderTools()->MapScreenToWorld( m_pMap->m_pEditor->m_WorldOffsetX, m_pMap->m_pEditor->m_WorldOffsetY, - m_ParallaxX, m_ParallaxY, m_OffsetX, m_OffsetY, + m_ParallaxX, m_ParallaxY, 100.0f, m_OffsetX, m_OffsetY, m_pMap->m_pEditor->Graphics()->ScreenAspect(), m_pMap->m_pEditor->m_WorldZoom, pPoints); pPoints[0] += m_pMap->m_pEditor->m_EditorOffsetX; @@ -2870,7 +2871,7 @@ void CEditor::DoMapEditor(CUIRect View) RenderTools()->MapScreenToWorld( m_WorldOffsetX, m_WorldOffsetY, - 100.0f, 100.0f, 0.0f, 0.0f, Aspect, 1.0f, aPoints); + 100.0f, 100.0f, 100.0f, 0.0f, 0.0f, Aspect, 1.0f, aPoints); if(i == 0) { @@ -2912,7 +2913,7 @@ void CEditor::DoMapEditor(CUIRect View) RenderTools()->MapScreenToWorld( m_WorldOffsetX, m_WorldOffsetY, - 100.0f, 100.0f, 0.0f, 0.0f, Aspect, 1.0f, aPoints); + 100.0f, 100.0f, 100.0f, 0.0f, 0.0f, Aspect, 1.0f, aPoints); CUIRect r; r.x = aPoints[0]; @@ -6118,7 +6119,7 @@ void CEditor::ZoomMouseTarget(float ZoomFactor) float aPoints[4]; RenderTools()->MapScreenToWorld( m_WorldOffsetX, m_WorldOffsetY, - 100.0f, 100.0f, 0.0f, 0.0f, Graphics()->ScreenAspect(), m_WorldZoom, aPoints); + 100.0f, 100.0f, 100.0f, 0.0f, 0.0f, Graphics()->ScreenAspect(), m_WorldZoom, aPoints); float WorldWidth = aPoints[2] - aPoints[0]; float WorldHeight = aPoints[3] - aPoints[1]; @@ -6230,6 +6231,7 @@ void CEditorMap::CreateDefault(IGraphics::CTextureHandle EntitiesTexture) CLayerGroup *pGroup = NewGroup(); pGroup->m_ParallaxX = 0; pGroup->m_ParallaxY = 0; + pGroup->m_ParallaxZoom = 0; CLayerQuads *pLayer = new CLayerQuads; pLayer->m_pEditor = m_pEditor; CQuad *pQuad = pLayer->NewQuad(0, 0, 1600, 1200); diff --git a/src/game/editor/editor.h b/src/game/editor/editor.h index 0c0ec15af..b0244ba38 100644 --- a/src/game/editor/editor.h +++ b/src/game/editor/editor.h @@ -176,6 +176,7 @@ public: int m_ParallaxX; int m_ParallaxY; + int m_ParallaxZoom; int m_UseClipping; int m_ClipX; diff --git a/src/game/editor/io.cpp b/src/game/editor/io.cpp index 3b441fc28..5aeb82f9a 100644 --- a/src/game/editor/io.cpp +++ b/src/game/editor/io.cpp @@ -184,6 +184,8 @@ int CEditorMap::Save(class IStorage *pStorage, const char *pFileName) // save group name StrToInts(GItem.m_aName, sizeof(GItem.m_aName) / sizeof(int), pGroup->m_aName); + GItem.m_ParallaxZoom = pGroup->m_ParallaxZoom; + for(const auto &pLayer : pGroup->m_vpLayers) { if(pLayer->m_Type == LAYERTYPE_TILES) @@ -607,6 +609,8 @@ int CEditorMap::Load(class IStorage *pStorage, const char *pFileName, int Storag if(pGItem->m_Version >= 3) IntsToStr(pGItem->m_aName, sizeof(pGroup->m_aName) / sizeof(int), pGroup->m_aName); + pGroup->m_ParallaxZoom = pGItem->GetParallaxZoom(); + for(int l = 0; l < pGItem->m_NumLayers; l++) { CLayer *pLayer = nullptr; diff --git a/src/game/editor/popups.cpp b/src/game/editor/popups.cpp index 42648aab4..4b63412f8 100644 --- a/src/game/editor/popups.cpp +++ b/src/game/editor/popups.cpp @@ -320,6 +320,7 @@ int CEditor::PopupGroup(CEditor *pEditor, CUIRect View, void *pContext) PROP_POS_Y, PROP_PARA_X, PROP_PARA_Y, + PROP_PARA_ZOOM, PROP_USE_CLIPPING, PROP_CLIP_X, PROP_CLIP_Y, @@ -334,6 +335,7 @@ int CEditor::PopupGroup(CEditor *pEditor, CUIRect View, void *pContext) {"Pos Y", -pEditor->m_Map.m_vpGroups[pEditor->m_SelectedGroup]->m_OffsetY, PROPTYPE_INT_SCROLL, -1000000, 1000000}, {"Para X", pEditor->m_Map.m_vpGroups[pEditor->m_SelectedGroup]->m_ParallaxX, PROPTYPE_INT_SCROLL, -1000000, 1000000}, {"Para Y", pEditor->m_Map.m_vpGroups[pEditor->m_SelectedGroup]->m_ParallaxY, PROPTYPE_INT_SCROLL, -1000000, 1000000}, + {"Para Zoom", pEditor->m_Map.m_vpGroups[pEditor->m_SelectedGroup]->m_ParallaxZoom, PROPTYPE_INT_SCROLL, -1000000, 1000000}, {"Use Clipping", pEditor->m_Map.m_vpGroups[pEditor->m_SelectedGroup]->m_UseClipping, PROPTYPE_BOOL, 0, 1}, {"Clip X", pEditor->m_Map.m_vpGroups[pEditor->m_SelectedGroup]->m_ClipX, PROPTYPE_INT_SCROLL, -1000000, 1000000}, @@ -364,6 +366,8 @@ int CEditor::PopupGroup(CEditor *pEditor, CUIRect View, void *pContext) pEditor->m_Map.m_vpGroups[pEditor->m_SelectedGroup]->m_ParallaxX = NewVal; else if(Prop == PROP_PARA_Y) pEditor->m_Map.m_vpGroups[pEditor->m_SelectedGroup]->m_ParallaxY = NewVal; + else if(Prop == PROP_PARA_ZOOM) + pEditor->m_Map.m_vpGroups[pEditor->m_SelectedGroup]->m_ParallaxZoom = NewVal; else if(Prop == PROP_POS_X) pEditor->m_Map.m_vpGroups[pEditor->m_SelectedGroup]->m_OffsetX = -NewVal; else if(Prop == PROP_POS_Y) diff --git a/src/game/layers.cpp b/src/game/layers.cpp index ef28343a9..d4024777a 100644 --- a/src/game/layers.cpp +++ b/src/game/layers.cpp @@ -66,6 +66,8 @@ void CLayers::Init(class IKernel *pKernel) m_pGameGroup->m_ClipH = 0; } + if(m_pGameGroup->m_Version >= 4) + m_pGameGroup->m_ParallaxZoom = 100; //break; } if(pTilemap->m_Flags & TILESLAYERFLAG_TELE) @@ -158,6 +160,9 @@ void CLayers::InitBackground(class IMap *pMap) m_pGameGroup->m_ClipW = 0; m_pGameGroup->m_ClipH = 0; } + + if(m_pGameGroup->m_Version >= 4) + m_pGameGroup->m_ParallaxZoom = 100; //We don't care about tile layers. } } diff --git a/src/game/mapitems.h b/src/game/mapitems.h index 64ac181fe..664c59461 100644 --- a/src/game/mapitems.h +++ b/src/game/mapitems.h @@ -278,7 +278,7 @@ struct CMapItemGroup : public CMapItemGroup_v1 { enum { - CURRENT_VERSION = 3 + CURRENT_VERSION = 4 }; int m_UseClipping; @@ -288,6 +288,18 @@ struct CMapItemGroup : public CMapItemGroup_v1 int m_ClipH; int m_aName[3]; + + // ItemGroup's perceived distance from camera when zooming. Similar to how + // Parallax{X,Y} works when camera is moving along the X and Y axes, + // this setting applies to camera moving closer or away (zooming in or out). + int m_ParallaxZoom; + int GetParallaxZoom() const + { + if(m_Version >= 4) + return m_ParallaxZoom; + else + return maximum(m_ParallaxX, m_ParallaxY); + } }; struct CMapItemLayer