Platon Technologies
neprihlásený Prihlásiť Registrácia
SlovakEnglish
open source software development oslavujeme 10 rokov vývoja otvoreného softvéru! Sobota, 24. máj 2025

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/
Copyright © 2002-2006 Platon Group
Stránka používa redakčný systém Metafox
Na začiatok