219 lines
5.8 KiB
ObjectPascal
219 lines
5.8 KiB
ObjectPascal
unit ugame;
|
|
|
|
{$mode objfpc}{$H+}
|
|
|
|
interface
|
|
|
|
uses
|
|
{$IFDEF WINDOWS}Windows,{$ENDIF} Classes, SysUtils, Forms, Graphics, Controls, LCLType;
|
|
|
|
procedure ToggleFullScreen(Form: TForm; ARect: TRect);
|
|
procedure CenterControl(Control: TControl);
|
|
function CalculateAspectRatioH(const W1, H1, W2: integer): integer; //result H2
|
|
function CalculateAspectRatioW(const W1, H1, H2: integer): integer; //result W2
|
|
function CalculateDestRect(ImageW, ImageH, DestW, DestH: integer;
|
|
Stretch, Proportional, Center: boolean): TRect;
|
|
procedure HighDPI(FromDPI: integer);
|
|
procedure ScaleDPI(Control: TControl; FromDPI: integer);
|
|
procedure ScaleAspectRatio(Control: TControl; OriginalParentW, OriginalParentH: integer);
|
|
procedure ScaleAspectRatio(Control: TControl; DestW, DestH: integer;
|
|
Stretch, Proportional, Center: boolean);
|
|
{$IFDEF WINDOWS}
|
|
procedure SetScreenResolution(
|
|
const Width, Height: integer); overload;
|
|
procedure SetScreenResolution(const Width, Height, colorDepth: integer); overload;
|
|
{$ENDIF}
|
|
|
|
implementation
|
|
|
|
procedure ToggleFullScreen(Form: TForm; ARect: TRect);
|
|
begin
|
|
Form.SetBounds(ARect.Left, ARect.Top, ARect.Right, ARect.Bottom);
|
|
if Form.BorderStyle <> bsNone then
|
|
begin
|
|
Form.BorderStyle := bsNone;
|
|
Form.WindowState := wsMaximized;
|
|
end
|
|
else
|
|
begin
|
|
Form.BorderStyle := bsDialog;
|
|
Form.WindowState := wsNormal;
|
|
end;
|
|
end;
|
|
|
|
procedure CenterControl(Control: TControl);
|
|
begin
|
|
if not Control.HasParent then
|
|
Exit;
|
|
Control.SetBounds(
|
|
Round((Control.Parent.Width - Control.Width) div 2),
|
|
Round((Control.Parent.Height - Control.Height) div 2),
|
|
Control.Width, Control.Height);
|
|
end;
|
|
|
|
function CalculateAspectRatioH(const W1, H1, W2: integer): integer;
|
|
begin
|
|
Result := Round(H1 / W1 * W2);
|
|
end;
|
|
|
|
function CalculateAspectRatioW(const W1, H1, H2: integer): integer;
|
|
begin
|
|
Result := Round(W1 / H1 * H2);
|
|
end;
|
|
|
|
function CalculateDestRect(ImageW, ImageH, DestW, DestH: integer;
|
|
Stretch, Proportional, Center: boolean): TRect;
|
|
var
|
|
w: integer;
|
|
h: integer;
|
|
begin
|
|
// Stretch or Proportional when Image (Width or Height) is bigger than Destination
|
|
if Stretch or (Proportional and ((ImageW > DestW) or (ImageH > DestH))) then
|
|
begin
|
|
// Proportional when Image (Width or Height) is bigger than 0
|
|
if Proportional and (ImageW > 0) and (ImageH > 0) then
|
|
begin
|
|
w := DestW;
|
|
h := CalculateAspectRatioH(ImageW, ImageH, DestW);
|
|
if h > DestH then
|
|
begin
|
|
h := DestH;
|
|
w := CalculateAspectRatioW(ImageW, ImageH, DestH);
|
|
end;
|
|
ImageW := w;
|
|
ImageH := h;
|
|
end
|
|
// Stretch not Proportional or when Image (Width or Height) is 0
|
|
else
|
|
begin
|
|
ImageW := DestW;
|
|
ImageH := DestH;
|
|
end;
|
|
end;
|
|
|
|
Result := Rect(0, 0, ImageW, ImageH);
|
|
|
|
// Center: Destination (Width or Height) - Image divided by 2
|
|
if Center then
|
|
begin
|
|
Result.Left := Round((DestW - ImageW) div 2);
|
|
Result.Top := Round((DestH - ImageH) div 2);
|
|
end;
|
|
end;
|
|
|
|
procedure HighDPI(FromDPI: integer);
|
|
var
|
|
i: integer;
|
|
begin
|
|
if Screen.PixelsPerInch = FromDPI then
|
|
exit;
|
|
|
|
for i := 0 to Screen.FormCount - 1 do
|
|
ScaleDPI(Screen.Forms[i], FromDPI);
|
|
end;
|
|
|
|
procedure ScaleDPI(Control: TControl; FromDPI: integer);
|
|
var
|
|
i: integer;
|
|
WinControl: TWinControl;
|
|
begin
|
|
if Screen.PixelsPerInch = FromDPI then
|
|
exit;
|
|
|
|
with Control do
|
|
begin
|
|
Left := ScaleX(Left, FromDPI);
|
|
Top := ScaleY(Top, FromDPI);
|
|
Width := ScaleX(Width, FromDPI);
|
|
Height := ScaleY(Height, FromDPI);
|
|
end;
|
|
|
|
if Control is TWinControl then
|
|
begin
|
|
WinControl := TWinControl(Control);
|
|
if WinControl.ControlCount = 0 then
|
|
exit;
|
|
|
|
with WinControl.ChildSizing do
|
|
begin
|
|
HorizontalSpacing := ScaleX(HorizontalSpacing, FromDPI);
|
|
LeftRightSpacing := ScaleX(LeftRightSpacing, FromDPI);
|
|
TopBottomSpacing := ScaleY(TopBottomSpacing, FromDPI);
|
|
VerticalSpacing := ScaleY(VerticalSpacing, FromDPI);
|
|
end;
|
|
|
|
for i := 0 to WinControl.ControlCount - 1 do
|
|
ScaleDPI(WinControl.Controls[i], FromDPI);
|
|
end;
|
|
end;
|
|
|
|
procedure ScaleAspectRatio(Control: TControl; OriginalParentW, OriginalParentH: integer);
|
|
var
|
|
l, t, w, h: integer;
|
|
begin
|
|
l := MulDiv(Control.Left, Control.Parent.Width, OriginalParentW);
|
|
t := MulDiv(Control.Top, Control.Parent.Height, OriginalParentH);
|
|
w := MulDiv(Control.Width, Control.Parent.Width, OriginalParentW);
|
|
h := MulDiv(Control.Height, Control.Parent.Height, OriginalParentH);
|
|
Control.SetBounds(l, t, w, h);
|
|
end;
|
|
|
|
procedure ScaleAspectRatio(Control: TControl; DestW, DestH: integer;
|
|
Stretch, Proportional, Center: boolean);
|
|
var
|
|
i: integer;
|
|
r: TRect;
|
|
WinControl: TWinControl;
|
|
w, h: integer;
|
|
begin
|
|
if Control is TWinControl then
|
|
begin
|
|
WinControl := TWinControl(Control);
|
|
w := WinControl.Width;
|
|
h := WinControl.Height;
|
|
|
|
r := CalculateDestRect(WinControl.Width, WinControl.Height, DestW,
|
|
DestH, Stretch, Proportional, Center);
|
|
WinControl.SetBounds(r.Left, r.Top, r.Right, r.Bottom);
|
|
|
|
if WinControl.ControlCount = 0 then
|
|
exit;
|
|
|
|
for i := 0 to WinControl.ControlCount - 1 do
|
|
ScaleAspectRatio(WinControl.Controls[i], w, h);
|
|
end;
|
|
end;
|
|
|
|
{$IFDEF WINDOWS}
|
|
procedure SetScreenResolution(
|
|
const Width, Height: integer); overload;
|
|
var
|
|
mode: TDevMode;
|
|
begin
|
|
zeroMemory(@mode, sizeof(TDevMode));
|
|
mode.dmSize := sizeof(TDevMode);
|
|
mode.dmPelsWidth := Width;
|
|
mode.dmPelsHeight := Height;
|
|
mode.dmFields := DM_PELSWIDTH or DM_PELSHEIGHT;
|
|
ChangeDisplaySettings(mode, 0);
|
|
end;
|
|
|
|
procedure SetScreenResolution(const Width, Height, colorDepth: integer); overload;
|
|
var
|
|
mode: TDevMode;
|
|
begin
|
|
zeroMemory(@mode, sizeof(TDevMode));
|
|
mode.dmSize := sizeof(TDevMode);
|
|
mode.dmPelsWidth := Width;
|
|
mode.dmPelsHeight := Height;
|
|
mode.dmBitsPerPel := colorDepth;
|
|
mode.dmFields := DM_PELSWIDTH or DM_PELSHEIGHT or DM_BITSPERPEL;
|
|
ChangeDisplaySettings(mode, 0);
|
|
end;
|
|
|
|
{$ENDIF}
|
|
|
|
end.
|
|
|
|
|