main.c 40 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165
  1. /*
  2. James William Fletcher ( notabug.org/Vandarin )
  3. December 2023 ( github.com/mrbid )
  4. Save your garden friends from the ghosts!
  5. */
  6. #include <math.h>
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. #include <string.h>
  10. #include <time.h>
  11. #ifdef WEB
  12. #include <emscripten.h>
  13. #include <emscripten/html5.h>
  14. #define GL_GLEXT_PROTOTYPES
  15. #define EGL_EGLEXT_PROTOTYPES
  16. #endif
  17. #define uint GLushort
  18. #define sint GLshort
  19. #include "inc/gl.h"
  20. #define GLFW_INCLUDE_NONE
  21. #include "inc/glfw3.h"
  22. #include "inc/esAux4.h"
  23. #include "inc/res.h"
  24. #include "assets/intro.h"
  25. #include "assets/scene.h"
  26. #include "assets/terrain.h"
  27. #include "assets/club.h"
  28. #include "assets/ghost.h"
  29. #include "assets/octo.h"
  30. #include "assets/baby.h"
  31. #include "assets/bones.h"
  32. #include "assets/bunny.h"
  33. #include "assets/cat.h"
  34. #include "assets/ginger.h"
  35. #include "assets/farmer.h"
  36. #include "assets/foxy.h"
  37. #include "assets/frog.h"
  38. #include "assets/rat.h"
  39. #include "assets/shroom.h"
  40. #include "assets/robot.h"
  41. #include "assets/teddy.h"
  42. #include "assets/treeman.h"
  43. #include "assets/dragon.h"
  44. #include "assets/banana.h"
  45. //*************************************
  46. // globals
  47. //*************************************
  48. const char appTitle[]="☃️ AI Generated Game ❄️ (Meshy.ai) 🤖";
  49. GLFWwindow* window;
  50. uint winw=1024, winh=768;
  51. float t=0.f, dt=0.f, lt=0.f, ltut=0.f, st=0.f, fc=0.f, lfct=0.f, aspect;
  52. double mx,my,lx,ly,ww,wh;
  53. // render state id's
  54. GLint projection_id;
  55. GLint modelview_id;
  56. GLint position_id;
  57. GLint normal_id;
  58. GLint color_id;
  59. GLint lightpos_id;
  60. GLint opacity_id;
  61. // render state
  62. mat projection, view, model, modelview;
  63. // models
  64. ESModel mdlIntro;
  65. ESModel mdlTerrain;
  66. ESModel mdlScene; // duplicating mesh into a scene like this makes the file bigger at a disproportionate ratio to making the renderer more efficient, but it was just faster to do this.
  67. ESModel mdlClub;
  68. ESModel mdlGhost;
  69. ESModel mdlOcto;
  70. ESModel mdlBaby;
  71. ESModel mdlBones;
  72. ESModel mdlBunny;
  73. ESModel mdlCat;
  74. ESModel mdlGinger;
  75. ESModel mdlFarmer;
  76. ESModel mdlFoxy;
  77. ESModel mdlFrog;
  78. ESModel mdlRat;
  79. ESModel mdlShroom;
  80. ESModel mdlRobot;
  81. ESModel mdlTeddy;
  82. ESModel mdlTreeman;
  83. ESModel mdlDragon;
  84. ESModel mdlBanana;
  85. // positions
  86. const vec baby_pos = (vec){ 0.31471309065818787, -0.18127848207950592, -1.588475424796343e-05 };
  87. const vec bones_pos = (vec){ 0.9441254138946533 , -4.923678398132324 , -1.8969178199768066e-05 };
  88. const vec bunny_pos = (vec){ -0.1463201642036438 , -3.3715295791625977 , -1.341104507446289e-06 };
  89. const vec cat_pos = (vec){ 2.409440517425537 , -0.08113411068916321, 0.0006199628114700317 };
  90. const vec ginger_pos = (vec){ -3.5621275901794434 , 1.3744210004806519 , -4.3662264943122864e-05 };
  91. const vec farmer_pos = (vec){ -5.638768672943115 , -2.3814315795898438 , -5.668585072271526e-05 };
  92. const vec foxy_pos = (vec){ 0.3325018882751465 , 3.407064437866211 , -2.3096799850463867e-06 };
  93. const vec frog_pos = (vec){ 2.815049886703491 , -2.359147787094116 , -0.0002002716064453125 };
  94. const vec rat_pos = (vec){ -1.9573389291763306 , -4.990877628326416 , -5.9857964515686035e-05 };
  95. const vec shroom_pos = (vec){ 2.9257962703704834 , 3.9158010482788086 , 6.631016731262207e-06 };
  96. const vec robot_pos = (vec){ -3.2104883193969727 , 0 , -2.0265579223632812e-06 };
  97. const vec teddy_pos = (vec){ -1.148323655128479 , -1.155029535293579 , -8.046627044677734e-06 };
  98. const vec treeman_pos = (vec){ 3.7293591499328613 , 0.10551458597183228, -2.2292137145996094e-05 };
  99. const vec dragon_pos = (vec){ -5.303407669067383 , -2.8256068229675293 , -9.742379188537598e-05 };
  100. const vec banana_pos = (vec){ 3.863978624343872 , -3.625526189804077 , -2.092123031616211e-05 };
  101. vec friend_pos[15];
  102. // game vars
  103. #define FAR_DISTANCE 128.f
  104. #define NEWGAME_SEED 1337
  105. char tts[32];
  106. uint keystate[5] = {0};
  107. // camera vars
  108. uint focus_cursor = 0;
  109. double sens = 0.003f;
  110. float xrot = 0.f;
  111. float yrot = d2PI;
  112. vec look_dir, lookx, looky;
  113. // player vars
  114. float MOVE_SPEED = 1.6f;
  115. vec pp;
  116. uint bonking = 0.f;
  117. // ghosts
  118. #define MAX_GHOSTS 32
  119. vec ghost_pos[MAX_GHOSTS];
  120. vec ghost_dir[MAX_GHOSTS];
  121. int ghost_tgt[MAX_GHOSTS];
  122. float ghost_opa[MAX_GHOSTS];
  123. // octo
  124. vec octo_pos;
  125. vec octo_dir;
  126. int octo_tgt;
  127. // stats
  128. uint ghostsbonked = 0;
  129. uint friendsalive = 15;
  130. //*************************************
  131. // utility functions
  132. //*************************************
  133. void timestamp(char* ts)
  134. {
  135. const time_t tt = time(0);
  136. strftime(ts, 16, "%H:%M:%S", localtime(&tt));
  137. }
  138. void timeTaken(uint ss)
  139. {
  140. if(ss == 1)
  141. {
  142. const double tt = t-st;
  143. if(tt < 60.0)
  144. sprintf(tts, "%.0f Sec", tt);
  145. else if(tt < 3600.0)
  146. sprintf(tts, "%.2f Min", tt * 0.016666667);
  147. else if(tt < 216000.0)
  148. sprintf(tts, "%.2f Hr", tt * 0.000277778);
  149. else if(tt < 12960000.0)
  150. sprintf(tts, "%.2f Days", tt * 0.00000463);
  151. }
  152. else
  153. {
  154. const double tt = t-st;
  155. if(tt < 60.0)
  156. sprintf(tts, "%.0f Seconds", tt);
  157. else if(tt < 3600.0)
  158. sprintf(tts, "%.2f Minutes", tt * 0.016666667);
  159. else if(tt < 216000.0)
  160. sprintf(tts, "%.2f Hours", tt * 0.000277778);
  161. else if(tt < 12960000.0)
  162. sprintf(tts, "%.2f Days", tt * 0.00000463);
  163. }
  164. }
  165. //*************************************
  166. // render functions
  167. //*************************************
  168. void modelBind(const ESModel* mdl)
  169. {
  170. glBindBuffer(GL_ARRAY_BUFFER, mdl->vid);
  171. glVertexAttribPointer(position_id, 3, GL_FLOAT, GL_FALSE, 0, 0);
  172. glEnableVertexAttribArray(position_id);
  173. glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mdl->iid);
  174. }
  175. void modelBind3(const ESModel* mdl)
  176. {
  177. glBindBuffer(GL_ARRAY_BUFFER, mdl->cid);
  178. glVertexAttribPointer(color_id, 3, GL_FLOAT, GL_FALSE, 0, 0);
  179. glEnableVertexAttribArray(color_id);
  180. glBindBuffer(GL_ARRAY_BUFFER, mdl->vid);
  181. glVertexAttribPointer(position_id, 3, GL_FLOAT, GL_FALSE, 0, 0);
  182. glEnableVertexAttribArray(position_id);
  183. glBindBuffer(GL_ARRAY_BUFFER, mdl->nid);
  184. glVertexAttribPointer(normal_id, 3, GL_FLOAT, GL_FALSE, 0, 0);
  185. glEnableVertexAttribArray(normal_id);
  186. glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mdl->iid);
  187. }
  188. //*************************************
  189. // game functions
  190. //*************************************
  191. void retargetGhost(uint i)
  192. {
  193. ghost_tgt[i] = esRand(0, 14);
  194. if(friend_pos[ghost_tgt[i]].z <= -0.74f)
  195. {
  196. uint fail = 1;
  197. for(uint j = 0; j < 15; j++)
  198. {
  199. if(friend_pos[j].z > -0.74f)
  200. {
  201. ghost_tgt[i] = j;
  202. fail = 0;
  203. break;
  204. }
  205. }
  206. if(fail == 1)
  207. {
  208. ghost_tgt[i] = -1;
  209. return;
  210. }
  211. }
  212. ghost_dir[i] = friend_pos[ghost_tgt[i]];
  213. vSub(&ghost_dir[i], ghost_dir[i], ghost_pos[i]);
  214. ghost_dir[i].z = 0.f;
  215. vNorm(&ghost_dir[i]);
  216. }
  217. void resetGhost(uint i)
  218. {
  219. const float radius = esRandFloat(20.f, 42.f);
  220. const float angle = esRandFloat(-PI, PI);
  221. ghost_pos[i] = (vec){radius*cosf(angle), radius*sinf(angle), -1.f};
  222. retargetGhost(i);
  223. ghost_opa[i] = 1.f;
  224. }
  225. void newGame(unsigned int seed)
  226. {
  227. srand(seed);
  228. xrot = 0.f;
  229. yrot = d2PI;
  230. pp = (vec){0.f, 1.f, 0.f};
  231. octo_pos = (vec){3.f, 1.f, 0.f};
  232. octo_dir = (vec){0.f, -1.f, 0.f};
  233. octo_tgt = -1;
  234. lt = 0.f;
  235. ltut = 0.f;
  236. for(uint i = 0; i < 15; i++)
  237. friend_pos[i].z = 0.f;
  238. for(uint i = 0; i < MAX_GHOSTS; i++)
  239. resetGhost(i);
  240. ghostsbonked = 0;
  241. friendsalive = 15;
  242. char strts[16];
  243. timestamp(&strts[0]);
  244. printf("[%s] 👋 Game Start 🎬 [%u] 🏁🫧🌎🥑🦄🎉.\n", strts, seed);
  245. glfwSetWindowTitle(window, appTitle);
  246. glfwSetTime(0.0);
  247. }
  248. void updateTitle()
  249. {
  250. if(t < 8.f){return;}
  251. friendsalive = 0;
  252. for(uint i = 0; i < 15; i++)
  253. {
  254. if(friend_pos[i].z > -0.369f){friendsalive++;}
  255. }
  256. char tmp[256];
  257. sprintf(tmp, "🫂 %u - 👻 %u", friendsalive, ghostsbonked);
  258. glfwSetWindowTitle(window, tmp);
  259. }
  260. //*************************************
  261. // update & render
  262. //*************************************
  263. void main_loop()
  264. {
  265. //*************************************
  266. // core logic
  267. //*************************************
  268. fc++;
  269. glfwPollEvents();
  270. t = (float)glfwGetTime();
  271. dt = t-lt;
  272. lt = t;
  273. #ifdef WEB
  274. EmscriptenPointerlockChangeEvent e;
  275. if(emscripten_get_pointerlock_status(&e) == EMSCRIPTEN_RESULT_SUCCESS)
  276. {
  277. if(focus_cursor == 0 && e.isActive == 1)
  278. {
  279. glfwGetCursorPos(window, &lx, &ly);
  280. }
  281. focus_cursor = e.isActive;
  282. }
  283. #endif
  284. //*************************************
  285. // game logic
  286. //*************************************
  287. // update title every second
  288. if(t > ltut)
  289. {
  290. updateTitle();
  291. ltut = t + 1.0f;
  292. }
  293. // forward & backward
  294. if(keystate[2] == 1)
  295. {
  296. vec m;
  297. vMulS(&m, look_dir, MOVE_SPEED * dt);
  298. vSub(&pp, pp, m);
  299. }
  300. else if(keystate[3] == 1)
  301. {
  302. vec m;
  303. vMulS(&m, look_dir, MOVE_SPEED * dt);
  304. vAdd(&pp, pp, m);
  305. }
  306. // strafe left & right
  307. if(keystate[0] == 1)
  308. {
  309. mGetViewX(&lookx, view);
  310. vec m;
  311. vMulS(&m, lookx, MOVE_SPEED * dt);
  312. vSub(&pp, pp, m);
  313. }
  314. else if(keystate[1] == 1)
  315. {
  316. mGetViewX(&lookx, view);
  317. vec m;
  318. vMulS(&m, lookx, MOVE_SPEED * dt);
  319. vAdd(&pp, pp, m);
  320. }
  321. // sprint
  322. if(keystate[4] == 1)
  323. {
  324. MOVE_SPEED = 4.20f;
  325. }
  326. else
  327. {
  328. MOVE_SPEED = 1.60f;
  329. }
  330. // lock to floor
  331. pp.z = -0.26f;
  332. //*************************************
  333. // camera
  334. //*************************************
  335. if(focus_cursor == 1)
  336. {
  337. glfwGetCursorPos(window, &mx, &my);
  338. xrot += (lx-mx)*sens;
  339. yrot += (ly-my)*sens;
  340. if(yrot > 2.5f)
  341. yrot = 2.5f;
  342. if(yrot < 0.55f)
  343. yrot = 0.55f;
  344. lx = mx;
  345. ly = my;
  346. }
  347. mIdent(&view);
  348. mRotate(&view, yrot, 1.f, 0.f, 0.f);
  349. mRotate(&view, xrot, 0.f, 0.f, 1.f);
  350. mTranslate(&view, pp.x, pp.y, pp.z);
  351. // get look dir/axes
  352. mGetViewZ(&look_dir, view);
  353. mGetViewX(&lookx, view);
  354. mGetViewY(&looky, view);
  355. //*************************************
  356. // render
  357. //*************************************
  358. // clear buffer
  359. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  360. ///
  361. // shader program change
  362. shadeFullbright(&position_id, &projection_id, &modelview_id, &color_id, &opacity_id);
  363. glUniformMatrix4fv(projection_id, 1, GL_FALSE, (float*)&projection.m[0][0]);
  364. // render terrain
  365. glUniformMatrix4fv(modelview_id, 1, GL_FALSE, (float*)&view.m[0][0]);
  366. modelBind(&mdlTerrain);
  367. glUniform3f(color_id, 1.f, 1.f, 1.f);
  368. glDrawElements(GL_TRIANGLES, terrain_numind, GL_UNSIGNED_BYTE, 0);
  369. ///
  370. // shader program change
  371. shadeLambert3(&position_id, &projection_id, &modelview_id, &lightpos_id, &normal_id, &color_id, &opacity_id);
  372. glUniformMatrix4fv(projection_id, 1, GL_FALSE, (float*)&projection.m[0][0]);
  373. // render scene
  374. glUniformMatrix4fv(modelview_id, 1, GL_FALSE, (float*)&view.m[0][0]);
  375. modelBind3(&mdlScene);
  376. glDrawElements(GL_TRIANGLES, scene_numind, GL_UNSIGNED_INT, 0);
  377. // baby
  378. mIdent(&model);
  379. mSetPos(&model, friend_pos[0]);
  380. mMul(&modelview, &model, &view);
  381. glUniformMatrix4fv(modelview_id, 1, GL_FALSE, (float*)&modelview.m[0][0]);
  382. modelBind3(&mdlBaby);
  383. glDrawElements(GL_TRIANGLES, baby_numind, GL_UNSIGNED_SHORT, 0);
  384. // bones
  385. mIdent(&model);
  386. mSetPos(&model, friend_pos[1]);
  387. mMul(&modelview, &model, &view);
  388. glUniformMatrix4fv(modelview_id, 1, GL_FALSE, (float*)&modelview.m[0][0]);
  389. modelBind3(&mdlBones);
  390. glDrawElements(GL_TRIANGLES, bones_numind, GL_UNSIGNED_SHORT, 0);
  391. // bunny
  392. mIdent(&model);
  393. mSetPos(&model, friend_pos[2]);
  394. mMul(&modelview, &model, &view);
  395. glUniformMatrix4fv(modelview_id, 1, GL_FALSE, (float*)&modelview.m[0][0]);
  396. modelBind3(&mdlBunny);
  397. glDrawElements(GL_TRIANGLES, bunny_numind, GL_UNSIGNED_SHORT, 0);
  398. // cat
  399. mIdent(&model);
  400. mSetPos(&model, friend_pos[3]);
  401. mMul(&modelview, &model, &view);
  402. glUniformMatrix4fv(modelview_id, 1, GL_FALSE, (float*)&modelview.m[0][0]);
  403. modelBind3(&mdlCat);
  404. glDrawElements(GL_TRIANGLES, cat_numind, GL_UNSIGNED_SHORT, 0);
  405. // ginger
  406. mIdent(&model);
  407. mSetPos(&model, friend_pos[4]);
  408. mMul(&modelview, &model, &view);
  409. glUniformMatrix4fv(modelview_id, 1, GL_FALSE, (float*)&modelview.m[0][0]);
  410. modelBind3(&mdlGinger);
  411. glDrawElements(GL_TRIANGLES, ginger_numind, GL_UNSIGNED_SHORT, 0);
  412. // farmer
  413. mIdent(&model);
  414. mSetPos(&model, friend_pos[5]);
  415. mMul(&modelview, &model, &view);
  416. glUniformMatrix4fv(modelview_id, 1, GL_FALSE, (float*)&modelview.m[0][0]);
  417. modelBind3(&mdlFarmer);
  418. glDrawElements(GL_TRIANGLES, farmer_numind, GL_UNSIGNED_SHORT, 0);
  419. // foxy
  420. mIdent(&model);
  421. mSetPos(&model, friend_pos[6]);
  422. mMul(&modelview, &model, &view);
  423. glUniformMatrix4fv(modelview_id, 1, GL_FALSE, (float*)&modelview.m[0][0]);
  424. modelBind3(&mdlFoxy);
  425. glDrawElements(GL_TRIANGLES, foxy_numind, GL_UNSIGNED_SHORT, 0);
  426. // frog
  427. mIdent(&model);
  428. mSetPos(&model, friend_pos[7]);
  429. mMul(&modelview, &model, &view);
  430. glUniformMatrix4fv(modelview_id, 1, GL_FALSE, (float*)&modelview.m[0][0]);
  431. modelBind3(&mdlFrog);
  432. glDrawElements(GL_TRIANGLES, frog_numind, GL_UNSIGNED_SHORT, 0);
  433. // rat
  434. mIdent(&model);
  435. mSetPos(&model, friend_pos[8]);
  436. mMul(&modelview, &model, &view);
  437. glUniformMatrix4fv(modelview_id, 1, GL_FALSE, (float*)&modelview.m[0][0]);
  438. modelBind3(&mdlRat);
  439. glDrawElements(GL_TRIANGLES, rat_numind, GL_UNSIGNED_SHORT, 0);
  440. // shroom
  441. mIdent(&model);
  442. mSetPos(&model, friend_pos[9]);
  443. mMul(&modelview, &model, &view);
  444. glUniformMatrix4fv(modelview_id, 1, GL_FALSE, (float*)&modelview.m[0][0]);
  445. modelBind3(&mdlShroom);
  446. glDrawElements(GL_TRIANGLES, shroom_numind, GL_UNSIGNED_SHORT, 0);
  447. // robot
  448. mIdent(&model);
  449. mSetPos(&model, friend_pos[10]);
  450. mMul(&modelview, &model, &view);
  451. glUniformMatrix4fv(modelview_id, 1, GL_FALSE, (float*)&modelview.m[0][0]);
  452. modelBind3(&mdlRobot);
  453. glDrawElements(GL_TRIANGLES, robot_numind, GL_UNSIGNED_SHORT, 0);
  454. // teddy
  455. mIdent(&model);
  456. mSetPos(&model, friend_pos[11]);
  457. mMul(&modelview, &model, &view);
  458. glUniformMatrix4fv(modelview_id, 1, GL_FALSE, (float*)&modelview.m[0][0]);
  459. modelBind3(&mdlTeddy);
  460. glDrawElements(GL_TRIANGLES, teddy_numind, GL_UNSIGNED_SHORT, 0);
  461. // treeman
  462. mIdent(&model);
  463. mSetPos(&model, friend_pos[12]);
  464. mMul(&modelview, &model, &view);
  465. glUniformMatrix4fv(modelview_id, 1, GL_FALSE, (float*)&modelview.m[0][0]);
  466. modelBind3(&mdlTreeman);
  467. glDrawElements(GL_TRIANGLES, treeman_numind, GL_UNSIGNED_SHORT, 0);
  468. // dragon
  469. mIdent(&model);
  470. mSetPos(&model, friend_pos[13]);
  471. mMul(&modelview, &model, &view);
  472. glUniformMatrix4fv(modelview_id, 1, GL_FALSE, (float*)&modelview.m[0][0]);
  473. modelBind3(&mdlDragon);
  474. glDrawElements(GL_TRIANGLES, dragon_numind, GL_UNSIGNED_SHORT, 0);
  475. // banana
  476. mIdent(&model);
  477. mSetPos(&model, friend_pos[14]);
  478. mMul(&modelview, &model, &view);
  479. glUniformMatrix4fv(modelview_id, 1, GL_FALSE, (float*)&modelview.m[0][0]);
  480. modelBind3(&mdlBanana);
  481. glDrawElements(GL_TRIANGLES, banana_numind, GL_UNSIGNED_SHORT, 0);
  482. // octo
  483. mIdent(&model);
  484. mSetDir(&model, octo_dir);
  485. mSetPos(&model, octo_pos);
  486. mMul(&modelview, &model, &view);
  487. glUniformMatrix4fv(modelview_id, 1, GL_FALSE, (float*)&modelview.m[0][0]);
  488. modelBind3(&mdlOcto);
  489. glDrawElements(GL_TRIANGLES, octo_numind, GL_UNSIGNED_SHORT, 0);
  490. if(octo_tgt != -1)
  491. {
  492. const float xm = (friend_pos[octo_tgt].x - octo_pos.x);
  493. const float ym = (friend_pos[octo_tgt].y - octo_pos.y);
  494. if(xm*xm + ym*ym > 0.0001f)
  495. {
  496. vec inc = friend_pos[octo_tgt];
  497. vSub(&inc, inc, octo_pos);
  498. inc.z = 0.f;
  499. vNorm(&inc);
  500. octo_dir = inc;
  501. vMulS(&inc, inc, 0.88888888f*dt);
  502. vAdd(&octo_pos, octo_pos, inc);
  503. }
  504. else if(friend_pos[octo_tgt].z < 0.f)
  505. {
  506. friend_pos[octo_tgt].z += 0.15f*dt;
  507. }
  508. else
  509. {
  510. octo_tgt = -1;
  511. updateTitle();
  512. }
  513. }
  514. else
  515. {
  516. uint fail = 1;
  517. for(uint i = 0; i < 15; i++)
  518. {
  519. if(friend_pos[i].z < -0.001f) // epsilon
  520. {
  521. octo_tgt = i;
  522. fail = 0;
  523. break;
  524. }
  525. }
  526. if(fail == 1){octo_tgt = -1;}
  527. }
  528. // ghosts
  529. for(uint i = 0; i < MAX_GHOSTS; i++)
  530. {
  531. // send ghost to another dimension? GHOST BUSTERS!?
  532. if(ghost_tgt[i] == -1)
  533. {
  534. if(ghost_opa[i] > 0.f)
  535. {
  536. ghost_opa[i] -= 0.42f * dt;
  537. }
  538. else
  539. {
  540. resetGhost(i);
  541. continue;
  542. }
  543. continue;
  544. }
  545. // target dead?
  546. if(friend_pos[ghost_tgt[i]].z <= -0.74f)
  547. retargetGhost(i); //ghost_tgt[i] = -1;
  548. // rise from the grave
  549. if(ghost_pos[i].z < -1.f){ghost_pos[i].z = -1.f;} // this is a quick fix to [1]
  550. if(ghost_pos[i].z < 0.f)
  551. {
  552. ghost_pos[i].z += 0.24f*dt; // [1] some how causes z to go way below -1 at times
  553. }
  554. else
  555. {
  556. const float xm = (-pp.x - ghost_pos[i].x);
  557. const float ym = (-pp.y - ghost_pos[i].y);
  558. const float xm1 = (friend_pos[ghost_tgt[i]].x - ghost_pos[i].x);
  559. const float ym1 = (friend_pos[ghost_tgt[i]].y - ghost_pos[i].y);
  560. const float fgd = xm1*xm1 + ym1*ym1;
  561. if(xm*xm + ym*ym > 0.17f && fgd > 0.1f)
  562. {
  563. vec inc = ghost_dir[i];
  564. vMulS(&inc, ghost_dir[i], 0.3f*dt);
  565. vAdd(&ghost_pos[i], ghost_pos[i], inc);
  566. }
  567. else if(fgd < 0.1f)
  568. {
  569. if(friend_pos[ghost_tgt[i]].z > -0.74f)
  570. {
  571. friend_pos[ghost_tgt[i]].z -= 0.03f*dt;
  572. }
  573. else
  574. {
  575. //ghost_tgt[i] = -1;
  576. retargetGhost(i);
  577. updateTitle();
  578. }
  579. }
  580. }
  581. // render
  582. mIdent(&model);
  583. mSetDir(&model, ghost_dir[i]);
  584. mSetPos(&model, ghost_pos[i]);
  585. mMul(&modelview, &model, &view);
  586. glUniformMatrix4fv(modelview_id, 1, GL_FALSE, (float*)&modelview.m[0][0]);
  587. modelBind3(&mdlGhost);
  588. glDrawElements(GL_TRIANGLES, ghost_numind, GL_UNSIGNED_SHORT, 0);
  589. }
  590. // do the transparent ghosts now
  591. for(uint i = 0; i < MAX_GHOSTS; i++)
  592. {
  593. if(ghost_tgt[i] == -1)
  594. {
  595. if(ghost_opa[i] > 0.f)
  596. {
  597. ghost_opa[i] -= 0.42f * dt;
  598. }
  599. else
  600. {
  601. resetGhost(i);
  602. continue;
  603. }
  604. mIdent(&model);
  605. mSetDir(&model, ghost_dir[i]);
  606. mSetPos(&model, ghost_pos[i]);
  607. mMul(&modelview, &model, &view);
  608. glUniformMatrix4fv(modelview_id, 1, GL_FALSE, (float*)&modelview.m[0][0]);
  609. modelBind3(&mdlGhost);
  610. glUniform1f(opacity_id, ghost_opa[i]);
  611. glEnable(GL_BLEND);
  612. glEnable(GL_CULL_FACE);
  613. glDrawElements(GL_TRIANGLES, ghost_numind, GL_UNSIGNED_SHORT, 0);
  614. glDisable(GL_CULL_FACE);
  615. glDisable(GL_BLEND);
  616. }
  617. }
  618. ///
  619. // render bonking tool
  620. mIdent(&model);
  621. vec ld = look_dir;
  622. ld.z = 0.f;
  623. vMulS(&ld, ld, 0.08f); // far from camera
  624. vec np = (vec){-pp.x, -pp.y, -pp.z};
  625. vAdd(&np, np, ld);
  626. // x offset
  627. vec vx = lookx;
  628. vMulS(&vx, vx, -0.08f);
  629. vAdd(&np, np, vx);
  630. // y offset
  631. vec vy = looky;
  632. vMulS(&vy, vy, 0.0788f); // 0.0388f or 0.0888f
  633. vAdd(&np, np, vy);
  634. // rotate to camera direction with slight offset and set pos
  635. mScale(&model, 0.6f, 0.6f, 0.6f);
  636. mRotZ(&model, -(xrot-PI));
  637. if(bonking == 1){mRotY(&model, -0.6f); mRotX(&model, -0.6f);}
  638. mSetPos(&model, np);
  639. // render it
  640. mMul(&modelview, &model, &view);
  641. glUniformMatrix4fv(modelview_id, 1, GL_FALSE, (float*)&modelview.m[0][0]);
  642. modelBind3(&mdlClub);
  643. glClear(GL_DEPTH_BUFFER_BIT);
  644. glDrawElements(GL_TRIANGLES, club_numind, GL_UNSIGNED_SHORT, 0);
  645. ///
  646. // render intro
  647. if(t < 5.f)
  648. {
  649. // shader program change
  650. shadeFullbright(&position_id, &projection_id, &modelview_id, &color_id, &opacity_id);
  651. glUniformMatrix4fv(projection_id, 1, GL_FALSE, (float*)&projection.m[0][0]);
  652. if(t < 4.f)
  653. {
  654. glUniform1f(opacity_id, 1.f);
  655. }
  656. else
  657. {
  658. glUniform1f(opacity_id, 1.f-(t-4.f));
  659. }
  660. glEnable(GL_BLEND);
  661. {
  662. vec ld = look_dir;
  663. vMulS(&ld, ld, 1.79f);
  664. vec np = (vec){-pp.x, -pp.y, -pp.z};
  665. vAdd(&np, np, ld);
  666. mIdent(&model);
  667. mSetPos(&model, np);
  668. mRotZ(&model, -xrot);
  669. mMul(&modelview, &model, &view);
  670. glUniformMatrix4fv(modelview_id, 1, GL_FALSE, (float*)&modelview.m[0][0]);
  671. modelBind(&mdlIntro);
  672. glUniform3f(color_id, 0.854f, 0.335f, 1.f);
  673. glDrawElements(GL_TRIANGLES, intro_numind, GL_UNSIGNED_SHORT, 0);
  674. }
  675. {
  676. vec ld = look_dir;
  677. vMulS(&ld, ld, 1.8f);
  678. vec np = (vec){-pp.x, -pp.y, -pp.z};
  679. vAdd(&np, np, ld);
  680. vec vy = looky;
  681. vMulS(&vy, vy, -0.004f);
  682. vAdd(&np, np, vy);
  683. mIdent(&model);
  684. mSetPos(&model, np);
  685. mRotZ(&model, -xrot);
  686. mMul(&modelview, &model, &view);
  687. glUniformMatrix4fv(modelview_id, 1, GL_FALSE, (float*)&modelview.m[0][0]);
  688. modelBind(&mdlIntro);
  689. glUniform3f(color_id, 0.f, 0.f, 0.f);
  690. glDrawElements(GL_TRIANGLES, intro_numind, GL_UNSIGNED_SHORT, 0);
  691. }
  692. glDisable(GL_BLEND);
  693. }
  694. ///
  695. // display render
  696. glfwSwapBuffers(window);
  697. }
  698. //*************************************
  699. // input
  700. //*************************************
  701. static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
  702. {
  703. if(action == GLFW_PRESS)
  704. {
  705. if( key == GLFW_KEY_A || key == GLFW_KEY_LEFT) { keystate[0] = 1; }
  706. else if(key == GLFW_KEY_D || key == GLFW_KEY_RIGHT) { keystate[1] = 1; }
  707. else if(key == GLFW_KEY_W || key == GLFW_KEY_UP) { keystate[2] = 1; }
  708. else if(key == GLFW_KEY_S || key == GLFW_KEY_DOWN) { keystate[3] = 1; }
  709. else if(key == GLFW_KEY_LEFT_SHIFT ||
  710. key == GLFW_KEY_RIGHT_CONTROL) { keystate[4] = 1;}
  711. else if(key == GLFW_KEY_N) // new game
  712. {
  713. timeTaken(0);
  714. char strts[16];
  715. timestamp(&strts[0]);
  716. printf("[%s] 🥶 Game End. 🥂 😎\n", strts);
  717. printf("[%s] 🫂 বন্ধুরা%u - 👻 বন্ধ %u\n", strts, friendsalive, ghostsbonked);
  718. printf("[%s] ⏳ Time-Taken: %s or %g Seconds 🫣\n\n", strts, tts, t-st);
  719. newGame(time(0));
  720. }
  721. else if(key == GLFW_KEY_ESCAPE) // toggle mouse focus
  722. {
  723. focus_cursor = 0;
  724. #ifndef WEB
  725. glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
  726. glfwGetCursorPos(window, &lx, &ly);
  727. #endif
  728. }
  729. else if(key == GLFW_KEY_F) // show average fps
  730. {
  731. if(t-lfct > 2.0)
  732. {
  733. char strts[16];
  734. timestamp(&strts[0]);
  735. printf("[%s] FPS: %g\n", strts, fc/(t-lfct));
  736. lfct = t;
  737. fc = 0;
  738. }
  739. }
  740. }
  741. else if(action == GLFW_RELEASE)
  742. {
  743. if( key == GLFW_KEY_A || key == GLFW_KEY_LEFT) { keystate[0] = 0; }
  744. else if(key == GLFW_KEY_D || key == GLFW_KEY_RIGHT) { keystate[1] = 0; }
  745. else if(key == GLFW_KEY_W || key == GLFW_KEY_UP) { keystate[2] = 0; }
  746. else if(key == GLFW_KEY_S || key == GLFW_KEY_DOWN) { keystate[3] = 0; }
  747. else if(key == GLFW_KEY_LEFT_SHIFT ||
  748. key == GLFW_KEY_RIGHT_CONTROL) { keystate[4] = 0;}
  749. }
  750. }
  751. void mouse_button_callback(GLFWwindow* window, int button, int action, int mods)
  752. {
  753. if(action == GLFW_PRESS)
  754. {
  755. if(focus_cursor == 0)
  756. {
  757. focus_cursor = 1;
  758. #ifndef WEB
  759. glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
  760. glfwGetCursorPos(window, &lx, &ly);
  761. #endif
  762. return;
  763. }
  764. if(button == GLFW_MOUSE_BUTTON_LEFT)
  765. {
  766. for(uint i = 0; i < MAX_GHOSTS; i++)
  767. {
  768. const float xm = (-pp.x - ghost_pos[i].x);
  769. const float ym = (-pp.y - ghost_pos[i].y);
  770. if(ghost_pos[i].z >= 0.f && xm*xm + ym*ym < 0.17f && ghost_tgt[i] != -1)
  771. {
  772. ghost_tgt[i] = -1;
  773. bonking = 1;
  774. ghostsbonked++;
  775. updateTitle();
  776. return;
  777. }
  778. }
  779. }
  780. else if(button == GLFW_MOUSE_BUTTON_RIGHT)
  781. {
  782. mIdent(&projection);
  783. mPerspective(&projection, 30.0f, aspect, 0.01f, FAR_DISTANCE);
  784. glUniformMatrix4fv(projection_id, 1, GL_FALSE, (float*)&projection.m[0][0]);
  785. }
  786. }
  787. else if(action == GLFW_RELEASE)
  788. {
  789. if(button == GLFW_MOUSE_BUTTON_LEFT)
  790. {
  791. bonking = 0;
  792. }
  793. else if(button == GLFW_MOUSE_BUTTON_RIGHT)
  794. {
  795. mIdent(&projection);
  796. mPerspective(&projection, 60.0f, aspect, 0.01f, FAR_DISTANCE);
  797. glUniformMatrix4fv(projection_id, 1, GL_FALSE, (float*)&projection.m[0][0]);
  798. }
  799. }
  800. }
  801. void window_size_callback(GLFWwindow* window, int width, int height)
  802. {
  803. winw = width, winh = height;
  804. glViewport(0, 0, winw, winh);
  805. aspect = (float)winw / (float)winh;
  806. ww = winw, wh = winh;
  807. mIdent(&projection);
  808. mPerspective(&projection, 60.0f, aspect, 0.01f, FAR_DISTANCE);
  809. glUniformMatrix4fv(projection_id, 1, GL_FALSE, (float*)&projection.m[0][0]);
  810. }
  811. #ifdef WEB
  812. EM_BOOL emscripten_resize_event(int eventType, const EmscriptenUiEvent *uiEvent, void *userData)
  813. {
  814. winw = uiEvent->documentBodyClientWidth;
  815. winh = uiEvent->documentBodyClientHeight;
  816. window_size_callback(window, winw, winh);
  817. emscripten_set_canvas_element_size("canvas", winw, winh);
  818. return EM_FALSE;
  819. }
  820. #endif
  821. //*************************************
  822. // process entry point
  823. //*************************************
  824. int main(int argc, char** argv)
  825. {
  826. // allow custom msaa level & mouse sensitivity
  827. int msaa = 16;
  828. if(argc >= 2){msaa = atoi(argv[1]);}
  829. if(argc >= 3){sens = atof(argv[2]);}
  830. // help
  831. printf("----\n");
  832. printf("🧊 James 💎 William 💎 Fletcher 🧊 (github.com/mrbid) 🐧 (notabug.org/Vandarin) 🕷️\n");
  833. printf("%s - Save 💾 your 🐌 garden 🧸 friends 🫂 from the 👻 ghosts! 🥸\n", appTitle);
  834. printf("----\n");
  835. #ifndef WEB
  836. printf("🤗 Two command line arguments, msaa 0-16, mouse sensitivity. 🫠\n");
  837. printf("e.g; ./aigeneratedgame 16 0.003\n");
  838. printf("----\n");
  839. #endif
  840. printf("🍒 ESCAPE = Unlock Mouse 🍆\n");
  841. printf("🚶 W,A,S,D / Arrow Keys = Move 🍌\n");
  842. printf("🏃 L-SHIFT / R-CTRL = Sprint 🕺\n");
  843. printf("🐰 Left Click = BONK! 🥰\n");
  844. printf("🔭 Right Click = Zoom 🎁\n");
  845. printf("----\n");
  846. printf("🦾 Every 3D 🌐😭🤪🥴🤯 model ⚕️ was 🖖 generated 🕵️ by a 🧮 tensor operation 😱, 🤓 machine learning, 👾 artificial intelligence, ☠️ cyberdyne inc 💀, but a 🗿 human 🧬 👽 programmed 🪬 the 🛸 game 🕹️ and the ॐ lord 🙏 created the game concept. 🚀 https://meshy.ai ☎️ Keep in 🧠 mind I 📽️ projected 🤔 all the 🍿 textures 🍭 to Vertex 🎨 Colors 🧐, if I had not 🙅 done that 🤫 the AI 🧬🤖 generated 👯 models would have 👀 looked 🔎 a 👁️ lot 🌎 better. 🤯 Font 🫠 is 🪼 https://www.fontspace.com/slimespooky-font-f84976 🪼 by ✨ jadaakbal ✨ (jadaakbaaal@gmail.com) 📨.\n");
  847. printf("----\n");
  848. printf("🎄 Merry Christmas 2023! 🧙‍♂️ and a happy new year 2024! 🎅\n");
  849. printf("----\n");
  850. printf("ﮩ٨ـﮩﮩ٨ـ♡ﮩ٨ـﮩﮩ٨ـ %s 👁️⃤\n", glfwGetVersionString());
  851. printf("----\n");
  852. // init glfw
  853. if(!glfwInit()){printf("glfwInit() failed. 🤡\n"); exit(EXIT_FAILURE);}
  854. #ifdef WEB
  855. double width, height;
  856. emscripten_get_element_css_size("body", &width, &height);
  857. winw = (uint)width, winh = (uint)height;
  858. #endif
  859. glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2);
  860. glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
  861. glfwWindowHint(GLFW_SAMPLES, msaa);
  862. window = glfwCreateWindow(winw, winh, appTitle, NULL, NULL);
  863. if(!window)
  864. {
  865. printf("glfwCreateWindow() failed. 🤡\n");
  866. glfwTerminate();
  867. exit(EXIT_FAILURE);
  868. }
  869. const GLFWvidmode* desktop = glfwGetVideoMode(glfwGetPrimaryMonitor());
  870. #ifndef WEB
  871. glfwSetWindowPos(window, (desktop->width/2)-(winw/2), (desktop->height/2)-(winh/2)); // center window on desktop
  872. #endif
  873. if(glfwRawMouseMotionSupported() == GLFW_TRUE){glfwSetInputMode(window, GLFW_RAW_MOUSE_MOTION, GLFW_TRUE);} // raw input, since it's an FPS
  874. glfwSetWindowSizeCallback(window, window_size_callback);
  875. glfwSetKeyCallback(window, key_callback);
  876. glfwSetMouseButtonCallback(window, mouse_button_callback);
  877. glfwMakeContextCurrent(window);
  878. gladLoadGL(glfwGetProcAddress);
  879. glfwSwapInterval(1); // 0 for immediate updates, 1 for updates synchronized with the vertical retrace, -1 for adaptive vsync
  880. // set icon
  881. glfwSetWindowIcon(window, 1, &(GLFWimage){16, 16, (unsigned char*)icon_image});
  882. //*************************************
  883. // bind vertex and index buffers
  884. //*************************************
  885. // ***** BIND INTRO *****
  886. esBind(GL_ARRAY_BUFFER, &mdlIntro.vid, intro_vertices, sizeof(intro_vertices), GL_STATIC_DRAW);
  887. esBind(GL_ELEMENT_ARRAY_BUFFER, &mdlIntro.iid, intro_indices, sizeof(intro_indices), GL_STATIC_DRAW);
  888. // ***** BIND TERRAIN *****
  889. esBind(GL_ARRAY_BUFFER, &mdlTerrain.vid, terrain_vertices, sizeof(terrain_vertices), GL_STATIC_DRAW);
  890. esBind(GL_ELEMENT_ARRAY_BUFFER, &mdlTerrain.iid, terrain_indices, sizeof(terrain_indices), GL_STATIC_DRAW);
  891. // ***** BIND SCENE *****
  892. esBind(GL_ARRAY_BUFFER, &mdlScene.vid, scene_vertices, sizeof(scene_vertices), GL_STATIC_DRAW);
  893. esBind(GL_ARRAY_BUFFER, &mdlScene.nid, scene_normals, sizeof(scene_normals), GL_STATIC_DRAW);
  894. esBind(GL_ARRAY_BUFFER, &mdlScene.cid, scene_colors, sizeof(scene_colors), GL_STATIC_DRAW);
  895. esBind(GL_ELEMENT_ARRAY_BUFFER, &mdlScene.iid, scene_indices, sizeof(scene_indices), GL_STATIC_DRAW);
  896. // ***** BIND CLUB *****
  897. esBind(GL_ARRAY_BUFFER, &mdlClub.vid, club_vertices, sizeof(club_vertices), GL_STATIC_DRAW);
  898. esBind(GL_ARRAY_BUFFER, &mdlClub.nid, club_normals, sizeof(club_normals), GL_STATIC_DRAW);
  899. esBind(GL_ARRAY_BUFFER, &mdlClub.cid, club_colors, sizeof(club_colors), GL_STATIC_DRAW);
  900. esBind(GL_ELEMENT_ARRAY_BUFFER, &mdlClub.iid, club_indices, sizeof(club_indices), GL_STATIC_DRAW);
  901. // ***** BIND GHOST *****
  902. esBind(GL_ARRAY_BUFFER, &mdlGhost.vid, ghost_vertices, sizeof(ghost_vertices), GL_STATIC_DRAW);
  903. esBind(GL_ARRAY_BUFFER, &mdlGhost.nid, ghost_normals, sizeof(ghost_normals), GL_STATIC_DRAW);
  904. esBind(GL_ARRAY_BUFFER, &mdlGhost.cid, ghost_colors, sizeof(ghost_colors), GL_STATIC_DRAW);
  905. esBind(GL_ELEMENT_ARRAY_BUFFER, &mdlGhost.iid, ghost_indices, sizeof(ghost_indices), GL_STATIC_DRAW);
  906. // ***** BIND OCTO *****
  907. esBind(GL_ARRAY_BUFFER, &mdlOcto.vid, octo_vertices, sizeof(octo_vertices), GL_STATIC_DRAW);
  908. esBind(GL_ARRAY_BUFFER, &mdlOcto.nid, octo_normals, sizeof(octo_normals), GL_STATIC_DRAW);
  909. esBind(GL_ARRAY_BUFFER, &mdlOcto.cid, octo_colors, sizeof(octo_colors), GL_STATIC_DRAW);
  910. esBind(GL_ELEMENT_ARRAY_BUFFER, &mdlOcto.iid, octo_indices, sizeof(octo_indices), GL_STATIC_DRAW);
  911. // ***** BIND BABY *****
  912. esBind(GL_ARRAY_BUFFER, &mdlBaby.vid, baby_vertices, sizeof(baby_vertices), GL_STATIC_DRAW);
  913. esBind(GL_ARRAY_BUFFER, &mdlBaby.nid, baby_normals, sizeof(baby_normals), GL_STATIC_DRAW);
  914. esBind(GL_ARRAY_BUFFER, &mdlBaby.cid, baby_colors, sizeof(baby_colors), GL_STATIC_DRAW);
  915. esBind(GL_ELEMENT_ARRAY_BUFFER, &mdlBaby.iid, baby_indices, sizeof(baby_indices), GL_STATIC_DRAW);
  916. // ***** BIND BONES *****
  917. esBind(GL_ARRAY_BUFFER, &mdlBones.vid, bones_vertices, sizeof(bones_vertices), GL_STATIC_DRAW);
  918. esBind(GL_ARRAY_BUFFER, &mdlBones.nid, bones_normals, sizeof(bones_normals), GL_STATIC_DRAW);
  919. esBind(GL_ARRAY_BUFFER, &mdlBones.cid, bones_colors, sizeof(bones_colors), GL_STATIC_DRAW);
  920. esBind(GL_ELEMENT_ARRAY_BUFFER, &mdlBones.iid, bones_indices, sizeof(bones_indices), GL_STATIC_DRAW);
  921. // ***** BIND BUNNY *****
  922. esBind(GL_ARRAY_BUFFER, &mdlBunny.vid, bunny_vertices, sizeof(bunny_vertices), GL_STATIC_DRAW);
  923. esBind(GL_ARRAY_BUFFER, &mdlBunny.nid, bunny_normals, sizeof(bunny_normals), GL_STATIC_DRAW);
  924. esBind(GL_ARRAY_BUFFER, &mdlBunny.cid, bunny_colors, sizeof(bunny_colors), GL_STATIC_DRAW);
  925. esBind(GL_ELEMENT_ARRAY_BUFFER, &mdlBunny.iid, bunny_indices, sizeof(bunny_indices), GL_STATIC_DRAW);
  926. // ***** BIND CAT *****
  927. esBind(GL_ARRAY_BUFFER, &mdlCat.vid, cat_vertices, sizeof(cat_vertices), GL_STATIC_DRAW);
  928. esBind(GL_ARRAY_BUFFER, &mdlCat.nid, cat_normals, sizeof(cat_normals), GL_STATIC_DRAW);
  929. esBind(GL_ARRAY_BUFFER, &mdlCat.cid, cat_colors, sizeof(cat_colors), GL_STATIC_DRAW);
  930. esBind(GL_ELEMENT_ARRAY_BUFFER, &mdlCat.iid, cat_indices, sizeof(cat_indices), GL_STATIC_DRAW);
  931. // ***** BIND GINGER *****
  932. esBind(GL_ARRAY_BUFFER, &mdlGinger.vid, ginger_vertices, sizeof(ginger_vertices), GL_STATIC_DRAW);
  933. esBind(GL_ARRAY_BUFFER, &mdlGinger.nid, ginger_normals, sizeof(ginger_normals), GL_STATIC_DRAW);
  934. esBind(GL_ARRAY_BUFFER, &mdlGinger.cid, ginger_colors, sizeof(ginger_colors), GL_STATIC_DRAW);
  935. esBind(GL_ELEMENT_ARRAY_BUFFER, &mdlGinger.iid, ginger_indices, sizeof(ginger_indices), GL_STATIC_DRAW);
  936. // ***** BIND FARMER *****
  937. esBind(GL_ARRAY_BUFFER, &mdlFarmer.vid, farmer_vertices, sizeof(farmer_vertices), GL_STATIC_DRAW);
  938. esBind(GL_ARRAY_BUFFER, &mdlFarmer.nid, farmer_normals, sizeof(farmer_normals), GL_STATIC_DRAW);
  939. esBind(GL_ARRAY_BUFFER, &mdlFarmer.cid, farmer_colors, sizeof(farmer_colors), GL_STATIC_DRAW);
  940. esBind(GL_ELEMENT_ARRAY_BUFFER, &mdlFarmer.iid, farmer_indices, sizeof(farmer_indices), GL_STATIC_DRAW);
  941. // ***** BIND FOXY *****
  942. esBind(GL_ARRAY_BUFFER, &mdlFoxy.vid, foxy_vertices, sizeof(foxy_vertices), GL_STATIC_DRAW);
  943. esBind(GL_ARRAY_BUFFER, &mdlFoxy.nid, foxy_normals, sizeof(foxy_normals), GL_STATIC_DRAW);
  944. esBind(GL_ARRAY_BUFFER, &mdlFoxy.cid, foxy_colors, sizeof(foxy_colors), GL_STATIC_DRAW);
  945. esBind(GL_ELEMENT_ARRAY_BUFFER, &mdlFoxy.iid, foxy_indices, sizeof(foxy_indices), GL_STATIC_DRAW);
  946. // ***** BIND FROG *****
  947. esBind(GL_ARRAY_BUFFER, &mdlFrog.vid, frog_vertices, sizeof(frog_vertices), GL_STATIC_DRAW);
  948. esBind(GL_ARRAY_BUFFER, &mdlFrog.nid, frog_normals, sizeof(frog_normals), GL_STATIC_DRAW);
  949. esBind(GL_ARRAY_BUFFER, &mdlFrog.cid, frog_colors, sizeof(frog_colors), GL_STATIC_DRAW);
  950. esBind(GL_ELEMENT_ARRAY_BUFFER, &mdlFrog.iid, frog_indices, sizeof(frog_indices), GL_STATIC_DRAW);
  951. // ***** BIND RAT *****
  952. esBind(GL_ARRAY_BUFFER, &mdlRat.vid, rat_vertices, sizeof(rat_vertices), GL_STATIC_DRAW);
  953. esBind(GL_ARRAY_BUFFER, &mdlRat.nid, rat_normals, sizeof(rat_normals), GL_STATIC_DRAW);
  954. esBind(GL_ARRAY_BUFFER, &mdlRat.cid, rat_colors, sizeof(rat_colors), GL_STATIC_DRAW);
  955. esBind(GL_ELEMENT_ARRAY_BUFFER, &mdlRat.iid, rat_indices, sizeof(rat_indices), GL_STATIC_DRAW);
  956. // ***** BIND SHROOM *****
  957. esBind(GL_ARRAY_BUFFER, &mdlShroom.vid, shroom_vertices, sizeof(shroom_vertices), GL_STATIC_DRAW);
  958. esBind(GL_ARRAY_BUFFER, &mdlShroom.nid, shroom_normals, sizeof(shroom_normals), GL_STATIC_DRAW);
  959. esBind(GL_ARRAY_BUFFER, &mdlShroom.cid, shroom_colors, sizeof(shroom_colors), GL_STATIC_DRAW);
  960. esBind(GL_ELEMENT_ARRAY_BUFFER, &mdlShroom.iid, shroom_indices, sizeof(shroom_indices), GL_STATIC_DRAW);
  961. // ***** BIND ROBOT *****
  962. esBind(GL_ARRAY_BUFFER, &mdlRobot.vid, robot_vertices, sizeof(robot_vertices), GL_STATIC_DRAW);
  963. esBind(GL_ARRAY_BUFFER, &mdlRobot.nid, robot_normals, sizeof(robot_normals), GL_STATIC_DRAW);
  964. esBind(GL_ARRAY_BUFFER, &mdlRobot.cid, robot_colors, sizeof(robot_colors), GL_STATIC_DRAW);
  965. esBind(GL_ELEMENT_ARRAY_BUFFER, &mdlRobot.iid, robot_indices, sizeof(robot_indices), GL_STATIC_DRAW);
  966. // ***** BIND TEDDY *****
  967. esBind(GL_ARRAY_BUFFER, &mdlTeddy.vid, teddy_vertices, sizeof(teddy_vertices), GL_STATIC_DRAW);
  968. esBind(GL_ARRAY_BUFFER, &mdlTeddy.nid, teddy_normals, sizeof(teddy_normals), GL_STATIC_DRAW);
  969. esBind(GL_ARRAY_BUFFER, &mdlTeddy.cid, teddy_colors, sizeof(teddy_colors), GL_STATIC_DRAW);
  970. esBind(GL_ELEMENT_ARRAY_BUFFER, &mdlTeddy.iid, teddy_indices, sizeof(teddy_indices), GL_STATIC_DRAW);
  971. // ***** BIND TREEMAN *****
  972. esBind(GL_ARRAY_BUFFER, &mdlTreeman.vid, treeman_vertices, sizeof(treeman_vertices), GL_STATIC_DRAW);
  973. esBind(GL_ARRAY_BUFFER, &mdlTreeman.nid, treeman_normals, sizeof(treeman_normals), GL_STATIC_DRAW);
  974. esBind(GL_ARRAY_BUFFER, &mdlTreeman.cid, treeman_colors, sizeof(treeman_colors), GL_STATIC_DRAW);
  975. esBind(GL_ELEMENT_ARRAY_BUFFER, &mdlTreeman.iid, treeman_indices, sizeof(treeman_indices), GL_STATIC_DRAW);
  976. // ***** BIND DRAGON *****
  977. esBind(GL_ARRAY_BUFFER, &mdlDragon.vid, dragon_vertices, sizeof(dragon_vertices), GL_STATIC_DRAW);
  978. esBind(GL_ARRAY_BUFFER, &mdlDragon.nid, dragon_normals, sizeof(dragon_normals), GL_STATIC_DRAW);
  979. esBind(GL_ARRAY_BUFFER, &mdlDragon.cid, dragon_colors, sizeof(dragon_colors), GL_STATIC_DRAW);
  980. esBind(GL_ELEMENT_ARRAY_BUFFER, &mdlDragon.iid, dragon_indices, sizeof(dragon_indices), GL_STATIC_DRAW);
  981. // ***** BIND BANANA *****
  982. esBind(GL_ARRAY_BUFFER, &mdlBanana.vid, banana_vertices, sizeof(banana_vertices), GL_STATIC_DRAW);
  983. esBind(GL_ARRAY_BUFFER, &mdlBanana.nid, banana_normals, sizeof(banana_normals), GL_STATIC_DRAW);
  984. esBind(GL_ARRAY_BUFFER, &mdlBanana.cid, banana_colors, sizeof(banana_colors), GL_STATIC_DRAW);
  985. esBind(GL_ELEMENT_ARRAY_BUFFER, &mdlBanana.iid, banana_indices, sizeof(banana_indices), GL_STATIC_DRAW);
  986. //*************************************
  987. // compile & link shader programs
  988. //*************************************
  989. makeFullbright();
  990. makeLambert3();
  991. //*************************************
  992. // configure render options
  993. //*************************************
  994. glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  995. //glEnable(GL_CULL_FACE);
  996. glDisable(GL_CULL_FACE);
  997. glEnable(GL_DEPTH_TEST);
  998. glClearColor(0.3f, 0.745f, 0.8863f, 0.f);
  999. shadeLambert3(&position_id, &projection_id, &modelview_id, &lightpos_id, &normal_id, &color_id, &opacity_id);
  1000. glUniformMatrix4fv(projection_id, 1, GL_FALSE, (float*)&projection.m[0][0]);
  1001. window_size_callback(window, winw, winh);
  1002. //*************************************
  1003. // execute update / render loop
  1004. //*************************************
  1005. // init
  1006. friend_pos[0] = baby_pos;
  1007. friend_pos[1] = bones_pos;
  1008. friend_pos[2] = bunny_pos;
  1009. friend_pos[3] = cat_pos;
  1010. friend_pos[4] = ginger_pos;
  1011. friend_pos[5] = farmer_pos;
  1012. friend_pos[6] = foxy_pos;
  1013. friend_pos[7] = frog_pos;
  1014. friend_pos[8] = rat_pos;
  1015. friend_pos[9] = shroom_pos;
  1016. friend_pos[10] = robot_pos;
  1017. friend_pos[11] = teddy_pos;
  1018. friend_pos[12] = treeman_pos;
  1019. friend_pos[13] = dragon_pos;
  1020. friend_pos[14] = banana_pos;
  1021. newGame(NEWGAME_SEED);
  1022. t = (float)glfwGetTime();
  1023. lfct = t;
  1024. #ifdef WEB
  1025. emscripten_set_resize_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW, NULL, EM_FALSE, emscripten_resize_event);
  1026. emscripten_set_main_loop(main_loop, 0, 1);
  1027. #else
  1028. while(!glfwWindowShouldClose(window)){main_loop();}
  1029. #endif
  1030. // end
  1031. timeTaken(0);
  1032. char strts[16];
  1033. timestamp(&strts[0]);
  1034. printf("[%s] 🥶 Game End. 🥂 😎\n", strts);
  1035. printf("[%s] 🫂 বন্ধুরা%u - 👻 বন্ধ %u\n", strts, friendsalive, ghostsbonked);
  1036. printf("[%s] ⏳ Time-Taken: 🍒 %s 🤟 or ✌ %g 🚨 Seconds 🫣\n\n", strts, tts, t-st);
  1037. // done
  1038. glfwDestroyWindow(window);
  1039. glfwTerminate();
  1040. exit(EXIT_SUCCESS);
  1041. return 0;
  1042. }