PageRenderTime 43ms CodeModel.GetById 11ms RepoModel.GetById 0ms app.codeStats 1ms

/branches/IsengardDev/IronHells/src/client/angband/main-lsl.c

#
C | 783 lines | 529 code | 143 blank | 111 comment | 79 complexity | 0e50968d7f0dd47cffc1be84b07d68dd MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.0, Apache-2.0
  1. /*****************************************************************************
  2. * File: main-lsl.c
  3. * Purpose: Support for Linux-SVGALIB Angband
  4. * Original Author: Jon Taylor (taylorj@gaia.ecs.csus.edu)
  5. * Update by: Dennis Payne (dulsi@identicalsoftware.com)
  6. * Version: 1.4.0, 12/05/99
  7. *
  8. * Some of the ideas in this code came from main-win.c by Skirmantas Kligys
  9. * (kligys@scf.usc.edu).
  10. ****************************************************************************/
  11. /* Angband header files */
  12. #include "angband.h"
  13. #ifdef USE_LSL
  14. #include "main.h"
  15. /* Standard C header files */
  16. #include <stdio.h>
  17. #include <stdlib.h>
  18. /* SVGAlib header files */
  19. #include <vga.h>
  20. #include <vgagl.h>
  21. #include <vgakeyboard.h>
  22. #include <zlib.h>
  23. static cptr ANGBAND_DIR_XTRA_GRAF;
  24. #define COLOR_OFFSET 240
  25. /* Define font/graphics cell width and height */
  26. #define CHAR_W 8
  27. #define CHAR_H 13
  28. /*****************************************************************************
  29. * .BMP file handling stuff. This needs to get reorganized someday....
  30. ****************************************************************************/
  31. /* BITMAPFILEHEADER
  32. *
  33. * Bitmap File Information
  34. *
  35. * The BITMAPFILEHEADER data structure contains information about the type,
  36. * size, and layout of a device-independent bitmap (DIB) file.
  37. */
  38. typedef struct BITMAPFILEHEADER {
  39. short bfType;
  40. int bfSize;
  41. short bfReserved1;
  42. short bfReserved2;
  43. int bfOffBits;
  44. } BITMAPFILEHEADER;
  45. typedef struct BITMAPINFOHEADER {
  46. unsigned int biSize;
  47. unsigned int biWidth;
  48. unsigned int biHeight;
  49. unsigned short biPlanes;
  50. unsigned short biBitCount;
  51. unsigned int biCompression;
  52. unsigned int biSizeImage;
  53. unsigned int biXPelsPerMeter;
  54. unsigned int biYPelsPerMeter;
  55. unsigned int biClrUsed;
  56. unsigned int biClrImportant;
  57. } BITMAPINFOHEADER;
  58. typedef struct BITMAPCOREHEADER {
  59. unsigned int bcSize;
  60. unsigned short bcWidth;
  61. unsigned short bcHeight;
  62. unsigned short bcPlanes;
  63. unsigned short bcBitCount;
  64. } BITMAPCOREHEADER;
  65. typedef struct {
  66. int width,height,bpp,numcols;
  67. char type[4];
  68. } PICINFO;
  69. static int flip(unsigned char *image, unsigned int w, unsigned int h);
  70. /*
  71. * Image palette, width, and height should be arguments but quickly hacked
  72. * in - Dennis */
  73. static unsigned char *pal;
  74. static unsigned int bw, bh;
  75. void *read_bmp_file(void)
  76. {
  77. FILE *infile;
  78. int i, j;
  79. int iswindows = 0;
  80. int dummy, count, done;
  81. int output_type = 0;
  82. unsigned char *buf, *bmap;
  83. unsigned char read[2];
  84. unsigned char *p, *ptr, *dptr, *hptr;
  85. unsigned int w, h, palsize;
  86. char path[255];
  87. BITMAPINFOHEADER bih;
  88. BITMAPCOREHEADER bch;
  89. PICINFO *pp;
  90. pp = malloc(sizeof(PICINFO));
  91. bmap = NULL;
  92. pal = NULL;
  93. strnfmt(path, sizeof(path), "%s/8x13.bmp", ANGBAND_DIR_XTRA_GRAF);
  94. if (!(infile = fopen(path, "r")))
  95. {
  96. printf("Unable to load bitmap data file %s, bailing out....\n", path);
  97. exit(-1);
  98. }
  99. buf = (unsigned char *)malloc(54);
  100. fread(buf, 1, 26, infile);
  101. memcpy(&bch, buf + 14, 12);
  102. /* Truly MS_Windows 3.x ? */
  103. if (bch.bcSize == 40)
  104. {
  105. fread(buf + 26, 1, 28, infile); /* Then we need the rest */
  106. memcpy(&bih, buf + 14, 40);
  107. iswindows = TRUE;
  108. }
  109. else
  110. {
  111. iswindows = FALSE;
  112. }
  113. p = malloc(768);
  114. pal = p;
  115. if (iswindows)
  116. {
  117. /* MS_Windows 3.x */
  118. pp->width = w = bih.biWidth;
  119. pp->height = h = bih.biHeight;
  120. pp->bpp = bih.biBitCount;
  121. /*
  122. * Here the "offbits" - we need 'em for the
  123. * palette size - e.g. XV uses different sizes
  124. */
  125. palsize = (*(unsigned *) (buf + 10) - 54) / 4;
  126. }
  127. else
  128. {
  129. /* OS/2 V1.1 */
  130. pp->width = w = bch.bcWidth;
  131. pp->height = h = bch.bcHeight;
  132. pp->bpp = bch.bcBitCount;
  133. palsize = (*(unsigned *) (buf + 10) - 26) / 3;
  134. }
  135. bw = pp->width;
  136. bh = pp->height;
  137. if ((pp->bpp >> 3) < 3) output_type = 1;
  138. /* w is the size of a horizontal line in bytes
  139. * bih.biWidth is the number of valid pixels in a line
  140. * the latter one is passed to vgadisp.c as pp->width
  141. */
  142. switch (pp->bpp)
  143. {
  144. case 1:
  145. if (w % 32)
  146. w = (w / 32) * 32 + 32;
  147. break;
  148. case 4:
  149. if (w % 8)
  150. w = (w / 8) * 8 + 8;
  151. break;
  152. case 8:
  153. if (w % 4)
  154. w = (w / 4) * 4 + 4;
  155. break;
  156. }
  157. if ((pp->bpp == 24) && (output_type == 3)) dummy = 3;
  158. else dummy = 1;
  159. bmap = malloc(w * (h + 2) * dummy);
  160. memset(bmap, 0, w * (h + 2) * dummy);
  161. switch (pp->bpp)
  162. {
  163. case 1:
  164. /* 1bit non compressed */
  165. ptr = pal;
  166. fread(ptr, 1, 3, infile);
  167. if (iswindows)
  168. fread(&dummy, 1, 1, infile);
  169. dummy = ptr[0];
  170. ptr[0] = ptr[2] / 4;
  171. ptr[1] /= 4;
  172. ptr[2] = dummy / 4;
  173. fread(ptr + 3, 1, 3, infile);
  174. if (iswindows)
  175. fread(&dummy, 1, 1, infile);
  176. dummy = ptr[3];
  177. ptr[3] = ptr[5] / 4;
  178. ptr[4] /= 4;
  179. ptr[5] = dummy / 4;
  180. ptr = bmap;
  181. for (j = h - 1; j >= 0; j--)
  182. {
  183. for (i = 0, count = 0 ; i < (w >> 3); i++)
  184. {
  185. hptr = ptr + j * pp->width;
  186. dummy = fgetc(infile);
  187. if (count < pp->width)
  188. {
  189. hptr[count] = (dummy & 128) ? 1 : 0; count++;
  190. hptr[count] = (dummy & 64) ? 1 : 0; count++;
  191. hptr[count] = (dummy & 32) ? 1 : 0; count++;
  192. hptr[count] = (dummy & 16) ? 1 : 0; count++;
  193. hptr[count] = (dummy & 8) ? 1 : 0; count++;
  194. hptr[count] = (dummy & 4) ? 1 : 0; count++;
  195. hptr[count] = (dummy & 2) ? 1 : 0; count++;
  196. hptr[count] = dummy & 1; count++;
  197. }
  198. }
  199. }
  200. pp->numcols = 2;
  201. break;
  202. case 4:
  203. /* 4bit non compressed */
  204. ptr = pal;
  205. for (i = 0; i < palsize; i++)
  206. {
  207. fread(ptr + 3 * i, 1, 3, infile);
  208. if (iswindows)
  209. fread(&dummy, 1, 1, infile);
  210. dummy = ptr[3 * i];
  211. ptr[3 * i] = ptr[3 * i + 2] / 4;
  212. ptr[3 * i + 1] /= 4;
  213. ptr[3 * i + 2] = dummy / 4;
  214. }
  215. ptr = bmap;
  216. if ((!iswindows) || (bih.biCompression == 0))
  217. {
  218. for (j = h - 1; j >= 0; j--)
  219. {
  220. for (i = 0, count = 0; i < (w / 2); i++)
  221. {
  222. dummy = fgetc(infile);
  223. if (count < pp->width)
  224. {
  225. ptr[count + j * pp->width] = dummy >> 4;
  226. count++;
  227. }
  228. if (count < pp->width)
  229. {
  230. ptr[count + j * pp->width] = dummy & 15;
  231. count++;
  232. }
  233. }
  234. }
  235. }
  236. else
  237. {
  238. /* 4bit RLE compressed */
  239. done = 0;
  240. count = 0;
  241. while (done == 0)
  242. {
  243. fread(read, 1, 2, infile);
  244. if (*read)
  245. {
  246. i = 0;
  247. do
  248. {
  249. *ptr = read[1] >> 4;
  250. ptr++;
  251. i++;
  252. if (i < (read[0]))
  253. {
  254. *ptr = read[1] & 15;
  255. ptr++;
  256. i++;
  257. }
  258. }
  259. while (i < (*read));
  260. }
  261. else if (read[1] == 0)
  262. {
  263. count++;
  264. }
  265. else if (read[1] == 1)
  266. done = 1;
  267. else if (read[1] == 2)
  268. {
  269. /* This isn't really tested */
  270. ptr += fgetc(infile) + bih.biWidth * fgetc(infile);
  271. }
  272. else
  273. {
  274. dptr = hptr = (unsigned char *) malloc(read[1] >> 1);
  275. fread(dptr, 1, read[1] >> 1, infile);
  276. if (read[1] % 4 > 1)
  277. dummy = fgetc(infile);
  278. i = 0;
  279. do
  280. {
  281. *ptr = (*dptr) >> 4;
  282. i++;
  283. ptr++;
  284. if (i < read[1])
  285. {
  286. *ptr = (*dptr) & 15;
  287. i++;
  288. ptr++;
  289. }
  290. dptr++;
  291. }
  292. while (i < read[1]);
  293. free(hptr);
  294. }
  295. }
  296. flip(bmap, bih.biWidth, bih.biHeight);
  297. }
  298. pp->width = w;
  299. pp->numcols= 16;
  300. break;
  301. case 8:
  302. /* 8bit non compressed */
  303. ptr = pal;
  304. for (i = 0; i < palsize; i++)
  305. {
  306. fread(ptr + 3 * i, 1, 3, infile);
  307. if (iswindows)
  308. dummy = fgetc(infile);
  309. dummy = ptr[3 * i];
  310. ptr[3 * i] = ptr[3 * i + 2] / 4;
  311. ptr[3 * i + 1] /= 4;
  312. ptr[3 * i + 2] = dummy / 4;
  313. }
  314. ptr = bmap;
  315. if ((!iswindows) || (bih.biCompression == 0))
  316. {
  317. for (i = h - 1; i >= 0; i--)
  318. {
  319. fread(ptr + pp->width * i, 1, w, infile);
  320. }
  321. }
  322. else
  323. {
  324. /* 8bit RLE compressed */
  325. done = 0;
  326. count = 0;
  327. while (done == 0)
  328. {
  329. fread(read, 1, 2, infile);
  330. if (read[0])
  331. {
  332. for (i = 0; i < (int)read[0]; i++)
  333. {
  334. *ptr = read[1];
  335. ptr++;
  336. }
  337. }
  338. else if (read[1] == 0)
  339. {
  340. count++;
  341. }
  342. else if (read[1] == 1)
  343. done = 1;
  344. else if (read[1] == 2)
  345. ptr += fgetc(infile) + bih.biWidth * fgetc(infile);
  346. else
  347. {
  348. fread(ptr, 1, read[1], infile);
  349. if (read[1] % 2)
  350. fgetc(infile);
  351. ptr += read[1];
  352. }
  353. }
  354. flip(bmap, bih.biWidth, bih.biHeight);
  355. }
  356. pp->numcols = 256;
  357. break;
  358. }
  359. free(buf);
  360. fclose(infile);
  361. return (bmap);
  362. }
  363. static int flip(unsigned char *image, unsigned int w, unsigned int h)
  364. {
  365. unsigned int i;
  366. unsigned char *hptr;
  367. hptr = (unsigned char *)malloc(w);
  368. for (i = 0; i < (h / 2); i++)
  369. {
  370. memcpy(hptr, image + i * w, w);
  371. memcpy(image + i * w, image + (h - i - 1) * w, w);
  372. memcpy(image + (h - i - 1) * w, hptr, w);
  373. }
  374. free(hptr);
  375. return (0);
  376. }
  377. /* ======================================================================= */
  378. /* The main "term" structure */
  379. static term term_screen_body;
  380. /* The visible and virtual screens */
  381. GraphicsContext *screen;
  382. GraphicsContext *backscreen;
  383. GraphicsContext *buffer;
  384. /* The font data */
  385. void *font;
  386. /* Initialize the screen font */
  387. void initfont(void)
  388. {
  389. gzFile fontfile;
  390. void *temp;
  391. long junk;
  392. if (!(fontfile = gzopen("/usr/lib/kbd/consolefonts/lat1-12.psfu.gz", "r")))
  393. {
  394. /* Try uncompressed */
  395. if (!(fontfile = gzopen("/usr/lib/kbd/consolefonts/lat1-12.psfu", "r")))
  396. {
  397. printf("Error: could not open font file. Aborting....\n");
  398. exit(1);
  399. }
  400. }
  401. /* Junk the 4-byte header */
  402. gzread(fontfile, &junk, 4);
  403. /* Initialize font */
  404. /* Haven't looked into why it is 3328 - Dennis */
  405. temp = malloc(/*12*256*/ 3328);
  406. gzread(fontfile, temp, 3328);
  407. font = malloc(256 * 8 * 12 * BYTESPERPIXEL);
  408. gl_expandfont(8, 12, 15, temp, font);
  409. gl_setfont(8, 12, font);
  410. free(temp);
  411. gzclose(fontfile);
  412. }
  413. /* Initialize palette values for colors 0-15 */
  414. void setpal(void)
  415. {
  416. int i;
  417. gl_setpalette(pal);
  418. for (i = 0; i < 16; i++)
  419. {
  420. gl_setpalettecolor(COLOR_OFFSET + i, angband_color_table[i][1] >> 2,
  421. angband_color_table[i][2] >> 2, angband_color_table[i][3] >> 2);
  422. }
  423. #if 0
  424. gl_setpalettecolor (0,00,00,00); /* Black */
  425. gl_setpalettecolor (3,63,63,63); /* White */
  426. gl_setpalettecolor (13,40,40,40); /* Gray */
  427. gl_setpalettecolor (11,25,15,05); /* Orange */
  428. gl_setpalettecolor (2,32,00,00); /* Red */
  429. gl_setpalettecolor (7,00,32,00); /* Green */
  430. gl_setpalettecolor (12,00,00,40); /* Blue */
  431. gl_setpalettecolor (5,50,25,00); /* Brown */
  432. gl_setpalettecolor (1,28,28,28); /* Dark Gray */
  433. gl_setpalettecolor (10,52,52,52); /* Light Gray */
  434. gl_setpalettecolor (15,41,00,63); /* Purple */
  435. gl_setpalettecolor (4,63,63,00); /* Yellow */
  436. gl_setpalettecolor (14,63,00,00); /* Light Red */
  437. gl_setpalettecolor (6,00,63,00); /* Light Green */
  438. gl_setpalettecolor (9,00,50,63); /* Light Blue */
  439. gl_setpalettecolor (8,63,52,32); /* Light Brown */
  440. #endif /* 0 */
  441. }
  442. /****************************************************************************
  443. * Check for "events"
  444. * If block, then busy-loop waiting for event, else check once and exit
  445. ***************************************************************************/
  446. static errr CheckEvents(int block)
  447. {
  448. int k = 0;
  449. if (block)
  450. {
  451. k = vga_getkey();
  452. if (k < 1) return (1);
  453. }
  454. else
  455. k = vga_getch();
  456. Term_keypress(k);
  457. return (0);
  458. }
  459. /****************************************************************************
  460. * Low-level graphics routine (assumes valid input)
  461. * Do a "special thing"
  462. ***************************************************************************/
  463. static errr term_xtra_svgalib(int n, int v)
  464. {
  465. switch (n)
  466. {
  467. case TERM_XTRA_EVENT:
  468. {
  469. /* Process some pending events */
  470. if (v) return (CheckEvents(FALSE));
  471. while (!CheckEvents(TRUE));
  472. return 0;
  473. }
  474. case TERM_XTRA_FLUSH:
  475. {
  476. /* Flush all pending events */
  477. /* Should discard all key presses but unimplemented */
  478. return 0;
  479. }
  480. case TERM_XTRA_CLEAR:
  481. {
  482. /* Clear the entire window */
  483. gl_fillbox(0, 0, 80 * CHAR_W, 25 * CHAR_H, 0);
  484. return 0;
  485. }
  486. case TERM_XTRA_DELAY:
  487. {
  488. /* Delay for some milliseconds */
  489. usleep(1000 * v);
  490. return 0;
  491. }
  492. }
  493. return 1;
  494. }
  495. /****************************************************************************
  496. * Low-level graphics routine (assumes valid input)
  497. * Draws a "cursor" at (x,y)
  498. ***************************************************************************/
  499. static errr term_curs_svgalib(int x, int y)
  500. {
  501. gl_fillbox(x * CHAR_W, y * CHAR_H, CHAR_W, CHAR_H, 15);
  502. return (0);
  503. }
  504. /****************************************************************************
  505. * Low-level graphics routine (assumes valid input)
  506. * Erases a rectangular block of characters from (x,y) to (x+w,y+h)
  507. ***************************************************************************/
  508. static errr term_wipe_svgalib(int x,int y,int n)
  509. {
  510. gl_fillbox(x * CHAR_W, y * CHAR_H, n * CHAR_W, CHAR_H, 0);
  511. return (0);
  512. }
  513. /****************************************************************************
  514. * Low-level graphics routine (assumes valid input)
  515. * Draw n chars at location (x,y) with value s and attribute a
  516. ***************************************************************************/
  517. errr term_text_svgalib(int x, int y, int n, unsigned char a, cptr s)
  518. {
  519. term_wipe_svgalib(x, y, n);
  520. gl_colorfont(8, 12, COLOR_OFFSET + (a & 0x0F)/*pal_trans[a]*/, font);
  521. gl_writen(x * CHAR_W, y * CHAR_H, n, (char *)s);
  522. return (0);
  523. }
  524. /****************************************************************************
  525. * Low-level graphics routine (assumes valid input)
  526. * Draw n chars at location (x,y) with value s and attribute a
  527. ***************************************************************************/
  528. errr term_pict_svgalib(int x, int y, int n, const byte *ap, const char *cp,
  529. const byte *tap, const char *tcp)
  530. {
  531. int i;
  532. int x2, y2;
  533. /* Unused parameters */
  534. (void)tap;
  535. (void)tcp;
  536. for (i = 0; i < n; i++)
  537. {
  538. x2 = (cp[i] & 0x1F) * CHAR_W;
  539. y2 = (ap[i] & 0x1F) * CHAR_H;
  540. gl_copyboxfromcontext(buffer, x2, y2, CHAR_W,
  541. CHAR_H, (x + i) * CHAR_W, y * CHAR_H);
  542. }
  543. return (0);
  544. }
  545. void term_load_bitmap(void)
  546. {
  547. void *temp;
  548. temp = read_bmp_file();
  549. /* Blit bitmap into buffer */
  550. gl_putbox(0, 0, bw, bh, temp);
  551. free(temp);
  552. return;
  553. }
  554. /****************************************************************************
  555. * Term hook
  556. * Initialize a new term
  557. ***************************************************************************/
  558. static void term_init_svgalib(term *t)
  559. {
  560. int VGAMODE, VIRTUAL;
  561. /* Hardwire this mode in for now */
  562. VGAMODE = G1024x768x256;
  563. VIRTUAL = 1;
  564. vga_init();
  565. /* Set up the bitmap buffer context */
  566. gl_setcontextvgavirtual(VGAMODE);
  567. buffer = gl_allocatecontext();
  568. gl_getcontext(buffer);
  569. /* Load bitmap into virtual screen */
  570. term_load_bitmap();
  571. /* Hardwire this mode in for now */
  572. VGAMODE = G640x480x256;
  573. /* Set up the physical screen context */
  574. if (vga_setmode(VGAMODE) < 0)
  575. {
  576. printf("Mode not available\n");
  577. exit(0);
  578. }
  579. gl_setcontextvga(VGAMODE);
  580. screen = gl_allocatecontext();
  581. gl_getcontext(screen);
  582. gl_enablepageflipping(screen);
  583. /* Set up palette colors */
  584. setpal();
  585. /* Load the character font data */
  586. initfont();
  587. /* Color 0 isn't transparent */
  588. gl_setwritemode(WRITEMODE_OVERWRITE);
  589. }
  590. /****************************************************************************
  591. * Term hook
  592. * Nuke an old term
  593. ***************************************************************************/
  594. static void term_nuke_svgalib(term *t)
  595. {
  596. vga_setmode(TEXT);
  597. }
  598. const char help_lsl[] = "SVGA (low level graphics) library";
  599. /****************************************************************************
  600. * Hook SVGAlib routines into term.c
  601. ***************************************************************************/
  602. errr init_lsl(int argc, char **argv)
  603. {
  604. char path[1024];
  605. term *t = &term_screen_body;
  606. /* Unused parameters */
  607. (void)argc;
  608. (void)argv;
  609. if (arg_graphics)
  610. {
  611. use_graphics = TRUE;
  612. }
  613. /* Build the "graf" path */
  614. path_build(path, sizeof(path), ANGBAND_DIR_XTRA, "graf");
  615. /* Allocate the path */
  616. ANGBAND_DIR_XTRA_GRAF = string_make(path);
  617. /* Initialize the term */
  618. term_init(t, 80, 24, 1024);
  619. /* The cursor is done via software and needs erasing */
  620. t->soft_cursor = TRUE;
  621. t->attr_blank = TERM_DARK;
  622. t->char_blank = ' ';
  623. /* Add hooks */
  624. t->init_hook = term_init_svgalib;
  625. t->nuke_hook = term_nuke_svgalib;
  626. t->text_hook = term_text_svgalib;
  627. if (use_graphics)
  628. {
  629. t->pict_hook = term_pict_svgalib;
  630. t->higher_pict = TRUE;
  631. }
  632. t->wipe_hook = term_wipe_svgalib;
  633. t->curs_hook = term_curs_svgalib;
  634. t->xtra_hook = term_xtra_svgalib;
  635. /* Save the term */
  636. term_screen = t;
  637. Term_activate(term_screen);
  638. return (0);
  639. }
  640. #endif /* USE_LSL */