/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
- /*****************************************************************************
- * File: main-lsl.c
- * Purpose: Support for Linux-SVGALIB Angband
- * Original Author: Jon Taylor (taylorj@gaia.ecs.csus.edu)
- * Update by: Dennis Payne (dulsi@identicalsoftware.com)
- * Version: 1.4.0, 12/05/99
- *
- * Some of the ideas in this code came from main-win.c by Skirmantas Kligys
- * (kligys@scf.usc.edu).
- ****************************************************************************/
- /* Angband header files */
- #include "angband.h"
- #ifdef USE_LSL
- #include "main.h"
- /* Standard C header files */
- #include <stdio.h>
- #include <stdlib.h>
- /* SVGAlib header files */
- #include <vga.h>
- #include <vgagl.h>
- #include <vgakeyboard.h>
- #include <zlib.h>
- static cptr ANGBAND_DIR_XTRA_GRAF;
- #define COLOR_OFFSET 240
- /* Define font/graphics cell width and height */
- #define CHAR_W 8
- #define CHAR_H 13
- /*****************************************************************************
- * .BMP file handling stuff. This needs to get reorganized someday....
- ****************************************************************************/
- /* BITMAPFILEHEADER
- *
- * Bitmap File Information
- *
- * The BITMAPFILEHEADER data structure contains information about the type,
- * size, and layout of a device-independent bitmap (DIB) file.
- */
- typedef struct BITMAPFILEHEADER {
- short bfType;
- int bfSize;
- short bfReserved1;
- short bfReserved2;
- int bfOffBits;
- } BITMAPFILEHEADER;
- typedef struct BITMAPINFOHEADER {
- unsigned int biSize;
- unsigned int biWidth;
- unsigned int biHeight;
- unsigned short biPlanes;
- unsigned short biBitCount;
- unsigned int biCompression;
- unsigned int biSizeImage;
- unsigned int biXPelsPerMeter;
- unsigned int biYPelsPerMeter;
- unsigned int biClrUsed;
- unsigned int biClrImportant;
- } BITMAPINFOHEADER;
- typedef struct BITMAPCOREHEADER {
- unsigned int bcSize;
- unsigned short bcWidth;
- unsigned short bcHeight;
- unsigned short bcPlanes;
- unsigned short bcBitCount;
- } BITMAPCOREHEADER;
- typedef struct {
- int width,height,bpp,numcols;
- char type[4];
- } PICINFO;
- static int flip(unsigned char *image, unsigned int w, unsigned int h);
- /*
- * Image palette, width, and height should be arguments but quickly hacked
- * in - Dennis */
- static unsigned char *pal;
- static unsigned int bw, bh;
- void *read_bmp_file(void)
- {
- FILE *infile;
- int i, j;
- int iswindows = 0;
- int dummy, count, done;
- int output_type = 0;
- unsigned char *buf, *bmap;
- unsigned char read[2];
- unsigned char *p, *ptr, *dptr, *hptr;
- unsigned int w, h, palsize;
- char path[255];
- BITMAPINFOHEADER bih;
- BITMAPCOREHEADER bch;
- PICINFO *pp;
- pp = malloc(sizeof(PICINFO));
- bmap = NULL;
- pal = NULL;
- strnfmt(path, sizeof(path), "%s/8x13.bmp", ANGBAND_DIR_XTRA_GRAF);
- if (!(infile = fopen(path, "r")))
- {
- printf("Unable to load bitmap data file %s, bailing out....\n", path);
- exit(-1);
- }
- buf = (unsigned char *)malloc(54);
- fread(buf, 1, 26, infile);
- memcpy(&bch, buf + 14, 12);
- /* Truly MS_Windows 3.x ? */
- if (bch.bcSize == 40)
- {
- fread(buf + 26, 1, 28, infile); /* Then we need the rest */
- memcpy(&bih, buf + 14, 40);
- iswindows = TRUE;
- }
- else
- {
- iswindows = FALSE;
- }
- p = malloc(768);
- pal = p;
- if (iswindows)
- {
- /* MS_Windows 3.x */
- pp->width = w = bih.biWidth;
- pp->height = h = bih.biHeight;
- pp->bpp = bih.biBitCount;
- /*
- * Here the "offbits" - we need 'em for the
- * palette size - e.g. XV uses different sizes
- */
- palsize = (*(unsigned *) (buf + 10) - 54) / 4;
- }
- else
- {
- /* OS/2 V1.1 */
- pp->width = w = bch.bcWidth;
- pp->height = h = bch.bcHeight;
- pp->bpp = bch.bcBitCount;
- palsize = (*(unsigned *) (buf + 10) - 26) / 3;
- }
- bw = pp->width;
- bh = pp->height;
- if ((pp->bpp >> 3) < 3) output_type = 1;
- /* w is the size of a horizontal line in bytes
- * bih.biWidth is the number of valid pixels in a line
- * the latter one is passed to vgadisp.c as pp->width
- */
- switch (pp->bpp)
- {
- case 1:
- if (w % 32)
- w = (w / 32) * 32 + 32;
- break;
- case 4:
- if (w % 8)
- w = (w / 8) * 8 + 8;
- break;
- case 8:
- if (w % 4)
- w = (w / 4) * 4 + 4;
- break;
- }
- if ((pp->bpp == 24) && (output_type == 3)) dummy = 3;
- else dummy = 1;
- bmap = malloc(w * (h + 2) * dummy);
- memset(bmap, 0, w * (h + 2) * dummy);
- switch (pp->bpp)
- {
- case 1:
- /* 1bit non compressed */
- ptr = pal;
- fread(ptr, 1, 3, infile);
- if (iswindows)
- fread(&dummy, 1, 1, infile);
- dummy = ptr[0];
- ptr[0] = ptr[2] / 4;
- ptr[1] /= 4;
- ptr[2] = dummy / 4;
- fread(ptr + 3, 1, 3, infile);
- if (iswindows)
- fread(&dummy, 1, 1, infile);
- dummy = ptr[3];
- ptr[3] = ptr[5] / 4;
- ptr[4] /= 4;
- ptr[5] = dummy / 4;
- ptr = bmap;
- for (j = h - 1; j >= 0; j--)
- {
- for (i = 0, count = 0 ; i < (w >> 3); i++)
- {
- hptr = ptr + j * pp->width;
- dummy = fgetc(infile);
- if (count < pp->width)
- {
- hptr[count] = (dummy & 128) ? 1 : 0; count++;
- hptr[count] = (dummy & 64) ? 1 : 0; count++;
- hptr[count] = (dummy & 32) ? 1 : 0; count++;
- hptr[count] = (dummy & 16) ? 1 : 0; count++;
- hptr[count] = (dummy & 8) ? 1 : 0; count++;
- hptr[count] = (dummy & 4) ? 1 : 0; count++;
- hptr[count] = (dummy & 2) ? 1 : 0; count++;
- hptr[count] = dummy & 1; count++;
- }
- }
- }
- pp->numcols = 2;
- break;
- case 4:
- /* 4bit non compressed */
- ptr = pal;
- for (i = 0; i < palsize; i++)
- {
- fread(ptr + 3 * i, 1, 3, infile);
- if (iswindows)
- fread(&dummy, 1, 1, infile);
- dummy = ptr[3 * i];
- ptr[3 * i] = ptr[3 * i + 2] / 4;
- ptr[3 * i + 1] /= 4;
- ptr[3 * i + 2] = dummy / 4;
- }
- ptr = bmap;
- if ((!iswindows) || (bih.biCompression == 0))
- {
- for (j = h - 1; j >= 0; j--)
- {
- for (i = 0, count = 0; i < (w / 2); i++)
- {
- dummy = fgetc(infile);
- if (count < pp->width)
- {
- ptr[count + j * pp->width] = dummy >> 4;
- count++;
- }
- if (count < pp->width)
- {
- ptr[count + j * pp->width] = dummy & 15;
- count++;
- }
- }
- }
- }
- else
- {
- /* 4bit RLE compressed */
- done = 0;
- count = 0;
- while (done == 0)
- {
- fread(read, 1, 2, infile);
- if (*read)
- {
- i = 0;
- do
- {
- *ptr = read[1] >> 4;
- ptr++;
- i++;
- if (i < (read[0]))
- {
- *ptr = read[1] & 15;
- ptr++;
- i++;
- }
- }
- while (i < (*read));
- }
- else if (read[1] == 0)
- {
- count++;
- }
- else if (read[1] == 1)
- done = 1;
- else if (read[1] == 2)
- {
- /* This isn't really tested */
- ptr += fgetc(infile) + bih.biWidth * fgetc(infile);
- }
- else
- {
- dptr = hptr = (unsigned char *) malloc(read[1] >> 1);
- fread(dptr, 1, read[1] >> 1, infile);
- if (read[1] % 4 > 1)
- dummy = fgetc(infile);
- i = 0;
- do
- {
- *ptr = (*dptr) >> 4;
- i++;
- ptr++;
- if (i < read[1])
- {
- *ptr = (*dptr) & 15;
- i++;
- ptr++;
- }
- dptr++;
- }
- while (i < read[1]);
- free(hptr);
- }
- }
- flip(bmap, bih.biWidth, bih.biHeight);
- }
- pp->width = w;
- pp->numcols= 16;
- break;
- case 8:
- /* 8bit non compressed */
- ptr = pal;
- for (i = 0; i < palsize; i++)
- {
- fread(ptr + 3 * i, 1, 3, infile);
- if (iswindows)
- dummy = fgetc(infile);
- dummy = ptr[3 * i];
- ptr[3 * i] = ptr[3 * i + 2] / 4;
- ptr[3 * i + 1] /= 4;
- ptr[3 * i + 2] = dummy / 4;
- }
- ptr = bmap;
- if ((!iswindows) || (bih.biCompression == 0))
- {
- for (i = h - 1; i >= 0; i--)
- {
- fread(ptr + pp->width * i, 1, w, infile);
- }
- }
- else
- {
- /* 8bit RLE compressed */
- done = 0;
- count = 0;
- while (done == 0)
- {
- fread(read, 1, 2, infile);
- if (read[0])
- {
- for (i = 0; i < (int)read[0]; i++)
- {
- *ptr = read[1];
- ptr++;
- }
- }
- else if (read[1] == 0)
- {
- count++;
- }
- else if (read[1] == 1)
- done = 1;
- else if (read[1] == 2)
- ptr += fgetc(infile) + bih.biWidth * fgetc(infile);
- else
- {
- fread(ptr, 1, read[1], infile);
- if (read[1] % 2)
- fgetc(infile);
- ptr += read[1];
- }
- }
- flip(bmap, bih.biWidth, bih.biHeight);
- }
- pp->numcols = 256;
- break;
- }
- free(buf);
- fclose(infile);
- return (bmap);
- }
- static int flip(unsigned char *image, unsigned int w, unsigned int h)
- {
- unsigned int i;
- unsigned char *hptr;
- hptr = (unsigned char *)malloc(w);
- for (i = 0; i < (h / 2); i++)
- {
- memcpy(hptr, image + i * w, w);
- memcpy(image + i * w, image + (h - i - 1) * w, w);
- memcpy(image + (h - i - 1) * w, hptr, w);
- }
- free(hptr);
- return (0);
- }
- /* ======================================================================= */
- /* The main "term" structure */
- static term term_screen_body;
- /* The visible and virtual screens */
- GraphicsContext *screen;
- GraphicsContext *backscreen;
- GraphicsContext *buffer;
- /* The font data */
- void *font;
- /* Initialize the screen font */
- void initfont(void)
- {
- gzFile fontfile;
- void *temp;
- long junk;
- if (!(fontfile = gzopen("/usr/lib/kbd/consolefonts/lat1-12.psfu.gz", "r")))
- {
- /* Try uncompressed */
- if (!(fontfile = gzopen("/usr/lib/kbd/consolefonts/lat1-12.psfu", "r")))
- {
- printf("Error: could not open font file. Aborting....\n");
- exit(1);
- }
- }
- /* Junk the 4-byte header */
- gzread(fontfile, &junk, 4);
- /* Initialize font */
- /* Haven't looked into why it is 3328 - Dennis */
- temp = malloc(/*12*256*/ 3328);
- gzread(fontfile, temp, 3328);
- font = malloc(256 * 8 * 12 * BYTESPERPIXEL);
- gl_expandfont(8, 12, 15, temp, font);
- gl_setfont(8, 12, font);
- free(temp);
- gzclose(fontfile);
- }
- /* Initialize palette values for colors 0-15 */
- void setpal(void)
- {
- int i;
- gl_setpalette(pal);
- for (i = 0; i < 16; i++)
- {
- gl_setpalettecolor(COLOR_OFFSET + i, angband_color_table[i][1] >> 2,
- angband_color_table[i][2] >> 2, angband_color_table[i][3] >> 2);
- }
- #if 0
- gl_setpalettecolor (0,00,00,00); /* Black */
- gl_setpalettecolor (3,63,63,63); /* White */
- gl_setpalettecolor (13,40,40,40); /* Gray */
- gl_setpalettecolor (11,25,15,05); /* Orange */
- gl_setpalettecolor (2,32,00,00); /* Red */
- gl_setpalettecolor (7,00,32,00); /* Green */
- gl_setpalettecolor (12,00,00,40); /* Blue */
- gl_setpalettecolor (5,50,25,00); /* Brown */
- gl_setpalettecolor (1,28,28,28); /* Dark Gray */
- gl_setpalettecolor (10,52,52,52); /* Light Gray */
- gl_setpalettecolor (15,41,00,63); /* Purple */
- gl_setpalettecolor (4,63,63,00); /* Yellow */
- gl_setpalettecolor (14,63,00,00); /* Light Red */
- gl_setpalettecolor (6,00,63,00); /* Light Green */
- gl_setpalettecolor (9,00,50,63); /* Light Blue */
- gl_setpalettecolor (8,63,52,32); /* Light Brown */
- #endif /* 0 */
- }
- /****************************************************************************
- * Check for "events"
- * If block, then busy-loop waiting for event, else check once and exit
- ***************************************************************************/
- static errr CheckEvents(int block)
- {
- int k = 0;
- if (block)
- {
- k = vga_getkey();
- if (k < 1) return (1);
- }
- else
- k = vga_getch();
- Term_keypress(k);
- return (0);
- }
- /****************************************************************************
- * Low-level graphics routine (assumes valid input)
- * Do a "special thing"
- ***************************************************************************/
- static errr term_xtra_svgalib(int n, int v)
- {
- switch (n)
- {
- case TERM_XTRA_EVENT:
- {
- /* Process some pending events */
- if (v) return (CheckEvents(FALSE));
- while (!CheckEvents(TRUE));
- return 0;
- }
- case TERM_XTRA_FLUSH:
- {
- /* Flush all pending events */
- /* Should discard all key presses but unimplemented */
- return 0;
- }
- case TERM_XTRA_CLEAR:
- {
- /* Clear the entire window */
- gl_fillbox(0, 0, 80 * CHAR_W, 25 * CHAR_H, 0);
- return 0;
- }
- case TERM_XTRA_DELAY:
- {
- /* Delay for some milliseconds */
- usleep(1000 * v);
- return 0;
- }
- }
- return 1;
- }
- /****************************************************************************
- * Low-level graphics routine (assumes valid input)
- * Draws a "cursor" at (x,y)
- ***************************************************************************/
- static errr term_curs_svgalib(int x, int y)
- {
- gl_fillbox(x * CHAR_W, y * CHAR_H, CHAR_W, CHAR_H, 15);
- return (0);
- }
- /****************************************************************************
- * Low-level graphics routine (assumes valid input)
- * Erases a rectangular block of characters from (x,y) to (x+w,y+h)
- ***************************************************************************/
- static errr term_wipe_svgalib(int x,int y,int n)
- {
- gl_fillbox(x * CHAR_W, y * CHAR_H, n * CHAR_W, CHAR_H, 0);
- return (0);
- }
- /****************************************************************************
- * Low-level graphics routine (assumes valid input)
- * Draw n chars at location (x,y) with value s and attribute a
- ***************************************************************************/
- errr term_text_svgalib(int x, int y, int n, unsigned char a, cptr s)
- {
- term_wipe_svgalib(x, y, n);
- gl_colorfont(8, 12, COLOR_OFFSET + (a & 0x0F)/*pal_trans[a]*/, font);
- gl_writen(x * CHAR_W, y * CHAR_H, n, (char *)s);
- return (0);
- }
- /****************************************************************************
- * Low-level graphics routine (assumes valid input)
- * Draw n chars at location (x,y) with value s and attribute a
- ***************************************************************************/
- errr term_pict_svgalib(int x, int y, int n, const byte *ap, const char *cp,
- const byte *tap, const char *tcp)
- {
- int i;
- int x2, y2;
- /* Unused parameters */
- (void)tap;
- (void)tcp;
- for (i = 0; i < n; i++)
- {
- x2 = (cp[i] & 0x1F) * CHAR_W;
- y2 = (ap[i] & 0x1F) * CHAR_H;
- gl_copyboxfromcontext(buffer, x2, y2, CHAR_W,
- CHAR_H, (x + i) * CHAR_W, y * CHAR_H);
- }
- return (0);
- }
- void term_load_bitmap(void)
- {
- void *temp;
- temp = read_bmp_file();
- /* Blit bitmap into buffer */
- gl_putbox(0, 0, bw, bh, temp);
- free(temp);
- return;
- }
- /****************************************************************************
- * Term hook
- * Initialize a new term
- ***************************************************************************/
- static void term_init_svgalib(term *t)
- {
- int VGAMODE, VIRTUAL;
- /* Hardwire this mode in for now */
- VGAMODE = G1024x768x256;
- VIRTUAL = 1;
- vga_init();
- /* Set up the bitmap buffer context */
- gl_setcontextvgavirtual(VGAMODE);
- buffer = gl_allocatecontext();
- gl_getcontext(buffer);
- /* Load bitmap into virtual screen */
- term_load_bitmap();
- /* Hardwire this mode in for now */
- VGAMODE = G640x480x256;
- /* Set up the physical screen context */
- if (vga_setmode(VGAMODE) < 0)
- {
- printf("Mode not available\n");
- exit(0);
- }
- gl_setcontextvga(VGAMODE);
- screen = gl_allocatecontext();
- gl_getcontext(screen);
- gl_enablepageflipping(screen);
- /* Set up palette colors */
- setpal();
- /* Load the character font data */
- initfont();
- /* Color 0 isn't transparent */
- gl_setwritemode(WRITEMODE_OVERWRITE);
- }
- /****************************************************************************
- * Term hook
- * Nuke an old term
- ***************************************************************************/
- static void term_nuke_svgalib(term *t)
- {
- vga_setmode(TEXT);
- }
- const char help_lsl[] = "SVGA (low level graphics) library";
- /****************************************************************************
- * Hook SVGAlib routines into term.c
- ***************************************************************************/
- errr init_lsl(int argc, char **argv)
- {
- char path[1024];
- term *t = &term_screen_body;
- /* Unused parameters */
- (void)argc;
- (void)argv;
- if (arg_graphics)
- {
- use_graphics = TRUE;
- }
- /* Build the "graf" path */
- path_build(path, sizeof(path), ANGBAND_DIR_XTRA, "graf");
- /* Allocate the path */
- ANGBAND_DIR_XTRA_GRAF = string_make(path);
- /* Initialize the term */
- term_init(t, 80, 24, 1024);
- /* The cursor is done via software and needs erasing */
- t->soft_cursor = TRUE;
- t->attr_blank = TERM_DARK;
- t->char_blank = ' ';
- /* Add hooks */
- t->init_hook = term_init_svgalib;
- t->nuke_hook = term_nuke_svgalib;
- t->text_hook = term_text_svgalib;
- if (use_graphics)
- {
- t->pict_hook = term_pict_svgalib;
- t->higher_pict = TRUE;
- }
- t->wipe_hook = term_wipe_svgalib;
- t->curs_hook = term_curs_svgalib;
- t->xtra_hook = term_xtra_svgalib;
- /* Save the term */
- term_screen = t;
- Term_activate(term_screen);
- return (0);
- }
- #endif /* USE_LSL */