Súbor: [Platon] / games / _shared / my-graph.c (stiahnutie)
Revízia 1.13, Tue Apr 6 09:54:16 2004 UTC (21 years, 1 month ago) by nepto
Zmeny od 1.12: +13 -6
[lines]
Headers update:
- switch to standard/classic Platon SDG source header
- bumped copyright year to 2004
- changelog dates reformatted to new format YYYY-MM-DD
|
/*
* games/_shared/ - shared routines for games
*
* my-graph.c - universal graphics library
* ____________________________________________________________
*
* Developed by Ondrej Jombik <nepto@platon.sk>
* Copyright (c) 2003-2004 Platon SDG, http://platon.sk/
* All rights reserved.
*
* See README file for more information about this software.
* See COPYING file for license information.
*
* Download the latest version from
* http://platon.sk/projects/games/
*
* Changelog:
* 2003-05-10 - created
* 2003-08-12 - X11 adaptations
*/
/* $Platon: games/_shared/my-graph.c,v 1.12 2003/10/07 12:20:29 nepto Exp $ */
#include <stdio.h>
#include <stdlib.h>
#include <system.h> /* target operating system type */
#if PLATON_SYSTEM_MSDOS
# include <graphics.h>
#endif
#if PLATON_SYSTEM_WIN32
# include <winbgim.h>
#endif
#if PLATON_SYSTEM_SVGALIB
# include <dos2linux.h>
# include <vga.h>
# include <vgagl.h>
# include "fontlib.c"
#endif
#if PLATON_SYSTEM_X11
# include <x11-bgi.h>
#endif
#include "my-graph.h"
#if PLATON_SYSTEM_MSDOS || PLATON_SYSTEM_WIN32 || PLATON_SYSTEM_X11
int my_graph_init(int pagging) /* {{{ */
{
int gdriver = VGA, gmode = VGAHI, errorcode;
#if PLATON_SYSTEM_MSDOS /* Win32 does not link EGAVGA.BGI into executable */
/* register a driver that was added into graphics.lib
For information on adding the driver, see the
BGIOBJ section of UTIL.DOC */
errorcode = registerbgidriver(EGAVGA_driver);
/* report any registration errors */
if (errorcode < 0) {
fprintf(stderr, "my_graph_init(): graphics error: %s\n",
grapherrormsg(errorcode));
return -1;
}
#endif
/* initialize graphics and local variables */
initgraph(&gdriver, &gmode, NULL);
/* read result of initialization */
errorcode = graphresult();
if (errorcode != grOk) /* an error occurred */ {
fprintf(stderr, "my_graph_init(): graphics error %d: %s\n",
errorcode, grapherrormsg(errorcode));
return -1;
}
pagging = pagging; /* not implemented */
return 0;
} /* }}} */
void my_graph_refresh(void) /* {{{ */
{
/* TODO */
/* not implemented yet */
} /* }}} */
void my_graph_close(void) /* {{{ */
{
closegraph();
} /* }}} */
#endif /* #if PLATON_SYSTEM_MSDOS || PLATON_SYSTEM_WIN32 */
#if ! PLATON_SYSTEM_MSDOS
static void *putimage_BGI_cache_pointers[PUTIMAGE_BGI_CACHE_SIZE];
static void *putimage_BGI_cache_data[PUTIMAGE_BGI_CACHE_SIZE];
static int putimage_BGI_cache_size = 0;
static void putimage_BGI_cache_free(void) /* {{{ */
{
register int i;
for (i = 0; i < putimage_BGI_cache_size; i++) {
free(putimage_BGI_cache_data[i]);
putimage_BGI_cache_data[i] = NULL;
putimage_BGI_cache_pointers[i] = NULL;
}
#if 0
fprintf(stderr, "putimage_BGI_cache_free(): %d entries freed\n",
putimage_BGI_cache_size);
#endif
putimage_BGI_cache_size = 0; /* To prevent double free */
} /* }}} */
void putimage_BGI_cached(const int x, const int y, void *image, const int op) /* {{{ */
{
register int i;
register short width, height;
for (i = 0; i < putimage_BGI_cache_size; i++) {
if (putimage_BGI_cache_pointers[i] == image) {
putimage(x, y, putimage_BGI_cache_data[i], op);
return;
}
}
if (putimage_BGI_cache_size == 0) {
/* We will free cache at the program exit */
atexit(putimage_BGI_cache_free);
}
putimage_BGI(x, y, image, op);
if (putimage_BGI_cache_size == PUTIMAGE_BGI_CACHE_SIZE) {
/* Remove first item from buffer */
for (i = 1; i < PUTIMAGE_BGI_CACHE_SIZE; i++) {
putimage_BGI_cache_data [i - 1] = putimage_BGI_cache_data [i];
putimage_BGI_cache_pointers[i - 1] = putimage_BGI_cache_pointers[i];
}
putimage_BGI_cache_size--;
}
width = ((short *) image)[0];
height = ((short *) image)[1];
putimage_BGI_cache_data[putimage_BGI_cache_size] =
malloc(imagesize(x, y, x + width, y + height));
if (putimage_BGI_cache_data[putimage_BGI_cache_size] == NULL) {
putimage_BGI_cache_pointers[putimage_BGI_cache_size] = NULL;
} else {
getimage(x, y, x + width, y + height,
putimage_BGI_cache_data[putimage_BGI_cache_size]);
putimage_BGI_cache_pointers[putimage_BGI_cache_size] = image;
putimage_BGI_cache_size++;
}
} /* }}} */
void putimage_BGI(const int x, const int y, void *image, const int op) /* {{{ */
{
register short width, height;
register int linesize, linesize2, linesize4;
register int i, j, k, mask;
register unsigned char r, g, b, B;
register unsigned char *offset;
static int pow2[] = {1, 2, 4, 8, 16, 32, 64, 128};
width = ((short *) image)[0];
height = ((short *) image)[1];
image = (void *) ((short *) image + 2);
linesize = 4 + ((width / 2) & ~3);
linesize2 = linesize / 2;
linesize4 = linesize2 / 2;
for (j = 0; j < height; j++) {
offset = (unsigned char *) image + (j * linesize);
for (i = 0; i < width; offset++) {
B = *offset;
r = *(offset + linesize4);
g = *(offset + linesize2);
b = *(offset + linesize2 + linesize4);
for (k = 7; k >= 0 && i < width; k--, i++) {
mask = pow2[k];
putpixel(x + i, y + j,
(r & mask ? 4 : 0) +
(g & mask ? 2 : 0) +
(b & mask ? 1 : 0) +
(B & mask ? 8 : 0) );
#if 0 /* text output */ /* {{{ */
putchar('0'
+ (r & mask ? 4 : 0)
+ (g & mask ? 2 : 0)
+ (b & mask ? 1 : 0)
+ (B & mask ? 8 : 0)
);
#endif /* }}} */
}
}
}
return;
} /* }}} */
#endif
#if PLATON_SYSTEM_SVGALIB
static int svgalib_gmode_initialized = 0;
static GraphicsContext *svgalib_physicalscreen = NULL;
static GraphicsContext *svgalib_virtualscreen = NULL;
int my_graph_init(int pagging) /* {{{ */
{
register int svgalib_mode = -1;
if (svgalib_gmode_initialized)
return 0;
vga_init();
svgalib_mode = G640x480x16;
svgalib_mode = G640x480x256;
if (! vga_hasmode(svgalib_mode)) {
fprintf(stderr, "my_graph_init(): mode not available\n");
return -1;
}
vga_setmode(svgalib_mode);
gl_setcontextvga(svgalib_mode);
svgalib_physicalscreen = gl_allocatecontext();
gl_getcontext(svgalib_physicalscreen);
gl_setcontextvgavirtual(svgalib_mode);
svgalib_virtualscreen = gl_allocatecontext();
gl_getcontext(svgalib_virtualscreen);
gl_setcontext(svgalib_virtualscreen);
if (! pagging) {
gl_setcontext(svgalib_physicalscreen);
}
#if 0
fprintf(stderr, "vga_getxdim(): %d\nvga_getydim(): %d\n",
vga_getxdim(), vga_getydim());
#endif
gl_enableclipping();
gl_setfontcolors(0, vga_white());
fontlib_default = gl_font8x8;
settextstyle(0, 0, 1);
setallpalette(NULL);
svgalib_gmode_initialized = 1;
return 0;
} /* }}} */
void my_graph_refresh(void) /* {{{ */
{
if (svgalib_physicalscreen != NULL)
gl_copyscreen(svgalib_physicalscreen);
} /* }}} */
void my_graph_close(void) /* {{{ */
{
settextstyle(0, 0, -1);
if (svgalib_gmode_initialized)
vga_setmode(TEXT);
} /* }}} */
/*
* Moving routines
*/
static int cursor_x = 0;
static int cursor_y = 0;
void moveto(const int x, const int y) /* {{{ */
{
cursor_x = x;
cursor_y = y;
} /* }}} */
void moverel(const int dx, const int dy) /* {{{ */
{
cursor_x += dx;
cursor_y += dy;
} /* }}} */
/*
* Drawing routines
*/
static int drawcolor = WHITE;
static int fillcolor = WHITE;
void setcolor(const int color) /* {{{ */
{
drawcolor = color;
} /* }}} */
void setfillstyle(const int pattern, const int color) /* {{{ */
{
fillcolor = color;
} /* }}} */
void line(const int x1, const int y1, const int x2, const int y2) /* {{{ */
{
#if 0
vga_setcolor(color);
vga_drawline(x1, y1, x2, y2);
#endif
gl_line(x1, y1, x2, y2, drawcolor);
} /* }}} */
void rectangle(const int x1, const int y1, const int x2, const int y2) /* {{{ */
{
#if 0
vga_setcolor(color);
vga_drawline(x1, y1, x2, y1);
vga_drawline(x1, y2, x2, y2);
vga_drawline(x1, y1, x1, y2);
vga_drawline(x2, y1, x2, y2);
#endif
gl_line(x1, y1, x2, y1, drawcolor);
gl_line(x1, y2, x2, y2, drawcolor);
gl_line(x1, y1, x1, y2, drawcolor);
gl_line(x2, y1, x2, y2, drawcolor);
} /* }}} */
void bar(const int x1, const int y1, const int x2, const int y2) /* {{{ */
{
register int w, h;
w = x1 > x2 ? x1 - x2 : x2 - x1;
h = y1 > y2 ? y1 - y2 : y2 - y1;
gl_fillbox(x1, y1, w + 1, h + 1, fillcolor);
} /* }}} */
void bar3d(const int x1, const int y1, const int x2, const int y2, /* {{{ */
const int depth, const int topflag)
{
bar(x1, y1, x2, y2);
rectangle(x1, y1, x2, y2);
if (depth > 0) {
register int depth2 = (depth / 4) * 3;
gl_line(x2, y2, x2 + depth, y2 - depth2, drawcolor);
gl_line(x2 + depth, y1 - depth2, x2 + depth, y2 - depth2, drawcolor);
if (topflag) {
gl_line(x1, y1, x1 + depth, y1 - depth2, drawcolor);
gl_line(x2, y1, x2 + depth, y1 - depth2, drawcolor);
gl_line(x1 + depth, y1 - depth2,
x2 + depth, y1 - depth2, drawcolor);
}
}
} /* }}} */
void ellipse(const int x, const int y, const int stangle, const int endangle, /* {{{ */
const int xradius, const int yradius)
{
register int radius = (xradius + yradius) / 2;
/* stangle = stangle; unused */
/* endangle = endangle; unused */
gl_circle(x, y, radius, drawcolor);
} /* }}} */
void fillellipse(const int x, const int y, const int xradius, const int yradius) /* {{{ */
{
register int i, radius = (xradius + yradius) / 2;
for (i = 0; i < radius; i++)
gl_circle(x, y, i, fillcolor);
gl_circle(x, y, radius, drawcolor);
} /* }}} */
/*
* Text functions
*/
static struct font_data
{
int width;
int height;
unsigned char *data;
void *memory;
} curfnt = {0, 0, NULL, NULL};
static struct textsettingstype textinfo = {0, 0, 0, LEFT_TEXT, TOP_TEXT};
static int text_lines(char *str) /* {{{ */
{
register int lines, possible_newline;
for (lines = 0, possible_newline = 1; *str != '\0'; str++) {
if (*str == '\n') {
possible_newline = 1;
} else if (possible_newline) {
lines++;
possible_newline = 0;
}
}
#if 0
fprintf(stderr, "text_lines(): str = [%s], lines = %d\n",
str, lines);
#endif
return lines;
} /* }}} */
static int text_max_line(char *str) /* {{{ */
{
register int cur, max;
for (cur = max = 0; *str != '\0'; str++) {
if (*str == '\n') {
max = cur > max ? cur : max;
cur = 0;
} else {
cur++;
}
}
max = cur > max ? cur : max;
#if 0
fprintf(stderr, "text_max_line(): str = [%s], max = %d\n",
str, lines);
#endif
return max;
} /* }}} */
int textheight(char *str) /* {{{ */
{
return textinfo.direction
? text_max_line(str) * curfnt.height
: text_lines(str) * curfnt.height;
} /* }}} */
int textwidth(char *str) /* {{{ */
{
return textinfo.direction
? text_lines(str) * curfnt.width
: text_max_line(str) * curfnt.width;
} /* }}} */
void gettextsettings(struct textsettingstype *texttypeinfo) /* {{{ */
{
*texttypeinfo = textinfo;
} /* }}} */
void settextstyle(int font, int direction, int charsize) /* {{{ */
{
textinfo.font = font;
textinfo.direction = direction;
if (textinfo.charsize != charsize) {
if (curfnt.memory != NULL) {
free(curfnt.memory);
curfnt.memory = NULL;
}
if (charsize > 0) {
if (charsize <= 1) {
curfnt.width = fontlib_default_width;
curfnt.height = fontlib_default_height;
curfnt.data = fontlib_default;
curfnt.memory = NULL;
} else {
curfnt.width = fontlib_font3_width;
curfnt.height = fontlib_font3_height;
curfnt.data = fontlib_font3;
#if 0
curfnt.memory = malloc(256 * BYTESPERPIXEL
* curfnt.width * curfnt.height);
gl_expandfont(curfnt.width, curfnt.height, 15,
(char *) curfnt.data, curfnt.memory);
#else
curfnt.memory = NULL;
#endif
}
gl_setfont(curfnt.width, curfnt.height,
curfnt.memory != NULL ? curfnt.memory : curfnt.data);
}
textinfo.charsize = charsize;
}
} /* }}} */
void settextjustify(int horiz, int vert) /* {{{ */
{
textinfo.horiz = horiz;
textinfo.vert = vert;
} /* }}} */
void outtext(char *str) /* {{{ */
{
outtextxy(cursor_x, cursor_y, str);
/* cursor_x += textwidth(str); */
} /* }}} */
void outtextxy(const int x, const int y, char *str) /* {{{ */
{
register int writex, writey;
writex = textinfo.horiz == LEFT_TEXT ? x : textinfo.horiz == RIGHT_TEXT
? x - textwidth(str)
: x - textwidth(str) / 2;
writey = textinfo.vert == TOP_TEXT ? y : textinfo.vert == BOTTOM_TEXT
? y - textheight(str)
: y - textheight(str) / 2;
if (drawcolor == 0) {
gl_setwritemode(FONT_COMPRESSED + WRITEMODE_OVERWRITE);
gl_setfontcolors(vga_getpixel(writex - 1, writey - 1), drawcolor);
} else {
gl_setwritemode(FONT_COMPRESSED + WRITEMODE_MASKED);
gl_setfontcolors(0 /* pixel #0 is not written in gl_write() */,
drawcolor);
}
if (! textinfo.direction) { /* native horizontal writing */
gl_write(writex, writey, str);
} else { /* emulated vertical writing */
register int base_y;
char buf[2];
for (base_y = writey, buf[1] = '\0'; *str != '\0'; str++) {
if (*str == '\n') {
writex += curfnt.width;
writey = base_y;
}
buf[0] = *str;
gl_write(writex, writey, buf);
writey += curfnt.height;
}
}
#if 0
fprintf(stderr, "gl_write(): x = %d (%d), y = %d (%d), str = [%s]\n",
x, writex, y, writey, str);
#endif
} /* }}} */
unsigned int imagesize(const int x1, const int y1, const int x2, const int y2) /* {{{ */
{
return 4 * sizeof(short) + (x2 - x1 + 1) * (y2 - y1 + 1) * BYTESPERPIXEL;
} /* }}} */
void getimage(const int x1, const int y1, const int x2, const int y2, void *image) /* {{{ */
{
register short width, height;
width = x2 - x1 + 1;
height = y2 - y1 + 1;
((short *) image)[0] = -1;
((short *) image)[1] = -1;
((short *) image)[2] = width;
((short *) image)[3] = height;
gl_getbox(x1, y1, x2 - x1 + 1, y2 - y1 + 1, (void *) ((short *) image + 4));
} /* }}} */
void putimage(const int x, const int y, void *image, const int op) /* {{{ */
{
register short width, height;
width = ((short *) image)[0];
height = ((short *) image)[1];
if (width == -1 && height == -1) {
width = ((short *) image)[2];
height = ((short *) image)[3];
gl_putbox(x, y, width, height, (void *) ((short *) image + 4));
} else {
putimage_BGI(x, y, image, op);
}
} /* }}} */
static struct palettetype default_palette;
static void init_default_palette(void)
{
register int i;
default_palette.size = MAXCOLORS;
for (i = 0; i < MAXCOLORS; i++) {
default_palette.colors[i] = 0;
}
}
struct palettetype *getdefaultpalette(void) /* {{{ */
{
return &default_palette;
} /* }}} */
void getpalette(struct palettetype *palette) /* {{{ */
{
*palette = default_palette;
return;
} /* }}} */
void setpalette(int colornum, int color) /* {{{ */
{
return;
} /* }}} */
void setallpalette(const struct palettetype *palette) /* {{{ */
{
if (palette == NULL)
init_default_palette();
return;
} /* }}} */
#endif /* #if PLATON_SYSTEM_SVGALIB */
/* Modeline for ViM {{{
* vim: set ts=4:
* vim600: fdm=marker fdl=0 fdc=0:
* }}} */
Platon Group <platon@platon.sk> http://platon.sk/
|