PageRenderTime 53ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/branches/IsengardDev/ironhells/src/main-lsl.c

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