· last year · Sep 15, 2024, 12:50 PM
1program new;
2{$DEFINE SRL_USE_REMOTEINPUT}
3{$I SRL-T/osr.simba}
4
5var
6 NativeClient: PtrInt;
7
8
9// -----------------------------------------------------------------------------
10// -----------------------------------------------------------------------------
11// WIN API stuff
12
13const WINAPI_CC = {$IFDEF CPU386}' stdcall'{$ELSE}' win64'{$ENDIF};
14const ffi_winapi = {$IFDEF CPU386}ffi_stdcall{$ELSE}ffi_win64{$ENDIF};
15
16type
17 _EnumWindowsProc = function(wnd:DWORD; Param:Pointer): LongBool;
18 TEnumWindowsProc = native(_EnumWindowsProc, ffi_winapi);
19
20function GetAsyncKeyState(vKey: Int32): Int16; external 'GetAsyncKeyState@user32.dll' + WINAPI_CC;
21function GetForegroundWindow(): PtrUInt; external 'GetForegroundWindow@user32.dll' + WINAPI_CC;
22function GetWindowThreadProcessId(wnd: PtrUInt; out dwProcessId: DWORD): DWORD; external 'GetWindowThreadProcessId@user32.dll' + WINAPI_CC;
23function EnumChildWindows(hWndParent: DWORD; func: TEnumWindowsProc; Param: Pointer): LongBool; external 'EnumChildWindows@user32.dll' + WINAPI_CC;
24
25function GetKeyDown(): Char;
26var
27 key: Word;
28 keys: array of Word;
29begin
30 keys := [VK_A..VK_Z];
31 keys += [VK_0..VK_9];
32 keys += [VK_OEM_PERIOD, VK_OEM_MINUS]; //add more keys if you need
33 for Key in keys do
34 if GetAsyncKeyState(key) and $8000 <> 0 then
35 begin
36 while GetAsyncKeyState(key) and $8000 <> 0 do Wait(10);
37 if key = VK_OEM_PERIOD then key := Ord('.');
38 if key = VK_OEM_MINUS then key := Ord('-');
39 Exit(Char(key));
40 end;
41end;
42
43function IsKeyDown2(vKey: Word): Boolean;
44begin
45 Result := GetAsyncKeyState(vKey) and $8000 <> 0;
46end;
47
48function GetRSAppletWnd(PID: DWORD): DWORD;
49 function GetLastChild(Handle: DWORD; Param: Pointer): LongBool; static;
50 begin
51 if handle <> 0 then
52 begin
53 DWORD(Param^) := handle;
54 Result := True;
55 end;
56 end;
57var
58 p: TSysProc;
59 client: DWORD;
60begin
61 for p in GetProcesses() do
62 if p.Pid = PID then
63 Break;
64 EnumChildWindows(p.Handle, @GetLastChild, @Result);
65 if Result = 0 then
66 Result := NativeClient;
67end;
68
69
70
71
72// ---------
73// ---------
74// ---------
75
76procedure Setup();
77var
78 r: String;
79 DefaultBox: TBox = [75,40, 425,140];
80 client2: TClient;
81
82type
83 TButtonBox = record
84 TextTPA: TPointArray;
85 Bounds: TBox;
86 end;
87
88 procedure WaitReleaseMouse(key:Int32);
89 begin
90 while client2.GetIOManager.IsMouseButtonDown(key) do Wait(10);
91 end;
92
93 function GetClick(out p: TPoint): Boolean;
94 begin
95 if not EIOS_HasFocus(RSClient.RemoteInput.EIOS) then Exit();
96
97 if client2.GetIOManager.IsMouseButtonDown(1) then
98 begin
99 client2.GetIOManager.GetMousePos(p.x,p.y);
100 Result := p.InBox(GetClientBounds);
101 WaitReleaseMouse(1);
102 end;
103 end;
104
105 function GetButton(txt: String): TButtonBox;
106 begin
107 Result.TextTPA := TPAFromText(txt, 'StatChars07');
108 Result.Bounds := GetTPABounds(Result.TextTPA).Expand(8);
109 end;
110
111 function DrawButton(p: TPoint; var Button: TButtonBox): TButtonBox;
112 var tmp: TButtonBox;
113 begin
114 Button.TextTPA := Button.TextTPA.Offset(p);
115 Button.Bounds := Button.Bounds.Offset(p);
116 RSClient.Image.DrawBoxFilled(Button.Bounds, False, 2502198);
117 RSClient.Image.DrawBoxFilled(Button.Bounds.Expand(-1), False, 4607315);
118 RSClient.Image.DrawTPA(Button.TextTPA, $FFFFFF);
119 end;
120
121 function MessageBox(Text: String; Area:TBox=[]): string;
122 var
123 xstart: Int32;
124 TPA: TPointArray;
125 box: TBox;
126 begin
127 if (Area.x1 = Area.x2) then Area := chat.Bounds();
128 RSClient.Image.DrawBox(Area.Expand(-0), $1F2F33);
129 RSClient.Image.DrawBox(Area.Expand(-1), $3F4A5A);
130 RSClient.Image.DrawBox(Area.Expand(-2), $1F2F33);
131 RSClient.Image.DrawBoxFilled(Area.Expand(-3), False, $171D20);
132
133 TPA := TPAFromText(Text, 'SmallChars07');
134 box := GetTPABounds(TPA);
135 xstart := (box.Width + Area.Width) div 2 - box.Width;
136 OffsetTPA(TPA, Point(Area.x1+xstart, Area.y1+20));
137 RSClient.Image.DrawTPA(TPA, $FFFFFF);
138 end;
139
140 function Query(Text: String; Alts:TStringArray; Area:TBox=[]): string;
141 var
142 i,xstart,CurrWidth: Int32;
143 p: TPoint;
144 Buttons: array of TButtonBox;
145 xOffset: TIntegerArray;
146 begin
147 if (Area.x1 = Area.x2) then Area := chat.Bounds;
148
149 // query
150 MessageBox(Text, Area);
151
152 // buttons
153 for i:=0 to High(Alts) do
154 begin
155 Buttons += GetButton(Alts[i]);
156 xOffset += CurrWidth;
157 CurrWidth += Buttons[i].Bounds.X2+20;
158 end;
159 CurrWidth -= 20;
160
161 xstart := (CurrWidth + Area.Width) div 2 - CurrWidth;
162 for i:=0 to High(Buttons) do
163 begin
164 DrawButton(Point(Area.x1+xstart+xOffset[i], Area.y1+50), Buttons[i]);
165 end;
166
167 // handling
168 while True do
169 begin
170 if GetClick(p) then
171 begin
172 for i:=0 to High(Buttons) do
173 if PointInBox(p, Buttons[i].Bounds) then
174 begin
175 RSClient.Image.DrawBoxFilled(Area, False, 0);
176 Exit(Alts[i]);
177 end;
178 end;
179 Wait(1);
180 end;
181 end;
182
183 function QueryStr(Text: String; Area:TBox=[]): string;
184 var
185 i: Int32;
186 pt, p: TPoint;
187 chr: Char;
188 B: TBox;
189 TPA: TPointArray;
190 Button: TButtonBox;
191 textArea: Tbox;
192 begin
193 if (Area.x1 = Area.x2) then
194 Area := Chat.Bounds;
195
196 // query
197 RSClient.Image.DrawBox(Area.Expand(-0), $1F2F33);
198 RSClient.Image.DrawBox(Area.Expand(-1), $3F4A5A);
199 RSClient.Image.DrawBox(Area.Expand(-2), $1F2F33);
200 RSClient.Image.DrawBoxFilled(Area.Expand(-3), False, $171D20);
201
202 TPA := TPAFromText(Text, 'SmallChars07');
203 OffsetTPA(TPA, Point(Area.x1+40, Area.y1+20));
204 RSClient.Image.DrawTPA(TPA, $FFFFFF);
205 B := GetTPABounds(TPA);
206
207 // button
208 Button := GetButton('OK');
209 DrawButton(Point(Area.x1+48, Area.y1+50), Button);
210
211 // handling
212 pt.x := B.x2+5;
213 pt.y := Area.y1+25;
214 repeat
215 while not EIOS_HasFocus(RSClient.RemoteInput.EIOS) do Wait(10);
216
217 if GetClick(p) then
218 if PointInBox(p, Button.Bounds) then
219 begin
220 RSClient.Image.DrawBoxFilled(Area, False, 0);
221 Exit(Result);
222 end;
223
224 chr := GetKeyDown();
225 if chr <> #0 then
226 begin
227 Result += Lowercase(chr);
228 PressKey(VK_BACK); //ensure deletion if bugged input blocking
229 RSClient.Image.DrawText(Result, pt, $FFCCAA);
230 end;
231
232 if IsKeyDown2(VK_BACK) and (Result <> '') then
233 begin
234 textArea := [pt.X, pt.y, RSClient.Image.TextWidth(Result)+pt.x, RSClient.Image.TextHeight(Result)+pt.y];
235 RSClient.Image.DrawBoxFilled(textArea, False, $171D20);
236 while IsKeyDown2(VK_BACK) do Wait(50);
237 SetLength(Result, Length(Result)-1);
238 RSClient.Image.DrawText(Result, pt, $FFCCAA);
239 end;
240 until False;
241 end;
242
243label
244 START, QUERY_CONFIG;
245
246begin
247 client2.Init(PluginPath);
248 client2.GetIOManager.SetTarget2(GetRSAppletWnd(RSClient.RemoteInput.PID));
249
250 RSClient.Image.setFontSize(10);
251 RSClient.Image.setFontAntialiasing(False);
252
253START:
254 r := Query('Do you wish to run setup?', ['Yes','No'], DefaultBox);
255 WriteLn(r);
256
257 Writeln QueryStr('Save config as: ', DefaultBox);
258
259 client2.Free();
260end;
261
262
263
264
265begin
266 NativeClient := GetNativeWindow();
267
268 if EIOS_IsMouseInputEnabled(RSClient.RemoteInput.EIOS) then
269 EIOS_SetMouseInputEnabled(RSClient.RemoteInput.EIOS, False);
270 if EIOS_IsKeyboardInputEnabled(RSClient.RemoteInput.EIOS) then
271 EIOS_SetKeyboardInputEnabled(RSClient.RemoteInput.EIOS, False);
272
273 Setup();
274
275 EIOS_SetMouseInputEnabled(RSClient.RemoteInput.EIOS, True);
276 EIOS_SetKeyboardInputEnabled(RSClient.RemoteInput.EIOS, True);
277end.