tilesnpc.cpp 32 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129
  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <math.h>
  4. #include <string.h> // for strlen
  5. #include "tilenpc.h"
  6. #define INFOSCREEN_LINECOUNT 17
  7. const char *info_screen_lines[INFOSCREEN_LINECOUNT] = {
  8. "Matchem Poker (v.0.9)",
  9. "A Nokia example",
  10. "",
  11. "Ported from iOS",
  12. "using Qt GameEnabler",
  13. "projects.forum.nokia",
  14. "/qtgameenabler",
  15. "",
  16. "Simply switch cards",
  17. "with eachother to",
  18. "create poker hands.",
  19. "",
  20. "Audio samples from",
  21. "FREESOUND.ORG used.",
  22. "Thanks to:",
  23. "milton, mattwasser,",
  24. "Christianjinnyzoe"
  25. };
  26. /*
  27. !"#$% ´()*+,-./
  28. 0123456789:;<=>?
  29. @ABCDEFGHIJKLMNO
  30. PQRSTUVWXYZ[\]^_
  31. `abcdefghijklmno
  32. pqrstuvwxyz{|}~
  33. */
  34. const char *happy_strings[] = {
  35. "Playing cards were most likely invented in China in 1120 AD and first introduced to Europe in the 1300s. ",
  36. "Due to French influence, Spades represent Royalty, Diamonds represent Merchants, Clubs represent Peasants, and Hearts represent the Clergy.",
  37. "A fifth suit was added in 1937 but never caught on because people had to buy all new decks.",
  38. "When Columbus landed on U.S. shores in 1492, his men plucked wide leaves from trees, marked them with images, and played cards. ",
  39. "There are 1,326 possible 2-card combinations a player can start with in Texas Hold’em.",
  40. "There is a 1 in 16 chance of being dealt pocket pairs.",
  41. "There is a 1 in 8.3 chance of flopping a set after being dealt pocket pairs."
  42. "Poker is…a fascinating, wonderful, intricate adventure on the high seas of human nature.",
  43. "40 to 50 million Americans regularly play poker. That’s more than one in five… ",
  44. "Each year more than 70 million decks of cards are sold in the U.S.",
  45. "Make a Waldorf salad, with apples, celery, walnuts, and dressing.",
  46. "\"Patience, and shuffle the cards.\" -Cervantes, Don Quixote.",
  47. "The next best thing to playing and winning is playing and losing. The main thing is to play.",
  48. "I must complain the cards are ill shuffled till I have a good hand.",
  49. "POKER, n. A game said to be played with cards for some purpose to this lexicographer unknown.",
  50. "If one is able and strong, then one should disguise oneself in order to appear inept and weak.",
  51. "Perception is reality.",
  52. "Clubs -Alexander, the Great.",
  53. "Spades - King David.",
  54. "It’s not enough to succeed. Others must fail.",
  55. "Diamonds - Julius Caesar.",
  56. "There are two \"one-eyed\" Jacks in a deck of cards. The Jack of Spades and the Jack of Hearts.",
  57. "A \"Dead man's hand\" is Aces and Eights.",
  58. "Hearts - Charlemagne.",
  59. "No one knows the true origins of poker.",
  60. "I'm getting tired of poker now...",
  61. "Don't play if you need to win.",
  62. "Sound effects are all from FreeSound.org from following tags: milton, mattwasser, and Christianjinnyzoe.",
  63. "...",
  64. "...",
  65. "...",
  66. "...",
  67. "...",
  68. "...",
  69. "...",
  70. "...",
  71. "...",
  72. "...",
  73. "...",
  74. "...",
  75. "...",
  76. "...",
  77. "...",
  78. "...",
  79. "...",
  80. "...",
  81. "...",
  82. "...",
  83. "...",
  84. "...",
  85. "...",
  86. "...",
  87. "...",
  88. "...",
  89. "...",
  90. "...",
  91. "...",
  92. "...",
  93. "...",
  94. "...",
  95. "...",
  96. "...",
  97. "...",
  98. "...",
  99. "...",
  100. "...",
  101. "...",
  102. "...",
  103. "...",
  104. "...",
  105. "...",
  106. "...",
  107. "...",
  108. "...",
  109. "Warning, End of the list.. ",
  110. };
  111. // score roll
  112. const int rollWidth = 10000;
  113. const int rollSpacing = 6500;
  114. const int scoreRollStart = 33000;
  115. const int scoreRollXPos[] = { 6500,6500 + rollSpacing, scoreRollStart,scoreRollStart+rollSpacing,scoreRollStart+rollSpacing*2,scoreRollStart+rollSpacing*3,scoreRollStart+rollSpacing*4 };
  116. GameTexture gameTextures[]=
  117. {
  118. { TexLogo, "logo",1,1},
  119. { TexPieces, "playing_cards", 4,5},
  120. { TexPiecesSelected, "playing_cards_selected", 4, 5},
  121. { TexFontScore, "scorefont",10,1},
  122. { TexGradient, "gradient"},
  123. { TexMeter, "timer_numbers",4,5},
  124. { TexMeterBase, "timer_frames",1,2},
  125. { TexParticle, "particles",2,2},
  126. { TexFont, "font", 16,6},
  127. { TexBackground, "menu_bg", 2,2,},
  128. { TexExtra1, "dice_pause_play", 2, 1},
  129. { TexEndOfList }
  130. };
  131. ITileGame *createTileGame( ITileRenderer *renderer, int x, int y, int width, int height ) {
  132. return new CTileNpc( renderer, x,y,width,height );
  133. };
  134. CTileNpc::CTileNpc( ITileRenderer *renderer, int x,int y, int width, int height ) : ITileGame( renderer,x,y,width,height ) {
  135. m_level = new CNpcLevel( renderer,m_pengine, TILE_GRIDWIDTH, TILE_GRIDHEIGHT );
  136. m_infoScreenDisplayCounter = -1;
  137. m_effectAngle = 0;
  138. m_bgIndex1 = 1;
  139. m_bgIndex2 = 0;
  140. m_fadingBgCounter = -1;
  141. m_menuCounter = -1;
  142. m_menuModeCounter = -1;
  143. m_timeSinceLastScore = 0;
  144. m_gameIsOn = 0;
  145. m_timer = 0;
  146. m_gameOverCounter = -1;
  147. m_pauseCounter = -1;
  148. m_levelCompletedPoem = "NOT_SET";
  149. m_timeTimerEffect = 65535;
  150. m_completedTextAngle = 0;
  151. m_completedTextCounter = -65536*21;
  152. m_eventCounter = 0;
  153. m_bgAngle = 0;
  154. m_logoWobble = 0;
  155. m_logoWobbleInc = 0;
  156. m_currentLevel = 0;
  157. m_blockTimerEffect = 0;
  158. m_targetTimer= 0;
  159. m_levelCompletedCounter = 0;
  160. m_highScore = 0;
  161. m_timer = 0;
  162. m_score = 0;
  163. m_displayScore =0;
  164. m_difficulty = 1; // adults, 0 for kids ?
  165. m_level->setGameArea(x-0000,y-8000,width+0000,height+6000 );
  166. //m_level->setGameArea( x,y, width, height );
  167. memset( m_scoreRollPos, 0, sizeof(int) *7 );
  168. memset( m_scoreRollTargetPos, 0, sizeof(int) *7 );
  169. memset( m_scoreRollExTargetPos, 0, sizeof(int) *7 );
  170. memset( m_scoreRollInc, 0, sizeof(int) *7 );
  171. };
  172. CTileNpc::~CTileNpc() {
  173. save();
  174. if (m_level) {
  175. delete m_level;
  176. m_level = 0;
  177. };
  178. if (m_pengine) {
  179. delete m_pengine;
  180. m_pengine = 0;
  181. };
  182. };
  183. void CTileNpc::gameStateChanged() {
  184. m_infoScreenDisplayCounter = -1;
  185. m_pauseCounter = -1;
  186. switch (m_state) {
  187. case eTILEGAMESTATE_PAUSED:
  188. m_completedTextCounter = -65536*21;
  189. m_pauseCounter = 0;
  190. break;
  191. case eTILEGAMESTATE_GAMEOVER:
  192. m_completedTextCounter = -65536*21;
  193. m_level->setLevelState( eLEVELSTATE_GAMEOVER );
  194. break;
  195. case eTILEGAMESTATE_RUNGAME:
  196. if (m_gameIsOn==0) {
  197. nextLevel(0);
  198. }
  199. break;
  200. case eTILEGAMESTATE_MENU:
  201. changeBg(0);
  202. m_timeTimerEffect = 65536;
  203. m_logoWobble = 65535;
  204. m_menuCounter = 0;
  205. m_menuModeCounter = 0;
  206. m_completedTextCounter = -65536*21;
  207. break;
  208. case eTILEGAMESTATE_SHOWINFOSCREEN:
  209. m_infoScreenDisplayCounter = 0;
  210. break;
  211. };
  212. };
  213. void CTileNpc::gameOver() {
  214. m_gameOverCounter = 0;
  215. m_gameIsOn = 0;
  216. setGameState( eTILEGAMESTATE_GAMEOVER );
  217. };
  218. void CTileNpc::levelCompleted() {
  219. m_levelCompletedCounter = 0;
  220. m_completedTextCounter = -65536*20;
  221. m_levelCompletedPoem = happy_strings[ m_currentLevel % 44 ];
  222. m_renderer->effectNotify( eEFFECT_LEVELCOMPLETED, 0,0 );
  223. m_level->setLevelState( eLEVELSTATE_LEVELCOMPLETED );
  224. m_score += m_currentLevel*100;
  225. m_pengine->spray(
  226. 20,
  227. 65536/2, 20000, 1000,
  228. 0,-50000, 65536,
  229. 0, &m_level->m_fruitSpray );
  230. };
  231. void CTileNpc::endGame() {
  232. gameOver();
  233. };
  234. void CTileNpc::changeBg( int newBg ) {
  235. if (newBg==-1) {
  236. newBg = ((m_currentLevel+1)&1);
  237. }
  238. m_bgIndex2 = newBg;
  239. if (m_bgIndex1==m_bgIndex2) return; // no need
  240. m_fadingBgCounter = 0; // START fading
  241. };
  242. int CTileNpc::gameRun( int fixedFrameTime ) {
  243. if (fixedFrameTime>8000) fixedFrameTime = 8000;
  244. if (m_infoScreenDisplayCounter>=0)
  245. m_infoScreenDisplayCounter+=fixedFrameTime;
  246. // if (m_state == eTILEGAMESTATE_
  247. m_effectAngle+=fixedFrameTime;
  248. if (m_fadingBgCounter>=0) {
  249. m_fadingBgCounter+=fixedFrameTime;
  250. if (m_fadingBgCounter>65535) {
  251. m_bgIndex1 = m_bgIndex2;
  252. m_bgIndex2 = 0;
  253. m_fadingBgCounter = -1;
  254. };
  255. };
  256. //if (m_state==eTILEGAMESTATE_SHOWINFOSCREEN) return 1;
  257. if (m_state==eTILEGAMESTATE_MENU) {
  258. m_menuCounter+=fixedFrameTime;
  259. m_menuModeCounter+=fixedFrameTime;
  260. } else {
  261. if (m_menuCounter>=0) {
  262. if (m_menuCounter>65536*3) m_menuCounter = 65536*3;
  263. m_menuCounter-=fixedFrameTime;
  264. }
  265. if (m_menuModeCounter>=0) {
  266. if (m_menuModeCounter>65536*2) m_menuModeCounter = 65536*2;
  267. m_menuModeCounter-=fixedFrameTime*2;
  268. }
  269. };
  270. if ( m_gameIsOn && (m_level->getState()==eLEVELSTATE_IDLE || m_level->getState()==eLEVELSTATE_LEVELCOMPLETED) ) {
  271. m_levelCompletedCounter+=fixedFrameTime;
  272. //if (m_levelCompletedCounter<65536*3)
  273. } else {
  274. if (m_levelCompletedCounter>65536*3) m_levelCompletedCounter = 65536*3;
  275. if (m_levelCompletedCounter>-1) m_levelCompletedCounter-=fixedFrameTime*2;
  276. };
  277. m_eventCounter+=fixedFrameTime*4;
  278. while ( m_eventCounter>65536) {
  279. if (m_state==eTILEGAMESTATE_MENU) { // RANDOM SQRUIT PARTICLES
  280. if ((rand()&255) < 128 ) {
  281. int dx = ((rand() & 511) - 256)<<6;
  282. int dy = ((rand() & 255) - 512)<<7;
  283. m_pengine->spray(
  284. (7+(rand()&3))*5,
  285. 65536/2+dx, 11000, (rand()&511)*12,
  286. dx,dy, (rand()&65535)/1,
  287. 0, &m_level->m_fruitSpray );
  288. };
  289. m_eventCounter = 0;
  290. };
  291. if (m_state==eTILEGAMESTATE_RUNGAME) {
  292. m_timeTimerEffect-=20; // fasten up the game.
  293. //qDebug() << "Tim:" << m_timeTimerEffect;
  294. if (m_level->getState() == eLEVELSTATE_IDLE ) {
  295. for (int j=0; j<3; j++)
  296. if ((rand()&255)<100)
  297. m_pengine->spray( 10, 2*(rand()&65535), 20000+(rand()&255)*40, 5000, 0,0, 32000, 0, &m_level->m_sparkleSpray );
  298. }
  299. int timeLimit = 4+m_currentLevel*4;
  300. if (timeLimit>20) timeLimit= 20;
  301. if (m_level->getState() == eLEVELSTATE_NORMAL && m_timeSinceLastScore>timeLimit*65536) {
  302. if ((rand()&255)<32)
  303. m_level->wobbleHint();
  304. };
  305. };
  306. m_eventCounter-=65536;
  307. int d=(m_score - m_displayScore);
  308. d>>=1;
  309. if (abs(d)<1) {
  310. if (m_displayScore>m_score) d=-1;
  311. else if (m_displayScore<m_score) d = 1;
  312. }
  313. //if (abs(d)<1) m_displayScore = m_score; else m_displayScore += d;
  314. m_displayScore += d;
  315. };
  316. int i = (m_timeTimerEffect>>9);
  317. if (i<1096) i = 1096;
  318. m_bgAngle+=(i*fixedFrameTime)>>12;
  319. //if (-40000+m_logoState*12<32000) {
  320. // m_logoWobble += (((30000-m_logoWobble)*fixedFrameTime)>>16);
  321. //};
  322. int g = ((m_logoWobble * fixedFrameTime)>>13); // string effect
  323. m_logoWobbleInc-=g;
  324. g = ((m_logoWobbleInc * fixedFrameTime)>>14); // slowdown
  325. m_logoWobbleInc -= g;
  326. g = ((m_logoWobbleInc * fixedFrameTime)>>13); // add
  327. m_logoWobble+=g;
  328. //
  329. if (m_gameOverCounter>=0) m_gameOverCounter+=fixedFrameTime;
  330. if (m_pauseCounter>=0) m_pauseCounter+=fixedFrameTime;
  331. m_completedTextAngle += fixedFrameTime;
  332. if (m_state==eTILEGAMESTATE_GAMEOVER || m_state==eTILEGAMESTATE_RUNGAME)
  333. m_level->run( fixedFrameTime );
  334. if (m_state == eTILEGAMESTATE_RUNGAME) {
  335. if (m_level->m_hasMoves==0) {
  336. // this should not happend
  337. };
  338. int scoreAdd = m_level->takeLevelScore();
  339. if (scoreAdd>0) {
  340. m_timeSinceLastScore = 0;
  341. };
  342. m_score+=scoreAdd;
  343. if (m_score>m_highScore) m_highScore = m_score;
  344. m_targetTimer += m_level->takeLevelProgressChange() * m_blockTimerEffect;
  345. // lowpass timer..
  346. //m_timer += (int)( (float)(m_targetTimer-m_timer) * (float)fixedFrameTime / 8000.0f );
  347. m_timer = m_targetTimer;
  348. if (m_completedTextCounter>=-65536*20) {
  349. if (m_level->getState() != eLEVELSTATE_LEVELCOMPLETED) { // WAIT FOR level to finish completedanimation
  350. int tlen = strlen(m_levelCompletedPoem);
  351. m_completedTextCounter += fixedFrameTime * 28;
  352. if (m_completedTextCounter>800*65536) m_completedTextCounter = -65536*21; // end and stop
  353. }
  354. }
  355. switch (m_level->getState()) {
  356. case eLEVELSTATE_NORMAL:
  357. m_timeSinceLastScore += fixedFrameTime;
  358. if (m_timeSinceLastScore>m_waitBeforeTimerStartsTime) {
  359. m_targetTimer += (int)( (float)fixedFrameTime * (float)m_timeTimerEffect / 65536.0f );
  360. }
  361. if (/*m_doingNothingCounter>65536 &&*/ m_level->doingNothing() == true) {
  362. if (m_targetTimer >=(65536<<8)) {
  363. //qDebug() << "levelcompleted : " << m_doingNothingCounter << "dn:" << m_level->doingNothing();
  364. levelCompleted();
  365. }
  366. if (m_targetTimer<=0) gameOver();
  367. }
  368. break;
  369. case eLEVELSTATE_IDLE:
  370. {
  371. /*
  372. int tlen = strlen(m_levelCompletedPoem);
  373. if (m_completedTextCounter>tlen*65536) {
  374. m_completedTextCounter = strlen( m_levelCompletedPoem )*65536;
  375. }
  376. */
  377. }
  378. break;
  379. default:
  380. break;
  381. }
  382. }
  383. /*
  384. if (m_level->doingNothing() == true)
  385. m_doingNothingCounter+=fixedFrameTime;
  386. else m_doingNothingCounter = 0;
  387. */
  388. // timer
  389. int v = ((m_timer>>8)*100) >> 16;
  390. if (v>99) v = 99;
  391. m_scoreRollTargetPos[1] = (v%10) << 16;
  392. m_scoreRollTargetPos[0] = ((v/10)%10) <<16;
  393. //m_scoreRollTargetPos[0] = ((v/100)%10) << 16;
  394. m_scoreRollTargetPos[6] = (m_displayScore%10) << 16;
  395. m_scoreRollTargetPos[5] = ((m_displayScore/10)%10) <<16;
  396. m_scoreRollTargetPos[4] = ((m_displayScore/100)%10) <<16;
  397. m_scoreRollTargetPos[3] = ((m_displayScore/1000)%10) <<16;
  398. m_scoreRollTargetPos[2] = ((m_displayScore/10000)%10) <<16;
  399. bool rollChanged = false;
  400. for (int sr = 0; sr<7; sr++) {
  401. if (m_scoreRollTargetPos[sr]!=m_scoreRollExTargetPos[sr]) rollChanged = true;
  402. m_scoreRollExTargetPos[sr] = m_scoreRollTargetPos[sr];
  403. int delta = m_scoreRollTargetPos[sr] - m_scoreRollPos[sr];
  404. int negDelta = (m_scoreRollTargetPos[sr]-65536*10) - m_scoreRollPos[sr];
  405. int plusDelta = (m_scoreRollTargetPos[sr]+65536*10) - m_scoreRollPos[sr];
  406. if (abs(delta)>abs(negDelta)) delta = negDelta;
  407. if (abs(delta)>abs(plusDelta)) delta = plusDelta;
  408. m_scoreRollInc[sr] += ((((delta)>>2)*fixedFrameTime ) >> 12);
  409. m_scoreRollInc[sr] -= (((m_scoreRollInc[sr]>>3) * fixedFrameTime) >> 10 );
  410. //m_scoreRollInc[sr] -= m_scoreRollInc[sr]*2/10;
  411. m_scoreRollPos[sr] += m_scoreRollInc[sr];
  412. if (m_scoreRollPos[sr]<0) m_scoreRollPos[sr] += 65536*10;
  413. if (m_scoreRollPos[sr]>65536*10) m_scoreRollPos[sr] -= 65536*10;
  414. };
  415. if (rollChanged) {
  416. m_renderer->effectNotify( eEFFECT_SCORECHANGED, 0,0 );
  417. };
  418. return 1;
  419. };
  420. #define BGTILE_OFF 40000
  421. int CTileNpc::gameDraw( ) {
  422. // background.
  423. if (m_fadingBgCounter==-1)
  424. m_renderer->renderTile( 0,0, 65536, 100000, 0, 0, (TexBackground<<16) + m_bgIndex1, 0 );
  425. else {
  426. int a = (m_fadingBgCounter>>8);
  427. m_renderer->renderTile( 0,0, 65536, 100000, 0, 0, (TexBackground<<16) + m_bgIndex1 | (a<<24), 0 );
  428. m_renderer->renderTile( 0,0, 65536, 100000, 0, 0, (TexBackground<<16) + m_bgIndex2 | ((255-a)<<24), 0 );
  429. };
  430. m_renderer->renderTile( -BGTILE_OFF,-BGTILE_OFF, 65536+BGTILE_OFF*2, 65536+BGTILE_OFF*2, ((m_bgAngle>>2)&65535), 1, ((TexBackground<<16) + 2) | (200<<24), 0 );
  431. if (m_state!=eTILEGAMESTATE_MENU && m_state!=eTILEGAMESTATE_PAUSED) { // HUD
  432. m_level->draw( *m_renderer );
  433. }
  434. if (m_infoScreenDisplayCounter>=0) {
  435. int f;
  436. for (int l=0; l<INFOSCREEN_LINECOUNT; l++)
  437. if (info_screen_lines[l][0]!=0)
  438. {
  439. f = 65536*2 + ((l)*32000) - m_infoScreenDisplayCounter * 2;
  440. if (f<0) f = 0;
  441. if (f>65535) f= 65535;
  442. writeEffectText( 3000+l * 5500, info_screen_lines[l], 5000, f );
  443. }
  444. //return 1;
  445. };
  446. if (m_menuCounter>=0) {
  447. int fade = 65536*2-(m_menuCounter);
  448. fade/=2;
  449. if (fade<0) fade = 0;
  450. writeEffectText( 65536 - 4500, "START", 14000, fade );
  451. char testr[64];
  452. sprintf(testr, "HI %d", m_highScore);
  453. writeText(0,0, testr, fade>>8, 5000,3500);
  454. #ifndef __APPLE__
  455. writeText(42000,0, "EXIT", fade>>8, 8000,5500 );
  456. #endif
  457. };
  458. if (m_menuModeCounter>0) {
  459. int fade = 65536-(m_menuModeCounter);
  460. if (fade<0) fade = 0;
  461. writeEffectText( 65536*5/4+4000, "INFO", 8000, fade );
  462. /*
  463. char *dif_string = "KIDS";
  464. if (m_difficulty==1) dif_string = "NORMAL";
  465. writeEffectText( 65536*5/4+6000, dif_string, 10000, fade );
  466. */
  467. }
  468. if (m_state!=eTILEGAMESTATE_MENU) {
  469. if (m_levelCompletedCounter>0) {
  470. int fade = 65536-(m_levelCompletedCounter);
  471. //fade/=2;
  472. if (fade<0) fade = 0;
  473. writeEffectText( 19000+fade, "LEVEL", 7000, fade );
  474. writeEffectText( 24000+fade, "COMPLETED", 9500, fade );
  475. };
  476. if (m_pauseCounter>0) {
  477. int fade = 65536-(m_pauseCounter*2);
  478. if (fade<0) fade = 0;
  479. writeEffectText( 65536/2-4000-fade, "GAME", 9500, fade );
  480. writeEffectText( 65536/2+4000+fade, "PAUSED", 9500, fade );
  481. writeEffectText( 65536*4/3-4000-fade, "RESUME", 5500, fade );
  482. writeEffectText( 65536*4/3+4000+fade, "END", 5500, fade );
  483. };
  484. if (m_gameOverCounter>0 && m_infoScreenDisplayCounter<0) {
  485. int fade = m_gameOverCounter-40000*2;
  486. if (fade>65535) fade = 65535;
  487. if (fade>0) {
  488. writeEffectText( 12000-4000-(65535-fade)/2, "TOO BAD", 5000, 65535-fade );
  489. fade = m_gameOverCounter-40000*3;
  490. if (fade>0) {
  491. if (fade>65535) fade = 65535;
  492. writeEffectText( 12000+4000+(65535-fade)/2, "GAME OVER", 9000, 65535-fade );
  493. fade = m_gameOverCounter-40000*4;
  494. if (fade>0) {
  495. if (fade>65535) fade = 65535;
  496. writeEffectText( 40000, "YOUR SCORE", 5000, 65535-fade );
  497. fade = m_gameOverCounter-40000*5;
  498. if (fade>0) {
  499. if (fade>65535) fade = 65535;
  500. char testr[12];
  501. sprintf(testr, "%d", m_score );
  502. writeEffectText( 45000, testr, 9000, 65535-fade );
  503. fade = m_gameOverCounter-40000*6;
  504. if (fade>0) {
  505. if (fade>65535) fade = 65535;
  506. writeEffectText( 60000, "AT LEVEL", 5000, 65535-fade );
  507. fade = m_gameOverCounter-40000*7;
  508. if (fade>0) {
  509. if (fade>65535) fade = 65535;
  510. sprintf(testr, "%d", m_currentLevel+1 );
  511. writeEffectText( 65000, testr, 9000, 65535-fade );
  512. }
  513. }
  514. }
  515. }
  516. }
  517. }
  518. };
  519. }
  520. writeLevelCompletedString(); // must be called always.
  521. if (m_hudState>0) { // hud
  522. // draw the meter, clocklike here
  523. int x = -3000;
  524. int w = 65536+7000; //65536/2;
  525. int h = 16000;
  526. int y = -(65536-m_hudState)/3 - 2000;
  527. m_renderer->renderTile(2000,y,15000,h,0,0, (TexMeterBase<<16) | 1, 0);
  528. m_renderer->renderTile(29000,y,35000,h,0,0, (TexMeterBase<<16) | 1, 0);
  529. for (int f=0; f<7; f++)
  530. m_renderer->renderTile(scoreRollXPos[f] - rollWidth/2,
  531. y+h/2-(h*7/32),
  532. rollWidth,
  533. h*14/32,
  534. 0,0, (TexMeter<<16), 0);
  535. for (int yroll = -2; yroll<=1; yroll++) {
  536. for (int f=0; f<7; f++) {
  537. int num = ((m_scoreRollPos[f] >> 16) - 1 - yroll ) % 10;
  538. if (num<0) num = 10+num;
  539. int yofs = ((m_scoreRollPos[f]&65535)>>4) + (yroll*4096);
  540. //m_level->getCosineTable()[ yofs&4096
  541. int ypos = sin( (float)yofs / 4096.0f * 3.14159f/4.0f )*(float)h/3.3f;
  542. //int numheight = (65536<<10) / (abs(ypos)+4096);
  543. int numheight = h/2 - abs(ypos)*13/8;
  544. //numheight/=3;
  545. m_renderer->renderTile(scoreRollXPos[f] - rollWidth/2,
  546. y+h/2-(numheight/2) + ypos,
  547. rollWidth,
  548. numheight,
  549. 0,0, (TexMeter<<16) | (1+num), 0 );
  550. }
  551. }
  552. m_renderer->renderTile(x,y,w,h,0,0, (TexMeterBase<<16) | 0, 0);
  553. // render pausebutton
  554. if (m_state == eTILEGAMESTATE_PAUSED)
  555. m_renderer->renderTile(x+21000,y-65536+m_hudState,h*2/3,h*2/3*m_areaHeight/m_areaWidth,0,0, (TexExtra1<<16) | 1, 0);
  556. else
  557. m_renderer->renderTile(x+21000,y-65536+m_hudState,h*2/3,h*2/3*m_areaHeight/m_areaWidth,0,0, (TexExtra1<<16) | 0, 0);
  558. m_renderer->renderTile( 14000,6000-65536+m_hudState,14000,14000*m_areaWidth/m_areaHeight,0, 0, (TexParticle<<16)+0,0 );
  559. int n = ((m_currentLevel+1)/10);
  560. if (n==0) n = 10;
  561. m_renderer->renderTile( 14200,6200-65536+m_hudState,13000,13000*m_areaWidth/m_areaHeight,0, 0, (TexMeter<<16)+n,0 );
  562. m_renderer->renderTile( 20000,9000-65536+m_hudState,14000,14000*m_areaWidth/m_areaHeight,0, 0, (TexParticle<<16)+0,0 );
  563. n = ((m_currentLevel+1)%10);
  564. if (n==0) n = 10;
  565. m_renderer->renderTile( 20200,9200-65536+m_hudState,13000,13000*m_areaWidth/m_areaHeight,0, 0, (TexMeter<<16)+n,0 );
  566. /*
  567. char testr[16];
  568. sprintf(testr, "#%.2d", m_currentLevel+1 );
  569. writeText( 65536 - 16000, 6000,testr, (255-(m_hudState>>8)), 5000,4000 );
  570. */
  571. }
  572. if (m_logoState>0) {
  573. int mx = 65536/2;
  574. int my = (-60536 + m_logoState*2);
  575. int w = ((((65535 - m_logoWobble*2)>>2) * 1200)>>8);
  576. int h = ((((65535 + m_logoWobble*2)>>2) * 1200)>>8);
  577. int fade = 255-(m_logoState>>4);
  578. if (fade<0) fade = 0;
  579. m_renderer->renderTile( mx-w/2,my-h,w,h, 0,0, (TexLogo<<16) | (fade<<24), 0 );
  580. }
  581. // test
  582. /*
  583. char testr[256];
  584. sprintf(testr, "dn: %d", m_doingNothingCounter );
  585. writeText( 6000,56000, testr, 0, 8000, 5000 );
  586. */
  587. m_pengine->draw();
  588. /*
  589. if (m_level->doingNothing() == true)
  590. writeText( 16000,56000, "TRUE", 0, 8000, 3000 );
  591. else
  592. writeText( 16000,56000, "FALSE", 0, 8000, 3000 );
  593. */
  594. return 1;
  595. };
  596. void CTileNpc::gameClick( int fixedx, int fixedy, eMOUSEEVENT etype ) {
  597. if (m_state==eTILEGAMESTATE_SHOWINFOSCREEN) {
  598. if (etype == eMOUSEEVENT_BUTTONDOWN) setGameState( eTILEGAMESTATE_MENU );
  599. return;
  600. };
  601. if (etype==eMOUSEEVENT_BUTTONDOWN) {
  602. switch (m_state) {
  603. case eTILEGAMESTATE_GAMEOVER:
  604. if (m_level->getState() == eLEVELSTATE_IDLE) {
  605. if (m_gameOverCounter<65536*6)
  606. m_gameOverCounter = 65536*6;
  607. else
  608. setGameState( eTILEGAMESTATE_MENU );
  609. }
  610. return;
  611. case eTILEGAMESTATE_PAUSED:
  612. if (fixedy>83000) {
  613. if (fixedy>90000) gameOver(); else setGameState( eTILEGAMESTATE_RUNGAME );
  614. } //else m_pengine->spray( 20, fixedx,fixedy, 5000, 0,0, 32000, 0, &m_level->m_destroySpray );
  615. return;
  616. case eTILEGAMESTATE_MENU:
  617. //m_pengine->spray( 20, fixedx,fixedy, 5000, 0,0, 32000, 0, &m_level->m_destroySpray );
  618. if (fixedx>42000 && fixedy<10000) {
  619. #ifndef __APPLE__
  620. m_renderer->effectNotify(eEFFECT_EXIT,0,0);
  621. #endif
  622. } else
  623. if (fixedy>84000) { // mode change
  624. /*
  625. if (m_difficulty==0) m_difficulty=1; else m_difficulty = 0;
  626. m_level->m_difficulty = m_difficulty;
  627. m_menuModeCounter = 0;
  628. */
  629. //showInfoScreen();
  630. setGameState(eTILEGAMESTATE_SHOWINFOSCREEN);
  631. } else {
  632. if (fixedy<60000) m_logoWobbleInc+=16000;
  633. else {
  634. setGameState( eTILEGAMESTATE_RUNGAME );
  635. m_logoWobble = -20000;
  636. }
  637. }
  638. return;
  639. default:
  640. if (m_level->getState() == eLEVELSTATE_IDLE) { // level completed
  641. nextLevel();
  642. } else {
  643. //if (m_level->getState() == eLEVELSTATE_NORMAL)
  644. if (fixedy<12000) {
  645. if (fixedx>21000 && fixedx<28000)
  646. setGameState( eTILEGAMESTATE_PAUSED );
  647. else return;
  648. } else {
  649. //levelCompleted();
  650. //
  651. //gameOver();
  652. }
  653. }
  654. break;
  655. };
  656. } // end of if eMOUSEEVENT_DOWN
  657. if (m_gameIsOn && m_state==eTILEGAMESTATE_RUNGAME && m_level->getState()!=eLEVELSTATE_IDLE) {
  658. switch (etype) {
  659. case eMOUSEEVENT_BUTTONDOWN: m_level->click( fixedx, fixedy, 0 ); break;
  660. case eMOUSEEVENT_MOUSEDRAG: m_level->click( fixedx, fixedy, 1 ); break;
  661. case eMOUSEEVENT_BUTTONUP: m_level->click( fixedx, fixedy, 2 ); break;
  662. }
  663. }
  664. };
  665. void CTileNpc::nextLevel( int restartAt ) {
  666. if (restartAt>=0) {
  667. m_currentLevel = restartAt;
  668. m_score = 0;
  669. m_displayScore =0;
  670. m_gameIsOn = 1; // mark game ongoing
  671. m_gameOverCounter = -1;
  672. } else {
  673. m_currentLevel++;
  674. m_score+=m_currentLevel*m_currentLevel*10;
  675. }
  676. m_timeSinceLastScore = 0;
  677. m_completedTextCounter = -21*65536;
  678. m_targetTimer = 65536*100;
  679. float temp = 5.0f / ((float)m_currentLevel+6.0f);
  680. m_timeTimerEffect = -(int)( 240000.0f*(1.0f-temp));
  681. m_timeTimerEffect -= m_currentLevel*13000; // linear component
  682. m_blockTimerEffect = (65536*22) / (m_currentLevel+60); // 30
  683. //m_waitBeforeTimerStartsTime = 65536 - m_currentLevel*5000;
  684. m_waitBeforeTimerStartsTime = 65536*15 / (3+m_currentLevel);
  685. if (m_waitBeforeTimerStartsTime<0) m_waitBeforeTimerStartsTime = 0;
  686. m_level->createLevel( m_currentLevel );
  687. changeBg();
  688. };
  689. void CTileNpc::setIntAttribyte( eTILEGAME_ATTRIBUTE att, int set ) {
  690. switch (att) {
  691. case eATTRIBUTE_DIFFICULTY:
  692. m_difficulty = set;
  693. m_level->m_difficulty = set;
  694. break;
  695. };
  696. };
  697. int CTileNpc::getIntAttribute( eTILEGAME_ATTRIBUTE att, unsigned int arg ) {
  698. switch (att) {
  699. default:
  700. return 0;
  701. case eATTRIBUTE_DIFFICULTY:
  702. return m_difficulty;
  703. break;
  704. case eATTRIBUTE_HIGHSCORE:
  705. return m_highScore;
  706. break;
  707. case eSCORE:
  708. return m_score;
  709. case eTIMELIMIT_CURRENT:
  710. return m_timer;
  711. case eTIMELIMIT_MAX:
  712. return 65536 * 256;
  713. case eATTRIBUTE_CURRENTLEVEL:
  714. return m_currentLevel;
  715. };
  716. };
  717. /*
  718. unsigned char m_gameState;
  719. int m_difficulty;
  720. int m_blockTimerEffect; // kuinka paljon blokin tuhoaminen kasvattaa progressia.
  721. int m_timeTimerEffect; // kuinka paljon aika hidastaa progressia
  722. int m_currentLevel;
  723. int m_targetTimer;
  724. int m_timer;
  725. int m_score;
  726. int m_highScore
  727. */
  728. #ifdef __APPLE__
  729. #define SAVE_FILE "../Documents/fcstate.bin"
  730. #else
  731. #define SAVE_FILE "fcstate.bin"
  732. #endif
  733. int CTileNpc::save() {
  734. FILE *file = fopen(SAVE_FILE, "wb" );
  735. if (!file) return 0;
  736. fwrite( &m_difficulty, 1,11*sizeof(int), file );
  737. if (m_gameIsOn==1) m_level->saveToFile( file );
  738. fclose(file);
  739. return 1;
  740. };
  741. int CTileNpc::load() {
  742. FILE *file = fopen(SAVE_FILE, "rb" );
  743. if (!file) return 0;
  744. int rval = 0;
  745. fread( &m_difficulty, 1,11*sizeof(int), file );
  746. if (m_gameIsOn) {
  747. m_level->loadFromFile( file );
  748. m_level->m_difficulty=m_difficulty;
  749. changeBg();
  750. rval = 1;
  751. }
  752. fclose(file);
  753. return rval;
  754. };
  755. void CTileNpc::writeEffectText( int y, const char *text, int charSize, int fade ) {
  756. char ch;
  757. int totcount =0;
  758. int *cosin = m_level->getCosineTable();
  759. int yadd;
  760. int xadd;
  761. int charSpace = charSize*5/8;
  762. int x= 65536/2 - strlen(text)*charSpace/2;
  763. while (*text!=0) {
  764. if (*text!=' ') {
  765. if (ch>='a' && ch<='z') ch = ch-'a'+'A'; // to high-case
  766. ch = *text -32;
  767. yadd = ((cosin[(totcount*850 + m_effectAngle/70)&4095]>>8)*fade)/600;
  768. yadd += (cosin[(1000+m_effectAngle/10+totcount*600)&4095]>>8);
  769. xadd = (cosin[(m_effectAngle/30+totcount*800)&4095]>>8);
  770. m_renderer->renderTile( x+xadd,y+yadd,
  771. charSize,charSize, fade*2, 0, (TexFont<<16) | ch | ((fade>>8)<<24), 0 );
  772. }
  773. totcount++;
  774. x+=charSpace;
  775. text++;
  776. };
  777. };
  778. void CTileNpc::writeText( int x,int y, const char *text, int fade, int charSize, int charSpace ) {
  779. char ch;
  780. while (*text!=0) {
  781. if (*text!=' ') {
  782. ch = *text-32;
  783. m_renderer->renderTile( x,y,charSize,charSize, 0, 0, (TexFont<<16) | ch | (fade<<24), 0 );
  784. }
  785. x+=charSpace;
  786. text++;
  787. };
  788. };
  789. void CTileNpc::writeLevelCompletedString() {
  790. int x = 0;
  791. int y = 38000;
  792. const char *text = m_levelCompletedPoem;
  793. int charSize = 6000;
  794. int charSpace = charSize*5/8;
  795. int fade = 0;
  796. int *cosineTable = m_level->getCosineTable();
  797. int totCount = 0;
  798. int f,g;
  799. char testr[128]; // Word, line.
  800. char cur_line[256];
  801. cur_line[0] = 0; // end the line
  802. int sizeinc;
  803. char ch;
  804. while (1) {
  805. while ((*text==' ' || *text==10 || *text==13) && *text!=0) *text++;
  806. f=0;
  807. while (*text!=' ' && *text!=13 && *text!=10 && *text!=0 && f<255) {
  808. testr[f] = *text;
  809. *text++;
  810. f++;
  811. };
  812. testr[f]=0;
  813. // cur_line must be drawn
  814. if ( f==0 || (strlen(testr)+strlen(cur_line))*charSpace > 62000 ) {
  815. f=0;
  816. int j = strlen(cur_line);
  817. x = 65536/2-j*charSpace/2;
  818. x-=charSpace/4;
  819. while (cur_line[f]!=0) {
  820. ch = cur_line[f];
  821. if (ch>='a' && ch<='z') ch = ch-'a'+'A'; // to high-case
  822. ch-=32;
  823. g= ((totCount<<16) - m_completedTextCounter);
  824. //if (g<0) g = 0;
  825. if (g<-128*65536) g = g+128*65536; else if (g<0) g= 0;
  826. sizeinc = -abs(g)/256;
  827. fade = (g>>11);
  828. if (fade>255) return;
  829. fade = abs(fade);
  830. if (ch!=255 && fade<255) {
  831. m_renderer->renderTile(
  832. x-sizeinc/2+(cosineTable[(1000+m_completedTextAngle/20+f*600)&4095]>>10),
  833. g/64+y-sizeinc/2+(cosineTable[(m_completedTextAngle/30+f*800)&4095]>>9),
  834. charSize+sizeinc,
  835. charSize+sizeinc,
  836. -((sizeinc*8)&65535),
  837. 0,
  838. (TexFont<<16) | ch | (fade<<24),
  839. 0 );
  840. }
  841. totCount++;
  842. x+=charSpace;
  843. f++;
  844. }
  845. // line drawn
  846. cur_line[0] = 0; // clear it.
  847. x=0;
  848. y+=charSpace*4/3;
  849. cur_line[0] = 0;
  850. } else strcat( cur_line, " ");
  851. if (testr[0]==0) break;
  852. // .. add
  853. strcat( cur_line, testr );
  854. };
  855. };