/* viDOOM - level editor for DOOM Copyright (C) 2000 Ian Cowburn (ianc@noddybox.demon.co.uk) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ------------------------------------------------------------------------- Graphics functions */ static const char rcs_id[]="$Id$"; #include "config.h" #include #include #include #include #include #include "gfx.h" #include "gui.h" #include "debug.h" /* ---------------------------------------- VARS */ #define COLDEP 16 #define ACOL(c) (makecol_depth(COLDEP,((c)&0xff0000)>>16, \ ((c)&0xff00)>>8, \ ((c)&0xff))) static int init=FALSE; static BITMAP *bm; static int width; static int height; static int mbuttons; static int dirty_min_x; static int dirty_max_x; static int dirty_min_y; static int dirty_max_y; #define DIRTY(x,y) do { \ dirty_min_x=MIN(x,dirty_min_x); \ dirty_min_y=MIN(y,dirty_min_y); \ dirty_max_x=MAX((x)+1,dirty_max_x); \ dirty_max_y=MAX((y)+1,dirty_max_y); \ } while(0) /* ---------------------------------------- PRIVATE FUNCTIONS */ static void GetKey(GFXKey *key) { static struct { int alleg; int code; } keym[]= { {KEY_F1,GFX_F1}, {KEY_F2,GFX_F2}, {KEY_F3,GFX_F3}, {KEY_F4,GFX_F4}, {KEY_F5,GFX_F5}, {KEY_F6,GFX_F6}, {KEY_F7,GFX_F7}, {KEY_F8,GFX_F8}, {KEY_F9,GFX_F9}, {KEY_F10,GFX_F10}, {KEY_F11,GFX_F11}, {KEY_F12,GFX_F12}, {KEY_ESC,GFX_ESC}, {KEY_INSERT,GFX_INSERT}, {KEY_HOME,GFX_HOME}, {KEY_PGUP,GFX_PGUP}, {KEY_DEL,GFX_DELETE}, {KEY_END,GFX_END}, {KEY_PGDN,GFX_PGDN}, {KEY_UP,GFX_UP}, {KEY_DOWN,GFX_DOWN}, {KEY_LEFT,GFX_LEFT}, {KEY_RIGHT,GFX_RIGHT}, {KEY_ENTER,GFX_ENTER}, {KEY_BACKSPACE,GFX_BACKSPACE}, {KEY_TAB,GFX_TAB}, {-1,-1}, }; int f; int k; while(TRUE) { k=readkey(); key->shift=key_shifts&KB_SHIFT_FLAG; key->ctrl=key_shifts&KB_CTRL_FLAG; key->alt=key_shifts&KB_ALT_FLAG; f=0; while(keym[f].code!=-1) { if (keym[f].alleg==k>>8) { key->ascii=0; key->code=keym[f].code; return; } f++; } if (isprint(k&0xff)) { key->ascii=(k&0xff); key->code=GFX_ASCII; return; } } } /* ---------------------------------------- EXPORTED FUNCTIONS */ void GFX_init(void) { if (!init) { init=TRUE; allegro_init(); install_keyboard(); install_timer(); if ((mbuttons=install_mouse())==-1) GFX_exit(EXIT_FAILURE,"Failed to install mouse handler\n"); set_color_depth(COLDEP); } } void GFX_close(void) { if (init) { allegro_exit(); init=FALSE; } } void GFX_open(int w,int h) { height=h; width=w; if (set_gfx_mode(GFX_AUTODETECT,w,h,0,0)<0) GFX_exit(EXIT_FAILURE,"Couldn't open screen of %dx%d\n",w,h); if (!(bm=create_bitmap(w,h))) GFX_exit(EXIT_FAILURE,"Couldn't create bitmap of %dx%d\n",w,h); show_mouse(screen); } void GFX_clear(int col) { clear_to_color(bm,ACOL(col)); dirty_min_x=0; dirty_max_x=width; dirty_min_y=0; dirty_max_y=width; } void GFX_redraw(void) { if (dirty_max_x1) mb=0; while (TRUE) { if (keypressed()) { ev->type=GFX_KEY_EVENT; GetKey(&ev->key); return; } if (mouse_b!=mb) { ev->mouse.shift=key_shifts&KB_SHIFT_FLAG; ev->mouse.ctrl=key_shifts&KB_CTRL_FLAG; ev->mouse.alt=key_shifts&KB_ALT_FLAG; ev->mouse.x=mouse_x; ev->mouse.y=mouse_y; ev->mouse.b=mb=mouse_b; ev->type=GFX_MOUSE_EVENT; return; } } } void GFX_await_input_full(GFXEvent *ev) { static time_t last_time=0; static int mx,my,mb; /* Assume that a gap of 1-2 seconds means that this is a new await input loop */ if (time(NULL)-last_time>1) { mx=-1; my=-1; mb=0; } while (TRUE) { if (keypressed()) { ev->type=GFX_KEY_EVENT; GetKey(&ev->key); last_time=time(NULL); return; } if ((mouse_b!=mb)||(mouse_x!=mx)||(mouse_y!=my)) { ev->mouse.shift=key_shifts&KB_SHIFT_FLAG; ev->mouse.ctrl=key_shifts&KB_CTRL_FLAG; ev->mouse.alt=key_shifts&KB_ALT_FLAG; ev->mouse.x=mx=mouse_x; ev->mouse.y=my=mouse_y; ev->mouse.b=mb=mouse_b; ev->type=GFX_MOUSE_EVENT; last_time=time(NULL); return; } } } void GFX_exit(int code,char *fmt,...) { va_list va; if (init) allegro_exit(); va_start(va,fmt); vfprintf(stderr,fmt,va); va_end(va); exit(code); } GFX_IMAGE GFX_create_image(GFX_BITMAP *bm) { BITMAP *b; RLE_SPRITE *ret; int x,y; if (!(b=create_bitmap(bm->w,bm->h))) return(NULL); clear(b); for(x=0;xw;x++) for(y=0;yh;y++) putpixel(b,x,y,ACOL(bm->pal[*(bm->data+(y*bm->w)+(x))])); ret=get_rle_sprite(b); destroy_bitmap(b); return((GFX_IMAGE)ret); } void GFX_destroy_image(GFX_IMAGE img) { destroy_rle_sprite(img); } void GFX_draw_image(GFX_IMAGE i, int x, int y) { RLE_SPRITE *s; s=i; draw_rle_sprite(bm,s,x,y); DIRTY(x,y); DIRTY(x+s->w,y+s->h); } void GFX_fill_screen(GFX_IMAGE i) { BITMAP *b; RLE_SPRITE *s; s=i; b=create_bitmap(s->w,s->h); draw_rle_sprite(b,s,0,0); stretch_blit(b,bm,0,0,s->w,s->h,0,0,width,height); destroy_bitmap(b); DIRTY(0,0); DIRTY(width,height); } void GFX_save_screen(char *path) { BITMAP *sub; sub=create_sub_bitmap(screen,0,0,width,height); save_bmp(path,sub,NULL); destroy_bitmap(sub); } /* END OF FILE */