IntroRenderer.c 118 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848
  1. #include "IntroRenderer.h"
  2. #include <math.h>
  3. #include <stdlib.h>
  4. #include <jni.h>
  5. static int32_t is_initialized = 0;
  6. static float _coefficientsX[TIMING_NUM][4], _coefficientsY[TIMING_NUM][4];
  7. static const float _c0x = 0.0;
  8. static const float _c0y = 0.0;
  9. static const float _c3x = 1.0;
  10. static const float _c3y = 1.0;
  11. float scale_factor;
  12. int width, height;
  13. int y_offset_absolute;
  14. static TextureProgram texture_program;
  15. static TextureProgram texture_program_one;
  16. static TextureProgram texture_program_red;
  17. static TextureProgram texture_program_blue;
  18. static TextureProgram texture_program_light_red;
  19. static TextureProgram texture_program_light_blue;
  20. static TextureProgram *texture_program_temp;
  21. static ColorProgram color_program;
  22. static float y_offset;
  23. #define BUFFER_OFFSET(i) ((void*)(i))
  24. static const vec4 black_color = {0.0f, 0.0f, 0.0f, 1.0f};
  25. static const vec4 white_color = {1.0f, 1.0f, 1.0f, 1.0f};
  26. static LayerParams ribbonLayer, privateLayer;
  27. static TexturedShape spiral;
  28. static Shape mask1;
  29. static Shape cloud_extra_mask1;
  30. static Shape cloud_extra_mask2;
  31. static Shape cloud_extra_mask3;
  32. static Shape cloud_extra_mask4;
  33. static int surfaceCreated = 0;
  34. static Shape cloud_cover;
  35. static Shape free_bg;
  36. static TexturedShape fast_body;
  37. static TexturedShape fast_arrow_shadow;
  38. static TexturedShape fast_arrow;
  39. static TexturedShape free_knot1;
  40. static TexturedShape free_knot2;
  41. static TexturedShape free_knot3;
  42. static TexturedShape free_knot4;
  43. static Shape powerful_bg;
  44. static TexturedShape powerful_mask, powerful_infinity, powerful_infinity_white;
  45. static Shape private_bg;
  46. static TexturedShape telegram_sphere, telegram_plane, telegram_mask;
  47. static Shape cloud_bg;
  48. #define starsCount 80
  49. static TexturedShape star;
  50. static Params stars[starsCount];
  51. static Shape ribbon1;
  52. static Shape ribbon2;
  53. static Shape ribbon3;
  54. static Shape ribbon4;
  55. static mat4x4 stars_matrix;
  56. static mat4x4 main_matrix;
  57. static mat4x4 ribbons_layer;
  58. static TexturedShape ic_bubble_dot, ic_bubble, ic_cam_lens, ic_cam, ic_pencil, ic_pin, ic_smile_eye, ic_smile, ic_videocam;
  59. static GLuint ic_bubble_dot_texture, ic_bubble_texture, ic_cam_lens_texture, ic_cam_texture, ic_pencil_texture, ic_pin_texture, ic_smile_eye_texture, ic_smile_texture, ic_videocam_texture;
  60. static GLuint telegram_sphere_texture, telegram_plane_texture, telegram_mask_texture;
  61. static GLuint fast_spiral_texture, fast_body_texture, fast_arrow_texture, fast_arrow_shadow_texture;
  62. static GLuint free_knot_up_texture, free_knot_down_texture;
  63. static GLuint powerful_mask_texture, powerful_star_texture, powerful_infinity_texture, powerful_infinity_white_texture;
  64. static GLuint private_door_texture, private_screw_texture, private_keyhole_body_texture;
  65. static Shape infinity;
  66. static TexturedShape private_door, private_screw, private_keyhole_body;
  67. static Shape private_stroke;
  68. static Shape start_button;
  69. static const float r1 = 58.5f;
  70. static const float r2 = 70;
  71. static double ms0;
  72. static float date, date0;
  73. static float duration_const = 0.3f;
  74. static int32_t direct;
  75. static int32_t i;
  76. static int32_t current_page, prev_page;
  77. static float time;
  78. static mat4x4 ic_matrix;
  79. static LayerParams ic_pin_layer, ic_cam_layer, ic_videocam_layer, ic_smile_layer, ic_bubble_layer, ic_pencil_layer;
  80. static float time_local = 0;
  81. static float knot_delays[4];
  82. static float offset_y;
  83. static float ribbonLength = 86.5f;
  84. static int32_t starsFar = 500;
  85. static float scroll_offset;
  86. static float calculated_speedometer_sin;
  87. float ms0_anim;
  88. int fps_anim;
  89. int last_stars_update_fps;
  90. int count_anim_fps;
  91. static float speedometer_scroll_offset = 0, free_scroll_offset = 0, private_scroll_offset = 0;
  92. float anim_pencil_start_time, anim_pencil_start_all_time, anim_pencil_start_all_end_time;
  93. int anim_pencil_stage;
  94. int anim_bubble_dots_stage;
  95. int anim_bubble_dots_end_period;
  96. float anim_videocam_start_time, anim_videocam_next_time, anim_videocam_duration, anim_videocam_angle, anim_videocam_old_angle;
  97. float anim_cam_start_time, anim_cam_next_time, anim_cam_duration, anim_cam_angle, anim_cam_old_angle;
  98. CPoint anim_cam_position, anim_cam_old_position;
  99. int qShot;
  100. float anim_camshot_start_time, anim_camshot_duration;
  101. float anim_smile_start_time1, anim_smile_start_time2, anim_smile_blink_start_time;
  102. int anim_smile_blink_one;
  103. int anim_smile_stage;
  104. static float scale;
  105. float anim_pin_start_time, anim_pin_duration;
  106. static int32_t anim_pencil_period;
  107. static mat4x4 private_matrix;
  108. float cloud_scroll_offset;
  109. vec4 background_color = {1, 1, 1, 1};
  110. static inline void vec2_add(vec2 r, vec2 a, vec2 b) {
  111. int32_t i;
  112. for (i = 0; i < 2; ++i) {
  113. r[i] = a[i] + b[i];
  114. }
  115. }
  116. static inline float vec2_mul_inner(vec2 a, vec2 b) {
  117. float p = 0.f;
  118. int32_t i;
  119. for (i = 0; i < 2; ++i) {
  120. p += b[i] * a[i];
  121. }
  122. return p;
  123. }
  124. static inline float vec2_len(vec2 v) {
  125. return sqrtf(vec2_mul_inner(v, v));
  126. }
  127. static inline void vec2_scale(vec2 r, vec2 v, float s) {
  128. int32_t i;
  129. for (i = 0; i < 2; ++i) {
  130. r[i] = v[i] * s;
  131. }
  132. }
  133. static inline void vec2_norm(vec2 r, vec2 v) {
  134. float k = 1.f / vec2_len(v);
  135. vec2_scale(r, v, k);
  136. }
  137. static inline void mat4x4_identity(mat4x4 M) {
  138. int32_t i, j;
  139. for (i = 0; i < 4; ++i) {
  140. for (j = 0; j < 4; ++j) {
  141. M[i][j] = i == j ? 1.f : 0.f;
  142. }
  143. }
  144. }
  145. static inline void mat4x4_dup(mat4x4 M, mat4x4 N) {
  146. int32_t i, j;
  147. for (i = 0; i < 4; ++i) {
  148. for (j = 0; j < 4; ++j) {
  149. M[i][j] = N[i][j];
  150. }
  151. }
  152. }
  153. static inline void vec4_scale(vec4 r, vec4 v, float s) {
  154. int32_t i;
  155. for (i = 0; i < 4; ++i) {
  156. r[i] = v[i] * s;
  157. }
  158. }
  159. static inline void mat4x4_scale_aniso(mat4x4 M, mat4x4 a, float x, float y, float z) {
  160. vec4_scale(M[0], a[0], x);
  161. vec4_scale(M[1], a[1], y);
  162. vec4_scale(M[2], a[2], z);
  163. }
  164. static inline void mat4x4_mul(mat4x4 M, mat4x4 a, mat4x4 b) {
  165. int32_t k, r, c;
  166. for (c = 0; c < 4; ++c) {
  167. for (r = 0; r < 4; ++r) {
  168. M[c][r] = 0.f;
  169. for (k = 0; k < 4; ++k) {
  170. M[c][r] += a[k][r] * b[c][k];
  171. }
  172. }
  173. }
  174. }
  175. static inline void mat4x4_mul_vec4(vec4 r, mat4x4 M, vec4 v) {
  176. int32_t i, j;
  177. for (j = 0; j < 4; ++j) {
  178. r[j] = 0.f;
  179. for (i = 0; i < 4; ++i) {
  180. r[j] += M[i][j] * v[i];
  181. }
  182. }
  183. }
  184. static inline void mat4x4_translate(mat4x4 T, float x, float y, float z) {
  185. mat4x4_identity(T);
  186. T[3][0] = x;
  187. T[3][1] = y;
  188. T[3][2] = z;
  189. }
  190. static inline void mat4x4_rotate_Z2(mat4x4 Q, mat4x4 M, float angle) {
  191. float s = sinf(angle);
  192. float c = cosf(angle);
  193. mat4x4 R = {
  194. {c, s, 0.f, 0.f},
  195. {-s, c, 0.f, 0.f},
  196. {0.f, 0.f, 1.f, 0.f},
  197. {0.f, 0.f, 0.f, 1.f}
  198. };
  199. mat4x4_mul(Q, M, R);
  200. }
  201. static inline void mat4x4_rotate_Z(mat4x4 Q, float angle) {
  202. mat4x4 temp;
  203. mat4x4_dup(temp, Q);
  204. mat4x4_rotate_Z2(Q, temp, angle);
  205. }
  206. static inline void mat4x4_translate_in_place(mat4x4 m, float x, float y, float z) {
  207. int32_t i;
  208. for (i = 0; i < 4; ++i) {
  209. m[3][i] += m[0][i] * x + m[1][i] * y + m[2][i] * z;
  210. }
  211. }
  212. static inline float deg_to_radf(float deg) {
  213. return deg * (float) M_PI / 180.0f;
  214. }
  215. static inline float MAXf(float a, float b) {
  216. return a > b ? a : b;
  217. }
  218. static inline float MINf(float a, float b) {
  219. return a < b ? a : b;
  220. }
  221. GLuint compile_shader(const GLenum type, const GLchar* source, const GLint length) {
  222. GLuint shader_object_id = glCreateShader(type);
  223. GLint compile_status;
  224. glShaderSource(shader_object_id, 1, &source, &length);
  225. glCompileShader(shader_object_id);
  226. glGetShaderiv(shader_object_id, GL_COMPILE_STATUS, &compile_status);
  227. return shader_object_id;
  228. }
  229. GLuint link_program(const GLuint vertex_shader, const GLuint fragment_shader) {
  230. GLuint program_object_id = glCreateProgram();
  231. GLint link_status;
  232. glAttachShader(program_object_id, vertex_shader);
  233. glAttachShader(program_object_id, fragment_shader);
  234. glLinkProgram(program_object_id);
  235. glGetProgramiv(program_object_id, GL_LINK_STATUS, &link_status);
  236. return program_object_id;
  237. }
  238. GLuint build_program(const GLchar * vertex_shader_source, const GLint vertex_shader_source_length, const GLchar * fragment_shader_source, const GLint fragment_shader_source_length) {
  239. GLuint vertex_shader = compile_shader(GL_VERTEX_SHADER, vertex_shader_source, vertex_shader_source_length);
  240. GLuint fragment_shader = compile_shader(GL_FRAGMENT_SHADER, fragment_shader_source, fragment_shader_source_length);
  241. return link_program(vertex_shader, fragment_shader);
  242. }
  243. GLuint create_vbo(const GLsizeiptr size, const GLvoid* data, const GLenum usage) {
  244. GLuint vbo_object;
  245. glGenBuffers(1, &vbo_object);
  246. glBindBuffer(GL_ARRAY_BUFFER, vbo_object);
  247. glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr) size, data, usage);
  248. glBindBuffer(GL_ARRAY_BUFFER, 0);
  249. return vbo_object;
  250. }
  251. TextureProgram get_texture_program(GLuint program) {
  252. return (TextureProgram) {
  253. program,
  254. (GLuint) glGetAttribLocation(program, "a_Position"),
  255. (GLuint) glGetAttribLocation(program, "a_TextureCoordinates"),
  256. glGetUniformLocation(program, "u_MvpMatrix"),
  257. glGetUniformLocation(program, "u_TextureUnit"),
  258. glGetUniformLocation(program, "u_Alpha")};
  259. }
  260. ColorProgram get_color_program(GLuint program) {
  261. return (ColorProgram) {
  262. program,
  263. (GLuint) glGetAttribLocation(program, "a_Position"),
  264. glGetUniformLocation(program, "u_MvpMatrix"),
  265. glGetUniformLocation(program, "u_Color"),
  266. glGetUniformLocation(program, "u_Alpha")};
  267. }
  268. float frand(float from, float to) {
  269. return (float) (((double) random() / RAND_MAX) * (to - from) + from);
  270. }
  271. int irand(int32_t from, int32_t to) {
  272. return (int32_t) (((double) random() / RAND_MAX) * (to - from + 1) + from);
  273. }
  274. int signrand() {
  275. return irand(0, 1) * 2 - 1;
  276. }
  277. static inline float evaluateAtParameterWithCoefficients(float t, float coefficients[]) {
  278. return coefficients[0] + t * coefficients[1] + t * t * coefficients[2] + t * t * t * coefficients[3];
  279. }
  280. static inline float evaluateDerivationAtParameterWithCoefficients(float t, float coefficients[]) {
  281. return coefficients[1] + 2 * t * coefficients[2] + 3 * t * t * coefficients[3];
  282. }
  283. static inline float calcParameterViaNewtonRaphsonUsingXAndCoefficientsForX(float x, float coefficientsX[]) {
  284. float t = x;
  285. int32_t i;
  286. for (i = 0; i < 10; i++) {
  287. float x2 = evaluateAtParameterWithCoefficients(t, coefficientsX) - x;
  288. float d = evaluateDerivationAtParameterWithCoefficients(t, coefficientsX);
  289. float dt = x2 / d;
  290. t = t - dt;
  291. }
  292. return t;
  293. }
  294. float timing(float x, timing_type type) {
  295. if (is_initialized == 0) {
  296. is_initialized = 1;
  297. float c[TIMING_NUM][4];
  298. c[Default][0] = 0.25f;
  299. c[Default][1] = 0.1f;
  300. c[Default][2] = 0.25f;
  301. c[Default][3] = 1.0f;
  302. c[EaseInEaseOut][0] = 0.42f;
  303. c[EaseInEaseOut][1] = 0.0f;
  304. c[EaseInEaseOut][2] = 0.58f;
  305. c[EaseInEaseOut][3] = 1.0f;
  306. c[EaseIn][0] = 0.42f;
  307. c[EaseIn][1] = 0.0f;
  308. c[EaseIn][2] = 1.0f;
  309. c[EaseIn][3] = 1.0f;
  310. c[EaseOut][0] = 0.0f;
  311. c[EaseOut][1] = 0.0f;
  312. c[EaseOut][2] = 0.58f;
  313. c[EaseOut][3] = 1.0f;
  314. c[EaseOutBounce][0] = 0.0f;
  315. c[EaseOutBounce][1] = 0.0f;
  316. c[EaseOutBounce][2] = 0.0f;
  317. c[EaseOutBounce][3] = 1.25;
  318. c[Linear][0] = 0.0;
  319. c[Linear][1] = 0.0;
  320. c[Linear][2] = 1.0;
  321. c[Linear][3] = 1.0;
  322. int32_t i;
  323. for (i = 0; i < TIMING_NUM; i++) {
  324. float _c1x = c[i][0];
  325. float _c1y = c[i][1];
  326. float _c2x = c[i][2];
  327. float _c2y = c[i][3];
  328. _coefficientsX[i][0] = _c0x;
  329. _coefficientsX[i][1] = -3.0f * _c0x + 3.0f * _c1x;
  330. _coefficientsX[i][2] = 3.0f * _c0x - 6.0f * _c1x + 3.0f * _c2x;
  331. _coefficientsX[i][3] = -_c0x + 3.0f * _c1x - 3.0f * _c2x + _c3x;
  332. _coefficientsY[i][0] = _c0y;
  333. _coefficientsY[i][1] = -3.0f * _c0y + 3.0f * _c1y;
  334. _coefficientsY[i][2] = 3.0f * _c0y - 6.0f * _c1y + 3.0f * _c2y;
  335. _coefficientsY[i][3] = -_c0y + 3.0f * _c1y - 3.0f * _c2y + _c3y;
  336. }
  337. }
  338. if (x == 0.0 || x == 1.0) {
  339. return x;
  340. }
  341. float t = calcParameterViaNewtonRaphsonUsingXAndCoefficientsForX(x, _coefficientsX[type]);
  342. float y = evaluateAtParameterWithCoefficients(t, _coefficientsY[type]);
  343. return y;
  344. }
  345. void set_y_offset_objects(float a) {
  346. y_offset = a;
  347. }
  348. void setup_shaders() {
  349. const char *vshader =
  350. "uniform mat4 u_MvpMatrix;"
  351. "attribute vec4 a_Position;"
  352. "void main(){"
  353. " gl_Position = u_MvpMatrix * a_Position;"
  354. "}";
  355. const char *fshader =
  356. "precision lowp float;"
  357. "uniform vec4 u_Color;"
  358. "uniform float u_Alpha;"
  359. "void main() {"
  360. " gl_FragColor = u_Color;"
  361. " gl_FragColor.w*=u_Alpha;"
  362. "}";
  363. color_program = get_color_program(build_program(vshader, (GLint) strlen(vshader), fshader, (GLint) strlen(fshader)));
  364. const char *vshader_texture =
  365. "uniform mat4 u_MvpMatrix;"
  366. "attribute vec4 a_Position;"
  367. "attribute vec2 a_TextureCoordinates;"
  368. "varying vec2 v_TextureCoordinates;"
  369. "void main(){"
  370. " v_TextureCoordinates = a_TextureCoordinates;"
  371. " gl_Position = u_MvpMatrix * a_Position;"
  372. "}";
  373. const char *fshader_texture =
  374. "precision lowp float;"
  375. "uniform sampler2D u_TextureUnit;"
  376. "varying vec2 v_TextureCoordinates;"
  377. "uniform float u_Alpha;"
  378. "void main(){"
  379. " gl_FragColor = texture2D(u_TextureUnit, v_TextureCoordinates);"
  380. " gl_FragColor.w *= u_Alpha;"
  381. "}";
  382. texture_program = get_texture_program(build_program(vshader_texture, (GLint) strlen(vshader_texture), fshader_texture, (GLint) strlen(fshader_texture)));
  383. const char *vshader_texture_blue =
  384. "uniform mat4 u_MvpMatrix;"
  385. "attribute vec4 a_Position;"
  386. "attribute vec2 a_TextureCoordinates;"
  387. "varying vec2 v_TextureCoordinates;"
  388. "void main(){"
  389. " v_TextureCoordinates = a_TextureCoordinates;"
  390. " gl_Position = u_MvpMatrix * a_Position;"
  391. "}";
  392. const char *fshader_texture_blue =
  393. "precision lowp float;"
  394. "uniform sampler2D u_TextureUnit;"
  395. "varying vec2 v_TextureCoordinates;"
  396. "uniform float u_Alpha;"
  397. "void main(){"
  398. " gl_FragColor = texture2D(u_TextureUnit, v_TextureCoordinates);"
  399. " float p = u_Alpha*gl_FragColor.w;"
  400. " gl_FragColor = vec4(0,0.6,0.898,p);"
  401. "}";
  402. texture_program_blue = get_texture_program(build_program(vshader_texture_blue, (GLint) strlen(vshader_texture_blue), fshader_texture_blue, (GLint) strlen(fshader_texture_blue)));
  403. const char *vshader_texture_red =
  404. "uniform mat4 u_MvpMatrix;"
  405. "attribute vec4 a_Position;"
  406. "attribute vec2 a_TextureCoordinates;"
  407. "varying vec2 v_TextureCoordinates;"
  408. "void main(){"
  409. " v_TextureCoordinates = a_TextureCoordinates;"
  410. " gl_Position = u_MvpMatrix * a_Position;"
  411. "}";
  412. const char *fshader_texture_red =
  413. "precision lowp float;"
  414. "uniform sampler2D u_TextureUnit;"
  415. "varying vec2 v_TextureCoordinates;"
  416. "uniform float u_Alpha;"
  417. "void main(){"
  418. " gl_FragColor = texture2D(u_TextureUnit, v_TextureCoordinates);"
  419. " float p = gl_FragColor.w*u_Alpha;"
  420. " gl_FragColor = vec4(210./255.,57./255.,41./255.,p);"
  421. "}";
  422. texture_program_red = get_texture_program(build_program(vshader_texture_red, (GLint) strlen(vshader_texture_red), fshader_texture_red, (GLint) strlen(fshader_texture_red)));
  423. vshader =
  424. "uniform mat4 u_MvpMatrix;"
  425. "attribute vec4 a_Position;"
  426. "attribute vec2 a_TextureCoordinates;"
  427. "varying vec2 v_TextureCoordinates;"
  428. "void main(){"
  429. " v_TextureCoordinates = a_TextureCoordinates;"
  430. " gl_Position = u_MvpMatrix * a_Position;"
  431. "}";
  432. fshader =
  433. "precision lowp float;"
  434. "uniform sampler2D u_TextureUnit;"
  435. "varying vec2 v_TextureCoordinates;"
  436. "uniform float u_Alpha;"
  437. "void main(){"
  438. " gl_FragColor = texture2D(u_TextureUnit, v_TextureCoordinates);"
  439. " float p = u_Alpha*gl_FragColor.w;"
  440. " gl_FragColor = vec4(246./255., 73./255., 55./255., p);"
  441. "}";
  442. texture_program_light_red = get_texture_program(build_program(vshader, (GLint) strlen(vshader), fshader, (GLint) strlen(fshader)));
  443. vshader =
  444. "uniform mat4 u_MvpMatrix;"
  445. "attribute vec4 a_Position;"
  446. "attribute vec2 a_TextureCoordinates;"
  447. "varying vec2 v_TextureCoordinates;"
  448. "void main(){"
  449. " v_TextureCoordinates = a_TextureCoordinates;"
  450. " gl_Position = u_MvpMatrix * a_Position;"
  451. "}";
  452. fshader =
  453. "precision lowp float;"
  454. "uniform sampler2D u_TextureUnit;"
  455. "varying vec2 v_TextureCoordinates;"
  456. "uniform float u_Alpha;"
  457. "void main(){"
  458. " gl_FragColor = texture2D(u_TextureUnit, v_TextureCoordinates);"
  459. " float p = u_Alpha*gl_FragColor.w;"
  460. " gl_FragColor = vec4(42./255.,180./255.,247./255.,p);"
  461. "}";
  462. texture_program_light_blue = get_texture_program(build_program(vshader, (GLint) strlen(vshader), fshader, (GLint) strlen(fshader)));
  463. vshader =
  464. "uniform mat4 u_MvpMatrix;"
  465. "attribute vec4 a_Position;"
  466. "attribute vec2 a_TextureCoordinates;"
  467. "varying vec2 v_TextureCoordinates;"
  468. "void main(){"
  469. " v_TextureCoordinates = a_TextureCoordinates;"
  470. " gl_Position = u_MvpMatrix * a_Position;"
  471. "}";
  472. fshader =
  473. "precision lowp float;"
  474. "uniform sampler2D u_TextureUnit;"
  475. "varying vec2 v_TextureCoordinates;"
  476. "uniform float u_Alpha;"
  477. "void main(){"
  478. " gl_FragColor = texture2D(u_TextureUnit, v_TextureCoordinates);"
  479. " gl_FragColor *= u_Alpha;"
  480. "}";
  481. texture_program_one = get_texture_program(build_program(vshader, (GLint) strlen(vshader), fshader, (GLint) strlen(fshader)));
  482. }
  483. CPoint CPointMake(float x, float y) {
  484. CPoint p = {x, y};
  485. return p;
  486. }
  487. CSize CSizeMake(float width, float height) {
  488. CSize s = {width, height};
  489. return s;
  490. }
  491. float D2R(float a) {
  492. return (float) (a * M_PI / 180.0);
  493. }
  494. float R2D(float a) {
  495. return (float) (a * 180.0 / M_PI);
  496. }
  497. xyz xyzMake(float x, float y, float z) {
  498. xyz result;
  499. result.x = x;
  500. result.y = y;
  501. result.z = z;
  502. return result;
  503. }
  504. LayerParams default_layer_params() {
  505. LayerParams params;
  506. params.anchor.x = params.anchor.y = params.anchor.z = 0;
  507. params.position.x = params.position.y = params.position.z = 0;
  508. params.rotation = 0;
  509. params.scale.x = params.scale.y = params.scale.z = 1.0f;
  510. return params;
  511. }
  512. Params default_params() {
  513. Params params;
  514. params.anchor.x = params.anchor.y = params.anchor.z = 0.0f;
  515. params.position.x = params.position.y = params.position.z = 0.0f;
  516. params.rotation = 0;
  517. params.scale.x = params.scale.y = params.scale.z = 1.0f;
  518. params.alpha = 1.0f;
  519. params.var_params.side_length = 0;
  520. params.var_params.start_angle = 0;
  521. params.var_params.end_angle = 0;
  522. params.var_params.angle = 0;
  523. params.var_params.size = CSizeMake(0, 0);
  524. params.var_params.radius = 0;
  525. params.var_params.width = 0;
  526. params.const_params.is_star = 0;
  527. params.layer_params = default_layer_params();
  528. return params;
  529. }
  530. void mat4x4_translate_independed(mat4x4 m, float x, float y, float z) {
  531. mat4x4 tr;
  532. mat4x4_identity(tr);
  533. mat4x4_translate_in_place(tr, x, y, z);
  534. mat4x4 m_dup;
  535. mat4x4_dup(m_dup, m);
  536. mat4x4_mul(m, tr, m_dup);
  537. }
  538. static inline void mvp_matrix(mat4x4 model_view_projection_matrix, Params params, mat4x4 view_projection_matrix) {
  539. mat4x4 model_matrix;
  540. mat4x4_identity(model_matrix);
  541. mat4x4 id;
  542. mat4x4_identity(id);
  543. mat4x4_translate(model_matrix, -params.anchor.x, -params.anchor.y, params.anchor.z);
  544. mat4x4 scaled;
  545. mat4x4_identity(scaled);
  546. mat4x4_scale_aniso(scaled, scaled, params.scale.x, -params.scale.y, params.scale.z);
  547. mat4x4 tmp;
  548. mat4x4_dup(tmp, model_matrix);
  549. mat4x4_mul(model_matrix, scaled, tmp);
  550. mat4x4 rotate;
  551. mat4x4_dup(rotate, id);
  552. mat4x4_rotate_Z2(rotate, id, deg_to_radf(-params.rotation));
  553. mat4x4_dup(tmp, model_matrix);
  554. mat4x4_mul(model_matrix, rotate, tmp);
  555. mat4x4_translate_independed(model_matrix, params.position.x, -params.position.y, params.position.z);
  556. mat4x4 model_matrix3;
  557. mat4x4_identity(model_matrix3);
  558. mat4x4 mm;
  559. mat4x4_mul(mm, model_matrix3, view_projection_matrix);
  560. mat4x4_mul(model_view_projection_matrix, mm, model_matrix);
  561. mat4x4_translate_independed(model_view_projection_matrix, 0, -y_offset / view_projection_matrix[3][3], 0);
  562. }
  563. void draw_shape(const Shape* shape, mat4x4 view_projection_matrix) {
  564. if (shape->params.alpha > 0 && (fabs(shape->params.scale.x) > 0 && fabs(shape->params.scale.y) > 0 && fabs(shape->params.scale.z) > 0)) {
  565. mat4x4 model_view_projection_matrix;
  566. mvp_matrix(model_view_projection_matrix, shape->params, view_projection_matrix);
  567. glUseProgram(color_program.program);
  568. glUniformMatrix4fv(color_program.u_mvp_matrix_location, 1, GL_FALSE, (GLfloat *) model_view_projection_matrix);
  569. if (shape->params.rotation == 5.0f) {
  570. glUniform4fv(color_program.u_color_location, 1, shape->color);
  571. } else if (shape->params.rotation == 10.0f) {
  572. vec4 col = {0, 1, 0, 1};
  573. glUniform4fv(color_program.u_color_location, 1, col);
  574. } else {
  575. glUniform4fv(color_program.u_color_location, 1, shape->color);
  576. }
  577. glUniform1f(color_program.u_alpha_loaction, shape->params.alpha);
  578. glVertexAttribPointer(color_program.a_position_location, 2, GL_FLOAT, GL_FALSE, sizeof(CPoint), &shape->data[0].x);
  579. glEnableVertexAttribArray(color_program.a_position_location);
  580. glDrawArrays(shape->params.const_params.triangle_mode, 0, shape->num_points);
  581. }
  582. }
  583. void draw_textured_shape(const TexturedShape* shape, mat4x4 view_projection_matrix, texture_program_type program_type) {
  584. if (shape->params.alpha > 0 && (fabs(shape->params.scale.x) > 0 && fabs(shape->params.scale.y) > 0 && fabs(shape->params.scale.z) > 0)) {
  585. mat4x4 model_view_projection_matrix;
  586. mvp_matrix(model_view_projection_matrix, shape->params, view_projection_matrix);
  587. if (shape->params.const_params.is_star == 1) {
  588. vec4 pos;
  589. vec4 vertex = {0, 0, 0, 1};
  590. mat4x4_mul_vec4(pos, model_view_projection_matrix, vertex);
  591. vec4 p_NDC = {pos[0] / pos[3], pos[1] / pos[3], pos[2] / pos[3], pos[3] / pos[3]};
  592. vec4 p_window = {p_NDC[0] * width, -p_NDC[1] * height, 0, 0};
  593. int32_t d = 160;
  594. if (fabs(p_window[0]) > d || p_window[1] > y_offset_absolute * 2 + d || p_window[1] < y_offset_absolute * 2 - d) {
  595. return;
  596. }
  597. }
  598. if (program_type == RED) {
  599. texture_program_temp = &texture_program_red;
  600. } else if (program_type == BLUE) {
  601. texture_program_temp = &texture_program_blue;
  602. } else if (program_type == LIGHT_RED) {
  603. texture_program_temp = &texture_program_light_red;
  604. } else if (program_type == LIGHT_BLUE) {
  605. texture_program_temp = &texture_program_light_blue;
  606. } else if (program_type == NORMAL_ONE) {
  607. texture_program_temp = &texture_program_one;
  608. } else {
  609. texture_program_temp = &texture_program;
  610. }
  611. glUseProgram(texture_program_temp->program);
  612. glActiveTexture(GL_TEXTURE0);
  613. glBindTexture(GL_TEXTURE_2D, shape->texture);
  614. glUniformMatrix4fv(texture_program_temp->u_mvp_matrix_location, 1, GL_FALSE, (GLfloat *) model_view_projection_matrix);
  615. glUniform1i(texture_program_temp->u_texture_unit_location, 0);
  616. glUniform1f(texture_program_temp->u_alpha_loaction, shape->params.alpha);
  617. glBindBuffer(GL_ARRAY_BUFFER, shape->buffer);
  618. glVertexAttribPointer(texture_program_temp->a_position_location, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(GL_FLOAT), BUFFER_OFFSET(0));
  619. glVertexAttribPointer(texture_program_temp->a_texture_coordinates_location, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(GL_FLOAT), BUFFER_OFFSET(2 * sizeof(GL_FLOAT)));
  620. glEnableVertexAttribArray(texture_program_temp->a_position_location);
  621. glEnableVertexAttribArray(texture_program_temp->a_texture_coordinates_location);
  622. glDrawArrays(shape->params.const_params.triangle_mode, 0, shape->num_points);
  623. glBindBuffer(GL_ARRAY_BUFFER, 0);
  624. }
  625. }
  626. static inline void gen_rounded_rectangle(CPoint* out, CSize size, float radius, int32_t round_count) {
  627. int32_t offset = 0;
  628. out[offset++] = CPointMake(0, 0);
  629. float k = (float) (M_PI / 2 / (round_count + 1));
  630. int32_t i = 0;
  631. int32_t n = 0;
  632. for (i = (round_count + 2) * n; i <= round_count + 1 + (round_count + 1) * n; i++) {
  633. out[offset++] = CPointMake(size.width / 2 - radius + cosf(i * k) * radius, size.height / 2 - radius + sinf(i * k) * radius);
  634. }
  635. n++;
  636. for (i = (round_count + 1) * n; i <= round_count + 1 + (round_count + 1) * n; i++) {
  637. out[offset++] = CPointMake(-size.width / 2 + radius + cosf(i * k) * radius, size.height / 2 - radius + sinf(i * k) * radius);
  638. }
  639. n++;
  640. for (i = (round_count + 1) * n; i <= round_count + 1 + (round_count + 1) * n; i++) {
  641. out[offset++] = CPointMake(-size.width / 2 + radius + cosf(i * k) * radius, -size.height / 2 + radius + sinf(i * k) * radius);
  642. }
  643. n++;
  644. for (i = (round_count + 1) * n; i <= round_count + 1 + (round_count + 1) * n; i++) {
  645. out[offset++] = CPointMake(size.width / 2 - radius + cosf(i * k) * radius, -size.height / 2 + radius + sinf(i * k) * radius);
  646. }
  647. out[offset] = CPointMake(size.width / 2, size.height / 2 - radius);
  648. }
  649. Shape create_rounded_rectangle(CSize size, float radius, int32_t round_count, const vec4 color) {
  650. int32_t real_vertex_count = 4 * (2 + round_count) + 2;
  651. Params params = default_params();
  652. params.const_params.datasize = sizeof(CPoint) * real_vertex_count * 2;
  653. params.const_params.round_count = round_count;
  654. params.const_params.triangle_mode = GL_TRIANGLE_FAN;
  655. params.var_params.size = size;
  656. params.var_params.radius = radius;
  657. CPoint *data = malloc((size_t) params.const_params.datasize);
  658. gen_rounded_rectangle(data, params.var_params.size, params.var_params.radius, params.const_params.round_count);
  659. return (Shape) {{color[0], color[1], color[2], color[3]}, data, create_vbo(params.const_params.datasize, data, GL_DYNAMIC_DRAW), real_vertex_count, params};
  660. }
  661. void change_rounded_rectangle(Shape* shape, CSize size, float radius) {
  662. if ((*shape).params.var_params.size.width != size.width || (*shape).params.var_params.size.height != size.height || (*shape).params.var_params.radius != radius) {
  663. (*shape).params.var_params.size.width = size.width;
  664. (*shape).params.var_params.size.height = size.height;
  665. (*shape).params.var_params.radius = radius;
  666. gen_rounded_rectangle((*shape).data, (*shape).params.var_params.size, (*shape).params.var_params.radius, (*shape).params.const_params.round_count);
  667. glBindBuffer(GL_ARRAY_BUFFER, shape->buffer);
  668. glBufferSubData(GL_ARRAY_BUFFER, 0, shape->params.const_params.datasize, shape->data);
  669. glBindBuffer(GL_ARRAY_BUFFER, 0);
  670. }
  671. }
  672. static inline CPoint square_point(float angle, float radius) {
  673. CPoint p = {0.0f, 0.0f};
  674. if (angle <= M_PI / 2 * 0.5f || angle > M_PI / 2 * 3.5f) {
  675. p = CPointMake(radius, radius * sinf(angle) / cosf(angle));
  676. } else if (angle <= M_PI / 2 * 1.5) {
  677. p = CPointMake(radius * cosf(angle) / sinf(angle), radius);
  678. } else if (angle <= M_PI / 2 * 2.5) {
  679. p = CPointMake(-radius, -radius * sinf(angle) / cosf(angle));
  680. } else if (angle <= (float) (M_PI / 2 * 3.5)) {
  681. p = CPointMake(-radius * cosf(angle) / sinf(angle), -radius);
  682. }
  683. return p;
  684. }
  685. static inline CPoint square_texture_point(CPoint p, float side_length) {
  686. return CPointMake((-p.x / side_length * 0.5f + 0.5f), -p.y / side_length * 0.5f + 0.5f);
  687. }
  688. static inline void gen_segmented_square(CPoint* out, float side_length, float start_angle, float end_angle) {
  689. CPoint p;
  690. float radius = side_length;
  691. int32_t offset = 0;
  692. float k = 1;
  693. float da = D2R(-2.6f * 2) * k;
  694. p = CPointMake(sinf(start_angle + end_angle) * 6 * k, -cosf(start_angle + end_angle) * 6 * k);
  695. out[offset++] = p;
  696. out[offset++] = square_texture_point(p, side_length);
  697. p = square_point(start_angle + da, radius);
  698. out[offset++] = p;
  699. out[offset++] = square_texture_point(p, side_length);
  700. int32_t q = 0;
  701. int32_t i;
  702. for (i = (int32_t) start_angle; i < floorf(R2D(start_angle + end_angle + da)); i++) {
  703. if ((i + 45) % 90 == 0) {
  704. p = square_point(D2R(i), radius);
  705. out[offset++] = p;
  706. out[offset++] = square_texture_point(p, side_length);
  707. q++;
  708. }
  709. }
  710. p = square_point(start_angle + end_angle + da, radius);
  711. out[offset++] = p;
  712. out[offset++] = square_texture_point(p, side_length);
  713. for (i = 0; i < 4 - q; i++) {
  714. p = square_point(start_angle + end_angle + da, radius);
  715. out[offset++] = p;
  716. out[offset++] = square_texture_point(p, side_length);
  717. }
  718. }
  719. TexturedShape create_segmented_square(float side_length, float start_angle, float end_angle, GLuint texture) {
  720. int32_t real_vertex_count = 7;
  721. Params params = default_params();
  722. params.const_params.datasize = sizeof(CPoint) * real_vertex_count * 2 * 2;
  723. params.const_params.triangle_mode = GL_TRIANGLE_FAN;
  724. CPoint *data = malloc((size_t) params.const_params.datasize);
  725. gen_segmented_square(data, side_length, start_angle, end_angle);
  726. return (TexturedShape) {texture, data, create_vbo(params.const_params.datasize, data, GL_DYNAMIC_DRAW), real_vertex_count, params};
  727. }
  728. void change_segmented_square(TexturedShape* shape, float side_length, float start_angle, float end_angle) {
  729. if ((*shape).params.var_params.side_length != side_length || (*shape).params.var_params.start_angle != start_angle || (*shape).params.var_params.end_angle != end_angle) {
  730. (*shape).params.var_params.side_length = side_length;
  731. (*shape).params.var_params.start_angle = start_angle;
  732. (*shape).params.var_params.end_angle = end_angle;
  733. gen_segmented_square((*shape).data, side_length, start_angle, end_angle);
  734. glBindBuffer(GL_ARRAY_BUFFER, shape->buffer);
  735. glBufferSubData(GL_ARRAY_BUFFER, 0, shape->params.const_params.datasize, shape->data);
  736. glBindBuffer(GL_ARRAY_BUFFER, 0);
  737. }
  738. }
  739. static inline void gen_rectangle(CPoint* out, CSize size) {
  740. out[0] = CPointMake(-size.width / 2, -size.height / 2);
  741. out[1] = CPointMake(size.width / 2, -size.height / 2);
  742. out[2] = CPointMake(-size.width / 2, size.height / 2);
  743. out[3] = CPointMake(size.width / 2, size.height / 2);
  744. }
  745. Shape create_rectangle(CSize size, const vec4 color) {
  746. int32_t real_vertex_count = 4;
  747. Params params = default_params();
  748. params.const_params.datasize = sizeof(CPoint) * real_vertex_count;
  749. params.const_params.triangle_mode = GL_TRIANGLE_STRIP;
  750. CPoint *data = malloc((size_t) params.const_params.datasize);
  751. gen_rectangle(data, size);
  752. return (Shape) {{color[0], color[1], color[2], color[3]}, data, create_vbo(params.const_params.datasize, data, GL_DYNAMIC_DRAW), real_vertex_count, params};
  753. }
  754. static inline CPoint rectangle_texture_point(CPoint p, CSize size) {
  755. return CPointMake(1 - (-p.x / size.width + 0.5f), p.y / size.height + 0.5f);
  756. }
  757. static inline void gen_textured_rectangle(CPoint* out, CSize size) {
  758. out[0] = CPointMake(-size.width / 2, -size.height / 2);
  759. out[1] = rectangle_texture_point(CPointMake(-size.width / 2, -size.height / 2), size);
  760. out[2] = CPointMake(size.width / 2, -size.height / 2);
  761. out[3] = rectangle_texture_point(CPointMake(size.width / 2, -size.height / 2), size);
  762. out[4] = CPointMake(-size.width / 2, size.height / 2);
  763. out[5] = rectangle_texture_point(CPointMake(-size.width / 2, size.height / 2), size);
  764. out[6] = CPointMake(size.width / 2, size.height / 2);
  765. out[7] = rectangle_texture_point(CPointMake(size.width / 2, size.height / 2), size);
  766. }
  767. TexturedShape create_textured_rectangle(CSize size, GLuint texture) {
  768. int32_t real_vertex_count = 4;
  769. Params params = default_params();
  770. params.const_params.datasize = sizeof(CPoint) * real_vertex_count * 2;
  771. params.const_params.triangle_mode = GL_TRIANGLE_STRIP;
  772. CPoint *data = malloc((size_t) params.const_params.datasize);
  773. gen_textured_rectangle(data, size);
  774. return (TexturedShape) {texture, data, create_vbo(params.const_params.datasize, data, GL_STATIC_DRAW), real_vertex_count, params};
  775. }
  776. static inline void gen_ribbon(CPoint* out, float length) {
  777. out[0] = CPointMake(-MAXf(length - 5.5f, 0), -5.5f);
  778. out[1] = CPointMake(0, -5.5f);
  779. out[2] = CPointMake(-MAXf(length, 0), 5.5f);
  780. out[3] = CPointMake(0, 5.5f);
  781. }
  782. Shape create_ribbon(float length, const vec4 color) {
  783. int32_t real_vertex_count = 4;
  784. Params params = default_params();
  785. params.const_params.datasize = sizeof(CPoint) * real_vertex_count;
  786. params.const_params.triangle_mode = GL_TRIANGLE_STRIP;
  787. params.var_params.side_length = length;
  788. CPoint *data = malloc((size_t) params.const_params.datasize);
  789. gen_ribbon(data, length);
  790. return (Shape) {{color[0], color[1], color[2], color[3]}, data, create_vbo(params.const_params.datasize, data, GL_DYNAMIC_DRAW), real_vertex_count, params};
  791. }
  792. void change_ribbon(Shape* shape, float length) {
  793. if ((*shape).params.var_params.side_length != length) {
  794. (*shape).params.var_params.side_length = length;
  795. gen_ribbon((*shape).data, length);
  796. glBindBuffer(GL_ARRAY_BUFFER, shape->buffer);
  797. glBufferSubData(GL_ARRAY_BUFFER, 0, shape->params.const_params.datasize, shape->data);
  798. glBindBuffer(GL_ARRAY_BUFFER, 0);
  799. }
  800. }
  801. static inline void gen_circle(CPoint* out, float radius, int32_t vertex_count) {
  802. int32_t offset = 0;
  803. out[offset++] = CPointMake(0, 0);
  804. int32_t i;
  805. for (i = 0; i <= vertex_count; i++) {
  806. out[offset++] = CPointMake(radius * (cosf(2 * (float) M_PI * (i / (float) vertex_count))), radius * sinf(2 * (float) M_PI * (i / (float) vertex_count)));
  807. }
  808. }
  809. Shape create_circle(float radius, int32_t vertex_count, const vec4 color) {
  810. int32_t real_vertex_count = vertex_count + 2;
  811. Params params = default_params();
  812. params.const_params.datasize = sizeof(CPoint) * real_vertex_count;
  813. params.const_params.triangle_mode = GL_TRIANGLE_FAN;
  814. params.const_params.round_count = vertex_count;
  815. CPoint *data = (CPoint *) malloc((size_t) params.const_params.datasize);
  816. gen_circle(data, radius, vertex_count);
  817. return (Shape) {{color[0], color[1], color[2], color[3]}, data, create_vbo(params.const_params.datasize, data, GL_STATIC_DRAW), real_vertex_count, params};
  818. }
  819. int size_of_infinity_in_vertices(int32_t segment_count) {
  820. return (segment_count + 1) * 2;
  821. }
  822. static inline void gen_infinity(CPoint* out, float width, float angle, int32_t segment_count) {
  823. CPoint path[13];
  824. path[0] = CPointMake(53, 23);
  825. path[1] = CPointMake(49, 31);
  826. path[2] = CPointMake(39, 47);
  827. path[3] = CPointMake(22, 47);
  828. path[4] = CPointMake(6, 47);
  829. path[5] = CPointMake(0, 31);
  830. path[6] = CPointMake(0, 23);
  831. path[7] = CPointMake(0, 16);
  832. path[8] = CPointMake(5, 0);
  833. path[9] = CPointMake(23, 0);
  834. path[10] = CPointMake(39, 0);
  835. path[11] = CPointMake(48, 15);
  836. path[12] = CPointMake(52, 21);
  837. int32_t offset = 0;
  838. int32_t seg;
  839. for (seg = 0; seg <= segment_count; seg++) {
  840. float tt = ((float) seg / (float) segment_count) * angle;
  841. int32_t q = 4;
  842. float tstep = 1.f / q;
  843. int32_t n = (int32_t) floor(tt / tstep);
  844. CPoint a = path[0 + 3 * n];;
  845. CPoint p1 = path[1 + 3 * n];
  846. CPoint p2 = path[2 + 3 * n];
  847. CPoint b = path[3 + 3 * n];
  848. float t = (tt - tstep * n) * q;
  849. float nt = 1.0f - t;
  850. vec2 p = {a.x * nt * nt * nt + 3.0f * p1.x * nt * nt * t + 3.0f * p2.x * nt * t * t + b.x * t * t * t,
  851. a.y * nt * nt * nt + 3.0f * p1.y * nt * nt * t + 3.0f * p2.y * nt * t * t + b.y * t * t * t};
  852. vec2 tangent = {-3.0f * a.x * nt * nt + 3.0f * p1.x * (1.0f - 4.0f * t + 3.0f * t * t) + 3.0f * p2.x * (2.0f * t - 3.0f * t * t) + 3.0f * b.x * t * t,
  853. -3.0f * a.y * nt * nt + 3.0f * p1.y * (1.0f - 4.0f * t + 3.0f * t * t) + 3.0f * p2.y * (2.0f * t - 3.0f * t * t) + 3.0f * b.y * t * t};
  854. vec2 tan_norm = {-tangent[1], tangent[0]};
  855. vec2 norm;
  856. vec2_norm(norm, tan_norm);
  857. vec2 v;
  858. vec2 norm_scaled;
  859. vec2_scale(norm_scaled, norm, +width / 2.f);
  860. vec2_add(v, p, norm_scaled);
  861. out[offset] = CPointMake(v[0], v[1]);
  862. offset++;
  863. vec2_scale(norm_scaled, norm, -width / 2.f);
  864. vec2_add(v, p, norm_scaled);
  865. out[offset] = CPointMake(v[0], v[1]);
  866. offset++;
  867. }
  868. }
  869. Shape create_infinity(float width, float angle, int32_t segment_count, const vec4 color) {
  870. int32_t real_vertex_count = size_of_infinity_in_vertices(segment_count);
  871. Params params = default_params();
  872. params.const_params.datasize = sizeof(CPoint) * real_vertex_count;
  873. params.const_params.triangle_mode = GL_TRIANGLE_STRIP;
  874. params.const_params.round_count = segment_count;
  875. params.var_params.width = width;
  876. params.var_params.angle = angle;
  877. CPoint *data = malloc((size_t) params.const_params.datasize);
  878. gen_infinity(data, width, angle, segment_count);
  879. return (Shape) {{color[0], color[1], color[2], color[3]}, data, create_vbo(params.const_params.datasize, data, GL_DYNAMIC_DRAW), real_vertex_count, params};
  880. }
  881. void change_infinity(Shape* shape, float angle) {
  882. if ((*shape).params.var_params.angle != angle) {
  883. (*shape).params.var_params.angle = angle;
  884. gen_infinity(shape->data, (*shape).params.var_params.width, (*shape).params.var_params.angle, (*shape).params.const_params.round_count);
  885. glBindBuffer(GL_ARRAY_BUFFER, shape->buffer);
  886. glBufferData(GL_ARRAY_BUFFER, shape->params.const_params.datasize, shape->data, GL_DYNAMIC_DRAW);
  887. glBindBuffer(GL_ARRAY_BUFFER, 0);
  888. }
  889. }
  890. static inline void gen_rounded_rectangle_stroked(CPoint* out, CSize size, float radius, float stroke_width, int32_t round_count) {
  891. int32_t offset = 0;
  892. float k = (float) (M_PI / 2 / (round_count + 1));
  893. float inner_radius = radius - stroke_width;
  894. int32_t i = 0;
  895. int32_t n = 0;
  896. for (i = (round_count + 2) * n; i <= round_count + 1 + (round_count + 1) * n; i++) {
  897. out[offset++] = CPointMake(size.width / 2 - radius + cosf(i * k) * radius, size.height / 2 - radius + sinf(i * k) * radius);
  898. out[offset++] = CPointMake(size.width / 2 - radius + cosf(i * k) * inner_radius, size.height / 2 - radius + sinf(i * k) * inner_radius);
  899. }
  900. n++;
  901. for (i = (round_count + 1) * n; i <= round_count + 1 + (round_count + 1) * n; i++) {
  902. out[offset++] = CPointMake(-size.width / 2 + radius + cosf(i * k) * radius, size.height / 2 - radius + sinf(i * k) * radius);
  903. out[offset++] = CPointMake(-size.width / 2 + radius + cosf(i * k) * inner_radius, size.height / 2 - radius + sinf(i * k) * inner_radius);
  904. }
  905. n++;
  906. for (i = (round_count + 1) * n; i <= round_count + 1 + (round_count + 1) * n; i++) {
  907. out[offset++] = CPointMake(-size.width / 2 + radius + cosf(i * k) * radius, -size.height / 2 + radius + sinf(i * k) * radius);
  908. out[offset++] = CPointMake(-size.width / 2 + radius + cosf(i * k) * inner_radius, -size.height / 2 + radius + sinf(i * k) * inner_radius);
  909. }
  910. n++;
  911. for (i = (round_count + 1) * n; i <= round_count + 1 + (round_count + 1) * n; i++) {
  912. out[offset++] = CPointMake(size.width / 2 - radius + cosf(i * k) * radius, -size.height / 2 + radius + sinf(i * k) * radius);
  913. out[offset++] = CPointMake(size.width / 2 - radius + cosf(i * k) * inner_radius, -size.height / 2 + radius + sinf(i * k) * inner_radius);
  914. }
  915. i = 0;
  916. out[offset++] = CPointMake(size.width / 2 - radius + cosf(i * k) * radius, size.height / 2 - radius + sinf(i * k) * radius);
  917. out[offset] = CPointMake(size.width / 2 - radius + cosf(i * k) * inner_radius, size.height / 2 - radius + sinf(i * k) * inner_radius);
  918. }
  919. Shape create_rounded_rectangle_stroked(CSize size, float radius, float stroke_width, int32_t round_count, const vec4 color) {
  920. int32_t real_vertex_count = 4 * (2 + round_count) * 2 + 2;
  921. Params params = default_params();
  922. params.const_params.round_count = round_count;
  923. params.const_params.datasize = sizeof(CPoint) * real_vertex_count * 2;
  924. params.var_params.size = size;
  925. params.var_params.radius = radius;
  926. params.var_params.width = stroke_width;
  927. CPoint *data = (CPoint *) malloc((size_t) params.const_params.datasize);
  928. gen_rounded_rectangle_stroked(data, params.var_params.size, params.var_params.radius, params.var_params.width, params.const_params.round_count);
  929. params.const_params.triangle_mode = GL_TRIANGLE_STRIP;
  930. return (Shape) {{color[0], color[1], color[2], color[3]}, data, create_vbo(params.const_params.datasize, data, GL_DYNAMIC_DRAW), real_vertex_count, params};
  931. }
  932. void change_rounded_rectangle_stroked(Shape* shape, CSize size, float radius) {
  933. if ((*shape).params.var_params.size.width != size.width || (*shape).params.var_params.size.height != size.height || (*shape).params.var_params.radius != radius) {
  934. (*shape).params.var_params.size.width = size.width;
  935. (*shape).params.var_params.size.height = size.height;
  936. (*shape).params.var_params.radius = radius;
  937. gen_rounded_rectangle_stroked((*shape).data, (*shape).params.var_params.size, (*shape).params.var_params.radius, (*shape).params.var_params.width, (*shape).params.const_params.round_count);
  938. glBindBuffer(GL_ARRAY_BUFFER, shape->buffer);
  939. glBufferSubData(GL_ARRAY_BUFFER, 0, shape->params.const_params.datasize, shape->data);
  940. glBindBuffer(GL_ARRAY_BUFFER, 0);
  941. }
  942. }
  943. //------------------------------
  944. float t(float start_value, float end_value, float start_time, float duration, timing_type type) {
  945. if (time > start_time + duration) {
  946. return end_value;
  947. }
  948. if (type == Linear) {
  949. return start_value + (end_value - start_value) * MINf(duration + start_time, MAXf(.0, (time - start_time))) / duration;
  950. }
  951. return start_value + (end_value - start_value) * timing(MINf(duration + start_time, MAXf(.0, (time - start_time))) / duration, type);
  952. }
  953. float t_reversed(float end_value, float start_value, float start_time, float duration, timing_type type) {
  954. if (time > start_time + duration) {
  955. return end_value;
  956. }
  957. if (type == Linear) {
  958. return start_value + (end_value - start_value) * MINf(duration + start_time, MAXf(0.0f, (time - start_time))) / duration;
  959. }
  960. return start_value + (end_value - start_value) * timing(MINf(duration + start_time, MAXf(0.0f, (time - start_time))) / duration, type);
  961. }
  962. float t_local(float start_value, float end_value, float start_time, float duration, timing_type type) {
  963. if (type == Sin) {
  964. return start_value + (end_value - start_value) * sinf(MINf(MAXf((time_local - start_time) / duration * (float) M_PI, 0), (float) M_PI));
  965. }
  966. if (time_local > start_time + duration) {
  967. return end_value;
  968. }
  969. if (type == Linear) {
  970. return start_value + (end_value - start_value) * MINf(duration + start_time, MAXf(.0, (time_local - start_time))) / duration;
  971. }
  972. return start_value + (end_value - start_value) * timing(MINf(duration + start_time, MAXf(.0, (time_local - start_time))) / duration, type);
  973. }
  974. xyz star_create_position(float far) {
  975. starsFar = 1500;
  976. int32_t minR = 100;
  977. int32_t maxR = 1000;
  978. return xyzMake(signrand() * frand(minR, maxR), signrand() * frand(minR, maxR), far);
  979. }
  980. xyz star_initial_position(int32_t randZ, int32_t forward) {
  981. starsFar = 1500;
  982. int32_t minR = 100;
  983. int32_t maxR = 1000;
  984. float z = 0;
  985. if (forward == 1) {
  986. if (randZ == 0) {
  987. z = -starsFar;
  988. } else {
  989. z = frand(0, -starsFar);
  990. }
  991. }
  992. return xyzMake(signrand() * frand(minR, maxR), signrand() * frand(minR, maxR), z);
  993. }
  994. void draw_stars() {
  995. int update = last_stars_update_fps != fps_anim;
  996. last_stars_update_fps = fps_anim;
  997. float k = (float) width / (float) height;
  998. set_y_offset_objects(-100 * k * 0);
  999. for (i = 0; i < starsCount; i++) {
  1000. float stars_scroll_offset = MAXf(0, scroll_offset) * 2;
  1001. float transition_speed;
  1002. if (direct == 1) {
  1003. float s = 5;
  1004. transition_speed = s - t(0, s, 0, duration_const + 1 + 0.8f, Linear);
  1005. } else {
  1006. transition_speed = t(-4, 0, 0, duration_const + 1, EaseOut);
  1007. }
  1008. float speed = stars_scroll_offset + transition_speed;
  1009. if (update) {
  1010. stars[i].position.z += speed;
  1011. }
  1012. if (stars[i].position.z > 0 && speed > 0) {
  1013. stars[i].position = star_initial_position(0, 1);
  1014. }
  1015. if (stars[i].position.z < -1500 && speed < 0) {
  1016. stars[i].position = star_initial_position(0, 0);
  1017. }
  1018. float inc = scroll_offset * 100;
  1019. stars[i].position.z = stars[i].position.z + inc;
  1020. star.params.position = stars[i].position;
  1021. float s = 1 + (-stars[i].position.z) / starsFar * 5;
  1022. star.params.scale = xyzMake(s, s, 1);
  1023. float far = starsFar;
  1024. star.params.alpha = (1 - (-stars[i].position.z) / far) * 10.0f;
  1025. star.params.alpha = star.params.alpha * star.params.alpha / 10.0f;
  1026. draw_textured_shape(&star, stars_matrix, NORMAL);
  1027. stars[i].position.z = stars[i].position.z - inc;
  1028. }
  1029. set_y_offset_objects(offset_y);
  1030. }
  1031. static inline void mat4x4_plain(mat4x4 M, int32_t width, int32_t height) {
  1032. int32_t i, j;
  1033. for (i = 0; i < 4; ++i) {
  1034. for (j = 0; j < 4; ++j) {
  1035. M[i][j] = 0.0f;
  1036. }
  1037. }
  1038. M[0][0] = 1;
  1039. M[1][1] = 1;
  1040. M[2][2] = 1;
  1041. M[0][0] = 1;
  1042. M[1][1] = (float) width / (float) height;
  1043. M[2][2] = 1;
  1044. M[3][3] = (float) width / 2.0f;
  1045. }
  1046. static inline void mat4x4_stars(mat4x4 m, float y_fov_in_degrees, float aspect, float n, float f, int32_t width, int32_t height) {
  1047. if (height >= width) {
  1048. float k = (float) width / (float) height;
  1049. float q = 1.4f;
  1050. m[0][0] = 1.0f / q;
  1051. m[1][0] = 0.0f;
  1052. m[2][0] = 0.0f;
  1053. m[3][0] = 0.0f;
  1054. m[1][0] = 0.0f;
  1055. m[1][1] = k / q;
  1056. m[1][2] = 0.0f;
  1057. m[1][3] = 0.0f;
  1058. m[2][0] = 0.0f;
  1059. m[2][1] = 0.0f;
  1060. m[2][2] = 1.0f;
  1061. m[2][3] = -1.25f;
  1062. m[3][0] = 0.0f;
  1063. m[3][1] = 0.0f;
  1064. m[3][2] = 0.0f;
  1065. m[3][3] = width * k;
  1066. } else {
  1067. float k = (float) height / (float) width;
  1068. float q = 2.0f;
  1069. m[0][0] = 1.0f / q;
  1070. m[1][0] = 0.0f;
  1071. m[2][0] = 0.0f;
  1072. m[3][0] = 0.0f;
  1073. m[1][0] = 0.0f;
  1074. m[1][1] = (1.0f / k) / q;
  1075. m[1][2] = 0.0f;
  1076. m[1][3] = 0.0f;
  1077. m[2][0] = 0.0f;
  1078. m[2][1] = 0.0f;
  1079. m[2][2] = 1.0f;
  1080. m[2][3] = -1.25f;
  1081. m[3][0] = 0.0f;
  1082. m[3][1] = 0.0f;
  1083. m[3][2] = 0.0f;
  1084. m[3][3] = height * k;
  1085. }
  1086. mat4x4_translate_independed(m, 0, -2 * y_offset_absolute / (float) height + 4 * scale_factor / (float) height, 0);
  1087. }
  1088. void rglNormalDraw() {
  1089. glDisable(GL_DEPTH_TEST);
  1090. glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  1091. glColorMask(1, 1, 1, 1);
  1092. glDepthMask(0);
  1093. }
  1094. void rglMaskDraw() {
  1095. glEnable(GL_DEPTH_TEST);
  1096. glDisable(GL_BLEND);
  1097. glDepthMask(1);
  1098. glColorMask(0, 0, 0, 0);
  1099. glDepthFunc(GL_GREATER);
  1100. glClearDepthf(0);
  1101. glClear(GL_DEPTH_BUFFER_BIT);
  1102. }
  1103. void rglNormalDrawThroughMask() {
  1104. glColorMask(1, 1, 1, 1);
  1105. glDepthFunc(GL_LESS);
  1106. glDepthMask(0);
  1107. }
  1108. void mat4x4_scaled(mat4x4 matrix, float s) {
  1109. mat4x4_identity(matrix);
  1110. mat4x4_scale_aniso(matrix, matrix, s, s, s);
  1111. }
  1112. void mat4x4_layer(mat4x4 matrix, LayerParams params, float s, float r) {
  1113. float a = main_matrix[1][1];
  1114. mat4x4 model_matrix;
  1115. mat4x4_identity(model_matrix);
  1116. mat4x4 id;
  1117. mat4x4_identity(id);
  1118. float sc = main_matrix[3][3];
  1119. mat4x4_translate(model_matrix, -params.anchor.x / sc, params.anchor.y / sc * a, params.anchor.z / sc);
  1120. mat4x4 scaled;
  1121. mat4x4_identity(scaled);
  1122. float f = 1.0f;
  1123. mat4x4_scale_aniso(scaled, scaled, params.scale.x * f, params.scale.y * f, params.scale.z * f);
  1124. mat4x4 tmp;
  1125. mat4x4_dup(tmp, model_matrix);
  1126. mat4x4_mul(model_matrix, scaled, tmp);
  1127. mat4x4 rotate;
  1128. mat4x4_dup(rotate, id);
  1129. mat4x4_rotate_Z2(rotate, id, -deg_to_radf(params.rotation));
  1130. mat4x4_dup(tmp, model_matrix);
  1131. mat4x4_mul(model_matrix, rotate, tmp);
  1132. mat4x4_translate_independed(model_matrix, params.position.x / sc, -params.position.y / sc * a, params.position.z / sc);
  1133. mat4x4 m;
  1134. mat4x4_mul(m, model_matrix, main_matrix);
  1135. m[1][0] /= a;
  1136. m[0][1] *= a;
  1137. mat4x4 scale_m;
  1138. mat4x4_scaled(scale_m, s);
  1139. mat4x4_rotate_Z(scale_m, r);
  1140. scale_m[1][0] /= a;
  1141. scale_m[0][1] *= a;
  1142. mat4x4_mul(matrix, scale_m, m);
  1143. }
  1144. float bubble_dots_sinf(float a) {
  1145. if (a < M_PI * 2 * anim_bubble_dots_end_period) {
  1146. return sinf(a);
  1147. }
  1148. return 0;
  1149. }
  1150. static void reset_ic() {
  1151. anim_smile_start_time1 = time_local;
  1152. anim_pencil_start_time = 0;
  1153. anim_pencil_start_all_end_time = 0;
  1154. anim_cam_next_time = time_local;
  1155. anim_smile_stage = 0;
  1156. anim_smile_blink_one = 0;
  1157. anim_pencil_stage = 0;
  1158. anim_bubble_dots_end_period = 4;
  1159. anim_pencil_period = 1;
  1160. }
  1161. static void draw_ic(int32_t type) {
  1162. float rotation;
  1163. float beginTimeK;
  1164. float commonDelay;
  1165. float beginY = 250;
  1166. int32_t bounce;
  1167. texture_program_type COLOR, LIGHT_COLOR;
  1168. if (type == 0) {
  1169. beginTimeK = 2.0f;
  1170. commonDelay = duration_const * 0.5f;
  1171. bounce = 1;
  1172. rotation = -D2R(free_scroll_offset);
  1173. cloud_scroll_offset = 0;
  1174. COLOR = RED, LIGHT_COLOR = LIGHT_RED;
  1175. } else {
  1176. rotation = 0;
  1177. beginTimeK = 2.5;
  1178. commonDelay = 0;
  1179. bounce = 1;
  1180. COLOR = BLUE, LIGHT_COLOR = LIGHT_BLUE;
  1181. }
  1182. float scale;
  1183. float t_y;
  1184. CPoint ic_pos;
  1185. float ic_layer_alpha;
  1186. if (current_page == 1 && direct == 0) {
  1187. ic_layer_alpha = t(1, 0, 0, duration_const * 0.25f, EaseOut);
  1188. } else {
  1189. ic_layer_alpha = 1;
  1190. }
  1191. ic_pin.params.alpha = ic_layer_alpha;
  1192. ic_cam.params.alpha = ic_layer_alpha;
  1193. ic_cam_lens.params.alpha = ic_layer_alpha;
  1194. ic_smile.params.alpha = ic_layer_alpha;
  1195. ic_smile_eye.params.alpha = ic_layer_alpha;
  1196. ic_videocam.params.alpha = ic_layer_alpha;
  1197. ic_bubble.params.alpha = ic_layer_alpha;
  1198. ic_bubble_dot.params.alpha = ic_layer_alpha;
  1199. ic_pencil.params.alpha = ic_layer_alpha;
  1200. if (type == 0) {
  1201. ic_pos = CPointMake(-106 / 2, 61 / 2);
  1202. if (current_page == 1 && direct == 0) {
  1203. t_y = 0;
  1204. } else {
  1205. t_y = t(beginY, 0, commonDelay + duration_const * 0.2f * beginTimeK, duration_const, EaseOut);
  1206. float arg = MAXf(0, time - (commonDelay + duration_const * 0.2f * beginTimeK)) * 50;
  1207. float value = beginY * powf(2.71, -0.055f * arg * 2) * cosf(0.08f * arg) * 0.4f;
  1208. t_y -= value * bounce;
  1209. }
  1210. } else {
  1211. ic_pos = CPointMake(-162 / 2 + 4, +26 / 2 + 20);
  1212. t_y = t(beginY, 0, commonDelay + duration_const * 0.2f * beginTimeK, duration_const, EaseOut);
  1213. float value = 0;
  1214. float e = 2.71;
  1215. float arg = MAXf(0, time - (commonDelay + duration_const * 0.2f * beginTimeK)) * 50;
  1216. value = beginY * powf(e, -0.055f * arg * 2) * cosf(0.08f * arg - (float) M_PI / 8.0f) * 0.4f;
  1217. t_y -= value * bounce;
  1218. }
  1219. if (time_local > anim_pin_start_time) {
  1220. if (time_local > anim_pin_start_time + anim_pin_duration) {
  1221. anim_pin_start_time = time_local + duration_const * frand(10, 20) * 2;
  1222. anim_pin_duration = duration_const * frand(10, 20) * 2;
  1223. }
  1224. }
  1225. float pinasin = 0;
  1226. ic_pin_layer.position = xyzMake(ic_pos.x + cosf(time_local * 5) * 3 * pinasin + cloud_scroll_offset, ic_pos.y + sinf(time_local * 5) * 1.5f * pinasin + t_y, 0);
  1227. mat4x4_layer(ic_matrix, ic_pin_layer, 1, rotation);
  1228. draw_textured_shape(&ic_pin, ic_matrix, COLOR);
  1229. if (type == 1) {
  1230. ic_videocam_layer.rotation = -30 + t_local(anim_videocam_old_angle, anim_videocam_angle, anim_videocam_start_time, anim_videocam_duration, EaseOut);
  1231. t_y = t(beginY, 0, commonDelay + duration_const * 0.45f * beginTimeK, duration_const, EaseOut);
  1232. float value = 0;
  1233. float e = 2.71;
  1234. float arg = MAXf(0, time - (commonDelay + duration_const * 0.45f * beginTimeK)) * 50;
  1235. value = beginY * powf(e, -0.055f * arg * 2) * cosf(0.08f * arg) * 0.4f;
  1236. t_y -= value * bounce;
  1237. if (t_y <= 1 && time_local > anim_videocam_next_time) {
  1238. anim_videocam_duration = duration_const * frand(1.0f, 1.5f) * 1.5f;
  1239. anim_videocam_old_angle = anim_videocam_angle;
  1240. anim_videocam_angle = 15 * irand(-1, 1);
  1241. anim_videocam_start_time = time_local;
  1242. anim_videocam_next_time = time_local + 1000000 + duration_const * frand(5, 8);
  1243. }
  1244. ic_videocam_layer.position = xyzMake(-68 / 2 + cloud_scroll_offset, +80 / 2 + t_y, 0);
  1245. mat4x4_layer(ic_matrix, ic_videocam_layer, 1, rotation);
  1246. draw_textured_shape(&ic_videocam, ic_matrix, COLOR);
  1247. }
  1248. if (type == 0) {
  1249. ic_pos = CPointMake(107 / 2, 78 / 2);
  1250. if (current_page == 1 && direct == 0) {
  1251. t_y = 0;
  1252. } else {
  1253. t_y = t(beginY, 0, commonDelay + duration_const * 0.3f * beginTimeK, duration_const, EaseOut);
  1254. float value = 0;
  1255. float e = 2.71;
  1256. float arg = MAXf(0, time - (commonDelay + duration_const * 0.3f * beginTimeK)) * 50;
  1257. value = beginY * powf(e, -0.055f * arg * 2) * cosf(0.08f * arg) * 0.4f;
  1258. t_y -= value * bounce;
  1259. }
  1260. } else {
  1261. ic_pos = CPointMake(-28 / 2, -20 / 2 + 2);
  1262. t_y = t(beginY, 0, commonDelay + duration_const * 0.15f * beginTimeK, duration_const, EaseOut);
  1263. float arg = MAXf(0, time - (commonDelay + duration_const * 0.15f * beginTimeK)) * 50;
  1264. float value = beginY * powf(2.71, -0.055f * arg * 2) * cosf(0.08f * arg) * 0.4f;
  1265. t_y -= value * bounce;
  1266. }
  1267. if (t_y <= 1 && time_local > anim_cam_next_time) {
  1268. anim_cam_duration = duration_const * frand(1.0, 1.5);
  1269. anim_cam_old_angle = anim_cam_angle;
  1270. anim_cam_old_position = anim_cam_position;
  1271. anim_cam_start_time = time_local;
  1272. anim_cam_next_time = time_local + 10000000;
  1273. int32_t r = irand(0, 1);
  1274. if (r == 0) {
  1275. anim_cam_position = CPointMake(-8 + 4, 0);
  1276. anim_cam_angle = signrand() * 10;
  1277. } else if (r == 1) {
  1278. anim_cam_position = CPointMake(4, -5);
  1279. anim_cam_angle = signrand() * 10;
  1280. } else if (r == 2) {
  1281. anim_cam_position = CPointMake(0, 0);
  1282. anim_cam_angle = 0;
  1283. }
  1284. qShot = irand(1, 2);
  1285. anim_camshot_start_time = time_local + duration_const * 0.5f;
  1286. anim_camshot_duration = duration_const * .4f;
  1287. }
  1288. ic_cam_layer.rotation = 15 + t_local(anim_cam_old_angle, anim_cam_angle, anim_cam_start_time, anim_cam_duration, EaseOut);
  1289. ic_cam_layer.position = xyzMake(
  1290. ic_pos.x + 0 * t_local(anim_cam_old_position.x, anim_cam_position.x, anim_cam_start_time, anim_cam_duration, EaseOut) + cloud_scroll_offset,
  1291. ic_pos.y + 0 * t_local(anim_cam_old_position.y, anim_cam_position.y, anim_cam_start_time, anim_cam_duration, EaseOut)
  1292. + t_y,
  1293. 0);
  1294. mat4x4_layer(ic_matrix, ic_cam_layer, 1, rotation);
  1295. draw_textured_shape(&ic_cam, ic_matrix, COLOR);
  1296. float lens_scale;
  1297. lens_scale = 1;
  1298. if (qShot >= 0 && time_local > anim_camshot_start_time) {
  1299. lens_scale = t_local(1, 0, anim_camshot_start_time, anim_camshot_duration, Sin);
  1300. if (time_local > anim_camshot_start_time + anim_camshot_duration) {
  1301. qShot--;
  1302. anim_camshot_start_time = time_local + anim_camshot_duration;
  1303. }
  1304. }
  1305. ic_cam_lens.params.scale = xyzMake(lens_scale, lens_scale, 1);
  1306. ic_cam_lens.params.position = xyzMake(0, 1.7, 0);
  1307. draw_textured_shape(&ic_cam_lens, ic_matrix, COLOR);
  1308. if (type == 0) {
  1309. ic_pos = CPointMake(70 / 2, -116 / 2);
  1310. if (current_page == 1 && direct == 0) {
  1311. t_y = 0;
  1312. } else {
  1313. t_y = t(beginY, 0, commonDelay + duration_const * .0f * beginTimeK, duration_const, EaseOut);
  1314. float value = 0;
  1315. float e = 2.71;
  1316. float arg = MAXf(0, time - (commonDelay + duration_const * .0f * beginTimeK)) * 50;
  1317. value = beginY * powf(e, -0.055f * arg * 2) * cosf(0.08f * arg) * .4f;
  1318. t_y -= value * bounce;
  1319. }
  1320. } else {
  1321. ic_pos = CPointMake(+60 / 2, 50 / 2);
  1322. t_y = t(beginY, 0, commonDelay + duration_const * 0.25f * beginTimeK, duration_const, EaseOut);
  1323. float value = 0;
  1324. float e = 2.71;
  1325. float arg = MAXf(0, time - (commonDelay + duration_const * 0.25f * beginTimeK)) * 50;
  1326. value = beginY * powf(e, -0.055f * arg * 2) * cosf(0.08f * arg - (float) M_PI / 8.0f) * .4f;
  1327. t_y -= value * bounce;
  1328. }
  1329. float smile_laught = 0;
  1330. float anim_smile_fade_duration = duration_const * 2;
  1331. float anim_smile_duration = duration_const * 2;
  1332. if (anim_smile_stage == 0) {
  1333. smile_laught = t_local(0, 1, anim_smile_start_time1, anim_smile_fade_duration, Linear);
  1334. if (time_local > anim_smile_duration * 3 + anim_smile_start_time1) {
  1335. anim_smile_stage = 1;
  1336. anim_smile_start_time2 = time_local;
  1337. }
  1338. }
  1339. if (anim_smile_stage == 1) {
  1340. smile_laught = t_local(1, 0, anim_smile_start_time2, anim_smile_fade_duration, Linear);
  1341. if (time_local > anim_smile_duration + anim_smile_start_time2) {
  1342. smile_laught = 0;
  1343. anim_smile_stage = 2;
  1344. anim_smile_blink_one = 1;
  1345. anim_smile_blink_start_time = time_local + duration_const;
  1346. }
  1347. }
  1348. float y = 0;
  1349. if (anim_smile_stage < 2) {
  1350. y = sinf(time_local * (float) M_PI * 10) * 1.5f * smile_laught;
  1351. }
  1352. ic_smile_layer.position = xyzMake(ic_pos.x + cloud_scroll_offset, y + ic_pos.y + t_y, 0);
  1353. mat4x4_layer(ic_matrix, ic_smile_layer, 1, rotation);
  1354. draw_textured_shape(&ic_smile, ic_matrix, COLOR);
  1355. if (time_local > anim_smile_blink_start_time + .1) {
  1356. float blink_pause = frand(3, 6);
  1357. if (irand(0, 3) == 0) {
  1358. blink_pause = .3;
  1359. }
  1360. if (anim_smile_blink_one == 1) {
  1361. blink_pause = frand(3, 6);
  1362. }
  1363. anim_smile_blink_start_time = time_local + blink_pause;
  1364. anim_smile_blink_one = 0;
  1365. }
  1366. int32_t stop_time = 5;
  1367. float eye_scale = t_local(1, 0, anim_smile_blink_start_time, 0.1f, Sin);
  1368. ic_smile_eye.params.scale = xyzMake(1, eye_scale, 1);
  1369. if (time > stop_time) ic_smile_eye.params.scale = xyzMake(1, 1, 1);
  1370. ic_smile_eye.params.position = xyzMake(-7, -4.5f, 0);
  1371. draw_textured_shape(&ic_smile_eye, ic_matrix, COLOR);
  1372. if (anim_smile_blink_one == 1) ic_smile_eye.params.scale = xyzMake(1, 1, 1);
  1373. if (time > stop_time) ic_smile_eye.params.scale = xyzMake(1, 1, 1);
  1374. ic_smile_eye.params.position = xyzMake(7, -4.5f, 0);
  1375. draw_textured_shape(&ic_smile_eye, ic_matrix, COLOR);
  1376. if (type == 0) {
  1377. ic_pos = CPointMake(-60 / 2, 110 / 2);
  1378. if (current_page == 1 && direct == 0) {
  1379. t_y = 0;
  1380. } else {
  1381. t_y = t(beginY, 0, commonDelay + duration_const * .45f * beginTimeK, duration_const, EaseOut);
  1382. float value = 0;
  1383. float e = 2.71;
  1384. float arg = MAXf(0, time - (commonDelay + duration_const * .45f * beginTimeK)) * 50;
  1385. value = beginY * powf(e, -0.055f * arg * 2) * cosf(0.08f * arg) * .4f;
  1386. t_y -= value * bounce;
  1387. }
  1388. } else {
  1389. ic_pos = CPointMake(72 / 2, -74 / 2);
  1390. t_y = t(beginY, 0, commonDelay + duration_const * .0f * beginTimeK, duration_const, EaseOut);
  1391. float value = 0;
  1392. float e = 2.71;
  1393. float arg = MAXf(0, time - (commonDelay + duration_const * .0f * beginTimeK)) * 50;
  1394. value = beginY * powf(e, -0.055f * arg * 2) * cosf(0.08f * arg) * .4f;
  1395. t_y -= value * bounce;
  1396. }
  1397. ic_bubble_layer.position = xyzMake(ic_pos.x + cloud_scroll_offset, ic_pos.y + t_y, 0);
  1398. mat4x4_layer(ic_matrix, ic_bubble_layer, 1, rotation);
  1399. draw_textured_shape(&ic_bubble, ic_matrix, COLOR);
  1400. scale = 0.7f + 0.2f * bubble_dots_sinf(time * 10);
  1401. ic_bubble_dot.params.scale = xyzMake(scale, scale, scale);
  1402. ic_bubble_dot.params.position = xyzMake(0 - 80.5f, -9 / 2.0f, 0);
  1403. draw_textured_shape(&ic_bubble_dot, ic_matrix, LIGHT_COLOR);
  1404. scale = 0.7f + 0.2f * bubble_dots_sinf((float) -M_PI * 2 / 3 + time * 10);
  1405. if (anim_bubble_dots_stage == 0) scale = MAXf(.7, scale);
  1406. ic_bubble_dot.params.scale = xyzMake(scale, scale, scale);
  1407. ic_bubble_dot.params.position = xyzMake(0, -9 / 2.0f, 0);
  1408. draw_textured_shape(&ic_bubble_dot, ic_matrix, LIGHT_COLOR);
  1409. scale = 0.7f + 0.2f * bubble_dots_sinf((float) -M_PI * 2 / 3 * 2 + time * 10);
  1410. if (anim_bubble_dots_stage == 0) scale = MAXf(.7, scale);
  1411. ic_bubble_dot.params.scale = xyzMake(scale, scale, scale);
  1412. ic_bubble_dot.params.position = xyzMake(0 + 80.5f, -9 / 2.0f, 0);
  1413. draw_textured_shape(&ic_bubble_dot, ic_matrix, LIGHT_COLOR);
  1414. if (type == 0) {
  1415. ic_pos = CPointMake(-88 / 2 - 15, -100 / 2 + 13);
  1416. if (current_page == 1 && direct == 0) {
  1417. t_y = 0;
  1418. } else {
  1419. t_y = t(beginY, 0, commonDelay + duration_const * .1f * beginTimeK, duration_const, EaseOut);
  1420. float value = 0;
  1421. float e = 2.71;
  1422. float arg = MAXf(0, time - (commonDelay + duration_const * .1f * beginTimeK)) * 50;
  1423. value = beginY * powf(e, -0.055f * arg * 2) * cosf(0.08f * arg) * .4f;
  1424. t_y -= value * bounce;
  1425. }
  1426. } else {
  1427. ic_pos = CPointMake(+152 / 2 - 17, +66 / 2 + 14);
  1428. t_y = t(beginY, 0, commonDelay + duration_const * 0.35f * beginTimeK, duration_const, EaseOut);
  1429. float value = 0;
  1430. float e = 2.71;
  1431. float arg = MAXf(0, time - (commonDelay + duration_const * 0.35f * beginTimeK)) * 50;
  1432. value = beginY * powf(e, -0.055f * arg * 2) * cosf(0.08f * arg) * 0.4f;
  1433. t_y -= value * bounce;
  1434. }
  1435. float pencil_x = 0;
  1436. if (anim_pencil_stage == 0) {
  1437. ic_pencil_layer.rotation = t_local(0, -5, anim_pencil_start_all_time, duration_const * 0.5f, EaseOut);
  1438. pencil_x = t_local(0, 14, anim_pencil_start_time, 1.5f * 0.85f, Linear);
  1439. if (time_local > anim_pencil_start_time + 1.5 * 0.85) {
  1440. anim_pencil_start_time = time_local;
  1441. anim_pencil_stage = 1;
  1442. }
  1443. } else if (anim_pencil_stage == 1) {
  1444. pencil_x = t_local(14, 0, anim_pencil_start_time, 1.5f * 0.15f, Linear);
  1445. if (time_local > anim_pencil_start_time + 1.5f * 0.15f) {
  1446. if (anim_pencil_period == 0) {
  1447. anim_pencil_start_all_end_time = time_local;
  1448. anim_pencil_start_time = time_local + duration_const * 1;
  1449. anim_pencil_stage = 2;
  1450. } else {
  1451. anim_pencil_period--;
  1452. anim_pencil_start_time = time_local;
  1453. anim_pencil_stage = 0;
  1454. }
  1455. }
  1456. } else if (anim_pencil_stage == 2) {
  1457. ic_pencil_layer.rotation = t_local(-5, 0, anim_pencil_start_all_end_time, duration_const * 0.5f, EaseOut);
  1458. if (time_local > anim_pencil_start_time) {
  1459. anim_pencil_start_all_time = time_local;
  1460. anim_pencil_start_time = time_local;
  1461. anim_pencil_stage = 3;
  1462. }
  1463. }
  1464. float pencil_v = (anim_pencil_stage < 2) ? sinf((float) (time_local * 2 * M_PI * 4)) * 0.8f : 0;
  1465. ic_pencil_layer.position = xyzMake(pencil_x + ic_pos.x + cloud_scroll_offset, pencil_v + ic_pos.y + t_y, 0);
  1466. mat4x4_layer(ic_matrix, ic_pencil_layer, 1, rotation);
  1467. draw_textured_shape(&ic_pencil, ic_matrix, COLOR);
  1468. }
  1469. void draw_safe(int32_t type, float alpha, float screw_alpha) {
  1470. float screw_distance = 53;
  1471. private_screw.params.alpha = alpha * screw_alpha;
  1472. scale = 1;
  1473. private_screw.params.scale = xyzMake(scale, scale, 1);
  1474. private_screw.params.position = xyzMake(-screw_distance, -screw_distance, 0);
  1475. draw_textured_shape(&private_screw, private_matrix, NORMAL_ONE);
  1476. private_screw.params.scale = xyzMake(scale, scale, 1);
  1477. private_screw.params.position = xyzMake(screw_distance, -screw_distance, 0);
  1478. draw_textured_shape(&private_screw, private_matrix, NORMAL_ONE);
  1479. private_screw.params.scale = xyzMake(scale, scale, 1);
  1480. private_screw.params.position = xyzMake(-screw_distance, screw_distance, 0);
  1481. draw_textured_shape(&private_screw, private_matrix, NORMAL_ONE);
  1482. private_screw.params.scale = xyzMake(scale, scale, 1);
  1483. private_screw.params.position = xyzMake(screw_distance, screw_distance, 0);
  1484. draw_textured_shape(&private_screw, private_matrix, NORMAL_ONE);
  1485. }
  1486. JNIEXPORT void Java_org_telegram_messenger_Intro_setBackgroundColor(JNIEnv *env, jclass class, jfloat r, jfloat g, jfloat b, jfloat a) {
  1487. background_color[0] = r;
  1488. background_color[1] = g;
  1489. background_color[2] = b;
  1490. background_color[3] = a;
  1491. cloud_cover = create_rectangle(CSizeMake(240, 100), background_color);
  1492. cloud_cover.params.anchor.y = -50;
  1493. TexturedShape was_mask = powerful_mask;
  1494. powerful_mask = create_textured_rectangle(CSizeMake(200, 200), powerful_mask_texture);
  1495. powerful_mask.params = was_mask.params;
  1496. telegram_mask = create_textured_rectangle(CSizeMake(200, 150), telegram_mask_texture);
  1497. }
  1498. JNIEXPORT void Java_org_telegram_messenger_Intro_onDrawFrame(JNIEnv *env, jclass class, jint deltaMs) {
  1499. if (surfaceCreated == 0) {
  1500. glClearColor(background_color[0], background_color[1], background_color[2], background_color[3]);
  1501. glClear(GL_COLOR_BUFFER_BIT);
  1502. return;
  1503. }
  1504. time_local += (float) deltaMs / 1000;
  1505. if (current_page != prev_page) {
  1506. reset_ic();
  1507. ms0_anim = date;
  1508. fps_anim = 0;
  1509. count_anim_fps = 1;
  1510. }
  1511. float knotDelayStep = 0.075f;
  1512. if (prev_page != current_page) {
  1513. for (i = 0; i < 4; i++) {
  1514. knot_delays[i] = (0.65f + knotDelayStep * i) * duration_const;
  1515. }
  1516. for (i = 0; i < 10; i++) {
  1517. int32_t j1 = irand(0, 3);
  1518. int32_t j2 = irand(0, 3);
  1519. float temp = knot_delays[j1];
  1520. knot_delays[j1] = knot_delays[j2];
  1521. knot_delays[j2] = temp;
  1522. }
  1523. if (current_page == 2) {
  1524. ic_pin_layer.rotation = -15;
  1525. ic_cam_layer.rotation = 15;
  1526. ic_smile_layer.rotation = -15;
  1527. ic_bubble_layer.rotation = -15;
  1528. }
  1529. if (current_page == 5) {
  1530. ic_pin_layer.rotation = -15;
  1531. ic_videocam_layer.rotation = -30;
  1532. ic_cam_layer.rotation = 15;
  1533. ic_smile_layer.rotation = -15;
  1534. ic_bubble_layer.rotation = -15;
  1535. }
  1536. }
  1537. // Normalize if FPS is greater than 60
  1538. fps_anim = (int)(time_local / 0.016f);
  1539. if (count_anim_fps == 1 && date - ms0_anim >= duration_const) {
  1540. count_anim_fps = 0;
  1541. }
  1542. if (date - ms0 >= 1.0f) {
  1543. ms0 = date;
  1544. }
  1545. time = date - date0;
  1546. float private_back_k = .8;
  1547. glClearColor(background_color[0], background_color[1], background_color[2], background_color[3]);
  1548. glClear(GL_COLOR_BUFFER_BIT);
  1549. if (current_page == 0) {
  1550. rglNormalDraw();
  1551. telegram_sphere.params.alpha = 1;
  1552. scale = 1;
  1553. float alpha = 1;
  1554. if (direct == 0) {
  1555. alpha = t(0, 1, 0, duration_const, Linear);
  1556. fast_body.params.alpha = 1;
  1557. fast_body.params.scale = xyzMake(scale, scale, 1);
  1558. draw_textured_shape(&fast_body, main_matrix, NORMAL);
  1559. }
  1560. telegram_sphere.params.alpha = alpha;
  1561. telegram_sphere.params.scale = xyzMake(scale, scale, 1);
  1562. telegram_plane.params.alpha = 1;
  1563. float tt = MINf(0, (float) (-M_PI * 125. / 180. + time * M_PI * 2 * 1.5));
  1564. float dx = sinf(tt) * 75;
  1565. float dy = -sinf(tt) * 60;
  1566. telegram_plane.params.position = xyzMake(dx, dy, 0);
  1567. float scale = (cosf(tt) + 1) * 0.5f;
  1568. telegram_plane.params.scale = xyzMake(cosf(tt) * scale, scale, 1);
  1569. if (tt < D2R(125)) {
  1570. glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
  1571. }
  1572. } else if (current_page == 1) {
  1573. rglNormalDraw();
  1574. if (direct == 1) {
  1575. fast_body.params.scale = xyzMake(1, 1, 1);
  1576. fast_body.params.alpha = 1;
  1577. draw_textured_shape(&fast_body, main_matrix, NORMAL);
  1578. } else {
  1579. fast_body.params.alpha = t(0, 1, .0, duration_const, Linear);;
  1580. float scale = t(.95, 1, 0, duration_const, EaseInEaseOut);
  1581. fast_body.params.scale = xyzMake(scale, scale, 1.0f);
  1582. draw_textured_shape(&fast_body, main_matrix, NORMAL);
  1583. }
  1584. } else if (current_page == 2) {
  1585. rglNormalDraw();
  1586. if (direct == 1) {
  1587. fast_body.params.alpha = t(1.0f, .0, .0, duration_const, Linear);;
  1588. float scale = t(1, .95, 0, duration_const, EaseInEaseOut);
  1589. fast_body.params.scale = xyzMake(scale, scale, 1.0f);
  1590. draw_textured_shape(&fast_body, main_matrix, NORMAL);
  1591. }
  1592. } else if (current_page == 4) {
  1593. if (direct == 1) {
  1594. privateLayer.rotation = private_scroll_offset + t(-90, 0, 0, duration_const, EaseOut);
  1595. } else {
  1596. privateLayer.rotation = private_scroll_offset + t(90, 0, 0, duration_const * private_back_k, EaseOut);
  1597. }
  1598. mat4x4_layer(private_matrix, privateLayer, 1.0f, 0);
  1599. }
  1600. rglMaskDraw();
  1601. mask1.params.position.z = cloud_extra_mask1.params.position.z = cloud_extra_mask2.params.position.z = cloud_extra_mask3.params.position.z = cloud_extra_mask4.params.position.z = 1;
  1602. if (current_page == 0) {
  1603. if (direct == 0) {
  1604. change_rounded_rectangle(&mask1, CSizeMake(r1 * 2, r1 * 2), r1);
  1605. mask1.params.rotation = 0;
  1606. }
  1607. } else if (current_page == 1) {
  1608. if (direct == 1) {
  1609. change_rounded_rectangle(&mask1, CSizeMake(r1 * 2, r1 * 2), r1);
  1610. mask1.params.rotation = 0;
  1611. } else {
  1612. float size = t(r2 * 2, r1 * 2, 0, duration_const, EaseInEaseOut);
  1613. float round = t(30, r1, 0, duration_const, EaseInEaseOut);
  1614. change_rounded_rectangle(&mask1, CSizeMake(size, size), round);
  1615. free_scroll_offset = 0;
  1616. mask1.params.rotation = t(180, 0.0f, 0, duration_const, EaseInEaseOut) + free_scroll_offset;
  1617. }
  1618. } else if (current_page == 2) {
  1619. if (direct == 1) {
  1620. float size = t(r1 * 2, r2 * 2, 0, duration_const, EaseInEaseOut);
  1621. float round = t(r1, 30, 0, duration_const, EaseInEaseOut);
  1622. change_rounded_rectangle(&mask1, CSizeMake(size, size), round);
  1623. free_scroll_offset = scroll_offset * 5;
  1624. mask1.params.rotation = t(0, 180.0f, 0, duration_const, EaseInEaseOut) + free_scroll_offset;
  1625. } else {
  1626. free_scroll_offset = scroll_offset * 5;
  1627. float r = 316 / 4.0f;
  1628. float size = t_reversed(r2 * 2, r * 2, 0, duration_const, EaseInEaseOut);
  1629. float round = t_reversed(30, 20, 0, duration_const, EaseInEaseOut);
  1630. change_rounded_rectangle(&mask1, CSizeMake(size, size), round);
  1631. mask1.params.rotation = t_reversed(180.0f + free_scroll_offset, 180.0f + 90.0f, 0, duration_const, EaseInEaseOut);
  1632. }
  1633. } else if (current_page == 3) {
  1634. if (direct == 1) {
  1635. float r = 316 / 4.0f;
  1636. float size = t(r2 * 2, r * 2, 0, duration_const, EaseInEaseOut);
  1637. float round = t(30, 20, 0, duration_const, EaseInEaseOut);
  1638. change_rounded_rectangle(&mask1, CSizeMake(size, size), round);
  1639. mask1.params.rotation = t(180.0f + free_scroll_offset, 180.0f + 90.0f, 0, duration_const, EaseInEaseOut);
  1640. } else {
  1641. float r = 316 / 4.0f;
  1642. float size = t_reversed(r * 2, r2 * 2, 0, duration_const, EaseOut);
  1643. float round = t_reversed(20, 30, 0, duration_const, EaseOut);
  1644. change_rounded_rectangle(&mask1, CSizeMake(size, size), round);
  1645. mask1.params.rotation = t_reversed(180.0f + 90.0f, 180.0f + 90.0f + 90.0f, 0, duration_const, EaseOut);
  1646. mask1.params.position = xyzMake(0, 0, mask1.params.position.z);
  1647. }
  1648. } else if (current_page == 4) {
  1649. if (direct == 1) {
  1650. float r = 316 / 4.0f;
  1651. float size = t(r * 2, r2 * 2, 0, duration_const, EaseOut);
  1652. float round = t(20, 30, 0, duration_const, EaseOut);
  1653. change_rounded_rectangle(&mask1, CSizeMake(size, size), round);
  1654. mask1.params.rotation = private_scroll_offset + t(180.0f + 90.0f, 180.0f + 90.0f + 90.0f, 0, duration_const, EaseOut);
  1655. mask1.params.position = xyzMake(0, 0, mask1.params.position.z);
  1656. } else {
  1657. float k = 0;
  1658. k = 1.0f * private_back_k;
  1659. float scale = t_reversed(r2 * 2, 100, 0, duration_const * k, EaseOut);
  1660. change_rounded_rectangle(&mask1, CSizeMake(scale, scale), t_reversed(30, 50, 0, duration_const * k, EaseOut));
  1661. mask1.params.position = xyzMake(t_reversed(0, 29 / 2, 0, duration_const * k, EaseOut), t_reversed(0, -19 / 2, 0, duration_const * k, EaseOut), mask1.params.position.z);
  1662. mask1.params.rotation = private_scroll_offset + t_reversed(180.0f + 90.0f + 90.0f, 180.0f + 90.0f + 90.0f + 90.0f, 0, duration_const * k, EaseOut);
  1663. k = 1.0f * private_back_k;
  1664. int32_t sublayer2_radius = 33;
  1665. cloud_extra_mask1.params.position = xyzMake(t_reversed(0, -122 / 2, 0, duration_const * k, EaseOut), t_reversed(0, 54 / 2 - 1, 0, duration_const * k, EaseOut), cloud_extra_mask1.params.position.z);
  1666. scale = t_reversed(0, sublayer2_radius, 0, duration_const * k, EaseOut);
  1667. cloud_extra_mask1.params.scale = xyzMake(scale, scale, 1);
  1668. draw_shape(&cloud_extra_mask1, main_matrix);
  1669. k = 1.15f * private_back_k;
  1670. int32_t sublayer3_radius = 94 / 4;
  1671. cloud_extra_mask2.params.position = xyzMake(t_reversed(0, -84 / 2, 0, duration_const * k, EaseOut), t_reversed(0, -29 / 2, 0, duration_const * k, EaseOut), cloud_extra_mask2.params.position.z);
  1672. scale = t_reversed(0, sublayer3_radius, 0, duration_const * k, EaseOut);
  1673. cloud_extra_mask2.params.scale = xyzMake(scale, scale, 1);
  1674. draw_shape(&cloud_extra_mask2, main_matrix);
  1675. k = 1.3f * private_back_k;
  1676. int32_t sublayer4_radius = 124 / 4;
  1677. cloud_extra_mask3.params.position = xyzMake(t_reversed(0, 128 / 2, 0, duration_const * k, EaseOut), t_reversed(0, 56 / 2, 0, duration_const * k, EaseOut), cloud_extra_mask3.params.position.z);
  1678. scale = t_reversed(0, sublayer4_radius, 0, duration_const * k, EaseOut);
  1679. cloud_extra_mask3.params.scale = xyzMake(scale, scale, 1);
  1680. draw_shape(&cloud_extra_mask3, main_matrix);
  1681. k = 1.5f * private_back_k;
  1682. int32_t sublayer5_radius = 64;
  1683. cloud_extra_mask4.params.position = xyzMake(t_reversed(0, 0, 0, duration_const * k, EaseOut), t_reversed(0, 50, 0, duration_const * k, EaseOut), cloud_extra_mask4.params.position.z);
  1684. scale = t_reversed(0, sublayer5_radius, 0, duration_const * k, EaseOut);
  1685. cloud_extra_mask4.params.scale = xyzMake(scale, scale, 1);
  1686. draw_shape(&cloud_extra_mask4, main_matrix);
  1687. }
  1688. } else if (current_page == 5) {
  1689. float k = 0.8f;
  1690. float scale = t(r2 * 2, 100, 0, duration_const * k, EaseOut);
  1691. change_rounded_rectangle(&mask1, CSizeMake(scale, scale), t(30, 50, 0, duration_const * k, EaseOut));
  1692. mask1.params.position = xyzMake(t(0, 29 / 2, 0, duration_const * k, EaseOut), t(0, -19 / 2, 0, duration_const * k, EaseOut), mask1.params.position.z);
  1693. mask1.params.rotation = t(180.0f + 90.0f + 90.0f, 180.0f + 90.0f + 90.0f + 90.0f, 0, duration_const * k, EaseOut);
  1694. k = 1.0f;
  1695. int32_t sublayer2_radius = 33;
  1696. cloud_extra_mask1.params.position = xyzMake(t(0, -122 / 2, 0, duration_const * k, EaseOut), t(0, 54 / 2 - 1, 0, duration_const * k, EaseOut), cloud_extra_mask1.params.position.z);
  1697. scale = t(0, sublayer2_radius, 0, duration_const * k, EaseOut);
  1698. cloud_extra_mask1.params.scale = xyzMake(scale, scale, 1);
  1699. draw_shape(&cloud_extra_mask1, main_matrix);
  1700. k = 1.15;
  1701. int32_t sublayer3_radius = 94 / 4;
  1702. cloud_extra_mask2.params.position = xyzMake(t(0, -84 / 2, 0, duration_const * k, EaseOut), t(0, -29 / 2, 0, duration_const * k, EaseOut), cloud_extra_mask2.params.position.z);
  1703. scale = t(0, sublayer3_radius, 0, duration_const * k, EaseOut);
  1704. cloud_extra_mask2.params.scale = xyzMake(scale, scale, 1);
  1705. draw_shape(&cloud_extra_mask2, main_matrix);
  1706. k = 1.3;
  1707. int32_t sublayer4_radius = 124 / 4;
  1708. cloud_extra_mask3.params.position = xyzMake(t(0, 128 / 2, 0, duration_const * k, EaseOut), t(0, 56 / 2, 0, duration_const * k, EaseOut), cloud_extra_mask3.params.position.z);
  1709. scale = t(0, sublayer4_radius, 0, duration_const * k, EaseOut);
  1710. cloud_extra_mask3.params.scale = xyzMake(scale, scale, 1);
  1711. draw_shape(&cloud_extra_mask3, main_matrix);
  1712. k = 1.5f;
  1713. int32_t sublayer5_radius = 64;
  1714. cloud_extra_mask4.params.position = xyzMake(t(0, 0, 0, duration_const * k, EaseOut), t(0, 50, 0, duration_const * k, EaseOut), cloud_extra_mask4.params.position.z);
  1715. scale = t(0, sublayer5_radius, 0, duration_const * k, EaseOut);
  1716. cloud_extra_mask4.params.scale = xyzMake(scale, scale, 1);
  1717. draw_shape(&cloud_extra_mask4, main_matrix);
  1718. }
  1719. draw_shape(&mask1, main_matrix);
  1720. int32_t rr = 30;
  1721. int32_t seg = 15;
  1722. int32_t ang = 180;
  1723. rglNormalDrawThroughMask();
  1724. if (current_page == 0) {
  1725. if (direct == 0) {
  1726. glEnable(GL_BLEND);
  1727. glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
  1728. change_segmented_square(&spiral, r1, D2R(rr + seg), D2R(speedometer_scroll_offset + calculated_speedometer_sin + t(-seg + ang, 0, 0, duration_const, EaseOut)));
  1729. spiral.params.scale = xyzMake(1, 1, 1);
  1730. spiral.params.rotation = t(180.0f, 0, 0, duration_const, EaseOut);
  1731. spiral.params.alpha = t(1, 0, 0, duration_const, Linear);
  1732. draw_textured_shape(&spiral, main_matrix, NORMAL_ONE);
  1733. fast_arrow.params.alpha = fast_arrow_shadow.params.alpha = t(1, 0, 0, duration_const, Linear);
  1734. fast_arrow.params.rotation = fast_arrow_shadow.params.rotation = t(rr, rr - 180 - 160, 0, duration_const, EaseOut) + speedometer_scroll_offset + calculated_speedometer_sin;
  1735. draw_textured_shape(&fast_arrow_shadow, main_matrix, NORMAL_ONE);
  1736. draw_textured_shape(&fast_arrow, main_matrix, NORMAL_ONE);
  1737. }
  1738. } else if (current_page == 1) {
  1739. glEnable(GL_BLEND);
  1740. glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
  1741. speedometer_scroll_offset = scroll_offset * 25;
  1742. calculated_speedometer_sin = 0;
  1743. if (direct == 1) {
  1744. float value = 0;
  1745. float e = 2.71;
  1746. float arg = time * 50;
  1747. value = 180 - 180 * powf(e, -0.055f * arg * 2) * cosf(0.08f * arg * 3);
  1748. float ta = t(0, 180.0f, 0, duration_const, EaseOut);
  1749. change_segmented_square(&spiral, r1, D2R(rr + seg), D2R(-seg + value + speedometer_scroll_offset));
  1750. spiral.params.scale = xyzMake(1, 1, 1);
  1751. spiral.params.rotation = ta;
  1752. spiral.params.alpha = t(0, 1, 0, duration_const, Linear);
  1753. draw_textured_shape(&spiral, main_matrix, NORMAL_ONE);
  1754. fast_arrow.params.alpha = fast_arrow_shadow.params.alpha = t(0, 1, 0, duration_const, Linear);
  1755. fast_arrow.params.rotation = fast_arrow_shadow.params.rotation = -330 + value + ta + speedometer_scroll_offset;
  1756. draw_textured_shape(&fast_arrow_shadow, main_matrix, NORMAL_ONE);
  1757. draw_textured_shape(&fast_arrow, main_matrix, NORMAL_ONE);
  1758. } else {
  1759. spiral.params.alpha = fast_arrow.params.alpha = fast_arrow_shadow.params.alpha = 1;
  1760. float value = 0;
  1761. float e = 2.71;
  1762. float arg = time * 50;
  1763. float dangle = 90;
  1764. value = 180 - 90 - (180 - 90) * powf(e, -0.055f * arg * 2) * cosf(0.08f * arg * 3);
  1765. value *= -1;
  1766. change_segmented_square(&spiral, r1, D2R(rr + seg), D2R(speedometer_scroll_offset + value + calculated_speedometer_sin + t(360, 360 - dangle - seg, 0, duration_const, EaseInEaseOut)));
  1767. float scale = t(1.18, 1, 0, duration_const, EaseInEaseOut);
  1768. spiral.params.scale = xyzMake(scale, scale, 1);
  1769. spiral.params.rotation = t(360, 180, 0, duration_const, EaseInEaseOut);
  1770. draw_textured_shape(&spiral, main_matrix, NORMAL);
  1771. fast_arrow.params.rotation = fast_arrow_shadow.params.rotation = speedometer_scroll_offset + value + calculated_speedometer_sin + t(rr + 360 + 6, rr + 360 - 180 - dangle, 0, duration_const, EaseInEaseOut);
  1772. draw_textured_shape(&fast_arrow_shadow, main_matrix, NORMAL);
  1773. draw_textured_shape(&fast_arrow, main_matrix, NORMAL);
  1774. glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  1775. free_bg.params.alpha = t(1, 0, 0, duration_const, Linear);
  1776. draw_shape(&free_bg, main_matrix);
  1777. draw_ic(0);
  1778. }
  1779. } else if (current_page == 2) {
  1780. glEnable(GL_BLEND);
  1781. glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
  1782. if (direct == 1) {
  1783. spiral.params.alpha = fast_arrow.params.alpha = fast_arrow_shadow.params.alpha = 1;
  1784. change_segmented_square(&spiral, r1, D2R(rr + seg + speedometer_scroll_offset), D2R(t(-seg + ang, 360, 0, duration_const, EaseInEaseOut)));
  1785. float scale = t(1, 1.18, 0, duration_const, EaseInEaseOut);
  1786. spiral.params.scale = xyzMake(scale, scale, 1);
  1787. spiral.params.rotation = t(180, 360, 0, duration_const, EaseInEaseOut);
  1788. draw_textured_shape(&spiral, main_matrix, NORMAL);
  1789. fast_arrow.params.rotation = fast_arrow_shadow.params.rotation = speedometer_scroll_offset + t(rr, rr + 360 + 6, 0, duration_const, EaseInEaseOut);
  1790. draw_textured_shape(&fast_arrow_shadow, main_matrix, NORMAL);
  1791. draw_textured_shape(&fast_arrow, main_matrix, NORMAL);
  1792. glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  1793. free_bg.params.alpha = t(0, 1, 0, duration_const, Linear);
  1794. draw_shape(&free_bg, main_matrix);
  1795. draw_ic(0);
  1796. } else {
  1797. glDisable(GL_BLEND);
  1798. free_bg.params.alpha = 1;
  1799. draw_shape(&free_bg, main_matrix);
  1800. glEnable(GL_BLEND);
  1801. glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  1802. draw_ic(0);
  1803. powerful_bg.params.alpha = t_reversed(0, 1, 0, duration_const, Linear);
  1804. draw_shape(&powerful_bg, main_matrix);
  1805. }
  1806. ribbon1.params.rotation = 0;
  1807. ribbon2.params.rotation = 90;
  1808. ribbon3.params.rotation = 180;
  1809. ribbon4.params.rotation = 270;
  1810. } else if (current_page == 3) {
  1811. if (direct == 1) {
  1812. glDisable(GL_BLEND);
  1813. free_bg.params.alpha = 1;
  1814. draw_shape(&free_bg, main_matrix);
  1815. glEnable(GL_BLEND);
  1816. glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  1817. powerful_bg.params.alpha = t(0, 1, 0, duration_const, Linear);
  1818. draw_shape(&powerful_bg, main_matrix);
  1819. draw_stars();
  1820. } else {
  1821. glDisable(GL_BLEND);
  1822. private_bg.params.alpha = 1;
  1823. draw_shape(&private_bg, main_matrix);
  1824. float a = t(0, 1.0f, 0, duration_const, EaseOut);
  1825. glEnable(GL_BLEND);
  1826. glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  1827. powerful_bg.params.rotation = 0;
  1828. powerful_bg.params.alpha = a;
  1829. draw_shape(&powerful_bg, main_matrix);
  1830. draw_stars();
  1831. }
  1832. } else if (current_page == 4) {
  1833. if (direct == 1) {
  1834. glDisable(GL_BLEND);
  1835. powerful_bg.params.alpha = 1;
  1836. draw_shape(&powerful_bg, main_matrix);
  1837. float a = t(0, 1.0f, 0, duration_const, EaseOut);
  1838. glEnable(GL_BLEND);
  1839. glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  1840. private_bg.params.rotation = t(45, 0, 0, duration_const, EaseOut);
  1841. private_bg.params.alpha = a;
  1842. draw_shape(&private_bg, main_matrix);
  1843. } else {
  1844. glDisable(GL_BLEND);
  1845. cloud_bg.params.alpha = 1;
  1846. draw_shape(&cloud_bg, main_matrix);
  1847. float a = t(0, 1.0f, 0, duration_const * private_back_k, EaseOut);
  1848. glEnable(GL_BLEND);
  1849. glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  1850. private_bg.params.alpha = a;
  1851. draw_shape(&private_bg, main_matrix);
  1852. }
  1853. } else if (current_page == 5) {
  1854. glDisable(GL_BLEND);
  1855. private_bg.params.alpha = 1.0f;
  1856. draw_shape(&private_bg, main_matrix);
  1857. float a = t(0, 1.0f, 0, duration_const, EaseOut);
  1858. glEnable(GL_BLEND);
  1859. glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  1860. cloud_bg.params.alpha = a;
  1861. draw_shape(&cloud_bg, main_matrix);
  1862. if (scroll_offset > 0) {
  1863. cloud_scroll_offset = -scroll_offset * 40;
  1864. } else {
  1865. cloud_scroll_offset = -scroll_offset * 15;
  1866. }
  1867. draw_ic(1);
  1868. }
  1869. if (current_page == 0) {
  1870. rglNormalDraw();
  1871. if (direct == 0) {
  1872. telegram_sphere.params.alpha = t(0, 1, 0, duration_const * 0.8f, Linear);
  1873. scale = 1;
  1874. telegram_sphere.params.scale = xyzMake(scale, scale, 1);
  1875. draw_textured_shape(&telegram_sphere, main_matrix, NORMAL);
  1876. float tt = MINf(0, (float) (-M_PI * 125.0f / 180.0f + time * M_PI * 2 * 1.5f));
  1877. float dx = t(-75, 0, 0, 0.15f, EaseIn);
  1878. float dy = t(75, 0, 0, 0.15f, EaseIn);
  1879. telegram_plane.params.position = xyzMake(dx, dy, 0);
  1880. float scale = t(0.1f, 1, 0.03f, 0.15f, EaseOut);
  1881. telegram_plane.params.scale = xyzMake(scale, scale, 1);
  1882. if (tt < D2R(125)) {
  1883. glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
  1884. draw_textured_shape(&telegram_plane, main_matrix, NORMAL_ONE);
  1885. draw_textured_shape(&telegram_mask, main_matrix, NORMAL);
  1886. }
  1887. }
  1888. } else if (current_page == 1) {
  1889. rglNormalDraw();
  1890. if (direct == 1) {
  1891. telegram_sphere.params.alpha = t(1, 0, 0, duration_const, Linear);
  1892. draw_textured_shape(&telegram_sphere, main_matrix, NORMAL);
  1893. double tt = time * M_PI * 2 * 1.5f;
  1894. float dx = t(0, 75, 0, 0.15f, EaseOut);
  1895. float dy = t(0, -75, 0, 0.15f, EaseOut);
  1896. telegram_plane.params.position = xyzMake(dx, dy, 0);
  1897. float scale = t(1, 0.1f, 0.03f, 0.15f, EaseOut);
  1898. telegram_plane.params.scale = xyzMake(scale, scale, 1);
  1899. if (tt < D2R(125)) {
  1900. glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
  1901. draw_textured_shape(&telegram_plane, main_matrix, NORMAL_ONE);
  1902. draw_textured_shape(&telegram_mask, main_matrix, NORMAL);
  1903. }
  1904. }
  1905. } else if (current_page == 2) {
  1906. rglNormalDraw();
  1907. float dribbon = 87;
  1908. if (direct == 1) {
  1909. glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
  1910. ribbonLayer.rotation = scroll_offset * 5 + t(180, 360, 0, duration_const, EaseInEaseOut);
  1911. mat4x4_layer(ribbons_layer, ribbonLayer, 1.0f, 0);
  1912. float scale;
  1913. float dur = duration_const * 0.5f;
  1914. free_knot1.params.position = xyzMake(5, -5 - 9, 0);
  1915. scale = t(0, 1, knot_delays[0], dur, EaseOut);
  1916. free_knot1.params.scale = xyzMake(scale, scale, 1);
  1917. draw_textured_shape(&free_knot1, ribbons_layer, NORMAL_ONE);
  1918. free_knot2.params.position = xyzMake(-5, -5 - 9, 0);
  1919. scale = t(0, 1, knot_delays[1], dur, EaseOut);
  1920. free_knot2.params.scale = xyzMake(-scale, scale, 1);
  1921. draw_textured_shape(&free_knot2, ribbons_layer, NORMAL_ONE);
  1922. free_knot3.params.position = xyzMake(-5, 5 - 9, 0);
  1923. scale = t(0, 1, knot_delays[2], dur, EaseOut);
  1924. free_knot3.params.scale = xyzMake(-scale, scale, 1);
  1925. draw_textured_shape(&free_knot3, ribbons_layer, NORMAL_ONE);
  1926. free_knot3.params.position = xyzMake(5, 5 - 9, 0);
  1927. scale = t(0, 1, knot_delays[3], dur, EaseOut);
  1928. free_knot3.params.scale = xyzMake(scale, scale, 1);
  1929. draw_textured_shape(&free_knot3, ribbons_layer, NORMAL_ONE);
  1930. glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  1931. ribbon1.params.alpha = ribbon2.params.alpha = ribbon3.params.alpha = ribbon4.params.alpha = t(0, 1, 0, dur, EaseInEaseOut);
  1932. int32_t ribbon_k = time > duration_const ? 1 : 0;
  1933. change_ribbon(&ribbon1, ribbonLength - 8.0f * ribbon_k - free_scroll_offset / 5.0f * (30 - 8 * ribbon_k));
  1934. ribbon1.params.position.x = scroll_offset * 30 * 0 + t(-dribbon, 0, 0, duration_const, EaseInEaseOut);
  1935. draw_shape(&ribbon1, ribbons_layer);
  1936. change_ribbon(&ribbon2, ribbonLength - 10.0f * ribbon_k - free_scroll_offset / 5.0f * (22 - 10 * ribbon_k));
  1937. ribbon2.params.position.y = scroll_offset * 15 + t(-9 - dribbon, -9, 0, duration_const, EaseInEaseOut);
  1938. draw_shape(&ribbon2, ribbons_layer);
  1939. ribbon3.params.position.x = t(dribbon, 0, 0, duration_const, EaseInEaseOut);;
  1940. draw_shape(&ribbon3, ribbons_layer);
  1941. ribbon4.params.position.y = t(-9 + dribbon, -9, 0, duration_const, EaseInEaseOut);;
  1942. draw_shape(&ribbon4, ribbons_layer);
  1943. ribbonLayer.anchor.y = 0;
  1944. ribbonLayer.position.y = 0;
  1945. change_ribbon(&ribbon1, ribbonLength);
  1946. change_ribbon(&ribbon2, ribbonLength);
  1947. change_ribbon(&ribbon3, ribbonLength);
  1948. change_ribbon(&ribbon4, ribbonLength);
  1949. } else {
  1950. glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
  1951. float scale = t(1, 2, 0, duration_const, EaseIn);
  1952. powerful_mask.params.scale = xyzMake(scale, scale, 1);
  1953. draw_textured_shape(&powerful_mask, main_matrix, NORMAL_ONE);
  1954. ribbonLayer.rotation = free_scroll_offset + t_reversed(360, 360 + (45 + 30), 0, duration_const, EaseOut);
  1955. ribbonLayer.position.y = t_reversed(0, -8, 0, duration_const * 0.8f, EaseOut);
  1956. ribbonLayer.anchor.y = t_reversed(0, -9, 0, duration_const * 0.8f, EaseOut);
  1957. mat4x4_layer(ribbons_layer, ribbonLayer, 1.0f, 0);
  1958. float dur = duration_const * 0.5f;
  1959. free_knot1.params.position = xyzMake(11 / 2, -11 / 2 - 9, 0);
  1960. scale = t(0, 1, knot_delays[0], dur, EaseOut);
  1961. free_knot1.params.scale = xyzMake(scale, scale, 1);
  1962. draw_textured_shape(&free_knot1, ribbons_layer, NORMAL_ONE);
  1963. free_knot2.params.position = xyzMake(-11 / 2, -11 / 2 - 9, 0);
  1964. scale = t(0, 1, knot_delays[1], dur, EaseOut);
  1965. free_knot2.params.scale = xyzMake(-scale, scale, 1);
  1966. draw_textured_shape(&free_knot2, ribbons_layer, NORMAL_ONE);
  1967. free_knot3.params.position = xyzMake(-11 / 2, 11 / 2 - 9, 0);
  1968. scale = t(0, 1, knot_delays[2], dur, EaseOut);
  1969. free_knot3.params.scale = xyzMake(-scale, scale, 1);
  1970. draw_textured_shape(&free_knot3, ribbons_layer, NORMAL_ONE);
  1971. free_knot3.params.position = xyzMake(11 / 2, 11 / 2 - 9, 0);
  1972. scale = t(0, 1, knot_delays[3], dur, EaseOut);
  1973. free_knot3.params.scale = xyzMake(scale, scale, 1);
  1974. draw_textured_shape(&free_knot3, ribbons_layer, NORMAL_ONE);
  1975. float a1 = -25;
  1976. ribbon1.params.rotation = t_reversed(0, a1, 0, duration_const, EaseOut);
  1977. ribbon3.params.rotation = t_reversed(180, 180 + a1, 0, duration_const, EaseOut);
  1978. float a2 = 0;
  1979. ribbon2.params.rotation = t_reversed(90, 90 + a2, 0, duration_const, EaseOut);
  1980. ribbon4.params.rotation = t_reversed(270, 270 + a2, 0, duration_const, EaseOut);
  1981. float k = 0.9f;
  1982. ribbon2.params.alpha = ribbon4.params.alpha = t_reversed(1, 0, duration_const * 0.5f, duration_const * 0.1f, Linear);
  1983. int32_t ribbon_k = 0;
  1984. change_ribbon(&ribbon1, t_reversed(ribbonLength - 8.0f * ribbon_k, 0, 0, duration_const * 0.9f, Linear) - free_scroll_offset / 5.0f * (30 - 8 * ribbon_k));
  1985. ribbon1.params.position.x = 0;
  1986. draw_shape(&ribbon1, ribbons_layer);
  1987. change_ribbon(&ribbon2, t_reversed(ribbonLength - 10.0f * ribbon_k, 0, 0, duration_const * k, Linear) - free_scroll_offset / 5.0f * (22 - 10 * ribbon_k));
  1988. ribbon2.params.position.y = scroll_offset * 15 + -9;
  1989. draw_shape(&ribbon2, ribbons_layer);
  1990. change_ribbon(&ribbon3, t_reversed(ribbonLength, 0, 0, duration_const * 0.9f, Linear));
  1991. draw_shape(&ribbon3, ribbons_layer);
  1992. change_ribbon(&ribbon4, t_reversed(ribbonLength, 0, duration_const * 0.6f * 0, duration_const * k, Linear));
  1993. draw_shape(&ribbon4, ribbons_layer);
  1994. float infinityDurK = 1.3;
  1995. rglMaskDraw();
  1996. change_infinity(&infinity, t_reversed(0, 0.99, 0, duration_const * infinityDurK, EaseOut));
  1997. float rot1 = t(0, -50, duration_const * 0.5f, duration_const * 0.8f, EaseOut);
  1998. float rot2 = t(0, -30, duration_const * 0.8f, duration_const, EaseOut);
  1999. infinity.params.rotation = rot1;
  2000. infinity.params.position.z = 1;
  2001. infinity.params.position.y = -6;
  2002. infinity.params.anchor = xyzMake(52.75, 23.5f, 0);
  2003. float infinity_scale = 1.025;
  2004. infinity.params.scale = xyzMake(infinity_scale, infinity_scale, 1);
  2005. draw_shape(&infinity, main_matrix);
  2006. infinity.params.scale = xyzMake(-infinity_scale, -infinity_scale, 1);
  2007. draw_shape(&infinity, main_matrix);
  2008. rglNormalDrawThroughMask();
  2009. glEnable(GL_BLEND);
  2010. glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
  2011. powerful_infinity_white.params.rotation = rot1 + rot2;
  2012. powerful_infinity_white.params.alpha = 1;
  2013. powerful_infinity_white.params.position.y = -6;
  2014. draw_textured_shape(&powerful_infinity_white, main_matrix, NORMAL_ONE);
  2015. }
  2016. } else if (current_page == 3) {
  2017. if (direct == 1) {
  2018. ribbon1.params.position.x = 0;
  2019. ribbon2.params.position.y = -9;
  2020. ribbon3.params.position.x = 0;
  2021. ribbon4.params.position.y = -9;
  2022. rglNormalDraw();
  2023. glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
  2024. float scale = t(2, 1, 0, duration_const, EaseOut);
  2025. powerful_mask.params.scale = xyzMake(scale, scale, 1);
  2026. draw_textured_shape(&powerful_mask, main_matrix, NORMAL_ONE);
  2027. glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  2028. ribbonLayer.rotation = free_scroll_offset + t(360, 360 + (45 + 30), 0, duration_const * 0.8f, EaseOut);
  2029. ribbonLayer.position.y = t(0, -8, 0, duration_const * 0.8f, EaseOut);
  2030. ribbonLayer.anchor.y = t(0, -9, 0, duration_const * 0.8f, EaseOut);
  2031. mat4x4_layer(ribbons_layer, ribbonLayer, 1.0f, 0);
  2032. float a1 = -25;
  2033. ribbon1.params.rotation = t(0, a1, 0, duration_const, EaseOut);
  2034. ribbon3.params.rotation = t(180, 180 + a1, 0, duration_const, EaseOut);
  2035. float a2 = 0;
  2036. ribbon2.params.rotation = t(90, 90 + a2, 0, duration_const, EaseOut);
  2037. ribbon4.params.rotation = t(270, 270 + a2, 0, duration_const, EaseOut);
  2038. float k = 0.5f;
  2039. ribbon2.params.alpha = ribbon4.params.alpha = t(1, 0, duration_const * k * 0.5f, duration_const * k * 0.1f, Linear);
  2040. int32_t ribbon_k = time > duration_const ? 1 : 0;
  2041. change_ribbon(&ribbon1, t(ribbonLength - 8.0f * ribbon_k - free_scroll_offset / 5.0f * (30 - 8 * ribbon_k), 0, 0, duration_const * 0.9f, Linear));
  2042. draw_shape(&ribbon1, ribbons_layer);
  2043. change_ribbon(&ribbon2, t(ribbonLength - 10.0f * ribbon_k - free_scroll_offset / 5.0f * (22 - 10 * ribbon_k), 0, 0, duration_const * k, Linear));
  2044. draw_shape(&ribbon2, ribbons_layer);
  2045. change_ribbon(&ribbon3, t(ribbonLength, 0, 0, duration_const * 0.9f, Linear));
  2046. draw_shape(&ribbon3, ribbons_layer);
  2047. change_ribbon(&ribbon4, t(ribbonLength, 0, 0, duration_const * k, Linear));
  2048. draw_shape(&ribbon4, ribbons_layer);
  2049. float infinityDurK = 1.1f;
  2050. if (time < duration_const * infinityDurK - 0.025f) {
  2051. rglMaskDraw();
  2052. change_infinity(&infinity, t(0, 0.99f, 0, duration_const * infinityDurK, Linear));
  2053. infinity.params.rotation = 0;
  2054. infinity.params.position.z = 1;
  2055. infinity.params.position.y = -6;
  2056. infinity.params.anchor = xyzMake(52.75, 23.5f, 0);
  2057. float infinity_scale = 1.025f;
  2058. infinity.params.scale = xyzMake(infinity_scale, infinity_scale, 1);
  2059. draw_shape(&infinity, main_matrix);
  2060. infinity.params.scale = xyzMake(-infinity_scale, -infinity_scale, 1);
  2061. draw_shape(&infinity, main_matrix);
  2062. rglNormalDrawThroughMask();
  2063. glEnable(GL_BLEND);
  2064. glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
  2065. powerful_infinity_white.params.rotation = 0;
  2066. powerful_infinity_white.params.alpha = 1;
  2067. powerful_infinity_white.params.position.y = -6;
  2068. draw_textured_shape(&powerful_infinity_white, main_matrix, NORMAL_ONE);
  2069. } else {
  2070. rglNormalDraw();
  2071. glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
  2072. powerful_infinity.params.position.y = -6;
  2073. powerful_infinity.params.alpha = 1;
  2074. draw_textured_shape(&powerful_infinity, main_matrix, NORMAL_ONE);
  2075. }
  2076. } else {
  2077. rglNormalDraw();
  2078. glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
  2079. float scale = t(2, 1, 0, duration_const, EaseOut);
  2080. powerful_mask.params.scale = xyzMake(scale, scale, 1);
  2081. draw_textured_shape(&powerful_mask, main_matrix, NORMAL_ONE);
  2082. glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  2083. scale = t(1, 2, 0, duration_const, EaseOut);
  2084. private_stroke.params.scale = xyzMake(scale, scale, 1);
  2085. private_stroke.params.rotation = t(0, -90, 0, duration_const, EaseOut);
  2086. private_stroke.params.alpha = t(1, 0, 0, duration_const, Linear);
  2087. private_stroke.params.position = xyzMake(0, t(0, -6, 0, duration_const, EaseOut), 0);
  2088. scale = t_reversed(63 * 2.0f, 63 * 2, 0, duration_const, EaseOut);
  2089. change_rounded_rectangle_stroked(&private_stroke, CSizeMake(scale, scale), scale / 2.0f);
  2090. draw_shape(&private_stroke, main_matrix);
  2091. float infinityDurK = 1.1;
  2092. if (time < duration_const * infinityDurK - 0.025f) {
  2093. rglMaskDraw();
  2094. change_infinity(&infinity, t(0, 0.99, 0, duration_const * infinityDurK, Linear));
  2095. infinity.params.rotation = 0;
  2096. infinity.params.position.z = 1;
  2097. infinity.params.position.y = -6;
  2098. infinity.params.anchor = xyzMake(52.75, 23.5f, 0);
  2099. float infinity_scale = 1.025;
  2100. infinity.params.scale = xyzMake(infinity_scale, infinity_scale, 1);
  2101. draw_shape(&infinity, main_matrix);
  2102. infinity.params.scale = xyzMake(-infinity_scale, -infinity_scale, 1);
  2103. draw_shape(&infinity, main_matrix);
  2104. rglNormalDrawThroughMask();
  2105. glEnable(GL_BLEND);
  2106. glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
  2107. powerful_infinity_white.params.rotation = 0;
  2108. powerful_infinity_white.params.alpha = 1;
  2109. powerful_infinity_white.params.position.y = -6;
  2110. draw_textured_shape(&powerful_infinity_white, main_matrix, NORMAL_ONE);
  2111. } else {
  2112. rglNormalDraw();
  2113. glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
  2114. powerful_infinity.params.position.y = -6;
  2115. powerful_infinity.params.alpha = 1;
  2116. draw_textured_shape(&powerful_infinity, main_matrix, NORMAL_ONE);
  2117. }
  2118. }
  2119. } else if (current_page == 4) {
  2120. private_stroke.params.scale = xyzMake(1, 1, 1);
  2121. private_scroll_offset = scroll_offset * 5;
  2122. rglNormalDraw();
  2123. glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
  2124. scale = t(1, 2, 0, duration_const, EaseOut);
  2125. if (scale < 1.5) {
  2126. powerful_mask.params.scale = xyzMake(scale, scale, 1);
  2127. }
  2128. if (direct == 1) {
  2129. privateLayer.rotation = private_scroll_offset + t(-90, 0, 0, duration_const, EaseOut);
  2130. } else {
  2131. privateLayer.rotation = private_scroll_offset + t(90, 0, 0, duration_const * private_back_k, EaseOut);
  2132. }
  2133. mat4x4_layer(private_matrix, privateLayer, 1, 0);
  2134. if (direct == 1) {
  2135. glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
  2136. powerful_infinity.params.position.y = -6;
  2137. powerful_infinity.params.alpha = t(1, 0, 0, duration_const * 0.25f, EaseIn);
  2138. draw_textured_shape(&powerful_infinity, main_matrix, NORMAL_ONE);
  2139. }
  2140. glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  2141. if (direct == 1) {
  2142. glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
  2143. scale = t(0.5f, 1.0f, 0, duration_const, EaseOut);
  2144. private_door.params.scale = xyzMake(scale, scale, 1);
  2145. private_door.params.alpha = t(.0, 1.0f, 0, duration_const, EaseOut);
  2146. draw_textured_shape(&private_door, main_matrix, NORMAL_ONE);
  2147. glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  2148. private_stroke.params.rotation = private_scroll_offset;
  2149. private_stroke.params.alpha = 1;
  2150. private_stroke.params.position = xyzMake(0, 0, 0);
  2151. scale = t(63, 63 * 2, 0, duration_const, EaseOut);
  2152. change_rounded_rectangle_stroked(&private_stroke, CSizeMake(scale, scale), scale / 2.0f);
  2153. draw_shape(&private_stroke, main_matrix);
  2154. glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
  2155. float k = .0;
  2156. scale = t(0.5f, 1.0f, duration_const * k, duration_const, EaseOut);
  2157. private_keyhole_body.params.rotation = private_scroll_offset;
  2158. private_keyhole_body.params.scale = xyzMake(scale, scale, 1);
  2159. private_keyhole_body.params.alpha = t(.0, 1.0f, duration_const * k, duration_const, EaseOut);
  2160. draw_safe(0, 1, t(0, 1, 0, duration_const, Linear));
  2161. } else {
  2162. glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
  2163. scale = t(0.5f, 1.0f, 0, duration_const * private_back_k, EaseOut);
  2164. private_door.params.scale = xyzMake(scale, scale, 1);
  2165. private_door.params.alpha = t(.0, 1.0f, 0, duration_const * private_back_k, EaseOut);
  2166. draw_textured_shape(&private_door, main_matrix, NORMAL_ONE);
  2167. glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  2168. private_stroke.params.rotation = private_scroll_offset;
  2169. private_stroke.params.alpha = t(0, 1, 0, duration_const * 0.25f, Linear);
  2170. private_stroke.params.position = xyzMake(0, 0, 0);
  2171. scale = t(63, 63 * 2, 0, duration_const * private_back_k, EaseOut);
  2172. change_rounded_rectangle_stroked(&private_stroke, CSizeMake(scale, scale), scale / 2.0f);
  2173. draw_shape(&private_stroke, main_matrix);
  2174. glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
  2175. scale = t(00.5f, 1.0, 0, duration_const * private_back_k, EaseOut);
  2176. private_keyhole_body.params.rotation = private_scroll_offset;
  2177. private_keyhole_body.params.scale = xyzMake(scale, scale, 1);
  2178. private_keyhole_body.params.alpha = t(.0, 1.0f, 0, duration_const * private_back_k, EaseOut);
  2179. if (time < duration_const * .4) {
  2180. cloud_cover.params.position.y = t_reversed(118 / 2 + 50, 118 / 2, duration_const * 0.8f * private_back_k, duration_const * private_back_k, EaseOut);
  2181. draw_shape(&cloud_cover, main_matrix);
  2182. }
  2183. draw_safe(0, t(0, 1, duration_const * private_back_k * 0.0f, duration_const * private_back_k, Linear), t(0, 1, 0, duration_const, Linear));
  2184. }
  2185. } else if (current_page == 5) {
  2186. float private_fade_k = 0.5f;
  2187. rglNormalDraw();
  2188. glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
  2189. scale = 1;
  2190. private_door.params.scale = xyzMake(scale, scale, 1);
  2191. private_door.params.alpha = t(1, 0, 0, duration_const * private_fade_k * 0.5f, EaseOut);
  2192. draw_textured_shape(&private_door, main_matrix, NORMAL_ONE);
  2193. glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  2194. private_stroke.params.rotation = private_scroll_offset;
  2195. private_stroke.params.alpha = t(1, 0, 0, duration_const * private_fade_k * 0.5f, EaseOut);
  2196. scale = t(244 / 2, r2 * 2, 0, duration_const, EaseOut);
  2197. change_rounded_rectangle_stroked(&private_stroke, CSizeMake(scale, scale), scale / 2.0f);
  2198. draw_shape(&private_stroke, main_matrix);
  2199. glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
  2200. scale = 1;
  2201. private_keyhole_body.params.rotation = private_scroll_offset;
  2202. private_keyhole_body.params.scale = xyzMake(scale, scale, 1);
  2203. private_keyhole_body.params.alpha = t(1.0, 0.0, 0, duration_const * private_fade_k * 0.5f, EaseOut);
  2204. privateLayer.rotation = private_scroll_offset;
  2205. mat4x4_layer(private_matrix, privateLayer, t(1, 0.9f, 0, duration_const * private_fade_k, EaseOut), 0);
  2206. cloud_cover.params.position.y = t(118 / 2 + 50, 118 / 2, 0, duration_const, EaseOut);
  2207. draw_shape(&cloud_cover, main_matrix);
  2208. }
  2209. prev_page = current_page;
  2210. }
  2211. JNIEXPORT void Java_org_telegram_messenger_Intro_setScrollOffset(JNIEnv *env, jclass class, float a_offset) {
  2212. scroll_offset = a_offset;
  2213. }
  2214. JNIEXPORT void Java_org_telegram_messenger_Intro_setPage(JNIEnv *env, jclass class, int32_t page) {
  2215. if (current_page == page) {
  2216. return;
  2217. } else {
  2218. prev_page = current_page;
  2219. current_page = page;
  2220. direct = current_page > prev_page ? 1 : 0;
  2221. date0 = date;
  2222. time = 0;
  2223. }
  2224. }
  2225. JNIEXPORT void Java_org_telegram_messenger_Intro_setDate(JNIEnv *env, jclass class, float a) {
  2226. date = a;
  2227. }
  2228. JNIEXPORT void Java_org_telegram_messenger_Intro_setIcTextures(JNIEnv *env, jclass class, GLuint a_ic_bubble_dot, GLuint a_ic_bubble, GLuint a_ic_cam_lens, GLuint a_ic_cam, GLuint a_ic_pencil, GLuint a_ic_pin, GLuint a_ic_smile_eye, GLuint a_ic_smile, GLuint a_ic_videocam) {
  2229. ic_bubble_dot_texture = a_ic_bubble_dot;
  2230. ic_bubble_texture = a_ic_bubble;
  2231. ic_cam_lens_texture = a_ic_cam_lens;
  2232. ic_cam_texture = a_ic_cam;
  2233. ic_pencil_texture = a_ic_pencil;
  2234. ic_pin_texture = a_ic_pin;
  2235. ic_smile_eye_texture = a_ic_smile_eye;
  2236. ic_smile_texture = a_ic_smile;
  2237. ic_videocam_texture = a_ic_videocam;
  2238. }
  2239. JNIEXPORT void Java_org_telegram_messenger_Intro_setTelegramTextures(JNIEnv *env, jclass class, GLuint a_telegram_sphere, GLuint a_telegram_plane, GLuint a_telegram_mask) {
  2240. telegram_sphere_texture = a_telegram_sphere;
  2241. telegram_plane_texture = a_telegram_plane;
  2242. telegram_mask_texture = a_telegram_mask;
  2243. }
  2244. JNIEXPORT void Java_org_telegram_messenger_Intro_setFastTextures(JNIEnv *env, jclass class, GLuint a_fast_body, GLuint a_fast_spiral, GLuint a_fast_arrow, GLuint a_fast_arrow_shadow) {
  2245. fast_spiral_texture = a_fast_spiral;
  2246. fast_body_texture = a_fast_body;
  2247. fast_arrow_shadow_texture = a_fast_arrow_shadow;
  2248. fast_arrow_texture = a_fast_arrow;
  2249. }
  2250. JNIEXPORT void Java_org_telegram_messenger_Intro_setFreeTextures(JNIEnv *env, jclass class, GLuint a_knot_up, GLuint a_knot_down) {
  2251. free_knot_up_texture = a_knot_up;
  2252. free_knot_down_texture = a_knot_down;
  2253. }
  2254. JNIEXPORT void Java_org_telegram_messenger_Intro_setPowerfulTextures(JNIEnv *env, jclass class, GLuint a_powerful_mask, GLuint a_powerful_star, GLuint a_powerful_infinity, GLuint a_powerful_infinity_white) {
  2255. powerful_mask_texture = a_powerful_mask;
  2256. powerful_star_texture = a_powerful_star;
  2257. powerful_infinity_texture = a_powerful_infinity;
  2258. powerful_infinity_white_texture = a_powerful_infinity_white;
  2259. }
  2260. JNIEXPORT void Java_org_telegram_messenger_Intro_setPrivateTextures(JNIEnv *env, jclass class, GLuint a_private_door, GLuint a_private_screw) {
  2261. private_door_texture = a_private_door;
  2262. private_screw_texture = a_private_screw;
  2263. }
  2264. JNIEXPORT void Java_org_telegram_messenger_Intro_onSurfaceCreated(JNIEnv *env, jclass class) {
  2265. ms0 = 0;
  2266. date = 1;
  2267. date0 = 0;
  2268. direct = 0;
  2269. i = 0;
  2270. current_page = 0;
  2271. prev_page = 0;
  2272. time = 0;
  2273. time_local = 0;
  2274. offset_y = 0;
  2275. ribbonLength = 86.5f;
  2276. starsFar = 500;
  2277. scroll_offset = 0;
  2278. calculated_speedometer_sin = 0;
  2279. ms0_anim = 0;
  2280. fps_anim = 0;
  2281. count_anim_fps = 0;
  2282. speedometer_scroll_offset = 0;
  2283. free_scroll_offset = 0;
  2284. private_scroll_offset = 0;
  2285. anim_pencil_start_time = 0;
  2286. anim_pencil_start_all_time = 0;
  2287. anim_pencil_start_all_end_time = 0;
  2288. anim_pencil_stage = 0;
  2289. anim_bubble_dots_stage = 0;
  2290. anim_bubble_dots_end_period = 0;
  2291. anim_videocam_start_time = 0;
  2292. anim_videocam_next_time = 0;
  2293. anim_videocam_duration = 0;
  2294. anim_videocam_angle = 0;
  2295. anim_videocam_old_angle = 0;
  2296. anim_cam_start_time = 0;
  2297. anim_cam_next_time = 0;
  2298. anim_cam_duration = 0;
  2299. anim_cam_angle = 0;
  2300. anim_cam_old_angle = 0;
  2301. qShot = 0;
  2302. anim_camshot_start_time = 0;
  2303. anim_camshot_duration = 0;
  2304. anim_smile_start_time1 = 0;
  2305. anim_smile_start_time2 = 0;
  2306. anim_smile_blink_start_time = 0;
  2307. anim_smile_blink_one = 0;
  2308. anim_smile_stage = 0;
  2309. scale = 0;
  2310. anim_pin_start_time = 0;
  2311. anim_pin_duration = 0;
  2312. anim_pencil_period = 0;
  2313. cloud_scroll_offset = 0;
  2314. setup_shaders();
  2315. vec4 start_button_col = {44 / 255.0f, 165 / 255.0f, 224 / 255.0f, 1.0f};
  2316. start_button = create_rounded_rectangle(CSizeMake(172, 44), 2, 3, start_button_col);
  2317. start_button.params.anchor.y = -22;
  2318. mask1 = create_rounded_rectangle(CSizeMake(60, 60), 0, 16, black_color);
  2319. telegram_sphere = create_textured_rectangle(CSizeMake(150, 150), telegram_sphere_texture);
  2320. telegram_mask = create_textured_rectangle(CSizeMake(200, 150), telegram_mask_texture);
  2321. telegram_plane = create_textured_rectangle(CSizeMake(82, 74), telegram_plane_texture);
  2322. telegram_plane.params.anchor = xyzMake(6, -5, 0);
  2323. fast_body = create_textured_rectangle(CSizeMake(148, 148), fast_body_texture);
  2324. fast_arrow_shadow = create_textured_rectangle(CSizeMake(164 / 2, 44 / 2), fast_arrow_shadow_texture);
  2325. fast_arrow_shadow.params.position.x = -1;
  2326. fast_arrow_shadow.params.position.y = 2;
  2327. fast_arrow = create_textured_rectangle(CSizeMake(164 / 2, 44 / 2), fast_arrow_texture);
  2328. fast_arrow.params.anchor.x = fast_arrow_shadow.params.anchor.x = -19;
  2329. int32_t ang = 180;
  2330. spiral = create_segmented_square(r1, D2R(35 + 1), D2R(35 + 1 - 10 + ang), fast_spiral_texture);
  2331. vec4 free_bg_color = {246 / 255.0f, 73 / 255.0f, 55 / 255.0f, 1};
  2332. free_bg = create_rectangle(CSizeMake(160 * 2, 160 * 2), free_bg_color);
  2333. free_knot1 = create_textured_rectangle(CSizeMake(138 / 3, 138 / 3), free_knot_up_texture);
  2334. free_knot1.params.anchor.x = -23 + 10;
  2335. free_knot1.params.anchor.y = 23 - 10;
  2336. free_knot2 = create_textured_rectangle(CSizeMake(138 / 3, 138 / 3), free_knot_up_texture);
  2337. free_knot2.params.anchor.x = -23 + 10;
  2338. free_knot2.params.anchor.y = 23 - 10;
  2339. free_knot3 = create_textured_rectangle(CSizeMake(150 / 3, 150 / 3), free_knot_down_texture);
  2340. free_knot3.params.anchor.x = -100 / 4.0f + 20 / 2.0f;
  2341. free_knot3.params.anchor.y = -100 / 4.0f + 20 / 2.0f;
  2342. free_knot4 = create_textured_rectangle(CSizeMake(150 / 3, 150 / 3), free_knot_down_texture);
  2343. free_knot4.params.anchor.x = -100 / 4.0f + 20 / 2.0f;
  2344. free_knot4.params.anchor.y = -100 / 4.0f + 20 / 2.0f;
  2345. ribbonLayer = default_layer_params();
  2346. ribbon1 = create_ribbon(ribbonLength, white_color);
  2347. ribbon1.params.layer_params = ribbonLayer;
  2348. ribbon2 = create_ribbon(ribbonLength, white_color);
  2349. ribbon2.params.rotation = 90;
  2350. ribbon2.params.layer_params = ribbonLayer;
  2351. ribbon3 = create_ribbon(ribbonLength, white_color);
  2352. ribbon3.params.rotation = 180;
  2353. ribbon3.params.layer_params = ribbonLayer;
  2354. ribbon4 = create_ribbon(ribbonLength, white_color);
  2355. ribbon4.params.rotation = 270;
  2356. ribbon4.params.layer_params = ribbonLayer;
  2357. ribbon1.params.position.y = ribbon2.params.position.y = ribbon3.params.position.y = ribbon4.params.position.y = -9;
  2358. ic_bubble_dot = create_textured_rectangle(CSizeMake(18 / 3, 18 / 3), ic_bubble_dot_texture);
  2359. ic_bubble = create_textured_rectangle(CSizeMake(102 / 3, 102 / 3), ic_bubble_texture);
  2360. ic_cam_lens = create_textured_rectangle(CSizeMake(36 / 3, 36 / 3), ic_cam_lens_texture);
  2361. ic_cam = create_textured_rectangle(CSizeMake(108 / 3, 96 / 3), ic_cam_texture);
  2362. ic_pencil = create_textured_rectangle(CSizeMake(86 / 3, 86 / 3), ic_pencil_texture);
  2363. ic_pin = create_textured_rectangle(CSizeMake(90 / 3, 120 / 3), ic_pin_texture);
  2364. ic_smile_eye = create_textured_rectangle(CSizeMake(18 / 3, 18 / 3), ic_smile_eye_texture);
  2365. ic_smile = create_textured_rectangle(CSizeMake(120 / 3, 120 / 3), ic_smile_texture);
  2366. ic_videocam = create_textured_rectangle(CSizeMake(144 / 3, 84 / 3), ic_videocam_texture);
  2367. ic_pin_layer = ic_cam_layer = ic_videocam_layer = ic_smile_layer = ic_bubble_layer = ic_pencil_layer = default_layer_params();
  2368. ic_pin_layer.anchor = xyzMake(0, 50 / 2, 0);
  2369. ic_pencil_layer.anchor = xyzMake(-30 / 2, 30 / 2, 0);
  2370. infinity = create_infinity(11.7, .0, 32, white_color);
  2371. vec4 powerful_bg_color = {47 / 255.f, 90 / 255.f, 131 / 255.f, 1};
  2372. powerful_bg = create_rectangle(CSizeMake(200, 200), powerful_bg_color);
  2373. powerful_mask = create_textured_rectangle(CSizeMake(200, 200), powerful_mask_texture);
  2374. powerful_infinity = create_textured_rectangle(CSizeMake(366 / 3, 180 / 3), powerful_infinity_texture);
  2375. powerful_infinity_white = create_textured_rectangle(CSizeMake(366 / 3, 180 / 3), powerful_infinity_white_texture);
  2376. float star_radius = 5.25;
  2377. star = create_textured_rectangle(CSizeMake(star_radius, star_radius), powerful_star_texture);
  2378. star.params.const_params.is_star = 1;
  2379. for (i = 0; i < starsCount; i++) {
  2380. stars[i] = default_params();
  2381. stars[i].position = star_create_position(-(i * 1500.0f) / starsCount);
  2382. }
  2383. privateLayer = default_layer_params();
  2384. vec4 private_bg_color = {200 / 255.f, 207 / 255.f, 212 / 255.f, 1};
  2385. private_bg = create_rectangle(CSizeMake(240, 240), private_bg_color);
  2386. private_door = create_textured_rectangle(CSizeMake(408 / 3, 408 / 3), private_door_texture);
  2387. private_keyhole_body = create_textured_rectangle(CSizeMake(216 / 3, 216 / 3), private_keyhole_body_texture);
  2388. private_screw = create_textured_rectangle(CSizeMake(30 / 3, 30 / 3), private_screw_texture);
  2389. private_stroke = create_rounded_rectangle_stroked(CSizeMake(244 / 2, 244 / 2), 21, 9, 16, white_color);
  2390. int32_t cloud_polygons_count = 64;
  2391. cloud_extra_mask1 = create_circle(1, cloud_polygons_count, black_color);
  2392. cloud_extra_mask2 = create_circle(1, cloud_polygons_count, black_color);
  2393. cloud_extra_mask3 = create_circle(1, cloud_polygons_count, black_color);
  2394. cloud_extra_mask4 = create_circle(1, cloud_polygons_count, black_color);
  2395. cloud_cover = create_rectangle(CSizeMake(240, 100), background_color);
  2396. cloud_cover.params.anchor.y = -50;
  2397. vec4 cloud_color = {42 / 255.0f, 180 / 255.0f, 247 / 255.0f, 1};
  2398. cloud_bg = create_rectangle(CSizeMake(160 * 2, 160 * 2), cloud_color);
  2399. surfaceCreated = 1;
  2400. }
  2401. JNIEXPORT void Java_org_telegram_messenger_Intro_onSurfaceChanged(JNIEnv *env, jclass class, int32_t a_width_px, int32_t a_height_px, float a_scale_factor, int32_t a1) {
  2402. glViewport(0, 0, a_width_px, a_height_px);
  2403. width = (int32_t) (a_width_px / a_scale_factor);
  2404. height = (int32_t) (a_height_px / a_scale_factor);
  2405. scale_factor = a_scale_factor;
  2406. mat4x4_plain(main_matrix, (int32_t) ((float) a_width_px / a_scale_factor), (int32_t) ((float) a_height_px / a_scale_factor));
  2407. offset_y = a1 * main_matrix[1][1];
  2408. set_y_offset_objects(offset_y);
  2409. y_offset_absolute = a1;
  2410. mat4x4_stars(stars_matrix, 45, 1, -1000, 0, (int32_t) ((float) a_width_px / a_scale_factor), (int32_t) ((float) a_height_px / a_scale_factor));
  2411. }