Add `ScrollRelative` function to initiate relative scrolling programmatically, to realise scroll regions that scroll when the mouse is being dragged at the edge.
Add `DoEdgeScrolling` to encapsulate all the necessary edge scrolling logic based on the position of the mouse. The edge scrolling starts at a fixed distance from the edges. The scrolling speed is dependent on the distance of the mouse from this border.
Remember the maximum animation time when initiating a smooth scroll, so the smooth scrolling does not change erratically when `ui_smooth_scroll_time` is changed while smooth scrolling is in progress.
According to cppchecker's `constParameter` error:
```
src\engine\gfx\image_manipulation.cpp:7:58: style: Parameter 'pSrc' can be declared as pointer to const [constParameter]
static void Dilate(int w, int h, int BPP, unsigned char *pSrc, unsigned char *pDest, unsigned char AlphaThreshold = TW_DILATE_ALPHA_THRESHOLD)
^
src\engine\gfx\image_manipulation.cpp:58:67: style: Parameter 'pSrc' can be declared as pointer to const [constParameter]
static void CopyColorValues(int w, int h, int BPP, unsigned char *pSrc, unsigned char *pDest)
^
src\engine\shared\network_conn.cpp:241:42: style: Parameter 'Addr' can be declared as reference to const [constParameter]
void CNetConnection::DirectInit(NETADDR &Addr, SECURITY_TOKEN SecurityToken, SECURITY_TOKEN Token, bool Sixup)
^
src\base\system.cpp:4060:71: style: Parameter 'random' can be declared as pointer to const [constParameter]
void generate_password(char *buffer, unsigned length, unsigned short *random, unsigned random_length)
^
src\engine\client\backend\vulkan\backend_vulkan.cpp:263:38: style: Parameter 'AllocatedMemory' can be declared as reference to const [constParameter]
void Free(SMemoryHeapQueueElement &AllocatedMemory)
^
src\engine\client\backend\vulkan\backend_vulkan.cpp:1708:47: style: Parameter 'ImgExtent' can be declared as reference to const [constParameter]
static size_t ImageMipLevelCount(VkExtent3D &ImgExtent)
^
src\engine\client\backend\vulkan\backend_vulkan.cpp:2801:29: style: Parameter 'Image' can be declared as reference to const [constParameter]
void ImageBarrier(VkImage &Image, size_t MipMapBase, size_t MipMapCount, size_t LayerBase, size_t LayerCount, VkFormat Format, VkImageLayout OldLayout, VkImageLayout NewLayout)
^
src\engine\client\backend\vulkan\backend_vulkan.cpp:6495:46: style: Parameter 'ExecBuffer' can be declared as reference to const [constParameter]
void Cmd_Clear(SRenderCommandExecuteBuffer &ExecBuffer, const CCommandBuffer::SCommand_Clear *pCommand)
^
src\game\client\components\skins.cpp:83:72: style: Parameter 'pImg' can be declared as pointer to const [constParameter]
static void CheckMetrics(CSkin::SSkinMetricVariable &Metrics, uint8_t *pImg, int ImgWidth, int ImgX, int ImgY, int CheckWidth, int CheckHeight)
^
src\game\client\prediction\entities\character.h:106:37: style: Parameter 'pNewInput' can be declared as pointer to const [constParameter]
void SetInput(CNetObj_PlayerInput *pNewInput)
^
src\game\client\prediction\gameworld.cpp:245:106: style: Parameter 'pNotThis' can be declared as pointer to const [constParameter]
CCharacter *CGameWorld::IntersectCharacter(vec2 Pos0, vec2 Pos1, float Radius, vec2 &NewPos, CCharacter *pNotThis, int CollideWith, class CCharacter *pThisOnly)
^
src\game\client\prediction\gameworld.cpp:245:151: style: Parameter 'pThisOnly' can be declared as pointer to const [constParameter]
CCharacter *CGameWorld::IntersectCharacter(vec2 Pos0, vec2 Pos1, float Radius, vec2 &NewPos, CCharacter *pNotThis, int CollideWith, class CCharacter *pThisOnly)
^
src\game\client\prediction\gameworld.cpp:283:116: style: Parameter 'pNotThis' can be declared as pointer to const [constParameter]
std::list<class CCharacter *> CGameWorld::IntersectedCharacters(vec2 Pos0, vec2 Pos1, float Radius, class CEntity *pNotThis)
^
src\game\client\ui.cpp:522:180: style: Parameter 'pReadCursor' can be declared as pointer to const [constParameter]
void CUI::DoLabel(CUIElement::SUIElementRect &RectEl, const CUIRect *pRect, const char *pText, float Size, int Align, const SLabelProperties &LabelProps, int StrLen, CTextCursor *pReadCursor)
^
src\game\client\ui_scrollregion.cpp:23:86: style: Parameter 'pParams' can be declared as pointer to const [constParameter]
void CScrollRegion::Begin(CUIRect *pClipRect, vec2 *pOutOffset, CScrollRegionParams *pParams)
^
src\game\server\scoreworker.h:239:29: style: Parameter 'aTimeCp' can be declared as const array [constParameter]
void Set(float Time, float aTimeCp[NUM_CHECKPOINTS])
^
src\game\server\score.cpp:135:80: style: Parameter 'aTimeCp' can be declared as const array [constParameter]
void CScore::SaveScore(int ClientID, float Time, const char *pTimestamp, float aTimeCp[NUM_CHECKPOINTS], bool NotEligible)
^
src\game\server\teeinfo.cpp:40:57: style: Parameter 'pUseCustomColors' can be declared as pointer to const [constParameter]
CTeeInfo::CTeeInfo(const char *apSkinPartNames[6], int *pUseCustomColors, int *pSkinPartColors)
^
src\game\server\teeinfo.cpp:40:80: style: Parameter 'pSkinPartColors' can be declared as pointer to const [constParameter]
CTeeInfo::CTeeInfo(const char *apSkinPartNames[6], int *pUseCustomColors, int *pSkinPartColors)
^
```