antispam-bee domain was triggered too early. This is usually an indicator for some code in the plugin or theme running too early. Translations should be loaded at the init action or later. Please see Debugging in WordPress for more information. (This message was added in version 6.7.0.) in /home/ruwritingagame/public_html/wp-includes/functions.php on line 6131\u0425\u043e\u0442\u044f \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c Android assets \u0438 \u043d\u0430\u043f\u0440\u044f\u043c\u0443\u044e (\u043a\u0430\u043a \u043c\u044b \u0442\u043e\u043b\u044c\u043a\u043e-\u0447\u0442\u043e \u0441\u0434\u0435\u043b\u0430\u043b\u0438 \u0432 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u0435). \u0432\u0441\u0451 \u0436\u0435 \u043d\u0430\u0434\u043e \u043f\u043e\u043c\u043d\u0438\u0442\u044c, \u0447\u0442\u043e “\u0430\u0441\u0441\u0435\u0442\u044b” – \u044d\u0442\u043e \u041d\u0415 \u0444\u0430\u0439\u043b\u044b \u0432 \u043e\u0431\u044b\u0447\u043d\u043e\u043c \u043f\u043e\u043d\u0438\u043c\u0430\u043d\u0438\u0438. \u0420\u0430\u0437\u043d\u0438\u0446\u0430 \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e::<\/p>\n\n\n\n
\u041f\u043e\u043d\u044f\u0442\u043d\u043e, \u0447\u0442\u043e \u0432 \u0438\u0442\u043e\u0433\u0435 \u043d\u0430\u043c \u043f\u0440\u0438\u0434\u0435\u0442\u0441\u044f \u0438\u043c\u0435\u0442\u044c \u0434\u0435\u043b\u043e \u0438 \u0441 \u043e\u0431\u044b\u0447\u043d\u044b\u043c\u0438 \u0444\u0430\u0439\u043b\u0430\u043c\u0438. \u042d\u0442\u043e \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u043d\u043e-\u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u0444\u0430\u0439\u043b\u044b, \u0438\u043b\u0438 \u0434\u0430\u043d\u043d\u044b\u0435 \u044e\u0437\u0435\u0440\u0430, \u0438\u043b\u0438 \u0444\u0430\u0439\u043b\u044b, \u0441\u0433\u0440\u0443\u0436\u0435\u043d\u043d\u044b\u0435 \u0441 \u0412\u0435\u0431\u0430. \u0412 \u043b\u044e\u0431\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435, \u043c\u044b \u043d\u0435 \u0441\u043c\u043e\u0436\u0435\u043c \u043e\u0431\u0440\u0430\u0449\u0430\u0442\u044c\u0441\u044f \u0441 \u043d\u0438\u043c\u0438 \u0442\u0430\u043a \u0436\u0435 \u043a\u0430\u043a \u0441 \u0430\u0441\u0441\u0435\u0442\u0430\u043c\u0438.<\/p>\n\n\n\n
\u041a\u043e\u043d\u0435\u0447\u043d\u043e, \u043c\u043e\u0436\u043d\u043e \u043e\u0431\u0440\u0430\u0449\u0430\u0442\u044c\u0441\u044f \u0441 \u0430\u0441\u0441\u0435\u0442\u0430\u043c\u0438 \u043a\u0430\u043a \u0441 \u0430\u0441\u0441\u0435\u0442\u0430\u043c\u0438, \u0430 \u0441 \u0444\u0430\u0439\u043b\u0430\u043c\u0438 – \u043a\u0430\u043a \u0441 \u0444\u0430\u0439\u043b\u0430\u043c\u0438. \u041f\u0440\u0430\u0432\u0434\u0430, \u0442\u0430\u043a\u043e\u0439 “\u0434\u0443\u0430\u043b\u0438\u0441\u0442\u0438\u0447\u043d\u044b\u0439” \u043f\u043e\u0434\u0445\u043e\u0434 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043d\u0435 \u043e\u0447\u0435\u043d\u044c \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u043c. \u041a\u0440\u043e\u043c\u0435 \u0442\u043e\u0433\u043e, \u043d\u0430 \u0441\u0442\u043e\u0440\u043e\u043d\u0435 Windows \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0441\u0432\u043e\u044f \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u0430\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f, \u0438\u043b\u0438 \u0434\u0430\u0436\u0435 \u0441\u043a\u043e\u0440\u0435\u0435 \u0438\u043c\u0438\u0442\u0430\u0446\u0438\u044f, \u0447\u0442\u043e \u0432\u043e\u043e\u0431\u0449\u0435 \u0431\u0443\u0434\u0435\u0442 \u0437\u0430\u043f\u0443\u0442\u0430\u043d\u043d\u043e \u0438 \u043d\u0435\u043e\u0431\u043e\u0441\u043d\u043e\u0432\u0430\u043d\u043d\u043e.<\/p>\n\n\n\n
\u041a\u043e\u0440\u043e\u0447\u0435, \u0434\u0443\u043c\u0430\u0435\u0442\u0441\u044f, \u0447\u0442\u043e \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u0435\u0435 \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0441\u043f\u0430\u043a\u043e\u0432\u0430\u0442\u044c \u0430\u0441\u0441\u0435\u0442\u044b \u0438 \u0441\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0438\u0445 \u0432 \u0432\u0438\u0434\u0435 \u043e\u0431\u044b\u0447\u043d\u044b\u0445 \u0444\u0430\u0439\u043b\u043e\u0432, \u0447\u0442\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441 \u043d\u0438\u043c\u0438 \u0435\u0434\u0438\u043d\u043e\u043e\u0431\u0440\u0430\u0437\u043d\u043e \u043d\u0430 \u0432\u0441\u0435\u0445 \u043d\u0430\u0448\u0438\u0445 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0430\u0445.<\/p>\n\n\n\n
\u0418 \u0441\u043d\u043e\u0432\u0430 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430. Assets NDK \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u0432\u0438\u0434\u0438\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u0444\u0430\u0439\u043b\u044b (\u0433\u0434\u0435 \u043c\u0430\u0440\u0448\u0440\u0443\u0442 – \u043f\u0440\u043e\u0441\u0442\u043e \u0447\u0430\u0441\u0442\u044c \u0438\u043c\u0435\u043d\u0438 <\/em>\u0430\u0441\u0441\u0435\u0442\u0430), \u043d\u0435 \u043f\u043e\u0434-\u043a\u0430\u0442\u0430\u043b\u043e\u0433\u0438, \u0447\u0442\u043e \u043d\u0435 \u0434\u0430\u0435\u0442 \u043d\u0430\u043c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u043f\u0440\u043e\u0447\u0438\u0442\u0430\u0442\u044c, \u043a\u0430\u043a\u0438\u0435 \u043f\u043e\u0434-\u043a\u0430\u0442\u0430\u043b\u043e\u0433\u0438 \u0432\u043d\u0443\u0442\u0440\u0438 “dt” \u0438 \u0442\u0430\u043a \u0434\u0430\u043b\u0435\u0435. \u041d\u043e \u043c\u043e\u0436\u043d\u043e \u0432\u043e\u0441\u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435 \u043a\u0430\u0442\u0430\u043b\u043e\u0433\u0430 \u0447\u0435\u0440\u0435\u0437 Java Layer Interface. \u042f \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0441\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u0435\u0439 list_assets()<\/strong> \u043e\u0442 \u041c\u0430\u0440\u0441\u0435\u043b\u044f \u0421\u043c\u0438\u0442\u0430<\/em>. \u042d\u0442\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435 \u0437\u0430\u0434\u0430\u043d\u043d\u043e\u0433\u043e \u043a\u0430\u0442\u0430\u043b\u043e\u0433\u0430 \u0432 \u0444\u043e\u0440\u043c\u0435 \u0432\u0435\u043a\u0442\u043e\u0440\u0430 \u0441\u0442\u0440\u043e\u043a. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043e\u043d\u0430 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442, \u0447\u0442\u043e \u043a\u0430\u0442\u0430\u043b\u043e\u0433 “dt” \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 1 \u044d\u043b\u0435\u043c\u0435\u043d\u0442 “shaders”, \u0438 \u0442.\u0434. \u0421 \u0435\u0435 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043c\u044b \u0421\u041c\u041e\u0416\u0415\u041c \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u0432\u043d\u043e \u043e\u0442\u0441\u043a\u0430\u043d\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0432\u0441\u0435 \u0430\u0441\u0441\u0435\u0442\u044b, \u0432\u043a\u043b\u044e\u0447\u0430\u044f \u043f\u043e\u0434-\u043a\u0430\u0442\u0430\u043b\u043e\u0433\u0438, \u043d\u0430\u0447\u0438\u043d\u0430\u044f \u0441 \u043a\u0430\u0442\u0430\u043b\u043e\u0433\u0430 “dt” \u0438 \u0441\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0438\u0445 \u043a\u0430\u043a \u0444\u0430\u0439\u043b\u044b. <\/p>\n\n\n\n \u0414\u043b\u044f \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f (\u0437\u0430\u043f\u0438\u0441\u0438) \u0444\u0430\u0439\u043b\u043e\u0432 \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0432\u044b\u044f\u0441\u043d\u0438\u0442\u044c \u043a\u043e\u0440\u043d\u0435\u0432\u043e\u0439 \u043a\u0430\u0442\u0430\u043b\u043e\u0433 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u043a\u0430\u043a \u0438 \u0432 Windows-\u0435. \u041d\u0430 \u0432\u0441\u044f\u043a\u0438\u0439 \u0441\u043b\u0443\u0447\u0430\u0439, \u0443 \u043c\u0435\u043d\u044f \u0431\u044b\u043b \/data\/user\/0\/com.p_android\/files<\/em><\/p>\n\n\n\n \u0418 \u0435\u0449\u0435 \u043e\u0434\u043d\u043e: \u043c\u044b \u041d\u0415 \u0445\u043e\u0442\u0438\u043c \u0440\u0430\u0437\u0432\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u0442\u044c \u0430\u0441\u0441\u0435\u0442\u044b \u043f\u0440\u0438 \u043a\u0430\u0436\u0434\u043e\u043c \u0437\u0430\u043f\u0443\u0441\u043a\u0435. \u042d\u0442\u043e \u043d\u0443\u0436\u043d\u043e \u0442\u043e\u043b\u044c\u043a\u043e \u0435\u0434\u0438\u043d\u043e\u0436\u0434\u044b \u043f\u043e\u0441\u043b\u0435 \u0438\u043d\u0441\u0442\u0430\u043b\u043b\u044f\u0446\u0438\u0438 \u0438\u043b\u0438 \u0430\u043f\u0434\u044d\u0439\u0442\u0430 APK. \u041c\u044b \u0441\u043e\u0445\u0440\u0430\u043d\u0438\u043c APK’s timestamp \u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u043c \u0444\u0430\u0439\u043b\u0435, \u0438 \u043f\u043e\u0442\u043e\u043c \u0431\u0443\u0434\u0435\u043c \u0441\u0440\u0430\u0432\u043d\u0438\u0432\u0430\u0442\u044c \u0435\u0433\u043e \u0441 timestamp-\u043e\u043c \u0438\u0437 \u0441\u0430\u043c\u043e\u0433\u041e APK. \u0415\u0441\u043b\u0438 \u0441\u043e\u0432\u043f\u0430\u0434\u0430\u044e\u0442, \u0437\u043d\u0430\u0447\u0438\u0442 \u0430\u0441\u0441\u0435\u0442\u044b \u0431\u044b\u043b\u0438 \u0440\u0430\u0437\u0432\u0435\u0440\u043d\u0443\u0442\u044b \u0438\u043c\u0435\u043d\u043d\u043e \u0438\u0437 \u044d\u0442\u043e\u0433\u043e APK. \u0415\u0441\u043b\u0438 \u0436\u0435 \u043d\u0435\u0442 – \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u0430\u043f\u0434\u044d\u0439\u0442. \u041f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0433\u043e – \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u0438\u043b\u0438 \u043f\u0435\u0440\u0435\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c \u0444\u0430\u0439\u043b \u0441 \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u043d\u044b\u043c timestamp-\u043e\u043c.<\/p>\n\n\n\n \u0417\u043d\u0430\u0447\u0438\u0442, main.cpp<\/em> \u0442\u0435\u043f\u0435\u0440\u044c \u0442\u0430\u043a\u043e\u0439:<\/p>\n\n\n <\/p>\n\n\n\n \u0417\u0430\u043c\u0435\u043d\u0438\u043c main.cpp<\/em> \u043a\u043e\u0434 \u044d\u0442\u0438\u043c.<\/p>\n\n\n\n \u0412\u043a\u043b\u044e\u0447\u0430\u0435\u043c Android, \u0440\u0430\u0437\u0431\u043b\u043e\u043a\u0438\u0440\u0443\u0435\u043c,\u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u0435\u043c, \u0440\u0430\u0437\u0440\u0435\u0448\u0430\u0435\u043c.<\/p>\n\n\n\n \u0417\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c Logcat, mylog, \u043e\u0447\u0438\u0449\u0430\u0435\u043c. \u041a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u044f \u0438 \u0437\u0430\u043f\u0443\u0441\u043a.<\/p>\n\n\n\n \u0412 Logcat-\u0435 \u0432\u0438\u0434\u0438\u043c \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u0440\u0430\u0437\u0432\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u043d\u0438\u044f \u0430\u0441\u0441\u0435\u0442\u043e\u0432:<\/p>\n\n\n\n \u0422\u0435\u043f\u0435\u0440\u044c – stop debugging, \u043e\u0447\u0438\u0449\u0430\u0435\u043c Logcat, \u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c OurProject \u0441 \u0442\u0435\u043b\u0435\u0444\u043e\u043d\u0430<\/strong>.<\/p>\n\n\n\n \u0427\u0442\u043e \u0443 \u043d\u0430\u0441 \u0432 Logcat-\u0435 \u043d\u0430 \u044d\u0442\u043e\u0442 \u0440\u0430\u0437?:<\/p>\n\n\n\n Assets are up to date<\/strong>!<\/p>\n\n\n\n <\/p>\n","protected":false},"excerpt":{"rendered":" \u0425\u043e\u0442\u044f \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c Android assets \u0438 \u043d\u0430\u043f\u0440\u044f\u043c\u0443\u044e (\u043a\u0430\u043a \u043c\u044b \u0442\u043e\u043b\u044c\u043a\u043e-\u0447\u0442\u043e \u0441\u0434\u0435\u043b\u0430\u043b\u0438 \u0432 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u0435). \u0432\u0441\u0451 \u0436\u0435 \u043d\u0430\u0434\u043e \u043f\u043e\u043c\u043d\u0438\u0442\u044c, \u0447\u0442\u043e “\u0430\u0441\u0441\u0435\u0442\u044b” – \u044d\u0442\u043e \u041d\u0415 \u0444\u0430\u0439\u043b\u044b \u0432 \u043e\u0431\u044b\u0447\u043d\u043e\u043c \u043f\u043e\u043d\u0438\u043c\u0430\u043d\u0438\u0438. \u0420\u0430\u0437\u043d\u0438\u0446\u0430 \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e:: \u041a \u0410\u0441\u0441\u0435\u0442\u0430\u043c \u043d\u0435\u043b\u044c\u0437\u044f \u0434\u043e\u0441\u0442\u0443\u043f\u0438\u0442\u044c\u0441\u044f \u043e\u0431\u044b\u0447\u043d\u044b\u043c\u0438 \u0444\u0430\u0439\u043b\u043e\u0432\u044b\u043c\u0438 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0430\u043c\u0438. \u0422\u043e\u043b\u044c\u043a\u043e \u0447\u0435\u0440\u0435\u0437 \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u0439 Assets \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441. \u041e\u043d\u0438 \u0432\u0441\u0435 read-only. \u041c\u044b \u043d\u0435 \u0441\u043c\u043e\u0436\u0435\u043c \u0438\u0445 \u043c\u043e\u0434\u0438\u0444\u0438\u0446\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0438\u043b\u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0442\u044c \u043d\u043e\u0432\u044b\u0435 […]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2],"tags":[],"class_list":["post-503","post","type-post","status-publish","format-standard","hentry","category-cross-platform-3d"],"_links":{"self":[{"href":"https:\/\/writingagame.ru\/index.php\/wp-json\/wp\/v2\/posts\/503","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/writingagame.ru\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/writingagame.ru\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/writingagame.ru\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/writingagame.ru\/index.php\/wp-json\/wp\/v2\/comments?post=503"}],"version-history":[{"count":8,"href":"https:\/\/writingagame.ru\/index.php\/wp-json\/wp\/v2\/posts\/503\/revisions"}],"predecessor-version":[{"id":1656,"href":"https:\/\/writingagame.ru\/index.php\/wp-json\/wp\/v2\/posts\/503\/revisions\/1656"}],"wp:attachment":[{"href":"https:\/\/writingagame.ru\/index.php\/wp-json\/wp\/v2\/media?parent=503"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/writingagame.ru\/index.php\/wp-json\/wp\/v2\/categories?post=503"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/writingagame.ru\/index.php\/wp-json\/wp\/v2\/tags?post=503"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}\ntypedef long unsigned int size_t;\n\n#include "platform.h"\n#include "TheGame.h"\n\n#include <string>\n#include <vector>\n\n#include <sys\/stat.h>\t\/\/mkdir for Android\n\nstd::string filesRoot;\n\nTheGame theGame;\n\nstruct android_app* androidApp;\n\nASensorManager* sensorManager;\nconst ASensor* accelerometerSensor;\nASensorEventQueue* sensorEventQueue;\n\nEGLDisplay androidDisplay;\nEGLSurface androidSurface;\nEGLContext androidContext;\n\n\/**\n* Initialize an EGL context for the current display.\n*\/\nstatic int engine_init_display(struct engine* engine) {\n\t\/\/ initialize OpenGL ES and EGL\n\n\t\/*\n\t* Here specify the attributes of the desired configuration.\n\t* Below, we select an EGLConfig with at least 8 bits per color\n\t* component compatible with on-screen windows\n\t*\/\n\tconst EGLint attribs[] = {\n\t\tEGL_SURFACE_TYPE, EGL_WINDOW_BIT,\n\t\tEGL_BLUE_SIZE, 8,\n\t\tEGL_GREEN_SIZE, 8,\n\t\tEGL_RED_SIZE, 8,\n\t\tEGL_NONE\n\t};\n\tEGLint format;\n\tEGLint numConfigs;\n\tEGLConfig config;\n\tEGLSurface surface;\n\tEGLContext context;\n\n\tEGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);\n\n\teglInitialize(display, 0, 0);\n\n\t\/* Here, the application chooses the configuration it desires. In this\n\t* sample, we have a very simplified selection process, where we pick\n\t* the first EGLConfig that matches our criteria *\/\n\teglChooseConfig(display, attribs, &config, 1, &numConfigs);\n\n\t\/* EGL_NATIVE_VISUAL_ID is an attribute of the EGLConfig that is\n\t* guaranteed to be accepted by ANativeWindow_setBuffersGeometry().\n\t* As soon as we picked a EGLConfig, we can safely reconfigure the\n\t* ANativeWindow buffers to match, using EGL_NATIVE_VISUAL_ID. *\/\n\teglGetConfigAttrib(display, config, EGL_NATIVE_VISUAL_ID, &format);\n\n\tANativeWindow_setBuffersGeometry(androidApp->window, 0, 0, format);\n\n\tsurface = eglCreateWindowSurface(display, config, androidApp->window, NULL);\n\n\tEGLint contextAttribs[] =\n\t{\n\t\tEGL_CONTEXT_CLIENT_VERSION, 3,\n\t\tEGL_NONE\n\t};\n\tcontext = eglCreateContext(display, config, NULL, contextAttribs);\n\n\n\tif (eglMakeCurrent(display, surface, surface, context) == EGL_FALSE) {\n\t\tmylog("ERROR: Unable to eglMakeCurrent");\n\t\treturn -1;\n\t}\n\n\tandroidDisplay = display;\n\tandroidContext = context;\n\tandroidSurface = surface;\n\n\t\/\/ Initialize GL state.\n\tglEnable(GL_CULL_FACE);\n\tglDisable(GL_DEPTH_TEST);\n\n\treturn 0;\n}\n\n\n\/**\n* Tear down the EGL context currently associated with the display.\n*\/\nstatic void engine_term_display() {\n\n\tif (androidDisplay != EGL_NO_DISPLAY) {\n\t\teglMakeCurrent(androidDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);\n\t\tif (androidContext != EGL_NO_CONTEXT) {\n\t\t\teglDestroyContext(androidDisplay, androidContext);\n\t\t}\n\t\tif (androidSurface != EGL_NO_SURFACE) {\n\t\t\teglDestroySurface(androidDisplay, androidSurface);\n\t\t}\n\t\teglTerminate(androidDisplay);\n\t}\n\tandroidDisplay = EGL_NO_DISPLAY;\n\tandroidContext = EGL_NO_CONTEXT;\n\tandroidSurface = EGL_NO_SURFACE;\n}\n\n\/**\n* Process the next input event.\n*\/\nstatic int32_t engine_handle_input(struct android_app* app, AInputEvent* event) {\n\tif (AInputEvent_getType(event) == AINPUT_EVENT_TYPE_MOTION) {\n\t\t\/\/engine->state.x = AMotionEvent_getX(event, 0);\n\t\t\/\/engine->state.y = AMotionEvent_getY(event, 0);\n\t\treturn 1;\n\t}\n\treturn 0;\n}\n\n\/**\n* Process the next main command.\n*\/\nstatic void engine_handle_cmd(struct android_app* app, int32_t cmd) {\n\tstruct engine* engine = (struct engine*)app->userData;\n\tswitch (cmd) {\n\tcase APP_CMD_INIT_WINDOW:\n\t\t\/\/ The window is being shown, get it ready.\n\t\tif (androidApp->window != NULL) {\n\t\t\tengine_init_display(engine);\n\t\t\t\/\/engine_draw_frame(engine);\n\t\t}\n\t\tbreak;\n\tcase APP_CMD_TERM_WINDOW:\n\t\t\/\/ The window is being hidden or closed, clean it up.\n\t\tengine_term_display();\n\t\tbreak;\n\tcase APP_CMD_GAINED_FOCUS:\n\t\t\/\/ When our app gains focus, we start monitoring the accelerometer.\n\t\tif (accelerometerSensor != NULL) {\n\t\t\tASensorEventQueue_enableSensor(sensorEventQueue,\n\t\t\t\taccelerometerSensor);\n\t\t\t\/\/ We'd like to get 60 events per second (in microseconds).\n\t\t\tASensorEventQueue_setEventRate(sensorEventQueue,\n\t\t\t\taccelerometerSensor, (1000L \/ 60) * 1000);\n\t\t}\n\t\tbreak;\n\tcase APP_CMD_LOST_FOCUS:\n\t\t\/\/ When our app loses focus, we stop monitoring the accelerometer.\n\t\t\/\/ This is to avoid consuming battery while not being used.\n\t\tif (accelerometerSensor != NULL) {\n\t\t\tASensorEventQueue_disableSensor(sensorEventQueue,\n\t\t\t\taccelerometerSensor);\n\t\t}\n\t\t\/\/ Also stop animating.\n\t\t\/\/engine_draw_frame(engine);\n\t\tbreak;\n\t}\n}\nstatic std::vector<std::string> list_assets(android_app* app, const char* asset_path)\n{ \/\/by Marcel Smit, stolen from https:\/\/github.com\/android\/ndk-samples\/issues\/603\n\tstd::vector<std::string> result;\n\n\tJNIEnv* env = nullptr;\n\tapp->activity->vm->AttachCurrentThread(&env, nullptr);\n\n\tauto context_object = app->activity->clazz;\n\tauto getAssets_method = env->GetMethodID(env->GetObjectClass(context_object), "getAssets", "()Landroid\/content\/res\/AssetManager;");\n\tauto assetManager_object = env->CallObjectMethod(context_object, getAssets_method);\n\tauto list_method = env->GetMethodID(env->GetObjectClass(assetManager_object), "list", "(Ljava\/lang\/String;)[Ljava\/lang\/String;");\n\n\tjstring path_object = env->NewStringUTF(asset_path);\n\tauto files_object = (jobjectArray)env->CallObjectMethod(assetManager_object, list_method, path_object);\n\tenv->DeleteLocalRef(path_object);\n\tauto length = env->GetArrayLength(files_object);\n\n\tfor (int i = 0; i < length; i++)\n\t{\n\t\tjstring jstr = (jstring)env->GetObjectArrayElement(files_object, i);\n\t\tconst char* filename = env->GetStringUTFChars(jstr, nullptr);\n\t\tif (filename != nullptr)\n\t\t{\n\t\t\tresult.push_back(filename);\n\t\t\tenv->ReleaseStringUTFChars(jstr, filename);\n\t\t}\n\t\tenv->DeleteLocalRef(jstr);\n\t}\n\tapp->activity->vm->DetachCurrentThread();\n\treturn result;\n}\n\nint updateAssets() {\n\t\/\/get APK apkLastUpdateTime timestamp\n\tJNIEnv* env = nullptr;\n\tandroidApp->activity->vm->AttachCurrentThread(&env, nullptr);\n\tjobject context_object = androidApp->activity->clazz;\n\tjmethodID getPackageNameMid_method = env->GetMethodID(env->GetObjectClass(context_object), "getPackageName", "()Ljava\/lang\/String;");\n\tjstring packageName = (jstring)env->CallObjectMethod(context_object, getPackageNameMid_method);\n\tjmethodID getPackageManager_method = env->GetMethodID(env->GetObjectClass(context_object), "getPackageManager", "()Landroid\/content\/pm\/PackageManager;");\n\tjobject packageManager_object = env->CallObjectMethod(context_object, getPackageManager_method);\n\tjmethodID getPackageInfo_method = env->GetMethodID(env->GetObjectClass(packageManager_object), "getPackageInfo", "(Ljava\/lang\/String;I)Landroid\/content\/pm\/PackageInfo;");\n\tjobject packageInfo_object = env->CallObjectMethod(packageManager_object, getPackageInfo_method, packageName, 0x0);\n\tjfieldID updateTimeFid = env->GetFieldID(env->GetObjectClass(packageInfo_object), "lastUpdateTime", "J");\n\tlong int apkLastUpdateTime = env->GetLongField(packageInfo_object, updateTimeFid);\n\t\/\/ APK updateTime timestamp retrieved\n\t\/\/ compare with saved timestamp\n\tstd::string updateTimeFilePath = filesRoot + "\/dt\/apk_update_time.bin";\n\tFILE* inFile = fopen(updateTimeFilePath.c_str(), "r");\n\tif (inFile != NULL)\n\t{\n\t\tlong int savedUpdateTime;\n\t\tfread(&savedUpdateTime, 1, sizeof(savedUpdateTime), inFile);\n\t\tfclose(inFile);\n\t\tif (savedUpdateTime == apkLastUpdateTime) {\n\t\t\tmylog("Assets are up to date.\\n");\n\t\t\treturn 0;\n\t\t}\n\t}\n\t\/\/ if here - need to update assets\n\tAAssetManager* am = androidApp->activity->assetManager;\n\tint buffSize = 1000000; \/\/guess, should be enough?\n\tchar* buff = new char[buffSize];\n\n\tstd::vector<std::string> dirsToCheck; \/\/list of assets folders to check\n\tdirsToCheck.push_back("dt"); \/\/root folder\n\twhile (dirsToCheck.size() > 0) {\n\t\t\/\/open last element from directories vector\n\t\tstd::string dirPath = dirsToCheck.back();\n\t\tdirsToCheck.pop_back(); \/\/delete last element\n\t\t\/\/mylog("Scanning directory <%s>\\n", dirPath.c_str());\n\t\t\/\/make sure folder exists on local drive\n\t\tstd::string outPath = filesRoot + "\/" + dirPath; \/\/ .c_str();\n\t\tstruct stat info;\n\t\tint statRC = stat(outPath.c_str(), &info);\n\t\tif (statRC == 0)\n\t\t\tmylog("%s folder exists.\\n", outPath.c_str());\n\t\telse {\n\t\t\t\/\/ mylog("Try to create %s\\n", outPath.c_str());\n\t\t\tint status = mkdir(outPath.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);\n\t\t\tif (status == 0)\n\t\t\t\tmylog("%s folder added.\\n", outPath.c_str());\n\t\t\telse {\n\t\t\t\tmylog("ERROR creating, status=%d, errno: %s.\\n", status, std::strerror(errno));\n\t\t\t}\n\t\t}\n\t\t\/\/get folder's content\n\t\tstd::vector<std::string> dirItems = list_assets(androidApp, dirPath.c_str());\n\t\tint itemsN = dirItems.size();\n\t\t\/\/scan directory items\n\t\tfor (int i = 0; i < itemsN; i++) {\n\t\t\tstd::string itemPath = dirPath + "\/" + dirItems.at(i).c_str();\n\t\t\t\/\/mylog("New item: <%s> - ", itemPath.c_str());\n\t\t\t\/\/try to open it to see if it's a file\n\t\t\tAAsset* asset = AAssetManager_open(am, itemPath.c_str(), AASSET_MODE_UNKNOWN);\n\t\t\tif (asset != NULL) {\n\t\t\t\tlong size = AAsset_getLength(asset);\n\t\t\t\t\/\/mylog("It's a file, size = %d - ", size);\n\t\t\t\tif (size > buffSize) {\n\t\t\t\t\tmylog("ERROR in main.cpp->updateAssets(): File %s is too big, skipped.\\n", itemPath.c_str());\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tAAsset_read(asset, buff, size);\n\t\t\t\t\toutPath = filesRoot + "\/" + itemPath;\n\t\t\t\t\tFILE* outFile = fopen(outPath.c_str(), "w+");\n\t\t\t\t\tif (outFile != NULL)\n\t\t\t\t\t{\n\t\t\t\t\t\tfwrite(buff, 1, size, outFile);\n\t\t\t\t\t\tfflush(outFile);\n\t\t\t\t\t\tfclose(outFile);\n\t\t\t\t\t\tmylog("%s saved\\n", outPath.c_str());\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t\tmylog("ERROR in main.cpp->updateAssets(): Can't create file %s\\n", itemPath.c_str());\n\t\t\t\t}\n\t\t\t\tAAsset_close(asset);\n\t\t\t}\n\t\t\telse {\n\t\t\t\tdirsToCheck.push_back(itemPath);\n\t\t\t\t\/\/mylog("It's a folder, add to folders list to check.\\n");\n\t\t\t}\n\t\t}\n\t\tdirItems.clear();\n\t}\n\tdelete[] buff;\n\t\/\/ save updateTime\n\tFILE* outFile = fopen(updateTimeFilePath.c_str(), "w+");\n\tif (outFile != NULL)\n\t{\n\t\tfwrite(&apkLastUpdateTime, 1, sizeof(apkLastUpdateTime), outFile);\n\t\tfflush(outFile);\n\t\tfclose(outFile);\n\t}\n\telse\n\t\tmylog("ERROR creating %s\\n", updateTimeFilePath.c_str());\n\treturn 1;\n}\n\/**\n* This is the main entry point of a native application that is using\n* android_native_app_glue. It runs in its own thread, with its own\n* event loop for receiving input events and doing other things.\n*\/\nvoid android_main(struct android_app* state) {\n\n\t\/\/state->userData = &engine;\n\tstate->onAppCmd = engine_handle_cmd;\n\tstate->onInputEvent = engine_handle_input;\n\tandroidApp = state;\n\n\t\/\/ Prepare to monitor accelerometer\n\tsensorManager = ASensorManager_getInstance();\n\taccelerometerSensor = ASensorManager_getDefaultSensor(sensorManager,\n\t\tASENSOR_TYPE_ACCELEROMETER);\n\tsensorEventQueue = ASensorManager_createEventQueue(sensorManager,\n\t\tstate->looper, LOOPER_ID_USER, NULL, NULL);\n\n\t\/\/ Read all pending events.\n\tint ident;\n\tint events;\n\tstruct android_poll_source* source;\n\t\/\/wait for display\n\twhile (androidDisplay == NULL) {\n\t\t\/\/ No display yet.\n\t\t\/\/std::this_thread::sleep_for(std::chrono::seconds(1));\n\t\t\/\/mylog("No display yet\\n");\n\t\t\/\/wait for event\n\t\twhile ((ident = ALooper_pollAll(0, NULL, &events,\n\t\t\t(void**)&source)) >= 0) {\n\t\t\t\/\/ Process this event.\n\t\t\tif (source != NULL) {\n\t\t\t\tsource->process(state, source);\n\t\t\t}\n\t\t}\n\t}\n\n\tEGLint w, h;\n\teglQuerySurface(androidDisplay, androidSurface, EGL_WIDTH, &w);\n\teglQuerySurface(androidDisplay, androidSurface, EGL_HEIGHT, &h);\n\ttheGame.onScreenResize(w, h);\n\n\t\/\/retrieving files root\n\tfilesRoot.assign(androidApp->activity->internalDataPath);\n\tmylog("filesRoot = %s\\n", filesRoot.c_str());\n\n\tupdateAssets();\n\n\ttheGame.run();\n\n\tengine_term_display();\n}\n\n<\/pre><\/div>\n\n\n
<\/p>\n\n\n\n
<\/p>\n\n\n\n
\n\n\n\n