You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

473 lines
9.1KB

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <unistd.h>
  4. #include <string.h>
  5. #include <sys/types.h>
  6. #include <netdb.h>
  7. #include <sys/socket.h>
  8. #include <sys/time.h>
  9. #include <signal.h>
  10. #include <fcntl.h>
  11. #include <stdarg.h>
  12. #include "bomber.h"
  13. #include "draw.h"
  14. #include "game.h"
  15. #include "gfx.h"
  16. #include "utils.h"
  17. #ifndef DATADIR
  18. #define DATADIR "data"
  19. #endif
  20. #define NUMCHARACTERS 50
  21. static figure font[NUMCHARACTERS];
  22. static figure bigfont[NUMCHARACTERS];
  23. gfxset gfxsets[NUMGFX];
  24. static char walkingname[256];
  25. static char colorsetname[256];
  26. static char backgroundname[256];
  27. static char blocksname[256];
  28. static char blocksxname[256];
  29. static char bombs1name[256];
  30. static char bombs2name[256];
  31. static char flamesname[256];
  32. static char tilesname[256];
  33. static char deathname[256];
  34. static char fontname[256];
  35. static char bigfontname[256];
  36. figure blocks[3];
  37. figure blocksx[9];
  38. figure bombs1[MAXSETS][NUMBOMBFRAMES];
  39. figure bombs2[MAXSETS][NUMBOMBFRAMES];
  40. figure flamefigs[MAXSETS][NUMFLAMEFRAMES];
  41. figure tiles[15];
  42. figure death[NUMDEATHFRAMES];
  43. int fontxsize,fontysize;
  44. int bigfontxsize,bigfontysize,bigfontyspace;
  45. static int textx,texty;
  46. static const unsigned char *remapstring = (const unsigned char*) "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ.:!?\177/\\*-,>< =";
  47. static char asciiremap[256];
  48. /* On screen array variables */
  49. int arraynumx=15;
  50. int arraynumy=11;
  51. int arraystartx=20;
  52. int arraystarty=70;
  53. int arrayspacex=40;
  54. int arrayspacey=36;
  55. static sprite sprites[MAXSPRITES];
  56. static int spritesused=0;
  57. #define IBUFFLEN 1024
  58. int ileft=0,ihand=0,byteswide;
  59. unsigned char ibuff[IBUFFLEN],*itake;
  60. static void freegfxset(gfxset *gs) {
  61. if(gs->gs_pic) free(gs->gs_pic);
  62. gs->gs_pic=0;
  63. }
  64. static int myci() {
  65. if (!ileft) {
  66. ileft=read(ihand,ibuff,IBUFFLEN);
  67. if(!ileft) return -1;
  68. itake=ibuff;
  69. }
  70. ileft--;
  71. return *itake++;
  72. }
  73. static int dopcxreal(char *name,gfxset *gs) {
  74. int xs,ys;
  75. int i,j,k;
  76. int totalsize;
  77. int width,height;
  78. unsigned char *bm,*lp;
  79. char tname[256];
  80. memset(gs,0,sizeof(gfxset));
  81. ileft=0;
  82. sprintf(tname,DATADIR "/%s",name);
  83. ihand=open(tname,O_RDONLY);
  84. if(ihand<0) {
  85. char tname2[256];
  86. sprintf(tname2,"%s.pcx",tname);
  87. ihand=open(tname2,O_RDONLY);
  88. if(ihand<0)
  89. return 1;
  90. }
  91. if(myci()!=10) {close(ihand);return 2;} // 10=zsoft .pcx
  92. if(myci()!=5) {close(ihand);return 3;} // version 3.0
  93. if(myci()!=1) {close(ihand);return 4;} //encoding method
  94. if(myci()!=8) {close(ihand);return 5;} //bpp
  95. xs=myci();
  96. xs|=myci()<<8;
  97. ys=myci();
  98. ys|=myci()<<8;
  99. width=myci();
  100. width|=myci()<<8;
  101. height=myci();
  102. height|=myci()<<8;
  103. width=width+1-xs;
  104. height=height+1-ys;
  105. for(i=0;i<48+4;++i) myci();
  106. myci();
  107. if(myci()!=1) {close(ihand);return 6;} // # of planes
  108. byteswide=myci();
  109. byteswide|=myci()<<8;
  110. i=myci();
  111. i|=myci()<<8;
  112. // if(i!=1) {close(ihand);return 7;} // 1=color/bw,2=grey
  113. for(i=0;i<58;++i) myci();
  114. totalsize=height*byteswide;
  115. bm=malloc(totalsize+1);
  116. if(!bm) {close(ihand);return 8;} // no memory
  117. gs->gs_pic=bm;
  118. gs->gs_xsize=width;
  119. gs->gs_ysize=height;
  120. while(height--) {
  121. lp=bm;
  122. i=byteswide;
  123. while(i>0) {
  124. j=myci();
  125. if(j<0xc0) {
  126. *lp++=j;
  127. --i;
  128. } else {
  129. j&=0x3f;
  130. k=myci();
  131. while(j-- && i) {
  132. *lp++=k;
  133. --i;
  134. }
  135. }
  136. }
  137. bm+=width;
  138. }
  139. lseek(ihand,-0x300,SEEK_END);
  140. read(ihand,gs->gs_colormap,0x300);
  141. close(ihand);
  142. return 0;
  143. }
  144. static int dopcx(char *name,gfxset *gs) {
  145. int err;
  146. err=dopcxreal(name,gs);
  147. if(err)
  148. printf("Error loading \"%s\":code %d\n",name,err);
  149. return err;
  150. }
  151. static void getgroup(char *name,gfxset *colorgs,figure *fig,int count) {
  152. int err;
  153. int i;
  154. gfxset gs;
  155. err=dopcx(name,&gs);
  156. if(err) exit(1000+err);
  157. createinout(&gs);
  158. for(i=0;i<MAXSETS;++i,fig+=count,++colorgs) {
  159. if(!colorgs->gs_pic) continue;
  160. memmove(gs.gs_colormap,colorgs->gs_colormap,
  161. sizeof(gs.gs_colormap));
  162. createinout(&gs);
  163. gfxfetch(&gs,fig,count);
  164. }
  165. freegfxset(&gs);
  166. }
  167. static void getsingle(char *name,figure *fig,int count) {
  168. gfxset gs;
  169. int err;
  170. err=dopcx(name,&gs);
  171. if(err) exit(1000+err);
  172. createinout(&gs);
  173. gfxfetch(&gs,fig,count);
  174. freegfxset(&gs);
  175. }
  176. static void texthome(void) {
  177. textx=texty=10;
  178. }
  179. void drawstring(int xpos, int ypos, const char *str) {
  180. char ch;
  181. while((ch=*str++)) {
  182. drawfigure(xpos,ypos,font+asciiremap[toupper(ch)]);
  183. xpos+=fontxsize;
  184. }
  185. }
  186. void drawbigstring(int xpos, int ypos, const char *str) {
  187. char ch;
  188. while('\0' != (ch=*str++)) {
  189. drawfigure(xpos,ypos,bigfont+asciiremap[toupper(ch)]);
  190. xpos+=bigfontxsize;
  191. }
  192. }
  193. void centerbig(int y, const char *str) {
  194. int w;
  195. w=strlen(str)*bigfontxsize;
  196. drawbigstring((IXSIZE-w)>>1,y,str);
  197. }
  198. // static void scrprintf(char *str,...) {
  199. // char output[256],*p,*p2;
  200. // va_list ap;
  201. //
  202. // va_start(ap, str);
  203. //
  204. // vsprintf(output,str,ap);
  205. // p=output;
  206. // for(;;) {
  207. // p2=p;
  208. // while(*p2 && *p2!='\n') ++p2;
  209. // if(*p2) {
  210. // *p2=0;
  211. // drawstring(textx,texty,p);
  212. // texty+=fontysize;
  213. // textx=10;
  214. // p=p2+1;
  215. // } else {
  216. // drawstring(textx,texty,p);
  217. // textx+=fontxsize*(p2-p);
  218. // break;
  219. // }
  220. // }
  221. // copyup();
  222. // }
  223. static void bigscrprintf(char *str,...) {
  224. char output[256],*p,*p2;
  225. va_list ap;
  226. va_start(ap, str);
  227. vsprintf(output,str,ap);
  228. p=output;
  229. for(;;) {
  230. p2=p;
  231. while(*p2 && *p2!='\n') ++p2;
  232. if(*p2) {
  233. *p2=0;
  234. drawbigstring(textx,texty,p);
  235. texty+=bigfontysize;
  236. textx=10;
  237. p=p2+1;
  238. } else {
  239. drawbigstring(textx,texty,p);
  240. textx+=bigfontxsize*(p2-p);
  241. break;
  242. }
  243. }
  244. copyup();
  245. }
  246. void addsprite(int x,int y,figure *fig) {
  247. sprite *sp;
  248. if(spritesused==MAXSPRITES) return;
  249. sp=sprites+spritesused++;
  250. sp->flags=0;
  251. sp->xpos=x;
  252. sp->ypos=y;
  253. sp->fig=fig;
  254. }
  255. void plotsprites(void) {
  256. int i;
  257. sprite *sp;
  258. sp=sprites;
  259. for(i=0;i<spritesused;++i) {
  260. drawfigure(sp->xpos,sp->ypos,sp->fig);
  261. ++sp;
  262. }
  263. }
  264. void erasesprites(void) {
  265. int i;
  266. sprite *sp;
  267. figure *fig;
  268. sp=sprites;
  269. for(i=0;i<spritesused;++i) {
  270. fig=sp->fig;
  271. solidcopy(&background,
  272. sp->xpos+fig->xdelta,sp->ypos+fig->ydelta,
  273. fig->xsize,fig->ysize);
  274. ++sp;
  275. }
  276. }
  277. void clearsprites(void) {
  278. int i;
  279. sprite *sp;
  280. figure *fig;
  281. sp=sprites;
  282. for(i=0;i<spritesused;++i) {
  283. fig=sp->fig;
  284. clearrect(sp->xpos+fig->xdelta,sp->ypos+fig->ydelta,
  285. fig->xsize,fig->ysize);
  286. ++sp;
  287. }
  288. }
  289. void clearspritelist(void) {
  290. spritesused=0;
  291. }
  292. int tovideox(int x) {
  293. return (x>>FRACTION)+arraystartx;
  294. }
  295. int tovideoy(int y) {
  296. return (y>>FRACTION)+arraystarty;
  297. }
  298. int screentoarrayx(int x) {
  299. x+=arrayspacex << (FRACTION+2);
  300. return ((x>>FRACTION)+(arrayspacex>>1))/arrayspacex-4;
  301. }
  302. int screentoarrayy(int y) {
  303. y+=arrayspacey << (FRACTION+2);
  304. return ((y>>FRACTION)+(arrayspacey>>1))/arrayspacey-4;
  305. }
  306. int arraytoscreenx(int x) {
  307. return arrayspacex*x<<FRACTION;
  308. }
  309. int arraytoscreeny(int y) {
  310. return arrayspacey*y<<FRACTION;
  311. }
  312. static void loadfonts(void) {
  313. int i,j;
  314. const unsigned char *p;
  315. getsingle(fontname,font,NUMCHARACTERS);
  316. getsingle(bigfontname,bigfont,NUMCHARACTERS);
  317. fontxsize=8;
  318. fontysize=12;
  319. bigfontxsize=16;
  320. bigfontysize=24;
  321. bigfontyspace=32;
  322. p=remapstring;
  323. j=0;while(*p && *p!=' ') ++p,++j;
  324. memset(asciiremap,j,sizeof(asciiremap));
  325. p=remapstring;
  326. i=0;
  327. while(*p && i<NUMCHARACTERS)
  328. asciiremap[(int)*p++]=i++;
  329. }
  330. void loadgfx() {
  331. gfxset *gs;
  332. gfxset *colorgs;
  333. int err;
  334. int i;
  335. char name[256];
  336. strcpy(walkingname,"walk");
  337. strcpy(colorsetname,"pal");
  338. strcpy(backgroundname,"field0");
  339. strcpy(blocksname,"blocks3");
  340. strcpy(blocksxname,"blocks3x");
  341. strcpy(bombs1name,"bomb1");
  342. strcpy(bombs2name,"bomb2");
  343. strcpy(flamesname,"flames");
  344. strcpy(tilesname,"tiles");
  345. strcpy(deathname,"death1");
  346. strcpy(fontname,"font");
  347. strcpy(bigfontname,"bigfont");
  348. gs=malloc((MAXSETS+1)*sizeof(gfxset));
  349. if(!gs)
  350. nomem("loadgfx");
  351. colorgs=gs+1;
  352. for(i=0;i<MAXSETS;++i) {
  353. sprintf(name,"%s%d",colorsetname,i);
  354. err=dopcx(name,colorgs+i);
  355. if(err) continue;
  356. }
  357. loadfonts();
  358. texthome();
  359. bigscrprintf("Loading graphics...\n");
  360. err=dopcx(backgroundname,gs);
  361. if(err) exit(1000+err);
  362. createinout(gs);
  363. solidfetch(gs,&background);
  364. solidfetch(gs,&backgroundoriginal);
  365. freegfxset(gs);
  366. bigscrprintf("Loading blocks\n");
  367. getsingle(blocksname,blocks,3);
  368. bigscrprintf("Loading block explosions\n");
  369. getsingle(blocksxname,blocksx,9);
  370. bigscrprintf("Loading walking figures\n");
  371. getgroup(walkingname,colorgs,walking[0],NUMWALKFRAMES);
  372. bigscrprintf("Loading normal bombs\n");
  373. getgroup(bombs1name,colorgs,bombs1[0],NUMBOMBFRAMES);
  374. bigscrprintf("Loading controlled bombs\n");
  375. getgroup(bombs2name,colorgs,bombs2[0],NUMBOMBFRAMES);
  376. bigscrprintf("Loading flames\n");
  377. // getgroup(flamesname,colorgs,flamefigs[0],NUMFLAMEFRAMES);
  378. getsingle(flamesname,flamefigs[0],NUMFLAMEFRAMES);
  379. bigscrprintf("Loading bonus tiles\n");
  380. getsingle(tilesname,tiles,15);
  381. bigscrprintf("Loading death sequence\n");
  382. getsingle(deathname,death,NUMDEATHFRAMES);
  383. for(i=0;i<MAXSETS;++i)
  384. freegfxset(colorgs+i);
  385. free(gs);
  386. bigscrprintf("Done loading graphics\n");
  387. }
  388. void failure(char *str,...) {
  389. char output[256];
  390. va_list ap;
  391. int len;
  392. long now;
  393. va_start(ap, str);
  394. len = vsnprintf(output, sizeof(output), str, ap);
  395. if (len >= 256) len = 255; /* truncated string */
  396. clear();
  397. drawbigstring((IXSIZE - len*bigfontxsize) / 2, (IYSIZE-bigfontysize) / 2, output);
  398. copyup();
  399. now = longtime();
  400. while (!exitflag && longtime()-now < 3) {
  401. scaninput();
  402. if (anydown()) {
  403. takedown();
  404. return;
  405. }
  406. }
  407. }