forked from Mirrors/openclonk
Improve the default Zoom and Zoom changes
The default Zoom should now show a piece of the landscape about the size of one Clonk's vision.
parent
349e463abd
commit
0f4e88db87
|
@ -36,6 +36,8 @@ extern C4Game Game;
|
|||
|
||||
const float C4GFX_ZoomStep = 1.1040895f;
|
||||
|
||||
#define C4FOW_Def_View_RangeX 500
|
||||
|
||||
class C4GraphicsSystem
|
||||
{
|
||||
public:
|
||||
|
|
|
@ -1148,8 +1148,8 @@ bool C4PlayerControl::GetCurrentPlayerCursorPos(int32_t *x_out, int32_t *y_out)
|
|||
if (!vp) return false;
|
||||
int32_t game_x = cursor_obj->GetX(), game_y=cursor_obj->GetY();
|
||||
// game coordinate to screen coordinates...
|
||||
float screen_x = (float(game_x) - vp->last_game_draw_cgo.TargetX - vp->last_game_draw_cgo.X) * vp->Zoom;
|
||||
float screen_y = (float(game_y) - vp->last_game_draw_cgo.TargetY - vp->last_game_draw_cgo.Y) * vp->Zoom;
|
||||
float screen_x = (float(game_x) - vp->last_game_draw_cgo.TargetX - vp->last_game_draw_cgo.X) * vp->GetZoom();
|
||||
float screen_y = (float(game_y) - vp->last_game_draw_cgo.TargetY - vp->last_game_draw_cgo.Y) * vp->GetZoom();
|
||||
// ...and screen coordinates to GUI coordinates (might push this into a helper function of C4Viewport?)
|
||||
float gui_x = (screen_x - vp->last_game_draw_cgo.X) / C4GUI::GetZoom() + vp->last_game_draw_cgo.X;
|
||||
float gui_y = (screen_y - vp->last_game_draw_cgo.Y) / C4GUI::GetZoom() + vp->last_game_draw_cgo.Y;
|
||||
|
|
|
@ -2012,8 +2012,8 @@ bool C4Object::ActivateMenu(int32_t iMenu, int32_t iMenuSelect,
|
|||
Menu->SetPermanent(true);
|
||||
Menu->SetAlignment(C4MN_Align_Free);
|
||||
C4Viewport *pViewport = ::GraphicsSystem.GetViewport(Controller); // Hackhackhack!!!
|
||||
if (pViewport) Menu->SetLocation((pTarget->GetX() + pTarget->Shape.GetX() + pTarget->Shape.Wdt + 10 - pViewport->ViewX) * pViewport->Zoom,
|
||||
(pTarget->GetY() + pTarget->Shape.GetY() - pViewport->ViewY) * pViewport->Zoom);
|
||||
if (pViewport) Menu->SetLocation((pTarget->GetX() + pTarget->Shape.GetX() + pTarget->Shape.Wdt + 10 - pViewport->ViewX) * pViewport->GetZoom(),
|
||||
(pTarget->GetY() + pTarget->Shape.GetY() - pViewport->ViewY) * pViewport->GetZoom());
|
||||
// Add info item
|
||||
fctSymbol.Create(C4PictureSize, C4PictureSize); pTarget->Def->Draw(fctSymbol, false, pTarget->Color, pTarget);
|
||||
Menu->Add(pTarget->GetName(), fctSymbol, "", C4MN_Item_NoCount, NULL, pTarget->GetInfoString().getData());
|
||||
|
|
|
@ -49,8 +49,6 @@
|
|||
#include <C4GameObjects.h>
|
||||
#include <C4GameControl.h>
|
||||
|
||||
#define C4FOW_Def_View_RangeX 500
|
||||
|
||||
C4Player::C4Player() : C4PlayerInfoCore()
|
||||
{
|
||||
Default();
|
||||
|
|
|
@ -285,9 +285,12 @@ namespace C4GUI
|
|||
C4Rect &rcClientRect = GetClientRect();
|
||||
C4Rect &rcClipArea = (IsComponentOutsideClientArea() ? GetBounds() : GetClientRect());
|
||||
// clip to window area
|
||||
float clx1, cly1, clx2, cly2;
|
||||
int clx1, cly1, clx2, cly2;
|
||||
lpDDraw->GetPrimaryClipper(clx1, cly1, clx2, cly2);
|
||||
lpDDraw->SubPrimaryClipper(cgo.TargetX+rcClipArea.x, cgo.TargetY+rcClipArea.y, cgo.TargetX+rcClipArea.x+rcClipArea.Wdt-1, cgo.TargetY+rcClipArea.y+rcClipArea.Hgt-1);
|
||||
float nclx1 = cgo.TargetX+rcClipArea.x, ncly1 = cgo.TargetY+rcClipArea.y, nclx2 = cgo.TargetX+rcClipArea.x+rcClipArea.Wdt-1, ncly2 = cgo.TargetY+rcClipArea.y+rcClipArea.Hgt-1;
|
||||
lpDDraw->ApplyZoom(nclx1, ncly1);
|
||||
lpDDraw->ApplyZoom(nclx2, ncly2);
|
||||
lpDDraw->SubPrimaryClipper(nclx1, ncly1, nclx2, ncly2);
|
||||
// update target area
|
||||
cgo.TargetX += rcClientRect.x; cgo.TargetY += rcClientRect.y;
|
||||
// draw contents
|
||||
|
|
|
@ -605,9 +605,12 @@ namespace C4GUI
|
|||
// default frame color
|
||||
Draw3DFrame(cgo);
|
||||
// clipping
|
||||
float cx0,cy0,cx1,cy1; bool fClip, fOwnClip;
|
||||
int cx0,cy0,cx1,cy1; bool fClip, fOwnClip;
|
||||
fClip = lpDDraw->GetPrimaryClipper(cx0,cy0,cx1,cy1);
|
||||
fOwnClip = lpDDraw->SetPrimaryClipper(rcClientRect.x+cgo.TargetX-2,rcClientRect.y+cgo.TargetY,rcClientRect.x+rcClientRect.Wdt+cgo.TargetX+1,rcClientRect.y+rcClientRect.Hgt+cgo.TargetY);
|
||||
float nclx1 = rcClientRect.x+cgo.TargetX-2, ncly1 = rcClientRect.y+cgo.TargetY, nclx2 = rcClientRect.x+rcClientRect.Wdt+cgo.TargetX+1, ncly2 = rcClientRect.y+rcClientRect.Hgt+cgo.TargetY;
|
||||
lpDDraw->ApplyZoom(nclx1, ncly1);
|
||||
lpDDraw->ApplyZoom(nclx2, ncly2);
|
||||
fOwnClip = lpDDraw->SetPrimaryClipper(nclx1, ncly1, nclx2, ncly2);
|
||||
// get usable height of edit field
|
||||
int32_t iHgt = pFont->GetLineHeight(), iY0;
|
||||
if (rcClientRect.Hgt <= iHgt)
|
||||
|
|
|
@ -212,7 +212,7 @@ namespace C4GUI
|
|||
void MultilineLabel::DrawElement(C4TargetFacet &cgo)
|
||||
{
|
||||
// get clipping
|
||||
float iClipX, iClipY, iClipX2, iClipY2;
|
||||
int iClipX, iClipY, iClipX2, iClipY2;
|
||||
lpDDraw->GetPrimaryClipper(iClipX, iClipY, iClipX2, iClipY2);
|
||||
// draw all lines
|
||||
int32_t iIndex = 0; const char *szLine;
|
||||
|
|
|
@ -75,12 +75,6 @@ namespace
|
|||
|
||||
#ifdef _WIN32
|
||||
|
||||
double round(double x)
|
||||
{
|
||||
// Dunno if this matches the implementation of round()
|
||||
return (x < 0.0) ? floor(x) : ceil(x);
|
||||
}
|
||||
|
||||
#include <shellapi.h>
|
||||
|
||||
LRESULT APIENTRY ViewportWinProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||
|
@ -988,7 +982,7 @@ void C4Viewport::Draw(C4TargetFacet &cgo0, bool fDrawOverlay)
|
|||
cgo.TargetX += BorderLeft/Zoom; cgo.TargetY += BorderTop/Zoom;
|
||||
// Apply Zoom
|
||||
lpDDraw->SetZoom(GameZoom);
|
||||
Application.DDraw->SetPrimaryClipper(cgo.X,cgo.Y,cgo.X+(ViewWdt-1-BorderRight-BorderLeft)/Zoom,cgo.Y+(ViewHgt-1-BorderBottom-BorderTop)/Zoom);
|
||||
Application.DDraw->SetPrimaryClipper(cgo.X,cgo.Y,DrawX+ViewWdt-1-BorderRight,DrawY+ViewHgt-1-BorderBottom);
|
||||
}
|
||||
last_game_draw_cgo = cgo;
|
||||
|
||||
|
@ -1044,7 +1038,7 @@ void C4Viewport::Draw(C4TargetFacet &cgo0, bool fDrawOverlay)
|
|||
float fGUIZoom = C4GUI::GetZoom();
|
||||
// now restore complete cgo range for overlay drawing
|
||||
lpDDraw->SetZoom(DrawX,DrawY, fGUIZoom);
|
||||
Application.DDraw->SetPrimaryClipper(DrawX,DrawY,DrawX+(ViewWdt-1)/fGUIZoom,DrawY+(ViewHgt-1)/fGUIZoom);
|
||||
Application.DDraw->SetPrimaryClipper(DrawX,DrawY,DrawX+(ViewWdt-1),DrawY+(ViewHgt-1));
|
||||
cgo.Set(cgo0);
|
||||
|
||||
cgo.X = DrawX; cgo.Y = DrawY;
|
||||
|
@ -1106,7 +1100,7 @@ void C4Viewport::Execute()
|
|||
C4TargetFacet cgo;
|
||||
CStdWindow * w = pWindow;
|
||||
if (!w) w = &FullScreen;
|
||||
cgo.Set(w->pSurface,DrawX,DrawY,int32_t(float(ViewWdt)/Zoom),int32_t(float(ViewHgt)/Zoom),ViewX,ViewY);
|
||||
cgo.Set(w->pSurface,DrawX,DrawY,int32_t(ceilf(float(ViewWdt)/Zoom)),int32_t(ceilf(float(ViewHgt)/Zoom)),ViewX,ViewY);
|
||||
lpDDraw->PrepareRendering(w->pSurface);
|
||||
// Draw
|
||||
Draw(cgo, true);
|
||||
|
@ -1125,61 +1119,69 @@ void C4Viewport::ChangeZoom(float by_factor)
|
|||
|
||||
void C4Viewport::AdjustPosition()
|
||||
{
|
||||
const float ZoomAdjustFactor = 1.08f; // must be > 1.0 to have effect
|
||||
const float ZoomAdjustFactor = 1.025f; // must be > 1.0 to have effect
|
||||
float ViewportScrollBorder = fIsNoOwnerViewport ? 0 : float(C4ViewportScrollBorder);
|
||||
C4Player *pPlr = ::Players.Get(Player);
|
||||
if (ZoomTarget < 0.000001f)
|
||||
{
|
||||
ZoomTarget = Max(float(ViewWdt)/GBackWdt, 1.0f);
|
||||
if (pPlr) ZoomTarget = Max(ViewWdt / (2.0f * C4FOW_Def_View_RangeX), ZoomTarget);
|
||||
Zoom = ZoomTarget;
|
||||
}
|
||||
// View position
|
||||
if (PlayerLock && ValidPlr(Player))
|
||||
{
|
||||
C4Player *pPlr = ::Players.Get(Player);
|
||||
float iScrollRange = Min(ViewWdt/(10*Zoom),ViewHgt/(10*Zoom));
|
||||
float iExtraBoundsX = 0, iExtraBoundsY = 0;
|
||||
float PrefViewX = ViewX + ViewWdt / (Zoom * 2) - ViewOffsX;
|
||||
float PrefViewY = ViewY + ViewHgt / (Zoom * 2) - ViewOffsY;
|
||||
// Change Zoom
|
||||
assert(Zoom>0);
|
||||
if (Zoom < ZoomTarget)
|
||||
Zoom *= ZoomAdjustFactor;
|
||||
if (Zoom > ZoomTarget)
|
||||
{
|
||||
Zoom /= ZoomAdjustFactor;
|
||||
if (Zoom < ZoomTarget)
|
||||
Zoom = ZoomTarget;
|
||||
}
|
||||
|
||||
float ScrollRange = Min(ViewWdt/(10*Zoom),ViewHgt/(10*Zoom));
|
||||
float ExtraBoundsX = 0, ExtraBoundsY = 0;
|
||||
if (pPlr->ViewMode == C4PVM_Scrolling)
|
||||
{
|
||||
iScrollRange=0;
|
||||
iExtraBoundsX=iExtraBoundsY=ViewportScrollBorder;
|
||||
ScrollRange=0;
|
||||
ExtraBoundsX=ExtraBoundsY=ViewportScrollBorder;
|
||||
}
|
||||
else
|
||||
{
|
||||
// if view is close to border, allow scrolling
|
||||
if (pPlr->ViewX < ViewportScrollBorder) iExtraBoundsX = Min<float>(ViewportScrollBorder - pPlr->ViewX, ViewportScrollBorder);
|
||||
else if (pPlr->ViewX >= GBackWdt - ViewportScrollBorder) iExtraBoundsX = Min<float>(float(pPlr->ViewX - GBackWdt), 0) + ViewportScrollBorder;
|
||||
if (pPlr->ViewY < ViewportScrollBorder) iExtraBoundsY = Min<float>(ViewportScrollBorder - pPlr->ViewY, ViewportScrollBorder);
|
||||
else if (pPlr->ViewY >= GBackHgt - ViewportScrollBorder) iExtraBoundsY = Min<float>(float(pPlr->ViewY - GBackHgt), 0) + ViewportScrollBorder;
|
||||
if (pPlr->ViewX < ViewportScrollBorder) ExtraBoundsX = Min<float>(ViewportScrollBorder - pPlr->ViewX, ViewportScrollBorder);
|
||||
else if (pPlr->ViewX >= GBackWdt - ViewportScrollBorder) ExtraBoundsX = Min<float>(float(pPlr->ViewX - GBackWdt), 0) + ViewportScrollBorder;
|
||||
if (pPlr->ViewY < ViewportScrollBorder) ExtraBoundsY = Min<float>(ViewportScrollBorder - pPlr->ViewY, ViewportScrollBorder);
|
||||
else if (pPlr->ViewY >= GBackHgt - ViewportScrollBorder) ExtraBoundsY = Min<float>(float(pPlr->ViewY - GBackHgt), 0) + ViewportScrollBorder;
|
||||
}
|
||||
iExtraBoundsX = Max(iExtraBoundsX, (ViewWdt/Zoom - GBackWdt) / 2+1);
|
||||
iExtraBoundsY = Max(iExtraBoundsY, (ViewHgt/Zoom - GBackHgt) / 2+1);
|
||||
ExtraBoundsX = Max(ExtraBoundsX, (ViewWdt/Zoom - GBackWdt) / 2+1);
|
||||
ExtraBoundsY = Max(ExtraBoundsY, (ViewHgt/Zoom - GBackHgt) / 2+1);
|
||||
// calc target view position
|
||||
float iTargetViewX = pPlr->ViewX - ViewWdt / (Zoom * 2);
|
||||
float iTargetViewY = pPlr->ViewY - ViewHgt / (Zoom * 2);
|
||||
float TargetViewX = pPlr->ViewX/* */;
|
||||
float TargetViewY = pPlr->ViewY/* */;
|
||||
// add mouse auto scroll
|
||||
float iPrefViewX = ViewX - ViewOffsX, iPrefViewY = ViewY - ViewOffsY;
|
||||
if (pPlr->MouseControl && ::MouseControl.InitCentered && Config.Controls.MouseAScroll)
|
||||
{
|
||||
iTargetViewX += (::MouseControl.VpX - ViewWdt / 2) / Zoom;
|
||||
iTargetViewY += (::MouseControl.VpY - ViewHgt / 2) / Zoom;
|
||||
TargetViewX += (::MouseControl.VpX - ViewWdt / 2) / Zoom;
|
||||
TargetViewY += (::MouseControl.VpY - ViewHgt / 2) / Zoom;
|
||||
}
|
||||
// scroll range
|
||||
iTargetViewX = BoundBy(iPrefViewX, iTargetViewX - iScrollRange, iTargetViewX + iScrollRange);
|
||||
iTargetViewY = BoundBy(iPrefViewY, iTargetViewY - iScrollRange, iTargetViewY + iScrollRange);
|
||||
TargetViewX = BoundBy(PrefViewX, TargetViewX - ScrollRange, TargetViewX + ScrollRange);
|
||||
TargetViewY = BoundBy(PrefViewY, TargetViewY - ScrollRange, TargetViewY + ScrollRange);
|
||||
// bounds
|
||||
iTargetViewX = BoundBy(iTargetViewX, -iExtraBoundsX, GBackWdt - ViewWdt / Zoom + iExtraBoundsX);
|
||||
iTargetViewY = BoundBy(iTargetViewY, -iExtraBoundsY, GBackHgt - ViewHgt / Zoom + iExtraBoundsY);
|
||||
TargetViewX = BoundBy(TargetViewX, ViewWdt / (Zoom * 2) - ExtraBoundsX, GBackWdt - ViewWdt / (Zoom * 2) + ExtraBoundsX);
|
||||
TargetViewY = BoundBy(TargetViewY, ViewHgt / (Zoom * 2) - ExtraBoundsY, GBackHgt - ViewHgt / (Zoom * 2) + ExtraBoundsY);
|
||||
// smooth
|
||||
ViewX += (iTargetViewX - ViewX) / BoundBy<int32_t>(Config.General.ScrollSmooth, 1, 50);
|
||||
ViewY += (iTargetViewY - ViewY) / BoundBy<int32_t>(Config.General.ScrollSmooth, 1, 50);
|
||||
// Change Zoom
|
||||
ViewX += ViewWdt / (Zoom * 2);
|
||||
ViewY += ViewHgt / (Zoom * 2);
|
||||
assert(Zoom>0);
|
||||
if (Zoom < ZoomTarget) Zoom *= ZoomAdjustFactor;
|
||||
if (Zoom > ZoomTarget) Zoom /= ZoomAdjustFactor;
|
||||
// snap to rounded target if it's near to avoid unsightly Zooms
|
||||
if (round(ZoomTarget * 10) == round(Zoom * 10))
|
||||
Zoom = round(ZoomTarget * 10) / 10;
|
||||
ViewX -= ViewWdt / (Zoom * 2);
|
||||
ViewY -= ViewHgt / (Zoom * 2);
|
||||
ViewX = PrefViewX + (TargetViewX - PrefViewX) / BoundBy<int32_t>(Config.General.ScrollSmooth, 1, 50);
|
||||
ViewY = PrefViewY + (TargetViewY - PrefViewY) / BoundBy<int32_t>(Config.General.ScrollSmooth, 1, 50);
|
||||
// apply offset
|
||||
ViewX += ViewOffsX; ViewY += ViewOffsY;
|
||||
ViewX -= ViewWdt / (Zoom * 2) - ViewOffsX;
|
||||
ViewY -= ViewHgt / (Zoom * 2) - ViewOffsY;
|
||||
}
|
||||
// NO_OWNER can't scroll
|
||||
if (fIsNoOwnerViewport) { ViewOffsX=0; ViewOffsY=0; }
|
||||
|
@ -1241,7 +1243,7 @@ void C4Viewport::Default()
|
|||
OutX=OutY=ViewWdt=ViewHgt=0;
|
||||
DrawX=DrawY=0;
|
||||
Zoom = 1.0;
|
||||
ZoomTarget = 1.0;
|
||||
ZoomTarget = 0.0;
|
||||
Next=NULL;
|
||||
PlayerLock=true;
|
||||
ResetMenuPositions=false;
|
||||
|
|
|
@ -91,9 +91,8 @@ public:
|
|||
// facets used for last drawing operations
|
||||
C4TargetFacet last_game_draw_cgo, last_gui_draw_cgo;
|
||||
// factor between "landscape" and "display"
|
||||
float Zoom;
|
||||
float ZoomTarget;
|
||||
bool fIsNoOwnerViewport; // this viewport is found for searches of NO_OWNER-viewports; even if it has a player assigned (for network obs)
|
||||
float GetZoom() { return Zoom; }
|
||||
void Default();
|
||||
void Clear();
|
||||
void Execute();
|
||||
|
@ -114,6 +113,8 @@ public:
|
|||
int32_t GetPlayer() { return Player; }
|
||||
void CenterPosition();
|
||||
protected:
|
||||
float Zoom;
|
||||
float ZoomTarget;
|
||||
int32_t Player;
|
||||
bool PlayerLock;
|
||||
int32_t OutX,OutY;
|
||||
|
|
|
@ -426,10 +426,10 @@ bool CStdDDraw::SetPrimaryPalette(BYTE *pBuf, BYTE *pAlphaBuf)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool CStdDDraw::SubPrimaryClipper(float iX1, float iY1, float iX2, float iY2)
|
||||
bool CStdDDraw::SubPrimaryClipper(int iX1, int iY1, int iX2, int iY2)
|
||||
{
|
||||
// Set sub primary clipper
|
||||
SetPrimaryClipper(Max(iX1,fClipX1),Max(iY1,fClipY1),Min(iX2,fClipX2),Min(iY2,fClipY2));
|
||||
SetPrimaryClipper(Max(iX1,iClipX1),Max(iY1,iClipY1),Min(iX2,iClipX2),Min(iY2,iClipY2));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -447,13 +447,11 @@ bool CStdDDraw::RestorePrimaryClipper()
|
|||
return true;
|
||||
}
|
||||
|
||||
bool CStdDDraw::SetPrimaryClipper(float iX1, float iY1, float iX2, float iY2)
|
||||
bool CStdDDraw::SetPrimaryClipper(int iX1, int iY1, int iX2, int iY2)
|
||||
{
|
||||
// set clipper
|
||||
fClipX1=iX1; fClipY1=iY1; fClipX2=iX2; fClipY2=iY2;
|
||||
float fZClipX1=fClipX1, fZClipY1=fClipY1, fZClipX2=fClipX2, fZClipY2=fClipY2;
|
||||
ApplyZoom(fZClipX1, fZClipY1); ApplyZoom(fZClipX2, fZClipY2);
|
||||
iClipX1=int32_t(fZClipX1); iClipY1=int32_t(fZClipY1); iClipX2=int32_t(fZClipX2); iClipY2=int32_t(fZClipY2);
|
||||
iClipX1=iX1; iClipY1=iY1; iClipX2=iX2; iClipY2=iY2;
|
||||
UpdateClipper();
|
||||
// Done
|
||||
return true;
|
||||
|
@ -861,7 +859,7 @@ bool CStdDDraw::CreatePrimaryClipper(unsigned int iXRes, unsigned int iYRes)
|
|||
// simply setup primary viewport
|
||||
// assume no zoom has been set yet
|
||||
assert(Zoom==1.0f);
|
||||
SetPrimaryClipper(0, 0, float(iXRes - 1), float(iYRes - 1));
|
||||
SetPrimaryClipper(0, 0, iXRes - 1, iYRes - 1);
|
||||
StorePrimaryClipper();
|
||||
return true;
|
||||
}
|
||||
|
@ -1266,7 +1264,7 @@ void CStdDDraw::Grayscale(SURFACE sfcSfc, int32_t iOffset)
|
|||
sfcSfc->Unlock();
|
||||
}
|
||||
|
||||
bool CStdDDraw::GetPrimaryClipper(float &rX1, float &rY1, float &rX2, float &rY2)
|
||||
bool CStdDDraw::GetPrimaryClipper(int &rX1, int &rY1, int &rX2, int &rY2)
|
||||
{
|
||||
// Store drawing clip values
|
||||
rX1=fClipX1; rY1=fClipY1; rX2=fClipX2; rY2=fClipY2;
|
||||
|
|
|
@ -258,9 +258,9 @@ public:
|
|||
bool SetPrimaryPaletteQuad(BYTE *pBuf);
|
||||
bool AttachPrimaryPalette(SURFACE sfcSurface);
|
||||
// Clipper
|
||||
bool GetPrimaryClipper(float &rX1, float &rY1, float &rX2, float &rY2);
|
||||
bool SetPrimaryClipper(float iX1, float iY1, float iX2, float iY2);
|
||||
bool SubPrimaryClipper(float iX1, float iY1, float iX2, float iY2);
|
||||
bool GetPrimaryClipper(int &rX1, int &rY1, int &rX2, int &rY2);
|
||||
bool SetPrimaryClipper(int iX1, int iY1, int iX2, int iY2);
|
||||
bool SubPrimaryClipper(int iX1, int iY1, int iX2, int iY2);
|
||||
bool StorePrimaryClipper();
|
||||
bool RestorePrimaryClipper();
|
||||
bool NoPrimaryClipper();
|
||||
|
|
Loading…
Reference in New Issue