zgl_application.pas 56 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822
  1. {
  2. * Copyright (c) 2012 Andrey Kemka
  3. *
  4. * This software is provided 'as-is', without any express or
  5. * implied warranty. In no event will the authors be held
  6. * liable for any damages arising from the use of this software.
  7. *
  8. * Permission is granted to anyone to use this software for any purpose,
  9. * including commercial applications, and to alter it and redistribute
  10. * it freely, subject to the following restrictions:
  11. *
  12. * 1. The origin of this software must not be misrepresented;
  13. * you must not claim that you wrote the original software.
  14. * If you use this software in a product, an acknowledgment
  15. * in the product documentation would be appreciated but
  16. * is not required.
  17. *
  18. * 2. Altered source versions must be plainly marked as such,
  19. * and must not be misrepresented as being the original software.
  20. *
  21. * 3. This notice may not be removed or altered from any
  22. * source distribution.
  23. }
  24. unit zgl_application;
  25. {$I zgl_config.cfg}
  26. {$IFDEF iOS}
  27. {$modeswitch objectivec1}
  28. {$ENDIF}
  29. interface
  30. uses
  31. {$IFDEF USE_X11}
  32. X, XLib, XRandr
  33. {$ENDIF}
  34. {$IFDEF WINDOWS}
  35. Windows, Messages
  36. {$ENDIF}
  37. {$IFDEF MACOSX}
  38. MacOSAll
  39. {$ENDIF}
  40. {$IFDEF iOS}
  41. iPhoneAll, CFRunLoop, CGGeometry, CFBase, CFString
  42. {$ENDIF}
  43. {$IFDEF ANDROID}
  44. jni
  45. {$ENDIF}
  46. ;
  47. procedure app_Init;
  48. procedure app_MainLoop;
  49. function app_CloseQuery : Boolean;
  50. procedure app_ProcessOS;
  51. {$IFDEF LINUX}
  52. function app_ProcessMessages : LongWord;
  53. {$ENDIF}
  54. {$IFDEF WINDOWS}
  55. function app_ProcessMessages( hWnd : HWND; Msg : UINT; wParam : WPARAM; lParam : LPARAM ) : LRESULT; stdcall;
  56. {$ENDIF}
  57. {$IFDEF MACOSX}
  58. function app_ProcessMessages( inHandlerCallRef: EventHandlerCallRef; inEvent: EventRef; inUserData: UnivPtr ): OSStatus; cdecl;
  59. {$ENDIF}
  60. {$IFDEF iOS}
  61. procedure app_InitPool;
  62. procedure app_FreePool;
  63. type
  64. zglCAppDelegate = objcclass(NSObject)
  65. procedure EnterMainLoop; message 'EnterMainLoop';
  66. procedure MainLoop; message 'MainLoop';
  67. procedure applicationDidFinishLaunching( application: UIApplication ); message 'applicationDidFinishLaunching:';
  68. procedure applicationWillResignActive( application: UIApplication ); message 'applicationWillResignActive:';
  69. procedure applicationDidEnterBackground( application: UIApplication ); message 'applicationDidEnterBackground:';
  70. procedure applicationWillTerminate( application: UIApplication ); message 'applicationWillTerminate:';
  71. procedure applicationWillEnterForeground( application: UIApplication ); message 'applicationWillEnterForeground:';
  72. procedure applicationDidBecomeActive( application: UIApplication ); message 'applicationDidBecomeActive:';
  73. procedure applicationDidReceiveMemoryWarning( application: UIApplication ); message 'applicationDidReceiveMemoryWarning:';
  74. // TextField
  75. function textFieldShouldBeginEditing( textField : UITextField ) : Boolean; message 'textFieldShouldBeginEditing:';
  76. function textField_shouldChangeCharactersInRange_replacementString( textField : UITextField; range : NSRange; string_ : NSString ) : Boolean; message 'textField:shouldChangeCharactersInRange:replacementString:';
  77. function textFieldShouldReturn( textField : UITextField ) : Boolean; message 'textFieldShouldReturn:';
  78. function textFieldShouldEndEditing( textField : UITextField ) : Boolean; message 'textFieldShouldEndEditing:';
  79. procedure textFieldEditingChanged; message 'textFieldEditingChanged';
  80. end;
  81. type
  82. zglCiOSViewController = objcclass(UIViewController)
  83. public
  84. function shouldAutorotateToInterfaceOrientation( interfaceOrientation : UIInterfaceOrientation ) : Boolean; override;
  85. procedure didRotateFromInterfaceOrientation( fromInterfaceOrientation : UIInterfaceOrientation ); override;
  86. function supportedInterfaceOrientations : LongWord; message 'supportedInterfaceOrientations';
  87. function shouldAutorotate : Boolean; message 'shouldAutorotate';
  88. end;
  89. type
  90. zglCiOSEAGLView = objcclass(UIView)
  91. protected
  92. procedure UpdateTouch( ID : Integer ); message 'UpdateTouch:';
  93. public
  94. class function layerClass: Pobjc_class; override;
  95. procedure touchesBegan_withEvent( touches : NSSet; event : UIevent ); override;
  96. procedure touchesMoved_withEvent( touches : NSSet; event : UIevent ); override;
  97. procedure touchesEnded_withEvent( touches : NSSet; event : UIevent ); override;
  98. procedure touchesCancelled_withEvent( touches : NSSet; event : UIevent ); override;
  99. procedure didMoveToSuperview; override;
  100. end;
  101. {$ENDIF}
  102. {$IFDEF ANDROID}
  103. function JNI_OnLoad( vm : PJavaVM; reserved : Pointer ) : jint; cdecl;
  104. function JNI_OnUnload( vm : PJavaVM; reserved : Pointer) : jint; cdecl;
  105. procedure Java_zengl_android_ZenGL_zglNativeInit( env : PJNIEnv; thiz : jobject; AppDirectory, HomeDirectory : jstring ); cdecl;
  106. procedure Java_zengl_android_ZenGL_zglNativeDestroy( env : PJNIEnv; thiz : jobject ); cdecl;
  107. procedure Java_zengl_android_ZenGL_zglNativeSurfaceCreated( env : PJNIEnv; thiz : jobject ); cdecl;
  108. procedure Java_zengl_android_ZenGL_zglNativeSurfaceChanged( env : PJNIEnv; thiz : jobject; Width, Height : jint ); cdecl;
  109. procedure Java_zengl_android_ZenGL_zglNativeDrawFrame( env : PJNIEnv; thiz : jobject ); cdecl;
  110. procedure Java_zengl_android_ZenGL_zglNativeActivate( env : PJNIEnv; thiz : jobject; Activate : jboolean ); cdecl;
  111. function Java_zengl_android_ZenGL_zglNativeCloseQuery( env : PJNIEnv; thiz : jobject ) : Boolean;
  112. procedure Java_zengl_android_ZenGL_zglNativeTouch( env : PJNIEnv; thiz : jobject; ID : jint; X, Y, Pressure : jfloat ); cdecl;
  113. procedure Java_zengl_android_ZenGL_zglNativeInputText( env : PJNIEnv; thiz : jobject; text : jstring ); cdecl;
  114. procedure Java_zengl_android_ZenGL_zglNativeBackspace( env : PJNIEnv; thiz : jobject ); cdecl;
  115. {$ENDIF}
  116. var
  117. appInitialized : Boolean;
  118. appGotSysDirs : Boolean;
  119. appWork : Boolean;
  120. appWorkTime : LongWord;
  121. appPause : Boolean;
  122. appAutoPause : Boolean = TRUE;
  123. appFocus : Boolean = TRUE;
  124. appLog : Boolean;
  125. appInitedToHandle : Boolean;
  126. appWorkDir : UTF8String;
  127. appHomeDir : UTF8String;
  128. // call-back
  129. app_PInit : procedure;
  130. app_PLoop : procedure;
  131. app_PLoad : procedure;
  132. app_PDraw : procedure;
  133. app_PExit : procedure;
  134. app_PUpdate : procedure( dt : Double );
  135. app_PActivate : procedure( activate : Boolean );
  136. app_PCloseQuery : function : Boolean;
  137. {$IFDEF iOS}
  138. app_PMemoryWarn : procedure;
  139. app_POrientation : procedure( orientation : UIInterfaceOrientation );
  140. {$ENDIF}
  141. {$IFDEF ANDROID}
  142. app_PRestore : procedure;
  143. {$ENDIF}
  144. {$IFDEF USE_X11}
  145. appCursor : TCursor = None;
  146. appXIM : PXIM;
  147. appXIC : PXIC;
  148. {$ENDIF}
  149. {$IFDEF WINDOWS}
  150. appTimer : LongWord;
  151. appMinimized : Boolean;
  152. {$ENDIF}
  153. {$IFDEF iOS}
  154. threadvar
  155. appPool : NSAutoreleasePool;
  156. appPoolInitialized : Boolean;
  157. var
  158. appDelegate : zglCAppDelegate;
  159. {$ENDIF}
  160. {$IFDEF ANDROID}
  161. appJVM : PJavaVM;
  162. appEnv : PJNIEnv;
  163. appClass : JClass;
  164. appObject : JObject;
  165. appFinish : JMethodID;
  166. appShowKeyboard : JMethodID;
  167. appHideKeyboard : JMethodID;
  168. //appIsLibrary : Byte public name 'TC_SYSTEM_ISLIBRARY'; // workaround for the latest revisions of FreePascal 2.6.x
  169. {$ENDIF}
  170. appShowCursor : Boolean;
  171. appdt : Double;
  172. appFPS : LongWord;
  173. appFPSCount : LongWord;
  174. appFPSAll : LongWord;
  175. appFlags : LongWord;
  176. implementation
  177. uses
  178. zgl_main,
  179. zgl_screen,
  180. zgl_window,
  181. {$IFNDEF USE_GLES}
  182. zgl_opengl,
  183. {$ELSE}
  184. zgl_opengles,
  185. {$ENDIF}
  186. zgl_render,
  187. {$IF DEFINED(iOS) or DEFINED(ANDROID)}
  188. zgl_touch,
  189. {$IFEND}
  190. zgl_mouse,
  191. zgl_keyboard,
  192. {$IFDEF USE_JOYSTICK}
  193. zgl_joystick,
  194. {$ENDIF}
  195. zgl_timers,
  196. zgl_resources,
  197. zgl_textures,
  198. zgl_font,
  199. {$IFDEF USE_SOUND}
  200. zgl_sound,
  201. {$ENDIF}
  202. zgl_utils;
  203. procedure app_Draw;
  204. begin
  205. SetCurrentMode();
  206. scr_Clear();
  207. if Assigned( app_PDraw ) Then
  208. app_PDraw();
  209. scr_Flush();
  210. if not appPause Then
  211. INC( appFPSCount );
  212. end;
  213. procedure app_CalcFPS;
  214. begin
  215. appFPS := appFPSCount;
  216. appFPSAll := appFPSAll + appFPSCount;
  217. appFPSCount := 0;
  218. INC( appWorkTime );
  219. end;
  220. procedure app_Init;
  221. begin
  222. managerZeroTexture := tex_CreateZero( 4, 4, $FFFFFFFF, TEX_DEFAULT_2D );
  223. SetCurrentMode();
  224. scr_Clear();
  225. if Assigned( app_PLoad ) Then
  226. app_PLoad();
  227. scr_Flush();
  228. res_Init();
  229. appdt := timer_GetTicks();
  230. timer_Reset();
  231. timer_Add( @app_CalcFPS, 1000 );
  232. end;
  233. procedure app_MainLoop;
  234. var
  235. t : Double;
  236. begin
  237. while appWork do
  238. begin
  239. app_ProcessOS();
  240. res_Proc();
  241. {$IFDEF USE_JOYSTICK}
  242. joy_Proc();
  243. {$ENDIF}
  244. {$IFDEF USE_SOUND}
  245. snd_MainLoop();
  246. {$ENDIF}
  247. if appPause Then
  248. begin
  249. timer_Reset();
  250. appdt := timer_GetTicks();
  251. u_Sleep( 10 );
  252. continue;
  253. end else
  254. timer_MainLoop();
  255. t := timer_GetTicks();
  256. {$IFDEF WINDESKTOP}
  257. // Workaround for a bug with unstable time between frames(happens when videocard trying to reclock GPU frequency/etc.)...
  258. if Assigned( app_PUpdate ) and ( scrVSync ) and ( appFPS > 0 ) and ( appFPS = scrRefresh ) and ( appFlags and APP_USE_DT_CORRECTION > 0 ) Then
  259. app_PUpdate( 1000 / appFPS )
  260. else
  261. {$ENDIF}
  262. if Assigned( app_PUpdate ) Then
  263. app_PUpdate( timer_GetTicks() - appdt );
  264. appdt := t;
  265. app_Draw();
  266. end;
  267. end;
  268. function app_CloseQuery : Boolean;
  269. begin
  270. Result := TRUE;
  271. end;
  272. procedure app_ProcessOS;
  273. {$IFDEF USE_X11}
  274. var
  275. root_return : TWindow;
  276. child_return : TWindow;
  277. root_x_return : Integer;
  278. root_y_return : Integer;
  279. mask_return : LongWord;
  280. {$ENDIF}
  281. {$IFDEF WINDOWS}
  282. var
  283. m : tagMsg;
  284. cursorpos : TPoint;
  285. {$ENDIF}
  286. {$IFDEF MACOSX}
  287. var
  288. event : EventRecord;
  289. mPos : Point;
  290. {$ENDIF}
  291. begin
  292. {$IFDEF USE_X11}
  293. XQueryPointer( scrDisplay, wndHandle, @root_return, @child_return, @root_x_return, @root_y_return, @mouseX, @mouseY, @mask_return );
  294. {$ENDIF}
  295. {$IFDEF WINDOWS}
  296. GetCursorPos( cursorpos );
  297. if wndFullScreen Then
  298. begin
  299. mouseX := cursorpos.X;
  300. mouseY := cursorpos.Y;
  301. end else
  302. begin
  303. mouseX := cursorpos.X - wndX - wndBrdSizeX;
  304. mouseY := cursorpos.Y - wndY - wndBrdSizeY - wndCpnSize;
  305. end;
  306. {$ENDIF}
  307. {$IFDEF MACOSX}
  308. GetGlobalMouse( mPos );
  309. mouseX := mPos.h - wndX;
  310. mouseY := mPos.v - wndY;
  311. {$ENDIF}
  312. if appFlags and CORRECT_RESOLUTION > 0 Then
  313. begin
  314. mouseDX := Round( ( mouseX - wndWidth div 2 - scrAddCX ) / scrResCX );
  315. mouseDY := Round( ( mouseY - wndHeight div 2 - scrAddCY ) / scrResCY );
  316. mouseX := Round( ( mouseX - scrAddCX ) / scrResCX );
  317. mouseY := Round( ( mouseY - scrAddCY ) / scrResCY );
  318. end else
  319. begin
  320. mouseDX := mouseX - wndWidth div 2;
  321. mouseDY := mouseY - wndHeight div 2;
  322. mouseX := mouseX;
  323. mouseY := mouseY;
  324. end;
  325. if ( mouseLX <> mouseX ) or ( mouseLY <> mouseY ) Then
  326. begin
  327. mouseLX := mouseX;
  328. mouseLY := mouseY;
  329. if Assigned( mouse_PMove ) Then
  330. mouse_PMove( mouseX, mouseY );
  331. end;
  332. {$IFDEF USE_X11}
  333. app_ProcessMessages();
  334. keysRepeat := 0;
  335. {$ENDIF}
  336. {$IFDEF WINDOWS}
  337. while PeekMessageW( m, 0{wnd_Handle}, 0, 0, PM_REMOVE ) do
  338. begin
  339. TranslateMessage( m );
  340. DispatchMessageW( m );
  341. end;
  342. {$ENDIF}
  343. {$IFDEF MACOSX}
  344. while GetNextEvent( everyEvent, event ) do;
  345. {$ENDIF}
  346. {$IFDEF iOS}
  347. while CFRunLoopRunInMode( kCFRunLoopDefaultMode, 0.01, TRUE ) = kCFRunLoopRunHandledSource do;
  348. {$ENDIF}
  349. end;
  350. {$IFNDEF iOS}
  351. function app_ProcessMessages;
  352. {$IFDEF MACOSX}
  353. type
  354. zglTModifier = record
  355. bit : Integer;
  356. key : Integer;
  357. end;
  358. const
  359. Modifier : array[ 0..7 ] of zglTModifier = ( ( bit: $010000; key: K_NUMLOCK ),
  360. ( bit: $008000; key: K_CTRL_R ),
  361. ( bit: $004000; key: K_ALT_R ),
  362. ( bit: $002000; key: K_SHIFT_R ),
  363. ( bit: $001000; key: K_CTRL_L ),
  364. ( bit: $000800; key: K_ALT_L ),
  365. ( bit: $000200; key: K_SHIFT_L ),
  366. ( bit: $000100; key: K_SUPER ) );
  367. {$ENDIF}
  368. var
  369. {$IFDEF USE_X11}
  370. event : TXEvent;
  371. keysym : TKeySym;
  372. status : TStatus;
  373. {$ENDIF}
  374. {$IFDEF MACOSX}
  375. eClass : UInt32;
  376. eKind : UInt32;
  377. command : HICommand;
  378. mButton : EventMouseButton;
  379. mWheel : Integer;
  380. bounds : HIRect;
  381. SCAKey : LongWord;
  382. i : Integer;
  383. {$ENDIF}
  384. len : Integer;
  385. c : array[ 0..5 ] of AnsiChar;
  386. str : UTF8String;
  387. key : LongWord;
  388. begin
  389. Result := 0;
  390. {$IFDEF USE_X11}
  391. while XPending( scrDisplay ) <> 0 do
  392. begin
  393. XNextEvent( scrDisplay, @event );
  394. if ( XRRUpdateConfiguration( @event ) = 1 ) and ( event._type - scrEventBase = RRScreenChangeNotify ) Then
  395. begin
  396. scr_Init();
  397. continue;
  398. end;
  399. if appWork Then
  400. case event._type of
  401. ClientMessage:
  402. if ( event.xclient.message_type = wndProtocols ) and ( event.xclient.data.l[ 0 ] = wndDestroyAtom ) Then appWork := not app_PCloseQuery();
  403. Expose:
  404. if appWork and appAutoPause Then
  405. app_Draw();
  406. FocusIn:
  407. begin
  408. appFocus := TRUE;
  409. appPause := FALSE;
  410. if appWork and Assigned( app_PActivate ) Then
  411. app_PActivate( TRUE );
  412. FillChar( keysDown[ 0 ], 256, 0 );
  413. key_ClearState();
  414. FillChar( mouseDown[ 0 ], 3, 0 );
  415. mouse_ClearState();
  416. end;
  417. FocusOut:
  418. begin
  419. appFocus := FALSE;
  420. if appAutoPause Then appPause := TRUE;
  421. if appWork and Assigned( app_PActivate ) Then
  422. app_PActivate( FALSE );
  423. end;
  424. ConfigureNotify:
  425. begin
  426. // For specially stupid window managers :)
  427. if wndFullScreen and ( ( event.xconfigure.x <> 0 ) or ( event.xconfigure.y <> 0 ) ) Then
  428. wnd_SetPos( 0, 0 );
  429. if ( event.xconfigure.width <> wndWidth ) or ( event.xconfigure.height <> wndHeight ) Then
  430. wnd_SetSize( wndWidth, wndHeight );
  431. end;
  432. ButtonPress:
  433. begin
  434. case event.xbutton.button of
  435. 1: // Left
  436. begin
  437. mouseDown[ M_BLEFT ] := TRUE;
  438. if mouseCanClick[ M_BLEFT ] Then
  439. begin
  440. mouseClick[ M_BLEFT ] := TRUE;
  441. mouseCanClick[ M_BLEFT ] := FALSE;
  442. if timer_GetTicks - mouseDblCTime[ M_BLEFT ] < mouseDblCInt Then
  443. mouseDblClick[ M_BLEFT ] := TRUE;
  444. mouseDblCTime[ M_BLEFT ] := timer_GetTicks();
  445. end;
  446. if Assigned( mouse_PPress ) Then
  447. mouse_PPress( M_BLEFT );
  448. end;
  449. 2: // Middle
  450. begin
  451. mouseDown[ M_BMIDDLE ] := TRUE;
  452. if mouseCanClick[ M_BMIDDLE ] Then
  453. begin
  454. mouseClick[ M_BMIDDLE ] := TRUE;
  455. mouseCanClick[ M_BMIDDLE ] := FALSE;
  456. if timer_GetTicks() - mouseDblCTime[ M_BMIDDLE ] < mouseDblCInt Then
  457. mouseDblClick[ M_BMIDDLE ] := TRUE;
  458. mouseDblCTime[ M_BMIDDLE ] := timer_GetTicks();
  459. end;
  460. if Assigned( mouse_PPress ) Then
  461. mouse_PPress( M_BMIDDLE );
  462. end;
  463. 3: // Right
  464. begin
  465. mouseDown[ M_BRIGHT ] := TRUE;
  466. if mouseCanClick[ M_BRIGHT ] Then
  467. begin
  468. mouseClick[ M_BRIGHT ] := TRUE;
  469. mouseCanClick[ M_BRIGHT ] := FALSE;
  470. if timer_GetTicks() - mouseDblCTime[ M_BRIGHT ] < mouseDblCInt Then
  471. mouseDblClick[ M_BRIGHT ] := TRUE;
  472. mouseDblCTime[ M_BRIGHT ] := timer_GetTicks();
  473. end;
  474. if Assigned( mouse_PPress ) Then
  475. mouse_PPress( M_BRIGHT );
  476. end;
  477. end;
  478. end;
  479. ButtonRelease:
  480. begin
  481. case event.xbutton.button of
  482. 1: // Left
  483. begin
  484. mouseDown[ M_BLEFT ] := FALSE;
  485. mouseUp [ M_BLEFT ] := TRUE;
  486. mouseCanClick[ M_BLEFT ] := TRUE;
  487. if Assigned( mouse_PRelease ) Then
  488. mouse_PRelease( M_BLEFT );
  489. end;
  490. 2: // Middle
  491. begin
  492. mouseDown[ M_BMIDDLE ] := FALSE;
  493. mouseUp [ M_BMIDDLE ] := TRUE;
  494. mouseCanClick[ M_BMIDDLE ] := TRUE;
  495. if Assigned( mouse_PRelease ) Then
  496. mouse_PRelease( M_BMIDDLE );
  497. end;
  498. 3: // Right
  499. begin
  500. mouseDown[ M_BRIGHT ] := FALSE;
  501. mouseUp [ M_BRIGHT ] := TRUE;
  502. mouseCanClick[ M_BRIGHT ] := TRUE;
  503. if Assigned( mouse_PRelease ) Then
  504. mouse_PRelease( M_BRIGHT );
  505. end;
  506. 4: // Up Wheel
  507. begin
  508. mouseWheel[ M_WUP ] := TRUE;
  509. if Assigned( mouse_PWheel ) Then
  510. mouse_PWheel( M_WUP );
  511. end;
  512. 5: // Down Wheel
  513. begin
  514. mouseWheel[ M_WDOWN ] := TRUE;
  515. if Assigned( mouse_PWheel ) Then
  516. mouse_PWheel( M_WDOWN );
  517. end;
  518. end;
  519. end;
  520. KeyPress:
  521. begin
  522. INC( keysRepeat );
  523. key := xkey_to_scancode( XLookupKeysym( @event.xkey, 0 ), event.xkey.keycode );
  524. keysDown[ key ] := TRUE;
  525. keysUp [ key ] := FALSE;
  526. keysLast[ KA_DOWN ] := key;
  527. doKeyPress( key );
  528. key := SCA( key );
  529. keysDown[ key ] := TRUE;
  530. keysUp [ key ] := FALSE;
  531. doKeyPress( key );
  532. if Assigned( key_PPress ) Then
  533. key_PPress( key );
  534. if keysCanText Then
  535. case key of
  536. K_SYSRQ, K_PAUSE,
  537. K_ESCAPE, K_ENTER, K_KP_ENTER,
  538. K_UP, K_DOWN, K_LEFT, K_RIGHT,
  539. K_INSERT, K_DELETE, K_HOME, K_END,
  540. K_PAGEUP, K_PAGEDOWN,
  541. K_CTRL_L, K_CTRL_R,
  542. K_ALT_L, K_ALT_R,
  543. K_SHIFT_L, K_SHIFT_R,
  544. K_SUPER_L, K_SUPER_R,
  545. K_APP_MENU,
  546. K_CAPSLOCK, K_NUMLOCK, K_SCROLL:;
  547. K_BACKSPACE: utf8_Backspace( keysText );
  548. K_TAB: key_InputText( ' ' );
  549. else
  550. len := Xutf8LookupString( appXIC, @event, @c[ 0 ], 6, @keysym, @status );
  551. if len > 0 Then
  552. begin
  553. SetLength( str, len );
  554. Move( c[ 0 ], str[ 1 ], len );
  555. key_InputText( str );
  556. end;
  557. end;
  558. end;
  559. KeyRelease:
  560. begin
  561. INC( keysRepeat );
  562. key := xkey_to_scancode( XLookupKeysym( @event.xkey, 0 ), event.xkey.keycode );
  563. keysDown[ key ] := FALSE;
  564. keysUp [ key ] := TRUE;
  565. keysLast[ KA_UP ] := key;
  566. key := SCA( key );
  567. keysDown[ key ] := FALSE;
  568. keysUp [ key ] := TRUE;
  569. if Assigned( key_PRelease ) Then
  570. key_PRelease( key );
  571. end;
  572. end
  573. end;
  574. {$ENDIF}
  575. {$IFDEF WINDOWS}
  576. if ( not appWork ) and ( Msg <> WM_ACTIVATEAPP ) Then
  577. begin
  578. Result := DefWindowProcW( hWnd, Msg, wParam, lParam );
  579. exit;
  580. end;
  581. case Msg of
  582. WM_CLOSE, WM_DESTROY, WM_QUIT:
  583. appWork := not app_PCloseQuery();
  584. WM_PAINT:
  585. begin
  586. app_Draw();
  587. ValidateRect( wndHandle, nil );
  588. end;
  589. WM_DISPLAYCHANGE:
  590. begin
  591. scr_Init();
  592. if not wndFullScreen Then
  593. wnd_Update();
  594. end;
  595. WM_SETFOCUS:
  596. begin
  597. if ( wndFullScreen ) and ( not wndFirst ) Then
  598. scr_SetOptions( scrWidth, scrHeight, scrRefresh, wndFullScreen, scrVSync );
  599. end;
  600. WM_ACTIVATEAPP:
  601. begin
  602. if appMinimized Then exit;
  603. if ( wParam > 0 ) and ( not appFocus ) Then
  604. begin
  605. appFocus := TRUE;
  606. appPause := FALSE;
  607. if appWork and Assigned( app_PActivate ) Then
  608. app_PActivate( TRUE );
  609. FillChar( keysDown[ 0 ], 256, 0 );
  610. key_ClearState();
  611. FillChar( mouseDown[ 0 ], 3, 0 );
  612. mouse_ClearState();
  613. end else
  614. if ( wParam = 0 ) and ( appFocus ) Then
  615. begin
  616. appFocus := FALSE;
  617. if appAutoPause Then appPause := TRUE;
  618. if appWork Then
  619. begin
  620. if Assigned( app_PActivate ) Then
  621. app_PActivate( FALSE );
  622. if ( wndFullScreen ) and ( not wndFirst ) Then
  623. begin
  624. scr_Reset();
  625. wnd_Update();
  626. end;
  627. end;
  628. end;
  629. end;
  630. WM_SIZE:
  631. begin
  632. if wParam = SIZE_MINIMIZED Then
  633. begin
  634. SendMessage( wndHandle, WM_ACTIVATEAPP, 0, 0 );
  635. appMinimized := TRUE;
  636. end;
  637. if ( wParam = SIZE_MAXIMIZED ) or ( wParam = SIZE_RESTORED ) Then
  638. begin
  639. appMinimized := FALSE;
  640. SendMessage( wndHandle, WM_ACTIVATEAPP, 1, 0 );
  641. end;
  642. end;
  643. WM_NCHITTEST:
  644. begin
  645. Result := DefWindowProcW( hWnd, Msg, wParam, lParam );
  646. if ( not appFocus ) and ( Result = HTCAPTION ) Then
  647. Result := HTCLIENT;
  648. end;
  649. WM_ENTERSIZEMOVE:
  650. begin
  651. if not appAutoPause Then
  652. appTimer := SetTimer( wndHandle, 1, 1, nil );
  653. end;
  654. WM_EXITSIZEMOVE:
  655. begin
  656. if appTimer > 0 Then
  657. begin
  658. KillTimer( wndHandle, appTimer );
  659. appTimer := 0;
  660. end;
  661. end;
  662. WM_MOVING:
  663. begin
  664. wndX := PRect( lParam ).Left;
  665. wndY := PRect( lParam ).Top;
  666. if appAutoPause Then
  667. timer_Reset();
  668. end;
  669. WM_TIMER:
  670. begin
  671. timer_MainLoop();
  672. app_Draw();
  673. end;
  674. WM_SETCURSOR:
  675. begin
  676. if ( appFocus ) and ( LOWORD ( lparam ) = HTCLIENT ) and ( not appShowCursor ) Then
  677. SetCursor( 0 )
  678. else
  679. SetCursor( LoadCursor( 0, IDC_ARROW ) );
  680. end;
  681. WM_LBUTTONDOWN, WM_LBUTTONDBLCLK:
  682. begin
  683. mouseDown[ M_BLEFT ] := TRUE;
  684. if mouseCanClick[ M_BLEFT ] Then
  685. begin
  686. mouseClick[ M_BLEFT ] := TRUE;
  687. mouseCanClick[ M_BLEFT ] := FALSE;
  688. end;
  689. if Msg = WM_LBUTTONDBLCLK Then
  690. mouseDblClick[ M_BLEFT ] := TRUE;
  691. if Assigned( mouse_PPress ) Then
  692. mouse_PPress( M_BLEFT );
  693. end;
  694. WM_MBUTTONDOWN, WM_MBUTTONDBLCLK:
  695. begin
  696. mouseDown[ M_BMIDDLE ] := TRUE;
  697. if mouseCanClick[ M_BMIDDLE ] Then
  698. begin
  699. mouseClick[ M_BMIDDLE ] := TRUE;
  700. mouseCanClick[ M_BMIDDLE ] := FALSE;
  701. end;
  702. if Msg = WM_MBUTTONDBLCLK Then
  703. mouseDblClick[ M_BMIDDLE ] := TRUE;
  704. if Assigned( mouse_PPress ) Then
  705. mouse_PPress( M_BMIDDLE );
  706. end;
  707. WM_RBUTTONDOWN, WM_RBUTTONDBLCLK:
  708. begin
  709. mouseDown[ M_BRIGHT ] := TRUE;
  710. if mouseCanClick[ M_BRIGHT ] Then
  711. begin
  712. mouseClick[ M_BRIGHT ] := TRUE;
  713. mouseCanClick[ M_BRIGHT ] := FALSE;
  714. end;
  715. if Msg = WM_RBUTTONDBLCLK Then
  716. mouseDblClick[ M_BRIGHT ] := TRUE;
  717. if Assigned( mouse_PPress ) Then
  718. mouse_PPress( M_BRIGHT );
  719. end;
  720. WM_LBUTTONUP:
  721. begin
  722. mouseDown[ M_BLEFT ] := FALSE;
  723. mouseUp [ M_BLEFT ] := TRUE;
  724. mouseCanClick[ M_BLEFT ] := TRUE;
  725. if Assigned( mouse_PRelease ) Then
  726. mouse_PRelease( M_BLEFT );
  727. end;
  728. WM_MBUTTONUP:
  729. begin
  730. mouseDown[ M_BMIDDLE ] := FALSE;
  731. mouseUp [ M_BMIDDLE ] := TRUE;
  732. mouseCanClick[ M_BMIDDLE ] := TRUE;
  733. if Assigned( mouse_PRelease ) Then
  734. mouse_PRelease( M_BMIDDLE );
  735. end;
  736. WM_RBUTTONUP:
  737. begin
  738. mouseDown[ M_BRIGHT ] := FALSE;
  739. mouseUp [ M_BRIGHT ] := TRUE;
  740. mouseCanClick[ M_BRIGHT ] := TRUE;
  741. if Assigned( mouse_PRelease ) Then
  742. mouse_PRelease( M_BRIGHT );
  743. end;
  744. WM_MOUSEWHEEL:
  745. begin
  746. if wParam > 0 Then
  747. begin
  748. mouseWheel[ M_WUP ] := TRUE;
  749. mouseWheel[ M_WDOWN ] := FALSE;
  750. if Assigned( mouse_PWheel ) Then
  751. mouse_PWheel( M_WUP );
  752. end else
  753. begin
  754. mouseWheel[ M_WUP ] := FALSE;
  755. mouseWheel[ M_WDOWN ] := TRUE;
  756. if Assigned( mouse_PWheel ) Then
  757. mouse_PWheel( M_WDOWN );
  758. end;
  759. end;
  760. WM_KEYDOWN, WM_SYSKEYDOWN:
  761. begin
  762. key := winkey_to_scancode( wParam );
  763. keysDown[ key ] := TRUE;
  764. keysUp [ key ] := FALSE;
  765. keysLast[ KA_DOWN ] := key;
  766. doKeyPress( key );
  767. key := SCA( key );
  768. keysDown[ key ] := TRUE;
  769. keysUp [ key ] := FALSE;
  770. doKeyPress( key );
  771. if Assigned( key_PPress ) Then
  772. key_PPress( key );
  773. if ( Msg = WM_SYSKEYDOWN ) and ( key = K_F4 ) Then
  774. appWork := not app_PCloseQuery();
  775. end;
  776. WM_KEYUP, WM_SYSKEYUP:
  777. begin
  778. key := winkey_to_scancode( wParam );
  779. keysDown[ key ] := FALSE;
  780. keysUp [ key ] := TRUE;
  781. keysLast[ KA_UP ] := key;
  782. key := SCA( key );
  783. keysDown[ key ] := FALSE;
  784. keysUp [ key ] := TRUE;
  785. if Assigned( key_PRelease ) Then
  786. key_PRelease( key );
  787. end;
  788. WM_CHAR:
  789. begin
  790. if keysCanText Then
  791. case winkey_to_scancode( wParam ) of
  792. K_ENTER:;
  793. K_BACKSPACE: utf8_Backspace( keysText );
  794. K_TAB: key_InputText( ' ' );
  795. else
  796. len := WideCharToMultiByte( CP_UTF8, 0, @wParam, 1, nil, 0, nil, nil );
  797. if len > 0 Then
  798. begin
  799. WideCharToMultiByte( CP_UTF8, 0, @wParam, 1, @c[ 0 ], 5, nil, nil );
  800. SetLength( str, len );
  801. Move( c[ 0 ], str[ 1 ], len );
  802. key_InputText( str );
  803. end;
  804. end;
  805. end;
  806. else
  807. Result := DefWindowProcW( hWnd, Msg, wParam, lParam );
  808. end;
  809. {$ENDIF}
  810. {$IFDEF MACOSX}
  811. eClass := GetEventClass( inEvent );
  812. eKind := GetEventKind( inEvent );
  813. Result := CallNextEventHandler( inHandlerCallRef, inEvent );
  814. if appWork Then
  815. case eClass of
  816. kEventClassCommand:
  817. case eKind of
  818. kEventProcessCommand:
  819. begin
  820. GetEventParameter( inEvent, kEventParamDirectObject, kEventParamHICommand, nil, SizeOf( HICommand ), nil, @command );
  821. if command.commandID = kHICommandQuit Then
  822. appWork := not app_PCloseQuery();
  823. end;
  824. end;
  825. kEventClassWindow:
  826. case eKind of
  827. kEventWindowDrawContent:
  828. begin
  829. app_Draw();
  830. end;
  831. kEventWindowActivated:
  832. begin
  833. appFocus := TRUE;
  834. appPause := FALSE;
  835. if Assigned( app_PActivate ) Then
  836. app_PActivate( TRUE );
  837. FillChar( keysDown[ 0 ], 256, 0 );
  838. key_ClearState();
  839. FillChar( mouseDown[ 0 ], 3, 0 );
  840. mouse_ClearState();
  841. if wndFullScreen Then
  842. scr_SetOptions( scrWidth, scrHeight, scrRefresh, wndFullScreen, scrVSync );
  843. end;
  844. kEventWindowDeactivated:
  845. begin
  846. appFocus := FALSE;
  847. if appAutoPause Then appPause := TRUE;
  848. if Assigned( app_PActivate ) Then
  849. app_PActivate( FALSE );
  850. if wndFullScreen Then scr_Reset();
  851. end;
  852. kEventWindowCollapsed:
  853. begin
  854. appFocus := FALSE;
  855. appPause := TRUE;
  856. end;
  857. kEventWindowClosed:
  858. begin
  859. wndHandle := nil;
  860. appWork := FALSE;
  861. end;
  862. kEventWindowBoundsChanged:
  863. begin
  864. if not wndFullScreen Then
  865. begin
  866. GetEventParameter( inEvent, kEventParamCurrentBounds, typeHIRect, nil, SizeOf( bounds ), nil, @bounds );
  867. wndX := Round( bounds.origin.x - ( bounds.size.width - wndWidth ) / 2 );
  868. wndY := Round( bounds.origin.y - ( bounds.size.height - wndHeight ) / 2 );
  869. end else
  870. begin
  871. wndX := 0;
  872. wndY := 0;
  873. end;
  874. end;
  875. end;
  876. kEventClassKeyboard:
  877. begin
  878. GetEventParameter( inEvent, kEventParamKeyCode, typeUInt32, nil, 4, nil, @Key );
  879. case eKind of
  880. kEventRawKeyModifiersChanged:
  881. begin
  882. GetEventParameter( inEvent, kEventParamKeyModifiers, typeUInt32, nil, 4, nil, @SCAKey );
  883. for i := 0 to 7 do
  884. if SCAKey and Modifier[ i ].bit > 0 Then
  885. begin
  886. if not keysDown[ Modifier[ i ].key ] Then
  887. doKeyPress( Modifier[ i ].key );
  888. keysDown[ Modifier[ i ].key ] := TRUE;
  889. keysUp [ Modifier[ i ].key ] := FALSE;
  890. keysLast[ KA_DOWN ] := Modifier[ i ].key;
  891. key := SCA( Modifier[ i ].key );
  892. if not keysDown[ key ] Then
  893. doKeyPress( key );
  894. keysDown[ key ] := TRUE;
  895. keysUp [ key ] := FALSE;
  896. end else
  897. begin
  898. if keysDown[ Modifier[ i ].key ] Then
  899. begin
  900. keysUp[ Modifier[ i ].key ] := TRUE;
  901. keysLast[ KA_UP ] := Modifier[ i ].key;
  902. end;
  903. keysDown[ Modifier[ i ].key ] := FALSE;
  904. key := SCA( Modifier[ i ].key );
  905. if keysDown[ key ] Then
  906. keysUp[ key ] := TRUE;
  907. keysDown[ key ] := FALSE;
  908. end;
  909. end;
  910. kEventRawKeyDown, kEventRawKeyRepeat:
  911. begin
  912. key := mackey_to_scancode( key );
  913. keysDown[ key ] := TRUE;
  914. keysUp [ key ] := FALSE;
  915. keysLast[ KA_DOWN ] := key;
  916. if eKind <> kEventRawKeyRepeat Then
  917. doKeyPress( key );
  918. key := SCA( key );
  919. keysDown[ key ] := TRUE;
  920. keysUp [ key ] := FALSE;
  921. if eKind <> kEventRawKeyRepeat Then
  922. doKeyPress( key );
  923. if Assigned( key_PPress ) Then
  924. key_PPress( key );
  925. if keysCanText Then
  926. case key of
  927. K_SYSRQ, K_PAUSE,
  928. K_ESCAPE, K_ENTER, K_KP_ENTER,
  929. K_UP, K_DOWN, K_LEFT, K_RIGHT,
  930. K_INSERT, K_DELETE, K_HOME, K_END,
  931. K_PAGEUP, K_PAGEDOWN,
  932. K_CTRL_L, K_CTRL_R,
  933. K_ALT_L, K_ALT_R,
  934. K_SHIFT_L, K_SHIFT_R,
  935. K_SUPER_L, K_SUPER_R,
  936. K_APP_MENU,
  937. K_CAPSLOCK, K_NUMLOCK, K_SCROLL:;
  938. K_BACKSPACE: utf8_Backspace( keysText );
  939. K_TAB: key_InputText( ' ' );
  940. else
  941. GetEventParameter( inEvent, kEventParamKeyUnicodes, typeUTF8Text, nil, 6, @len, @c[ 0 ] );
  942. if len > 0 Then
  943. begin
  944. SetLength( str, len );
  945. System.Move( c[ 0 ], str[ 1 ], len );
  946. key_InputText( str );
  947. end;
  948. end;
  949. end;
  950. kEventRawKeyUp:
  951. begin
  952. key := mackey_to_scancode( key );
  953. keysDown[ key ] := FALSE;
  954. keysUp [ key ] := TRUE;
  955. keysLast[ KA_UP ] := key;
  956. key := SCA( key );
  957. keysDown[ key ] := FALSE;
  958. keysUp [ key ] := TRUE;
  959. if Assigned( key_Prelease ) Then
  960. key_Prelease( key );
  961. end;
  962. end;
  963. end;
  964. kEventClassMouse:
  965. case eKind of
  966. kEventMouseMoved, kEventMouseDragged:
  967. begin
  968. wndMouseIn := ( mouseX >= 0 ) and ( mouseX <= wndWidth ) and ( mouseY >= 0 ) and ( mouseY <= wndHeight );
  969. if wndMouseIn Then
  970. begin
  971. if ( not appShowCursor ) and ( CGCursorIsVisible = 1 ) Then
  972. CGDisplayHideCursor( scrDisplay );
  973. if ( appShowCursor ) and ( CGCursorIsVisible = 0 ) Then
  974. CGDisplayShowCursor( scrDisplay );
  975. end else
  976. if CGCursorIsVisible = 0 Then
  977. CGDisplayShowCursor( scrDisplay );
  978. end;
  979. kEventMouseDown:
  980. begin
  981. GetEventParameter( inEvent, kEventParamMouseButton, typeMouseButton, nil, SizeOf( EventMouseButton ), nil, @mButton );
  982. // Magic Mouse !!! XD
  983. if keysDown[ K_SUPER ] and ( mButton = kEventMouseButtonPrimary ) Then
  984. mButton := kEventMouseButtonSecondary;
  985. case mButton of
  986. kEventMouseButtonPrimary: // Left
  987. begin
  988. mouseDown[ M_BLEFT ] := TRUE;
  989. if mouseCanClick[ M_BLEFT ] Then
  990. begin
  991. mouseClick[ M_BLEFT ] := TRUE;
  992. mouseCanClick[ M_BLEFT ] := FALSE;
  993. if timer_GetTicks() - mouseDblCTime[ M_BLEFT ] < mouseDblCInt Then
  994. mouseDblClick[ M_BLEFT ] := TRUE;
  995. mouseDblCTime[ M_BLEFT ] := timer_GetTicks();
  996. end;
  997. if Assigned( mouse_PPress ) Then
  998. mouse_PPress( M_BLEFT );
  999. end;
  1000. kEventMouseButtonTertiary: // Middle
  1001. begin
  1002. mouseDown[ M_BMIDDLE ] := TRUE;
  1003. if mouseCanClick[ M_BMIDDLE ] Then
  1004. begin
  1005. mouseClick[ M_BMIDDLE ] := TRUE;
  1006. mouseCanClick[ M_BMIDDLE ] := FALSE;
  1007. if timer_GetTicks() - mouseDblCTime[ M_BMIDDLE ] < mouseDblCInt Then
  1008. mouseDblClick[ M_BMIDDLE ] := TRUE;
  1009. mouseDblCTime[ M_BMIDDLE ] := timer_GetTicks();
  1010. end;
  1011. if Assigned( mouse_PPress ) Then
  1012. mouse_PPress( M_BMIDDLE );
  1013. end;
  1014. kEventMouseButtonSecondary: // Right
  1015. begin
  1016. mouseDown[ M_BRIGHT ] := TRUE;
  1017. if mouseCanClick[ M_BRIGHT ] Then
  1018. begin
  1019. mouseClick[ M_BRIGHT ] := TRUE;
  1020. mouseCanClick[ M_BRIGHT ] := FALSE;
  1021. if timer_GetTicks() - mouseDblCTime[ M_BRIGHT ] < mouseDblCInt Then
  1022. mouseDblClick[ M_BRIGHT ] := TRUE;
  1023. mouseDblCTime[ M_BRIGHT ] := timer_GetTicks();
  1024. end;
  1025. if Assigned( mouse_PPress ) Then
  1026. mouse_PPress( M_BRIGHT );
  1027. end;
  1028. end;
  1029. end;
  1030. kEventMouseUp:
  1031. begin
  1032. GetEventParameter( inEvent, kEventParamMouseButton, typeMouseButton, nil, SizeOf( EventMouseButton ), nil, @mButton );
  1033. // Magic Mouse !!! XD
  1034. if keysDown[ K_SUPER ] and ( mButton = kEventMouseButtonPrimary ) Then
  1035. mButton := kEventMouseButtonSecondary;
  1036. case mButton of
  1037. kEventMouseButtonPrimary: // Left
  1038. begin
  1039. mouseDown[ M_BLEFT ] := FALSE;
  1040. mouseUp [ M_BLEFT ] := TRUE;
  1041. mouseCanClick[ M_BLEFT ] := TRUE;
  1042. if Assigned( mouse_PRelease ) Then
  1043. mouse_PRelease( M_BLEFT );
  1044. end;
  1045. kEventMouseButtonTertiary: // Middle
  1046. begin
  1047. mouseDown[ M_BMIDDLE ] := FALSE;
  1048. mouseUp [ M_BMIDDLE ] := TRUE;
  1049. mouseCanClick[ M_BMIDDLE ] := TRUE;
  1050. if Assigned( mouse_PRelease ) Then
  1051. mouse_PRelease( M_BMIDDLE );
  1052. end;
  1053. kEventMouseButtonSecondary: // Right
  1054. begin
  1055. mouseDown[ M_BRIGHT ] := FALSE;
  1056. mouseUp [ M_BRIGHT ] := TRUE;
  1057. mouseCanClick[ M_BRIGHT ] := TRUE;
  1058. if Assigned( mouse_PRelease ) Then
  1059. mouse_PRelease( M_BRIGHT );
  1060. end;
  1061. end;
  1062. end;
  1063. kEventMouseWheelMoved:
  1064. begin
  1065. GetEventParameter( inEvent, kEventParamMouseWheelDelta, typeSInt32, nil, 4, nil, @mWheel );
  1066. if mWheel > 0 then
  1067. begin
  1068. mouseWheel[ M_WUP ] := TRUE;
  1069. if Assigned( mouse_PWheel ) Then
  1070. mouse_PWheel( M_WUP );
  1071. end else
  1072. begin
  1073. mouseWheel[ M_WDOWN ] := TRUE;
  1074. if Assigned( mouse_PWheel ) Then
  1075. mouse_PWheel( M_WDOWN );
  1076. end;
  1077. end;
  1078. end;
  1079. end;
  1080. {$ENDIF}
  1081. end;
  1082. {$ELSE}
  1083. procedure app_InitPool;
  1084. begin
  1085. if not Assigned( appPool ) Then
  1086. appPool := NSAutoreleasePool.alloc.init();
  1087. end;
  1088. procedure app_FreePool;
  1089. begin
  1090. if Assigned( appPool ) Then
  1091. appPool.release();
  1092. end;
  1093. procedure zglCAppDelegate.EnterMainLoop;
  1094. begin
  1095. zgl_Init( oglFSAA, oglStencil );
  1096. end;
  1097. procedure zglCAppDelegate.MainLoop;
  1098. var
  1099. t : Double;
  1100. begin
  1101. res_Proc();
  1102. {$IFDEF USE_JOYSTICK}
  1103. joy_Proc();
  1104. {$ENDIF}
  1105. {$IFDEF USE_SOUND}
  1106. snd_MainLoop();
  1107. {$ENDIF}
  1108. if appPause Then
  1109. begin
  1110. timer_Reset();
  1111. appdt := timer_GetTicks();
  1112. exit;
  1113. end else
  1114. timer_MainLoop();
  1115. t := timer_GetTicks();
  1116. if Assigned( app_PUpdate ) Then
  1117. app_PUpdate( timer_GetTicks() - appdt );
  1118. appdt := t;
  1119. app_Draw();
  1120. end;
  1121. procedure zglCAppDelegate.applicationDidFinishLaunching( application: UIApplication );
  1122. begin
  1123. appDelegate := Self;
  1124. scr_Init();
  1125. performSelector_withObject_afterDelay( objcselector( 'EnterMainLoop' ), nil, 0.2{magic} );
  1126. end;
  1127. procedure zglCAppDelegate.applicationWillResignActive( application : UIApplication );
  1128. begin
  1129. {$IFDEF USE_SOUND}
  1130. if sndInitialized Then AudioSessionSetActive( FALSE );
  1131. {$ENDIF}
  1132. if appAutoPause Then appPause := TRUE;
  1133. if appWork and Assigned( app_PActivate ) Then
  1134. app_PActivate( FALSE );
  1135. FillChar( touchActive[ 0 ], MAX_TOUCH, 0 );
  1136. FillChar( touchDown[ 0 ], MAX_TOUCH, 0 );
  1137. FillChar( mouseDown[ 0 ], 3, 0 );
  1138. touch_ClearState();
  1139. mouse_ClearState();
  1140. end;
  1141. procedure zglCAppDelegate.applicationDidEnterBackground( application: UIApplication );
  1142. begin
  1143. // appWork := FALSE;
  1144. end;
  1145. procedure zglCAppDelegate.applicationWillTerminate( application: UIApplication );
  1146. begin
  1147. // appWork := FALSE;
  1148. end;
  1149. procedure zglCAppDelegate.applicationWillEnterForeground( application: UIApplication );
  1150. begin
  1151. end;
  1152. procedure zglCAppDelegate.applicationDidBecomeActive( application: UIApplication );
  1153. begin
  1154. {$IFDEF USE_SOUND}
  1155. if sndInitialized Then AudioSessionSetActive( TRUE );
  1156. {$ENDIF}
  1157. appPause := FALSE;
  1158. if appWork and Assigned( app_PActivate ) Then
  1159. app_PActivate( TRUE );
  1160. end;
  1161. procedure zglCAppDelegate.applicationDidReceiveMemoryWarning;
  1162. begin
  1163. if Assigned( app_PMemoryWarn ) Then
  1164. app_PMemoryWarn();
  1165. end;
  1166. function zglCAppDelegate.textFieldShouldBeginEditing( textField : UITextField ) : Boolean;
  1167. begin
  1168. Result := keysCanText;
  1169. end;
  1170. function zglCAppDelegate.textField_shouldChangeCharactersInRange_replacementString( textField : UITextField; range : NSRange; string_ : NSString ) : Boolean;
  1171. var
  1172. buffer : array[ 0..3 ] of AnsiChar;
  1173. begin
  1174. Result := TRUE;
  1175. keysTextChanged := TRUE;
  1176. FillChar( buffer, 4, 0 );
  1177. CFStringGetCString( CFStringRef( string_ ), @buffer[ 0 ], 4, kCFStringEncodingUTF8 );
  1178. if buffer[ 0 ] = #0 Then
  1179. utf8_Backspace( keysText )
  1180. else
  1181. key_InputText( buffer );
  1182. end;
  1183. function zglCAppDelegate.textFieldShouldReturn( textField : UITextField ) : Boolean;
  1184. begin
  1185. Result := TRUE;
  1186. keysCanText := FALSE;
  1187. keysTextField.resignFirstResponder();
  1188. keysTextField.removeFromSuperview();
  1189. end;
  1190. function zglCAppDelegate.textFieldShouldEndEditing( textField : UITextField ) : Boolean;
  1191. begin
  1192. Result := textFieldShouldReturn( textField );
  1193. end;
  1194. procedure zglCAppDelegate.textFieldEditingChanged;
  1195. var
  1196. i, len : Integer;
  1197. buffer : PAnsiChar;
  1198. begin
  1199. if not keysTextChanged Then
  1200. begin
  1201. len := CFStringGetLength( CFStringRef( keysTextField.text() ) ) * 2;
  1202. zgl_GetMem( buffer, len );
  1203. CFStringGetCString( CFStringRef( keysTextField.text() ), @buffer[ 0 ], len, kCFStringEncodingUTF8 );
  1204. keysText := PAnsiChar( @buffer[ 0 ] );
  1205. zgl_FreeMem( buffer );
  1206. end else
  1207. keysTextChanged := FALSE;
  1208. end;
  1209. function zglCiOSViewController.shouldAutorotateToInterfaceOrientation( interfaceOrientation : UIInterfaceOrientation ) : Boolean;
  1210. begin
  1211. Result := ( scrCanPortrait and ( ( interfaceOrientation = UIInterfaceOrientationPortrait ) or ( interfaceOrientation = UIInterfaceOrientationPortraitUpsideDown ) ) ) or
  1212. ( scrCanLandscape and ( ( interfaceOrientation = UIInterfaceOrientationLandscapeLeft ) or ( interfaceOrientation = UIInterfaceOrientationLandscapeRight ) ) );
  1213. end;
  1214. function zglCiOSViewController.supportedInterfaceOrientations : LongWord;
  1215. begin
  1216. Result := ( 1 shl UIInterfaceOrientationPortrait + 1 shl UIInterfaceOrientationPortraitUpsideDown ) * Byte( scrCanPortrait ) +
  1217. ( 1 shl UIInterfaceOrientationLandscapeLeft + 1 shl UIInterfaceOrientationLandscapeRight ) * Byte( scrCanLandscape );
  1218. end;
  1219. function zglCiOSViewController.shouldAutorotate : Boolean;
  1220. begin
  1221. Result := TRUE;
  1222. end;
  1223. procedure zglCiOSViewController.didRotateFromInterfaceOrientation( fromInterfaceOrientation : UIInterfaceOrientation );
  1224. begin
  1225. FillChar( touchActive[ 0 ], MAX_TOUCH, 0 );
  1226. FillChar( touchDown[ 0 ], MAX_TOUCH, 0 );
  1227. FillChar( mouseDown[ 0 ], 3, 0 );
  1228. touch_ClearState();
  1229. mouse_ClearState();
  1230. scrOrientation := Self.interfaceOrientation;
  1231. if scrCanPortrait and ( ( scrOrientation = UIInterfaceOrientationPortrait ) or ( scrOrientation = UIInterfaceOrientationPortraitUpsideDown ) ) Then
  1232. begin
  1233. wndPortrait := TRUE;
  1234. scrDesktopW := scrCurrModeW;
  1235. scrDesktopH := scrCurrModeH;
  1236. end;
  1237. if scrCanLandscape and ( ( scrOrientation = UIInterfaceOrientationLandscapeLeft ) or ( scrOrientation = UIInterfaceOrientationLandscapeRight ) ) Then
  1238. begin
  1239. wndPortrait := FALSE;
  1240. scrDesktopW := scrCurrModeH;
  1241. scrDesktopH := scrCurrModeW;
  1242. end;
  1243. scr_SetOptions( scrDesktopW, scrDesktopH, REFRESH_MAXIMUM, TRUE, TRUE );
  1244. if appWork and Assigned( app_POrientation ) Then
  1245. app_POrientation( scrOrientation );
  1246. end;
  1247. class function zglCiOSEAGLView.layerClass : Pobjc_class;
  1248. begin
  1249. Result := CAEAGLLayer.classClass;
  1250. end;
  1251. procedure zglCiOSEAGLView.UpdateTouch( ID : Integer );
  1252. begin
  1253. if not touchActive[ ID ] Then
  1254. begin
  1255. touchDown[ ID ] := FALSE;
  1256. touchUp[ ID ] := TRUE;
  1257. touchTap[ ID ] := FALSE;
  1258. touchDblTap[ ID ] := FALSE;
  1259. touchCanTap[ ID ] := TRUE;
  1260. if Assigned( touch_PRelease ) Then
  1261. touch_PRelease( ID );
  1262. end else
  1263. begin
  1264. if ( not touchDown[ ID ] ) and ( not touchTap[ ID ] ) and ( touchCanTap[ ID ] ) Then
  1265. begin
  1266. touchTap[ ID ] := TRUE;
  1267. touchCanTap[ ID ] := FALSE;
  1268. if Assigned( touch_PPress ) Then
  1269. touch_PPress( ID );
  1270. end else
  1271. touchDblTap[ M_BLEFT ] := touchDown[ ID ] and ( not touchCanTap[ ID ] );
  1272. touchDown[ ID ] := TRUE;
  1273. touchUp[ ID ] := FALSE;
  1274. if Assigned( touch_PMove ) Then
  1275. touch_PMove( ID, touchX[ ID ], touchY[ ID ] );
  1276. end;
  1277. // mouse emulation
  1278. if ID = 0 Then
  1279. begin
  1280. mouseX := touchX[ 0 ];
  1281. mouseY := touchY[ 0 ];
  1282. if ( mouseLX <> mouseX ) or ( mouseLY <> mouseY ) Then
  1283. begin
  1284. mouseLX := mouseX;
  1285. mouseLY := mouseY;
  1286. if Assigned( mouse_PMove ) Then
  1287. mouse_PMove( mouseX, mouseY );
  1288. end;
  1289. if ( touchDown[ 0 ] ) and ( not mouseDown[ M_BLEFT ] ) Then
  1290. begin
  1291. mouseDown[ M_BLEFT ] := TRUE;
  1292. if mouseCanClick[ M_BLEFT ] Then
  1293. begin
  1294. mouseClick[ M_BLEFT ] := TRUE;
  1295. mouseCanClick[ M_BLEFT ] := FALSE;
  1296. if Assigned( mouse_PPress ) Then
  1297. mouse_PPress( M_BLEFT );
  1298. end;
  1299. end else
  1300. if ( not touchDown[ 0 ] ) and ( mouseDown[ M_BLEFT ] ) Then
  1301. begin
  1302. mouseDown[ M_BLEFT ] := FALSE;
  1303. mouseUp [ M_BLEFT ] := TRUE;
  1304. mouseCanClick[ M_BLEFT ] := TRUE;
  1305. if Assigned( mouse_PRelease ) Then
  1306. mouse_PRelease( M_BLEFT );
  1307. end else
  1308. if touchDown[ 0 ] Then
  1309. begin
  1310. if timer_GetTicks - mouseDblCTime[ M_BLEFT ] < mouseDblCInt Then
  1311. mouseDblClick[ M_BLEFT ] := TRUE;
  1312. mouseDblCTime[ M_BLEFT ] := timer_GetTicks();
  1313. end;
  1314. end;
  1315. end;
  1316. procedure zglCiOSEAGLView.touchesBegan_withEvent( touches : NSSet; event : UIevent );
  1317. var
  1318. i, j : Integer;
  1319. touch : UITouch;
  1320. scale : Single;
  1321. begin
  1322. scale := eglView.contentScaleFactor;
  1323. for i := 0 to touches.allObjects().count - 1 do
  1324. begin
  1325. touch := UITouch( touches.allObjects().objectAtIndex( i ) );
  1326. for j := 0 to MAX_TOUCH - 1 do
  1327. if ( ( not touchActive[ j ] ) and ( not touchUp[ j ] ) ) or ( touch.tapCount = 2 ) Then
  1328. begin
  1329. if appFlags and CORRECT_RESOLUTION > 0 Then
  1330. begin
  1331. touchX[ j ] := Round( ( touch.locationInView( Self ).x * scale - scrAddCX ) / scrResCX );
  1332. touchY[ j ] := Round( ( touch.locationInView( Self ).y * scale - scrAddCY ) / scrResCY );
  1333. end else
  1334. begin
  1335. touchX[ j ] := Round( touch.locationInView( Self ).x * scale );
  1336. touchY[ j ] := Round( touch.locationInView( Self ).y * scale );
  1337. end;
  1338. touchActive[ j ] := TRUE;
  1339. UpdateTouch( j );
  1340. break;
  1341. end;
  1342. end;
  1343. end;
  1344. procedure zglCiOSEAGLView.touchesMoved_withEvent( touches : NSSet; event : UIevent );
  1345. var
  1346. i, j : Integer;
  1347. touch : UITouch;
  1348. prevX : Integer;
  1349. prevY : Integer;
  1350. scale : Single;
  1351. begin
  1352. scale := eglView.contentScaleFactor;
  1353. for i := 0 to touches.allObjects().count - 1 do
  1354. begin
  1355. touch := UITouch( touches.allObjects().objectAtIndex( i ) );
  1356. if appFlags and CORRECT_RESOLUTION > 0 Then
  1357. begin
  1358. prevX := Round( ( touch.previousLocationInView( Self ).x * scale - scrAddCX ) / scrResCX );
  1359. prevY := Round( ( touch.previousLocationInView( Self ).y * scale - scrAddCY ) / scrResCY );
  1360. end else
  1361. begin
  1362. prevX := Round( touch.previousLocationInView( Self ).x * scale );
  1363. prevY := Round( touch.previousLocationInView( Self ).y * scale );
  1364. end;
  1365. for j := 0 to MAX_TOUCH - 1 do
  1366. if ( touchX[ j ] = prevX ) and ( touchY[ j ] = prevY ) Then
  1367. begin
  1368. if appFlags and CORRECT_RESOLUTION > 0 Then
  1369. begin
  1370. touchX[ j ] := Round( ( touch.locationInView( Self ).x * scale - scrAddCX ) / scrResCX );
  1371. touchY[ j ] := Round( ( touch.locationInView( Self ).y * scale - scrAddCY ) / scrResCY );
  1372. end else
  1373. begin
  1374. touchX[ j ] := Round( touch.locationInView( Self ).x * scale );
  1375. touchY[ j ] := Round( touch.locationInView( Self ).y * scale );
  1376. end;
  1377. touchActive[ j ] := TRUE;
  1378. UpdateTouch( j );
  1379. break;
  1380. end;
  1381. end;
  1382. end;
  1383. procedure zglCiOSEAGLView.touchesEnded_withEvent( touches : NSSet; event : UIevent );
  1384. var
  1385. i, j : Integer;
  1386. touch : UITouch;
  1387. currX : Integer;
  1388. currY : Integer;
  1389. prevX : Integer;
  1390. prevY : Integer;
  1391. scale : Single;
  1392. begin
  1393. scale := eglView.contentScaleFactor;
  1394. for i := 0 to touches.allObjects().count - 1 do
  1395. begin
  1396. touch := UITouch( touches.allObjects().objectAtIndex( i ) );
  1397. if appFlags and CORRECT_RESOLUTION > 0 Then
  1398. begin
  1399. currX := Round( ( touch.locationInView( Self ).x * scale - scrAddCX ) / scrResCX );
  1400. currY := Round( ( touch.locationInView( Self ).y * scale - scrAddCY ) / scrResCY );
  1401. prevX := Round( ( touch.previousLocationInView( Self ).x * scale - scrAddCX ) / scrResCX );
  1402. prevY := Round( ( touch.previousLocationInView( Self ).y * scale - scrAddCY ) / scrResCY );
  1403. end else
  1404. begin
  1405. currX := Round( touch.locationInView( Self ).x * scale );
  1406. currY := Round( touch.locationInView( Self ).y * scale );
  1407. prevX := Round( touch.previousLocationInView( Self ).x * scale );
  1408. prevY := Round( touch.previousLocationInView( Self ).y * scale );
  1409. end;
  1410. for j := 0 to MAX_TOUCH - 1 do
  1411. if ( ( touchX[ j ] = currX ) and ( touchY[ j ] = currY ) ) or ( ( touchX[ j ] = prevX ) and ( touchY[ j ] = prevY ) ) Then
  1412. begin
  1413. touchX[ j ] := currX;
  1414. touchY[ j ] := currY;
  1415. touchActive[ j ] := FALSE;
  1416. UpdateTouch( j );
  1417. break;
  1418. end;
  1419. end;
  1420. end;
  1421. procedure zglCiOSEAGLView.touchesCancelled_withEvent( touches : NSSet; event : UIevent );
  1422. begin
  1423. touchesEnded_withEvent( touches, event );
  1424. end;
  1425. procedure zglCiOSEAGLView.didMoveToSuperview;
  1426. begin
  1427. FillChar( touchActive[ 0 ], MAX_TOUCH, 0 );
  1428. FillChar( mouseDown[ 0 ], 3, 0 );
  1429. touch_ClearState();
  1430. mouse_ClearState();
  1431. end;
  1432. {$ENDIF}
  1433. {$IFDEF ANDROID}
  1434. function JNI_OnLoad( vm : PJavaVM; reserved : Pointer) : jint;
  1435. begin
  1436. appJVM := vm;
  1437. appJVM^.GetEnv( appJVM, @appEnv, JNI_VERSION_1_6 );
  1438. appClass := appEnv^.FindClass( appEnv, 'zengl/android/ZenGL' );
  1439. appFinish := appEnv^.GetMethodID( appEnv, appClass, 'Finish', '()V' );
  1440. appShowKeyboard := appEnv^.GetMethodID( appEnv, appClass, 'ShowKeyboard', '()V' );
  1441. appHideKeyboard := appEnv^.GetMethodID( appEnv, appClass, 'HideKeyboard', '()V' );
  1442. Result := JNI_VERSION_1_6;
  1443. end;
  1444. function JNI_OnUnload( vm : PJavaVM; reserved : Pointer) : jint;
  1445. begin
  1446. Result := 0;
  1447. end;
  1448. procedure Java_zengl_android_ZenGL_zglNativeInit( env : PJNIEnv; thiz : jobject; AppDirectory, HomeDirectory : jstring );
  1449. begin
  1450. appEnv := env;
  1451. appObject := thiz;
  1452. appWorkDir := appEnv^.GetStringUTFChars( appEnv, AppDirectory, nil );
  1453. appHomeDir := appEnv^.GetStringUTFChars( appEnv, HomeDirectory, nil ) + '/';
  1454. appGotSysDirs := TRUE;
  1455. end;
  1456. procedure Java_zengl_android_ZenGL_zglNativeDestroy( env : PJNIEnv; thiz : jobject );
  1457. begin
  1458. appEnv := env;
  1459. appObject := thiz;
  1460. appWork := FALSE;
  1461. zgl_Destroy();
  1462. end;
  1463. procedure Java_zengl_android_ZenGL_zglNativeSurfaceCreated( env : PJNIEnv; thiz : jobject );
  1464. begin
  1465. appEnv := env;
  1466. appObject := thiz;
  1467. if appInitialized Then
  1468. begin
  1469. oglVRAMUsed := 0;
  1470. gl_ResetState();
  1471. if Assigned( app_PRestore ) Then
  1472. app_PRestore();
  1473. timer_Reset();
  1474. end;
  1475. end;
  1476. procedure Java_zengl_android_ZenGL_zglNativeSurfaceChanged( env : PJNIEnv; thiz : jobject; Width, Height : jint );
  1477. begin
  1478. if not appInitialized Then
  1479. begin
  1480. scrDesktopW := Width;
  1481. scrDesktopH := Height;
  1482. wndWidth := Width;
  1483. wndHeight := Height;
  1484. zgl_Init();
  1485. end else
  1486. wnd_SetSize( Width, Height );
  1487. end;
  1488. procedure Java_zengl_android_ZenGL_zglNativeDrawFrame( env : PJNIEnv; thiz : jobject );
  1489. var
  1490. t : Double;
  1491. begin
  1492. appEnv := env;
  1493. appObject := thiz;
  1494. if not appWork Then
  1495. begin
  1496. appEnv^.CallVoidMethod( appEnv, appObject, appFinish );
  1497. exit;
  1498. end;
  1499. res_Proc();
  1500. {$IFDEF USE_JOYSTICK}
  1501. joy_Proc();
  1502. {$ENDIF}
  1503. {$IFDEF USE_SOUND}
  1504. snd_MainLoop();
  1505. {$ENDIF}
  1506. if appPause Then
  1507. begin
  1508. timer_Reset();
  1509. appdt := timer_GetTicks();
  1510. exit;
  1511. end else
  1512. timer_MainLoop();
  1513. t := timer_GetTicks();
  1514. if Assigned( app_PUpdate ) Then
  1515. app_PUpdate( timer_GetTicks() - appdt );
  1516. appdt := t;
  1517. app_Draw();
  1518. end;
  1519. procedure Java_zengl_android_ZenGL_zglNativeActivate( env : PJNIEnv; thiz : jobject; Activate : jboolean );
  1520. begin
  1521. appEnv := env;
  1522. appObject := thiz;
  1523. if Activate > 0 Then
  1524. begin
  1525. appFocus := TRUE;
  1526. appPause := FALSE;
  1527. if appWork and Assigned( app_PActivate ) Then
  1528. app_PActivate( TRUE );
  1529. FillChar( keysDown[ 0 ], 256, 0 );
  1530. key_ClearState();
  1531. FillChar( mouseDown[ 0 ], 3, 0 );
  1532. mouse_ClearState();
  1533. touch_ClearState();
  1534. timer_Reset();
  1535. end else
  1536. begin
  1537. appFocus := FALSE;
  1538. appPause := TRUE;
  1539. if appWork and Assigned( app_PActivate ) Then
  1540. app_PActivate( FALSE );
  1541. {$IFDEF USE_SOUND}
  1542. snd_MainLoop();
  1543. {$ENDIF}
  1544. end;
  1545. end;
  1546. function Java_zengl_android_ZenGL_zglNativeCloseQuery( env : PJNIEnv; thiz : jobject ) : Boolean;
  1547. begin
  1548. Result := app_PCloseQuery();
  1549. if Result Then zgl_Exit();
  1550. end;
  1551. procedure Java_zengl_android_ZenGL_zglNativeTouch( env : PJNIEnv; thiz : jobject; ID : jint; X, Y, Pressure : jfloat );
  1552. begin
  1553. if appFlags and CORRECT_RESOLUTION > 0 Then
  1554. begin
  1555. touchX[ ID ] := Round( ( X - scrAddCX ) / scrResCX );
  1556. touchY[ ID ] := Round( ( Y - scrAddCY ) / scrResCY );
  1557. end else
  1558. begin
  1559. touchX[ ID ] := Round( X );
  1560. touchY[ ID ] := Round( Y );
  1561. end;
  1562. if ( not touchDown[ ID ] ) and ( Pressure > 0 ) Then
  1563. begin
  1564. touchDown[ ID ] := TRUE;
  1565. touchUp[ ID ] := FALSE;
  1566. if touchCanTap[ ID ] Then
  1567. touchTap[ ID ] := TRUE;
  1568. if Assigned( touch_PPress ) Then
  1569. touch_PPress( ID );
  1570. end else
  1571. if ( touchDown[ ID ] ) and ( Pressure <= 0 ) Then
  1572. begin
  1573. touchDown[ ID ] := FALSE;
  1574. touchUp[ ID ] := TRUE;
  1575. touchTap[ ID ] := FALSE;
  1576. touchCanTap[ ID ] := TRUE;
  1577. if Assigned( touch_PRelease ) Then
  1578. touch_PRelease( ID );
  1579. end;
  1580. if Assigned( touch_PMove ) Then
  1581. touch_PMove( ID, touchX[ ID ], touchY[ ID ] );
  1582. // mouse emulation
  1583. if ID = 0 Then
  1584. begin
  1585. mouseX := touchX[ 0 ];
  1586. mouseY := touchY[ 0 ];
  1587. if ( mouseLX <> mouseX ) or ( mouseLY <> mouseY ) Then
  1588. begin
  1589. mouseLX := mouseX;
  1590. mouseLY := mouseY;
  1591. if Assigned( mouse_PMove ) Then
  1592. mouse_PMove( mouseX, mouseY );
  1593. end;
  1594. if ( Pressure > 0 ) and ( not mouseDown[ M_BLEFT ] ) Then
  1595. begin
  1596. mouseDown[ M_BLEFT ] := TRUE;
  1597. if mouseCanClick[ M_BLEFT ] Then
  1598. begin
  1599. mouseClick[ M_BLEFT ] := TRUE;
  1600. mouseCanClick[ M_BLEFT ] := FALSE;
  1601. if timer_GetTicks - mouseDblCTime[ M_BLEFT ] < mouseDblCInt Then
  1602. mouseDblClick[ M_BLEFT ] := TRUE;
  1603. mouseDblCTime[ M_BLEFT ] := timer_GetTicks();
  1604. if Assigned( mouse_PPress ) Then
  1605. mouse_PPress( M_BLEFT );
  1606. end;
  1607. end else
  1608. if ( Pressure <= 0 ) and ( mouseDown[ M_BLEFT ] ) Then
  1609. begin
  1610. mouseDown[ M_BLEFT ] := FALSE;
  1611. mouseUp [ M_BLEFT ] := TRUE;
  1612. mouseCanClick[ M_BLEFT ] := TRUE;
  1613. if Assigned( mouse_PRelease ) Then
  1614. mouse_PRelease( M_BLEFT );
  1615. end;
  1616. end;
  1617. end;
  1618. procedure Java_zengl_android_ZenGL_zglNativeInputText( env : PJNIEnv; thiz : jobject; text : jstring );
  1619. begin
  1620. appEnv := env;
  1621. appObject := thiz;
  1622. key_InputText( appEnv^.GetStringUTFChars( appEnv, text, nil ) );
  1623. end;
  1624. procedure Java_zengl_android_ZenGL_zglNativeBackspace( env : PJNIEnv; thiz : jobject );
  1625. begin
  1626. utf8_Backspace( keysText );
  1627. end;
  1628. {$ENDIF}
  1629. initialization
  1630. app_PInit := @app_Init;
  1631. app_PLoop := @app_MainLoop;
  1632. app_PCloseQuery := @app_CloseQuery;
  1633. appFlags := WND_USE_AUTOCENTER or APP_USE_LOG or COLOR_BUFFER_CLEAR or CLIP_INVISIBLE or APP_USE_AUTOPAUSE {$IFDEF WINDESKTOP} or APP_USE_DT_CORRECTION {$ENDIF};
  1634. {$IFDEF iOS}
  1635. appFlags := appFlags or SCR_ORIENTATION_LANDSCAPE or SCR_ORIENTATION_PORTRAIT;
  1636. {$ENDIF}
  1637. end.