-
Notifications
You must be signed in to change notification settings - Fork 30
Expand file tree
/
Copy pathApus.Engine.Types.pas
More file actions
257 lines (223 loc) · 8.78 KB
/
Copy pathApus.Engine.Types.pas
File metadata and controls
257 lines (223 loc) · 8.78 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
// This is the lowest level unit of the Apus Game Engine.
// It should not use any other Engine's units.
//
unit Apus.Engine.Types;
interface
uses Types, Apus.Core, Apus.Geom2D, Apus.Geom3D,
Apus.Colors, Apus.VertexLayout;
type
// 2D geometry
TVec2d = Apus.Geom2D.TVec2d;
PVec2d = Apus.Geom2D.PVec2d;
TVec2 = Apus.Geom2D.TVec2;
PVec2 = Apus.Geom2D.PVec2;
TVec2Array = Apus.Geom2D.TVec2Array;
TRect2 = Apus.Geom2D.TRect2;
PRect2 = Apus.Geom2D.PRect2;
TMat2d = Apus.Geom2D.TMat2d;
TMat32d = Apus.Geom2D.TMat32d;
TMat32 = Apus.Geom2D.TMat32;
// 3D geometry
TVec3d = Apus.Geom3D.TVec3d;
PVec3d = Apus.Geom3D.PVec3d;
TVec3 = Apus.Geom3D.TVec3;
PVec3 = Apus.Geom3D.PVec3;
TVec3Array = Apus.Geom3D.TVec3Array;
TVec4d = Apus.Geom3D.TVec4d;
TVec4 = Apus.Geom3D.TVec4;
PVec4 = Apus.Geom3D.PVec4;
TQuatd = Apus.Geom3D.TQuatd;
TQuat = Apus.Geom3D.TQuat;
TMat3d = Apus.Geom3D.TMat3d;
TMat3 = Apus.Geom3D.TMat3;
PMat3 = Apus.Geom3D.PMat3;
TMat34d = Apus.Geom3D.TMat34d;
TMat34 = Apus.Geom3D.TMat34;
PMat34 = Apus.Geom3D.PMat34;
TMat4d = Apus.Geom3D.TMat4d;
TMat4 = Apus.Geom3D.TMat4;
PMat4 = Apus.Geom3D.PMat4;
TPlane = Apus.Geom3D.TPlane;
TBox3 = Apus.Geom3D.TBox3;
PBox3 = Apus.Geom3D.PBox3;
TAsyncProc = function(param:UIntPtr):integer;
TVertexComponent = Apus.VertexLayout.TVertexComponent;
TVertexLayout = Apus.VertexLayout.TVertexLayout;
TIndices=WordArray;
// Kind of a mouse-move event delivered to a gameplay scene, set by the UI dispatcher
// before calling the scene handler (read it via window.moveKind):
// mkLeave - cursor just moved from the world onto a consuming UI element (act: stop/hide world cursor)
// mkMove - cursor moved within the world (no UI consuming it) — the only kind that carries a real delta
// mkEnter - cursor just returned to the world from UI (no delta — don't apply movement)
TMoveKind=(mkLeave,mkMove,mkEnter);
TTextAlignment=(taLeft, // normal output
taCenter, // output point indicates the text center
taRight, // output point indicates the right edge; use boundary-1 to keep ink before a guide/border line
taJustify); // output point indicates the left edge, while spacing is the line width
// (falls back to left-aligned output when actual width is too small or the line ends with #10/#13)
// Display mode
TDisplayMode=(dmNone, //< not specified
dmSwitchResolution, //< Fullscreen: switch to desired display mode (change screen resolution)
dmFullScreen, //< Use current resolution with fullscreen window
dmFixedWindow, //< Use fixed-size window
dmWindow, //< Use resizeable window
dmBorderless); //< Use borderless window (non-fullscreen), app should manually resize it if needed
// How the rendered image should appear in the output window (display)
TDisplayFitMode=(dfmCenter, //< image is centered in the output window rect (1:1) (DisplayScaleMode is ignored)
dfmFullSize, //< image is stretched to fill the whole output window
dfmKeepAspectRatio); //< image is stretched to fill the output window while keeping it's original aspect ratio (black padding)
// How rendering is processed if the backbuffer size doesn't match the output area
TDisplayScaleMode=(dsmDontScale, //< Backbuffer size is updated to match the output area
dsmStretch, //< Stretch rendered image to the output rect
dsmScale); //< Use scale transformation matrix to map render area to the output rect (scaled rendering)
// Note that scaled rendering produces error in clipping due to rounding
// Display settings
TDisplaySettings=record
displayMode:TDisplayMode;
displayFitMode:TDisplayFitMode;
displayScaleMode:TDisplayScaleMode;
end;
// Runtime display/window configuration.
TGameSettings=record
title:string; // window/program title
width,height:integer; // backbuffer size and desired output area
colorDepth:integer; // requested backbuffer format (16/24/32)
refresh:integer; // display refresh rate (0 - default)
vSync:integer; // 0 - max FPS, N - FPS = refresh/N
mode,altMode:TDisplaySettings; // primary and alternate display mode (Alt+Enter)
showSystemCursor:boolean; // draw system cursor instead of engine cursor
zbuffer:byte; // desired precision for a depth buffer (0 - don't use depth buffer)
stencil:boolean; // request a stencil-buffer (at least 8-bit)
multisampling:byte; // full-screen anti-aliasing samples (<2 - disabled)
slowmotion:boolean; // hint: prefer redraw optimizations for low/unstable frame rates
end;
// Packed ARGB color
TARGBColor=Apus.Colors.TARGBColor;
PARGBColor=Apus.Colors.PARGBColor;
// Primitive types
TPrimitiveType=(
LINE_LIST,
LINE_STRIP,
TRG_FAN,
TRG_STRIP,
TRG_LIST);
TFontHandle=cardinal;
TColorVector=record
red,green,blue,alpha:single;
constructor Init(red,green,blue,alpha:single);
class function FromColor(color:cardinal;scale:single=1):TColorVector; static;
function ToQuat:TQuat; inline;
end;
TMonoGradient=record
base,dx,dy:single;
procedure Init(v1,v2,angle,scale:single);
function ValueAt(x,y:single):single; inline;
end;
// Linear gradient
TColorGradient=record
red,green,blue,alpha:TMonoGradient;
procedure Init(color1,color2:cardinal;angle,scale:single);
function ColorAt(x,y:single):cardinal;
end;
PRoundRectExtParams=^TRoundRectExtParams;
TRoundRectExtParams=record
origin:TVec2; // normalized local coords: (0,0)=center, (-1,-1)..(1,1)=corners
fillDx,fillDy:TColorVector; // signed color delta per normalized local axis
constructor Init(const fillDx,fillDy:TColorVector;const origin:TVec2);
end;
TDisplayModeHelper = record helper for TDisplayMode
function ToString:string;
end;
TDisplayFitModeHelper = record helper for TDisplayFitMode
function ToString:string;
end;
TDisplayScaleModeHelper = record helper for TDisplayScaleMode
function ToString:string;
end;
TPointCompatHelper = record helper for TPoint
function Equals(const p:TPoint):boolean; inline;
function IsNear(x,y,radius:single):boolean; inline;
end;
implementation
uses Apus.Utils;
{$EXCESSPRECISION OFF}
// TODO: trim this unit to engine-specific types only and move Base-type re-exports
// to explicit imports or a dedicated facade, as documented in Work/engine_work_ahead.md.
{ TGradient }
const
k255 = 1/255;
minGradientScale = 1E-6;
function TDisplayModeHelper.ToString:string;
begin
result:=GetEnumNameSafe(TypeInfo(TDisplayMode),ord(self));
end;
function TDisplayFitModeHelper.ToString: string;
begin
result:=GetEnumNameSafe(TypeInfo(TDisplayFitMode),ord(self));
end;
function TDisplayScaleModeHelper.ToString: string;
begin
result:=GetEnumNameSafe(TypeInfo(TDisplayScaleMode),ord(self));
end;
function TPointCompatHelper.Equals(const p:TPoint):boolean;
begin
result:=(x=p.x) and (y=p.y);
end;
function TPointCompatHelper.IsNear(x,y,radius:single):boolean;
begin
result:=Sqr(self.x-x)+Sqr(self.y-y)<=sqr(radius);
end;
{ TColorVector }
constructor TColorVector.Init(red,green,blue,alpha:single);
begin
self.red:=red;
self.green:=green;
self.blue:=blue;
self.alpha:=alpha;
end;
class function TColorVector.FromColor(color:cardinal;scale:single):TColorVector;
begin
result.red:=PARGBColor(@color).r*k255*scale;
result.green:=PARGBColor(@color).g*k255*scale;
result.blue:=PARGBColor(@color).b*k255*scale;
result.alpha:=PARGBColor(@color).a*k255*scale;
end;
function TColorVector.ToQuat:TQuat;
begin
result:=TQuat.Init(red,green,blue,alpha);
end;
{ TRoundRectExtParams }
constructor TRoundRectExtParams.Init(const fillDx,fillDy:TColorVector;const origin:TVec2);
begin
self.origin:=origin;
self.fillDx:=fillDx;
self.fillDy:=fillDy;
end;
function TColorGradient.ColorAt(x,y:single):cardinal;
begin
result:=Color.ARGBf(alpha.ValueAt(x,y),red.valueAt(x,y),green.ValueAt(x,y),blue.ValueAt(x,y));
end;
procedure TColorGradient.Init(color1,color2:cardinal;angle,scale:single);
begin
alpha.Init(PARGBColor(@color1).a*k255,PARGBColor(@color2).a*k255,angle,scale);
red.Init(PARGBColor(@color1).r*k255,PARGBColor(@color2).r*k255,angle,scale);
green.Init(PARGBColor(@color1).g*k255,PARGBColor(@color2).g*k255,angle,scale);
blue.Init(PARGBColor(@color1).b*k255,PARGBColor(@color2).b*k255,angle,scale);
end;
{ TMonoGradient }
procedure TMonoGradient.Init(v1,v2,angle,scale:single);
begin
base:=(v1+v2)/2;
if abs(scale)<=minGradientScale then begin
dx:=0;
dy:=0;
end else begin
dx:=(v2-v1)*cos(angle)/scale;
dy:=(v2-v1)*sin(angle)/scale;
end;
end;
function TMonoGradient.ValueAt(x,y:single):single;
begin
result:=Clamp(base+(x*2-1)*dx+(y*2-1)*dy,0,1);
end;
end.