/source/pintor.c

http://github.com/llopisillo/fail0verflow2 · C · 1217 lines · 900 code · 185 blank · 132 comment · 216 complexity · 98cb22ed776229ecd515a4bfab4cdcb8 MD5 · raw file

  1. /* PINTOR for GP32
  2. Copyright (C) 2005 Hermes/PS2Reality
  3. This program is free software; you can redistribute it and/or modify
  4. it under the terms of the GNU General Public License as published by
  5. the Free Software Foundation; either version 2 of the License, or
  6. (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program; if not, write to the Free Software
  13. Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  14. */
  15. #include <stdio.h>
  16. #include <stdlib.h>
  17. #include <string.h>
  18. #include <math.h>
  19. #include <time.h>
  20. #include <malloc.h>
  21. #include <stdlib.h>
  22. #include <unistd.h>
  23. #include <sys/time.h>
  24. #include "pad.h"
  25. #include "audioplayer.h"
  26. #include "spu_soundlib.h"
  27. #define WIDTH 256
  28. #define HEIGHT 192
  29. #define BORDER 10
  30. static int pause_audio = 0;
  31. unsigned GetTicks()
  32. {
  33. struct timeval tv;
  34. gettimeofday( &tv, 0 );
  35. return ((tv.tv_sec * 1000000) + tv.tv_usec) / 1000;
  36. }
  37. // VARIABLES DEL PROGRAMA
  38. #define PAD_RIGHT BUTTON_RIGHT
  39. #define PAD_LEFT BUTTON_LEFT
  40. #define PAD_DOWN BUTTON_DOWN
  41. #define PAD_UP BUTTON_UP
  42. int PADEVENT=0; // si 1 se puede leer el PAD
  43. /****************************************************************************************************************************************/
  44. // PANTALLA
  45. /****************************************************************************************************************************************/
  46. extern unsigned char msx[]; // define la fuente externa usada para dibujar letras y numeros
  47. unsigned *video=NULL; // memoria que almacena la pantalla virtual
  48. unsigned *video_text=NULL; // memoria que almacena la textura
  49. #define SIZEVIDEO 4*256*192 // tama?o en bytes de la pantalla vir.
  50. #define SCANVIDEO 256 // ancho de la pantalla vir.
  51. #define DESPL8VID 11 // usado para ajustar Y a scans (se utilizan graficos de 8x8 pixeles, 8*SCANVIDEO=2048=2^11
  52. #define ANCHO 32 // ancho de la pantalla en bloques de 8 pixeles
  53. #define ALTO 24 // alto d ela pantalla en bloques de 8 pixeles
  54. #define ALTO2 22 // se usa para presentar la puntuacion, vidas, etc en pantalla
  55. unsigned COLORFONDO=0x80804000; // color de fondo (vaya noticia :P)
  56. void ClearVideo(unsigned val) // se usa para 'borrar' la pantalla virtual con un color
  57. {
  58. int n;
  59. for(n=0;n<SIZEVIDEO/4;n++)
  60. {
  61. video[n]=val;
  62. }
  63. }
  64. extern void drawScene();
  65. void DrawScreen() // funcion evento que dibuja todos los elementos de la pantalla virtaul al LCD
  66. {
  67. int n;
  68. unsigned c,c2;
  69. volatile unsigned *v;
  70. c2=0xff00102f;
  71. for(n = 0; n < (256 * 192); n++) {
  72. v=((unsigned *) video) + n;
  73. c=(*v & 0xff00ff00) | ((*v<<16) & 0xff0000) | ((*v>>16) & 0xff);
  74. if(!c || c < 0x11000000) c = c2;
  75. video_text[n] = c;
  76. }
  77. drawScene();
  78. ps3pad_read();PADEVENT=1;
  79. }
  80. void v_putchar( unsigned x, unsigned y, unsigned color, unsigned char ch) // rutina usada para dibujar caracteres (coordenadas de 8x8)
  81. {
  82. int i,j,v;
  83. unsigned char *font;
  84. if(x>=ANCHO || y>=ALTO) return;
  85. v=(y<<DESPL8VID);
  86. font = &msx[ (int)ch * 8];
  87. for (i=0; i < 8; i++, font++)
  88. {
  89. for (j=0; j < 8; j++)
  90. {
  91. if ((*font & (128 >> j)))
  92. {
  93. video[v+(((x<<3)+j))]=color;
  94. }
  95. else video[v+(((x<<3)+j))]=0;
  96. }
  97. v+=SCANVIDEO;
  98. }
  99. }
  100. // display array of chars
  101. void v_putcad(int x,int y,unsigned color,char *cad) // dibuja una cadena de texto
  102. {
  103. while(cad[0]!=0) {v_putchar(x,y,color,cad[0]);cad++;x++;}
  104. }
  105. /****************************************************************************************************************************************/
  106. // rutinas y definicion de UDG (User Defined Graphic) (8x8 pixeles)
  107. /****************************************************************************************************************************************/
  108. // paleta de conversion de caracter/color
  109. unsigned PALETA[10]={0x0,0xff0000ff,0xff00ff00,0xff00ffff,0xffff0000,0xffff00ff,0xffffff00,0xffffffff,0xff000000,1};
  110. void SetUDG(unsigned x,unsigned y,unsigned char *punt) // dibuja un UDG
  111. {
  112. int n,m,v;
  113. unsigned col;
  114. if(x>=ANCHO || y>=ALTO) return;
  115. v=(y<<DESPL8VID);
  116. for(n=0;n<8;n++)
  117. {
  118. for(m=0;m<8;m++)
  119. {
  120. col=(unsigned )*punt++;
  121. col-=48;
  122. col=PALETA[col];
  123. //if(col==1) col=COLORFONDO;
  124. if(col!=0)
  125. video[v+(((x<<3)+m))]=col;
  126. }
  127. v+=SCANVIDEO;
  128. }
  129. }
  130. // lista de UDG's usados en el juego
  131. unsigned char gdu_sprite[20][8][8]={
  132. {
  133. "33388333",
  134. "33388333",
  135. "33383383",
  136. "38888833",
  137. "83383333",
  138. "33838833",
  139. "33833833",
  140. "38333383",
  141. },
  142. {
  143. "99999999",
  144. "99999999",
  145. "99999999",
  146. "99999999",
  147. "99999999",
  148. "99999999",
  149. "99999999",
  150. "99999999",
  151. },
  152. {
  153. "77777777",
  154. "77777777",
  155. "77777777",
  156. "77777777",
  157. "77777777",
  158. "77777777",
  159. "77777777",
  160. "77777777",
  161. },
  162. {
  163. "33333333",
  164. "33333333",
  165. "33333333",
  166. "33333333",
  167. "33333333",
  168. "33333333",
  169. "33333333",
  170. "33333333",
  171. },
  172. {
  173. "33388333",
  174. "33388333",
  175. "38338333",
  176. "33888883",
  177. "33338338",
  178. "33883833",
  179. "33833833",
  180. "38333383",
  181. },
  182. {
  183. "22222222",
  184. "22222222",
  185. "22222222",
  186. "22222222",
  187. "22222222",
  188. "22222222",
  189. "22222222",
  190. "22222222",
  191. },
  192. {
  193. // 6
  194. "00001100",
  195. "10111110",
  196. "11111011",
  197. "01111111",
  198. "01111000",
  199. "00110111",
  200. "00111110",
  201. "00001100",
  202. },
  203. {
  204. "00001100",
  205. "00111110",
  206. "01111011",
  207. "01111111",
  208. "01111000",
  209. "11110001",
  210. "10111110",
  211. "00001100",
  212. },
  213. {
  214. // 8
  215. "00110000",
  216. "01111101",
  217. "11011111",
  218. "11111110",
  219. "00011110",
  220. "11101100",
  221. "01111100",
  222. "00110000",
  223. },
  224. {
  225. "00110000",
  226. "01111100",
  227. "11011110",
  228. "11111110",
  229. "00011110",
  230. "10001111",
  231. "01111101",
  232. "00110000",
  233. },
  234. };
  235. /****************************************************************************************************************************************/
  236. // definicion de mapas del juego
  237. /****************************************************************************************************************************************/
  238. // definicion d elos mapas: A,B,C,D->representa donde aparecen los bichos, 1,2->caminos
  239. unsigned char map_screens[8][22][32]={
  240. {
  241. ////////////////////////////////////
  242. " 2 2 ",
  243. " 2 2 ",
  244. " ",
  245. " 22222222 ",
  246. " ",
  247. "11111111111 ",
  248. " 1 11 ",
  249. " 1 1 1 ",
  250. " 1 11 1 ",
  251. " 1111111111 111111111 ",
  252. " 1 1 1 11",
  253. " 1 2 1 11111 1 1111 111 ",
  254. " 1 111 1 1 11 11 1 ",
  255. " 1 1 1 111 1 1 1 ",
  256. " 1111 1 1 1 1 111 ",
  257. " 1 1 1 1 1 1 1 1 ",
  258. " 1 11 1 1 11 11 11 1 ",
  259. " A 1111D 1 11B11111 C ",
  260. " ",
  261. "22222222222222222222222222222222",
  262. "22222222222222222222222222222222",
  263. " ",
  264. },
  265. {
  266. //////////////////////////////////
  267. "A1111111 1111111D",
  268. "1 1 1 1",
  269. "1 11111111$111111111 1",
  270. "1 1 1 1",
  271. "1 1 1 1",
  272. "1 111111111111111111 1",
  273. "1 1 1 1 1 1",
  274. "11111111 1 1 11111111",
  275. " 1 1 111111111111 1 1 ",
  276. " 1 1 1 1 1 1 ",
  277. " 1 1 1 1 1 1 ",
  278. " 1 1 1 1 1 1 ",
  279. " 1 1 1 1 1 1 ",
  280. " 1 1 111111111111 1 1 ",
  281. "11111111 1 1 11111111",
  282. "1 1 1 1 1 1",
  283. "1 111111111111111111 1",
  284. "1 1 1 1",
  285. "1 1 1 1",
  286. "1 111111111111111111 1",
  287. "1 1 1 1",
  288. "C1111111 1111111B",
  289. },
  290. {
  291. ////////////////////////////////////
  292. " A11111 11111D ",
  293. " 1 1 1 1 ",
  294. "111111111111 111111111111",
  295. "1 1 1 1",
  296. "1 1 1 1",
  297. "111111111111 111111111111",
  298. " 1 1 11111111 1 1 ",
  299. " 1 1 1 1 1 1 ",
  300. " 1 1 1 1 1 1 ",
  301. "1111111111111111$111111111111111",
  302. "1 1",
  303. "1 1",
  304. "1 1",
  305. "11111111111111111111111111111111",
  306. " 1 1 1 1 ",
  307. " 1 1 1 1 ",
  308. " 1 1 1 1 ",
  309. " 1 1 1 1 ",
  310. " 1 1 1 1 ",
  311. " C111111111 111111111B ",
  312. " ",
  313. " ",
  314. ////////////////////////////////////
  315. },
  316. {
  317. ////////////////////////////////////
  318. "A1111 11111 ",
  319. "1 1 1 1 ",
  320. "1 1 1 1 ",
  321. "1 111111111111111111111111111D",
  322. "1 1 1 1 1",
  323. "1 1 1 1 1",
  324. "1 1111111111111$11111111111111",
  325. "1 1 1 1 ",
  326. "1 1 1 1 ",
  327. "1 1 1111111111111111 ",
  328. "1 1 1 1 ",
  329. "1 1 1 1 ",
  330. "1 1 1 1 ",
  331. "1 1 111111111111111111111111",
  332. "1 1 1 1",
  333. "1 1 1 1",
  334. "1 1111111111111111111111111111",
  335. "1 1 1 ",
  336. "1 1 1 ",
  337. "1 111111111111111111111111B ",
  338. "1 1 1 1 ",
  339. "C1111 11111111111111 ",
  340. },
  341. {
  342. ////////////////////////////////////
  343. " A11111 111111111111D ",
  344. " 1 1 1 1 ",
  345. " 111111111 11111111111111111111",
  346. " 1 1 1 1 1 1",
  347. " 1 1 1 1 1 1",
  348. " 111111111 1 1 1 1",
  349. " 1 1 1 1 1 1",
  350. " 1 1 1 1 1 1",
  351. " 1 1 1 1111111111111",
  352. " 1 1 1 1 1",
  353. " 1 1 1 1 1",
  354. " 1 1 1 1 1",
  355. " 1 1 1111$111111111111111",
  356. " 1 1 1 1 1 1",
  357. " 1 1 1 1 1 1",
  358. " 1 1 1 1 1 1",
  359. " 1 1 1 1 1 1",
  360. "11111111111111111111111111111111",
  361. "1 1 ",
  362. "1 1 ",
  363. "1 1 ",
  364. "C1111111111111111111111111111B ",
  365. ////////////////////////////////////
  366. },
  367. {
  368. ////////////////////////////////////
  369. "A11111111 11111111 11111111D",
  370. "1 1 1 1 1 1",
  371. "1 1 1 1 1 1",
  372. "1 1 111111111111 1 1",
  373. "111111111 1 1 111111111",
  374. " 1 1 1 1 ",
  375. "1111111111111111$111111111111111",
  376. "1 1 1 1",
  377. "1 1 1 1",
  378. "1 1 1 1",
  379. "1 111111111111 1",
  380. "1 1 1 1 1 1",
  381. "1 1 1 1 1 1",
  382. "11111111111 1 1 11111111111",
  383. " 1 1 1 1 1 1 ",
  384. " 1 1111111111111111 1 ",
  385. " 1 1 1 1 ",
  386. " 1 1 1 1 ",
  387. "11111111111111111111111111111111",
  388. "1 1 1 1",
  389. "1 1 1 1",
  390. "C11111111111 11111111111B",
  391. ////////////////////////////////////
  392. },
  393. {
  394. ////////////////////////////////////
  395. " ",
  396. " ",
  397. " ",
  398. " ",
  399. " ",
  400. " ",
  401. " ",
  402. " ",
  403. " ",
  404. " ",
  405. " ",
  406. " ",
  407. " ",
  408. " ",
  409. " ",
  410. " ",
  411. " ",
  412. " ",
  413. " ",
  414. " ",
  415. " ",
  416. " ",
  417. ////////////////////////////////////
  418. },
  419. };
  420. // numero de anillos por mapa
  421. int map_screen_rings[10]={66,11,10,10,12,13,0,0,0,0};
  422. /****************************************************************************************************************************************/
  423. // variables del juego
  424. /****************************************************************************************************************************************/
  425. int pausa=0; // 1- juego pausado
  426. unsigned puntos=0; // si te tengo que explicar esto, mejor lo dejamos :P
  427. unsigned hiscore=0;
  428. int vidas=3;
  429. int nbichos=2;
  430. int rings=0; // anillos completados
  431. unsigned protadir=0; // para donde miramos
  432. int bichodir[4]={0,0,0,0}; // para donde miran los bichos
  433. int ACTMAP=0; // mapa actual
  434. unsigned char map_screen[24][32]; // aqui se trabaja (se copia el mapa aqui para ello)
  435. // control de eventos de sonido
  436. int message_scroll=0;
  437. int message_effect1=0;
  438. int message_effect2=0;
  439. int message_camina[4]={0,0,0,0};
  440. int piok=0;
  441. int message_piok=0; // me han 'picado' me temo :D
  442. /****************************************************************************************************************************************/
  443. // manejo y control de mapas del juego
  444. /****************************************************************************************************************************************/
  445. void copyMAP()
  446. {
  447. int n,m;
  448. unsigned char c;
  449. protadir=0;
  450. rings=0;
  451. piok=0;
  452. message_piok=0;
  453. for(n=0;n<4;n++)
  454. {bichodir[n]=0;
  455. message_camina[n]=0;
  456. }
  457. message_effect2=0;
  458. message_effect1=0;
  459. message_scroll=0;
  460. ClearVideo(0);
  461. switch(ACTMAP)
  462. {
  463. case 0:COLORFONDO=0x80800000;PALETA[2]=0x80ff8000;break;
  464. case 2:COLORFONDO=0x80004020;PALETA[2]=0x8000ff80;break;
  465. case 3:COLORFONDO=0x80404040;PALETA[2]=0x808000ff;break;
  466. case 4:COLORFONDO=0x80404000;PALETA[2]=0x8000ff00;break;
  467. case 5:COLORFONDO=0x80402040;PALETA[2]=0x80ff00ff;break;
  468. default:COLORFONDO=0x80804000;PALETA[2]=0x80ff8000;
  469. }
  470. //memcpy(map_screen,&map_screens[ACTMAP][0][0],32*22);
  471. for(n=0;n<22;n++)
  472. {
  473. for(m=0;m<32;m++)
  474. {
  475. c=map_screens[ACTMAP][n][m];
  476. // esto sucede la primera vez
  477. if(c==' ') c=0;
  478. else
  479. if(c=='1') c=1;
  480. else
  481. if(c=='2') c=2;
  482. else
  483. if(c=='$') c=130;
  484. else
  485. if(c=='A') c=65;
  486. else
  487. if(c=='B' && nbichos>1) c=33;
  488. else
  489. if(c=='C' && nbichos>2) c=17;
  490. else
  491. if(c=='D' && nbichos>3) c=9;
  492. else c=1;
  493. map_screen[n][m]=c;
  494. }
  495. }
  496. }
  497. int AnalizeMAP();
  498. void scrollMAP() // efecto de scroll lateral de cuando completamos un mapa
  499. {
  500. int n,m;
  501. for(n=0;n<22;n++)
  502. {
  503. for(m=30;m>=0;m--)
  504. {
  505. map_screen[n][m+1]=map_screen[n][m];
  506. }
  507. map_screen[n][0]=0;
  508. }
  509. }
  510. static int screen_count0 = 0;
  511. void DrawMAP() // dibuja el mapa y actualiza variables
  512. {
  513. int n,m,v;
  514. unsigned char c;
  515. char cad[256];
  516. static int paso=0,count=0,count2=0;
  517. screen_count0++;
  518. count2++;
  519. if(count2>=50) {count2=0;}
  520. count++;
  521. if(count>=32){count=0;paso^=1;}
  522. if(rings>=map_screen_rings[ACTMAP] || piok || pausa || ACTMAP==0) count2=20; // evita efectos de sonido
  523. else
  524. rings+=AnalizeMAP();
  525. //if(rings>map_screen_rings[ACTMAP]) return ; // si se han comppletado los anillos retorna
  526. for(n=0;n<22;n++)
  527. {
  528. for(m=0;m<32;m++)
  529. {
  530. c=map_screen[n][m];
  531. // esto sucede la primera vez
  532. /*if(c=='$') {c='2' | 128;map_screen[n][m]=c; }
  533. if(c=='A') {c='1' | 128;map_screen[n][m]=c; }*/
  534. // pinta fondo mapa
  535. v=(c & 7)+1;
  536. SetUDG(m,n,(unsigned char *) &gdu_sprite[v][0][0]);
  537. // mi personaje esta aqui?
  538. if(c & 128) {if((c & 120) && piok==0){piok=16384+(n<<5)+m;message_piok=1;}SetUDG(m,n,(unsigned char *) &gdu_sprite[4*(protadir==1 || protadir==4)][0][0]);c=(c & 0xfc) | 130;map_screen[n][m]=c;}
  539. // veo bichos!!
  540. if(c & 64) {if((c & 128) && piok==0){piok=16384+(n<<5)+m;message_piok=1;}
  541. if(count2==0) message_camina[0]=(m-16)+(m==16);SetUDG(m,n,(unsigned char *) &gdu_sprite[6+paso+2*(bichodir[0]==1 || bichodir[0]==4)][0][0]);}
  542. if(c & 32) {if((c & 128) && piok==0){piok=16384+(n<<5)+m;message_piok=1;}
  543. if(count2==0) message_camina[1]=(m-16)+(m==16);SetUDG(m,n,(unsigned char *) &gdu_sprite[6+paso+2*(bichodir[1]==1 || bichodir[1]==4)][0][0]);}
  544. if(c & 16) {if((c & 128) && piok==0){piok=16384+(n<<5)+m;message_piok=1;}
  545. if(count2==0) message_camina[2]=(m-16)+(m==16);SetUDG(m,n,(unsigned char *) &gdu_sprite[6+paso+2*(bichodir[2]==1 || bichodir[2]==4)][0][0]);}
  546. if(c & 8) {if((c & 128) && piok==0){piok=16384+(n<<5)+m;message_piok=1;}
  547. if(count2==0) message_camina[3]=(m-16)+(m==16);SetUDG(m,n,(unsigned char *) &gdu_sprite[6+paso+2*(bichodir[3]==1 || bichodir[3]==4)][0][0]);}
  548. }
  549. }
  550. if(ACTMAP!=0) // si no es pantalla 0
  551. {if(puntos>hiscore) hiscore=puntos;
  552. sprintf(cad,"SCORE:%6.6u HI:%6.6u ",puntos,hiscore);
  553. v_putcad(0,23,0xffffFFff,cad);
  554. v_putcad(23,23,0xffffFFff,"LIVES:");
  555. for(n=0;n<vidas;n++) SetUDG(29+n,23,(unsigned char *) &gdu_sprite[0]);
  556. screen_count0 = 0;
  557. }
  558. else
  559. {
  560. if(screen_count0<30)
  561. {
  562. v_putcad(7,22,0xffffffff,"by HermesEOL / 2011");
  563. v_putcad(6,23,0xffffffff,"Fail0verflow Version");
  564. }
  565. else
  566. {
  567. memset(video, 0, SIZEVIDEO);
  568. v_putcad(11, 1,0xff00ffff,"Starring:");
  569. SetUDG(3,3,(unsigned char *) &gdu_sprite[0]);
  570. v_putcad(4, 3,0xffffffff,"..... 1 to 100 John Does");
  571. SetUDG(3,5,(unsigned char *) &gdu_sprite[8]);
  572. v_putcad(4, 5,0xffffffff,"..... Giant Crab S.C.E.A.");
  573. SetUDG(3,7,(unsigned char *) &gdu_sprite[9]);
  574. v_putcad(4, 7,0xffffffff,"..... Attorneys lapdogs");
  575. v_putcad(13, 9,0xff00ffff,"Music:");
  576. v_putcad(0, 11,0xffffffff,"The Light It Up Contest-Geohot");
  577. v_putcad(11, 13,0xff00ffff,"No Thanks:");
  578. v_putcad(0, 15,0xffffffff,"To github to erase the original");
  579. v_putcad(0, 16,0xffffffff,"fail0verflow repository cowardly ");
  580. v_putcad(0, 17,0xffffffff,"without any reason to justify it.");
  581. v_putcad(7,22,0xffffffff,"by HermesEOL / 2011");
  582. v_putcad(6,23,0xffffffff,"Fail0verflow Version");
  583. if(screen_count0>60) screen_count0 = 0;
  584. }
  585. }
  586. }
  587. int subanalizeMAP(int x,int y) // llamada por analizeMAP(), me gustan los nombres rarus
  588. {
  589. int n,m;
  590. int xx1,yy1,xx2,yy2;
  591. if(x>29 || y>19) return 0;
  592. if((map_screen[y][x+1] & 3)!=2 || (map_screen[y+1][x] & 3)!=2) return 0;
  593. xx1=xx2=x;yy1=yy2=y;
  594. // busca una bifurcacion hacia abajo
  595. for(m=x+1;m<32;m++)
  596. {
  597. if((map_screen[y][m] & 3)==2)
  598. {
  599. if((map_screen[y+1][m] & 3)==1) break;
  600. if((map_screen[y+1][m] & 3)==2) {xx2=m;break;}
  601. } else break;
  602. }
  603. // busca una bifurcacion a la derecha
  604. for(m=y+1;m<22;m++)
  605. {
  606. if((map_screen[m][x] & 3)==2)
  607. {
  608. if((map_screen[m][x+1] & 3)==1) break;
  609. if((map_screen[m][x+1] & 3)==2) {yy2=m;break;}
  610. } else break;
  611. }
  612. if(xx1==xx2 || yy1==yy2) return 0;
  613. for(m=xx1;m<=xx2;m++)
  614. {
  615. if((map_screen[yy2][m] & 3)!=2) break;
  616. }
  617. if(m<=xx2) return 0; // no esta completo el circulo
  618. for(m=yy1;m<=yy2;m++)
  619. {
  620. if((map_screen[m][xx2] & 3)!=2) break;
  621. }
  622. if(m<=yy2) return 0; // no esta completo el circulo
  623. // recuadro a iluminar
  624. for(n=yy1+1;n<yy2;n++)
  625. {
  626. for(m=xx1+1;m<xx2;m++)
  627. {
  628. if(map_screen[n][m]==4) return 0; // ya estaba pintado
  629. map_screen[n][m]=4;
  630. }
  631. }
  632. message_effect1=1; // emite un sonido
  633. return 1;
  634. }
  635. int AnalizeMAP() // rutina que sirve para que el programa se entere de lo que pasa en el mapa (busca anillos)
  636. {
  637. int numrec=0;
  638. int n,m;
  639. for(n=0;n<22;n++)
  640. {
  641. for(m=0;m<32;m++)
  642. {
  643. if((map_screen[n][m] & 3)==2)
  644. {
  645. if(subanalizeMAP(m,n)) numrec++;
  646. }
  647. }
  648. }
  649. puntos+=10*numrec*nbichos;
  650. return numrec;
  651. }
  652. void Borra_Prota()
  653. {
  654. int n,m;
  655. for(n=0;n<22;n++)
  656. {
  657. for(m=0;m<32;m++)
  658. {
  659. map_screen[n][m]&=127;
  660. }
  661. }
  662. }
  663. void Move_Bicho(unsigned nbi) // mola el spanglish :D
  664. {
  665. int n,m;
  666. unsigned char c,mask,mask2;
  667. int testmove=0,contmove=0;
  668. switch(nbi)
  669. {
  670. case 1: mask=32;mask2=255-32;break;
  671. case 2: mask=16;mask2=255-16;break;
  672. case 3: mask=8;mask2=255-8;break;
  673. default: mask=64;mask2=255-64;
  674. }
  675. //busca al bichin :P
  676. for(n=0;n<22;n++)
  677. {
  678. for(m=0;m<32;m++)
  679. {
  680. c=map_screen[n][m];
  681. if(c & mask) // detectado bicho
  682. {
  683. do
  684. {
  685. if(bichodir[nbi]==0)
  686. {bichodir[nbi]=(rand() & 1)+1; message_effect2=1;}
  687. if(bichodir[nbi]==1 || bichodir[nbi]==2)
  688. {
  689. if(n>0) if(map_screen[n-1][m] & 3) if((rand() & 15)<4) {bichodir[nbi]=4;message_effect2=1;}
  690. if(n<21) if(map_screen[n+1][m] & 3) if((rand() & 15)<4) {bichodir[nbi]=8;message_effect2=1;}
  691. }
  692. else
  693. {
  694. {
  695. if(m>0) if(map_screen[n][m-1] & 3) if((rand() & 15)<4) {bichodir[nbi]=1;message_effect2=1;}
  696. if(m<31) if(map_screen[n][m+1] & 3) if((rand() & 15)<4) {bichodir[nbi]=2;message_effect2=1;}
  697. }
  698. }
  699. if(bichodir[nbi] & 1)
  700. {
  701. if(m>0) if(map_screen[n][m-1] & 3) {map_screen[n][m]&=mask2;map_screen[n][m-1]|=mask;testmove++;}
  702. }
  703. else
  704. if(bichodir[nbi] & 2)
  705. {
  706. if(m<31) if(map_screen[n][m+1] & 3) {map_screen[n][m]&=mask2;map_screen[n][m+1]|=mask;testmove++;}
  707. }
  708. else
  709. if(bichodir[nbi] & 4)
  710. {
  711. if(n>0) if(map_screen[n-1][m] & 3) {map_screen[n][m]&=mask2;map_screen[n-1][m]|=mask;testmove++;}
  712. }
  713. else
  714. if(bichodir[nbi] & 8)
  715. {
  716. if(n<21) if(map_screen[n+1][m] & 3) {map_screen[n][m]&=mask2;map_screen[n+1][m]|=mask;testmove++;}
  717. }
  718. contmove++;
  719. if(contmove>32 && testmove==0) { // anticuelgue
  720. contmove=0;
  721. bichodir[nbi]=0;
  722. }
  723. }while(testmove==0);
  724. if((c & 128) && piok==0){piok=16384+(n<<5)+m;message_piok=1;}
  725. return;
  726. }
  727. }
  728. }
  729. }
  730. void Move_Prota(unsigned pad)
  731. {
  732. int n,m;
  733. unsigned char c;
  734. for(n=0;n<nbichos;n++) Move_Bicho(n);
  735. //busca a mi personaje
  736. for(n=0;n<22;n++)
  737. {
  738. for(m=0;m<32;m++)
  739. {
  740. c=map_screen[n][m];
  741. if(c & 128) // detectado protagonista
  742. {
  743. if((c & 120) && piok==0){piok=16384+(n<<5)+m;message_piok=1;}
  744. if((pad & PAD_LEFT) && protadir!=1)
  745. {
  746. if(m>0) if(map_screen[n][m-1] & 3) protadir=1;
  747. }
  748. else
  749. if((pad & PAD_RIGHT) && protadir!=2)
  750. {
  751. if(m<31) if(map_screen[n][m+1] & 3)protadir=/*(protadir & 12) |*/ 2;
  752. }
  753. else
  754. if((pad & PAD_UP) && protadir!=4)
  755. {
  756. if(n>0) if(map_screen[n-1][m] & 3)protadir=/*(protadir & 3) |*/ 4;
  757. }
  758. else
  759. if((pad & PAD_DOWN) && protadir!=8)
  760. {
  761. if(n<21) if(map_screen[n+1][m] & 3) protadir=/*(protadir & 3) |*/ 8;
  762. }
  763. //protadir=1;
  764. if(protadir & 1)
  765. {
  766. if(m>0) if(map_screen[n][m-1] & 3) {map_screen[n][m]&=127;map_screen[n][m-1]=(map_screen[n][m-1] & 0xfc) | 130;}
  767. }
  768. else
  769. if(protadir & 2)
  770. {
  771. if(m<31) if(map_screen[n][m+1] & 3) {map_screen[n][m]&=127;map_screen[n][m+1]=(map_screen[n][m+1] & 0xfc) | 130;}
  772. }
  773. else
  774. if(protadir & 4)
  775. {
  776. if(n>0) if(map_screen[n-1][m] & 3) {map_screen[n][m]&=127;map_screen[n-1][m]=(map_screen[n-1][m] & 0xfc) | 130;}
  777. }
  778. else
  779. if(protadir & 8)
  780. {
  781. if(n<21) if(map_screen[n+1][m] & 3) {map_screen[n][m]&=127;map_screen[n+1][m]=(map_screen[n+1][m] & 0xfc) | 130;}
  782. }
  783. if((c & 120) && piok==0){piok=16384+(n<<5)+m;message_piok=1;}
  784. return;
  785. }
  786. }
  787. }
  788. }
  789. /****************************************************************************************************************************************/
  790. // SONIDO (generación)
  791. /****************************************************************************************************************************************/
  792. int time1_sound=0;
  793. int time2_sound=0;
  794. int time3_sound=0;
  795. int time4_sound=0;
  796. int count_sound=0;
  797. int count2_sound=0;
  798. int vol_sound=0;
  799. int mod_sound=1;
  800. /* set_sonido
  801. vol=volumen (0-0x7fff)
  802. hz=frecuencia en hz del sonido
  803. time_on=tiempo en ms que se reproduce la onda
  804. time_off=tiempo en ms deonda en off (intermitencia)
  805. times=numero de veces que se repite (-1=infinito)
  806. */
  807. void set_sonido(int vol,int hz,int time_on,int time_off,int times) // programa un sonido
  808. {
  809. int a;
  810. time4_sound=0;
  811. //time_on>>=1;
  812. //time_off>>=1;
  813. vol_sound=vol;
  814. a=44100/hz;
  815. if(a==0) a=2;
  816. time1_sound=a;
  817. time_on=(11025*time_on)/(a*1000);
  818. if(time_on==0) time_on=1;
  819. time2_sound=time_on;
  820. time3_sound=(11025*time_off)/1000;
  821. time4_sound=times;
  822. }
  823. // mezclador de audio de las SDL llamado como eventos
  824. void mixaudio(void *unused, u8 *stream, int len)
  825. {
  826. int n;
  827. int mid;
  828. short *pu;
  829. mid=time1_sound>>1;
  830. pu=(short *) stream;
  831. for(n=0;n<(len>>2);n++)
  832. {
  833. if(time4_sound!=0)
  834. {
  835. if(count2_sound<time2_sound)
  836. {
  837. if(count_sound==mid) {pu[0]=pu[1]=0;pu+=2;} else
  838. if(count_sound<mid) {pu[0]=pu[1]=vol_sound;pu+=2;} else {pu[0]=pu[1]=-vol_sound;pu+=2;}
  839. count_sound++;if(count_sound>=time1_sound) {count_sound=0;count2_sound++;}
  840. }
  841. else
  842. {
  843. if(count_sound<time3_sound) {pu[0]=pu[1]=0;pu+=2;count_sound++;}
  844. else {count_sound=count2_sound=0;if(time4_sound>0) time4_sound--;}
  845. }
  846. }
  847. }
  848. }
  849. /****************************************************************************************************************************************/
  850. // MAIN
  851. /****************************************************************************************************************************************/
  852. unsigned oldtime=0; // se usa para conocer el tiempo transcurrido en ms
  853. int count20ms=0; // variable rara vinculada al temporizador
  854. //int temp_keys,new_keys=0,old_keys=0; // usadas para leer el pad
  855. static short pcmout[2][2048];
  856. int pcm_flip=0;
  857. static void audio_add_callback(int voice)
  858. {
  859. if(SND_TestVoiceBufferReady(1)==1)
  860. {
  861. //void mixaudio(void *unused, u8 *stream, int len)
  862. mixaudio(NULL, (void *) &pcmout[pcm_flip][0],2048);
  863. if(SND_AddVoice(1, (void *) &pcmout[pcm_flip][0],2048)==0)
  864. {
  865. pcm_flip^=1;
  866. }
  867. }
  868. }
  869. int pintor()
  870. {
  871. unsigned time1,n;
  872. video=malloc(SIZEVIDEO);
  873. //video_text=memalign(32,WIDTH*HEIGHT*4);
  874. SND_SetVoice(1, VOICE_STEREO_16BIT, 11025*2,0, (void *) &pcmout[pcm_flip][0], 2048, 63, 63, audio_add_callback);
  875. pcm_flip^=1;
  876. /////////////////////////////////////////////////////////////
  877. do
  878. {
  879. ACTMAP=0;
  880. vidas=3;
  881. puntos=0;
  882. pausa=0;
  883. do
  884. {
  885. copyMAP();
  886. new_pad=old_pad=0;
  887. while(1==1) // bucle principal donde se desarrolla toda la accion :O
  888. {
  889. if(!time4_sound && !pausa)
  890. {if(message_effect1) {mod_sound=0;message_effect1=0; set_sonido(127<<8,1200,125,0,1);}
  891. else
  892. if(message_effect2) {mod_sound=1;message_effect2=0; set_sonido((63<<8),300,75,125,1);}
  893. else /*if(message_effect1)*/ {mod_sound=1;message_effect1=0; set_sonido((32<<8),150,60,125,1);}
  894. }
  895. if(rings>=map_screen_rings[ACTMAP]) break; // pasa a sigueinte pantalla
  896. if(PADEVENT)
  897. {
  898. PADEVENT=0; // anula el evento (lectura cada 20ms, recuerda)
  899. #define J_DEATHZ 64 // death zone for sticks
  900. if(pad_alive)
  901. {
  902. if(paddata.ANA_R_V > (127+J_DEATHZ)) old_pad|=BUTTON_DOWN;
  903. if(paddata.ANA_R_V < (127-J_DEATHZ)) old_pad|=BUTTON_UP;
  904. if(paddata.ANA_L_V > (127+J_DEATHZ)) old_pad|=BUTTON_DOWN;
  905. if(paddata.ANA_L_V < (127-J_DEATHZ)) old_pad|=BUTTON_UP;
  906. if(paddata.ANA_R_H > (127+J_DEATHZ)) old_pad|=BUTTON_RIGHT;
  907. if(paddata.ANA_R_H < (127-J_DEATHZ)) old_pad|=BUTTON_LEFT;
  908. if(paddata.ANA_L_H > (127+J_DEATHZ)) old_pad|=BUTTON_RIGHT;
  909. if(paddata.ANA_L_H < (127-J_DEATHZ)) old_pad|=BUTTON_LEFT;
  910. pad_alive = 0;
  911. }
  912. /*
  913. if(wmote_datas!=NULL && wmote_datas->exp.type==WPAD_EXP_CLASSIC)
  914. {
  915. if(temp_pad & WPAD_CLASSIC_BUTTON_UP) temp_pad|=BUTTON_RIGHT;
  916. if(temp_pad & WPAD_CLASSIC_BUTTON_DOWN) temp_pad|=BUTTON_LEFT;
  917. if(temp_pad & WPAD_CLASSIC_BUTTON_LEFT) temp_pad|=BUTTON_UP;
  918. if(temp_pad & WPAD_CLASSIC_BUTTON_RIGHT) temp_pad|=BUTTON_DOWN;
  919. if(new_pad & WPAD_CLASSIC_BUTTON_A) new_pad|=BUTTON_CROSS;
  920. if(old_pad & WPAD_CLASSIC_BUTTON_A) old_pad|=BUTTON_CROSS;
  921. if(new_pad & WPAD_CLASSIC_BUTTON_B) new_pad|=WPAD_BUTTON_B;
  922. if(old_pad & WPAD_CLASSIC_BUTTON_B) old_pad|=WPAD_BUTTON_B;
  923. if(new_pad & WPAD_CLASSIC_BUTTON_X) new_pad|=WPAD_BUTTON_1;
  924. if(old_pad & WPAD_CLASSIC_BUTTON_X) old_pad|=WPAD_BUTTON_1;
  925. if(new_pad & WPAD_CLASSIC_BUTTON_Y) new_pad|=WPAD_BUTTON_2;
  926. if(old_pad & WPAD_CLASSIC_BUTTON_Y) old_pad|=WPAD_BUTTON_2;
  927. if(new_pad & WPAD_CLASSIC_BUTTON_HOME) new_pad|=BUTTON_START;
  928. if(old_pad & WPAD_CLASSIC_BUTTON_HOME) old_pad|=WPAD_BUTTON_HOME;
  929. }
  930. */
  931. if(new_pad & BUTTON_START) {goto sal_del_juego;}
  932. if((new_pad & BUTTON_SQUARE)) {pause_audio^=1;PauseAudio(pause_audio);}
  933. if(ACTMAP==0)
  934. {
  935. if((new_pad & BUTTON_CROSS)) {pausa=0;rings=500;screen_count0 = -128;} // empieza
  936. // ajusta bichos
  937. if(new_pad & (BUTTON_UP)) {nbichos--;if(nbichos<2) nbichos=2;copyMAP();}
  938. if(new_pad & (BUTTON_DOWN)) {nbichos++;if(nbichos>4) nbichos=4;copyMAP();}
  939. }
  940. // pausa
  941. if(new_pad & BUTTON_SELECT) pausa^=1;
  942. }
  943. time1=GetTicks();
  944. count20ms=(time1-oldtime)/20;
  945. //if(count20ms & 1) {
  946. /*if(PADEVENT==0)
  947. {
  948. PADEVENT=1;}
  949. // }
  950. */
  951. //if(pausa) count20ms=0;
  952. if(count20ms>8 || pausa)
  953. {
  954. oldtime=time1;
  955. if(!pausa) Move_Prota(old_pad);DrawMAP();DrawScreen();
  956. count20ms=0;
  957. }
  958. if(piok) break;
  959. }
  960. n=0;
  961. if(piok==0)
  962. { // rutina fin de pantalla
  963. message_scroll=1;
  964. set_sonido(127<<8,200,100,100,-1);mod_sound=0;
  965. //n=100;
  966. while(n<36)
  967. {
  968. time1=GetTicks();
  969. count20ms=(time1-oldtime)/20;
  970. if(count20ms>2)
  971. {
  972. oldtime=time1;
  973. n++;scrollMAP();
  974. count20ms=0;
  975. }
  976. DrawMAP();DrawScreen();
  977. }
  978. ACTMAP++;mod_sound=1;time4_sound=0;
  979. }
  980. else
  981. {
  982. Borra_Prota();
  983. mod_sound=0;
  984. while(n<26)
  985. {
  986. time1=GetTicks();
  987. count20ms=(time1-oldtime)/20;
  988. if(count20ms>2)
  989. {
  990. n++;set_sonido(127<<8,1900-300*n/26,50,0,1);
  991. oldtime=time1;
  992. map_screen[(piok>>5) & 31][piok & 31]&=127;
  993. if(((piok>>5) & 31)<21)
  994. {
  995. piok+=32;
  996. map_screen[(piok>>5) & 31][piok & 31]&=0xf8;
  997. map_screen[(piok>>5) & 31][piok & 31]|=130;
  998. }
  999. count20ms=0;
  1000. }
  1001. DrawMAP();DrawScreen();
  1002. }
  1003. mod_sound=1;time4_sound=0;
  1004. vidas--;
  1005. }
  1006. if(vidas<=0) break;
  1007. if(map_screen_rings[ACTMAP]==0) ACTMAP=1;
  1008. }while(map_screen_rings[ACTMAP]!=0);
  1009. }while(1);
  1010. sal_del_juego:
  1011. SND_StopVoice(1);
  1012. if(video) free(video); video=NULL;
  1013. //if(video_text) free(video_text); video_text=NULL;
  1014. return 0;
  1015. }