summaryrefslogtreecommitdiff
path: root/djgpp/gfx.c
diff options
context:
space:
mode:
Diffstat (limited to 'djgpp/gfx.c')
-rw-r--r--djgpp/gfx.c559
1 files changed, 559 insertions, 0 deletions
diff --git a/djgpp/gfx.c b/djgpp/gfx.c
new file mode 100644
index 0000000..b93f6ea
--- /dev/null
+++ b/djgpp/gfx.c
@@ -0,0 +1,559 @@
+/*
+
+ 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 <stdio.h>
+#include <allegro.h>
+#include <stdarg.h>
+#include <ctype.h>
+#include <time.h>
+#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_SETTEXT(void)
+{
+ if (set_gfx_mode(GFX_TEXT,80,25,0,0)<0)
+ GFX_exit(EXIT_FAILURE,"Couldn't open text screen\n");
+
+ show_mouse(NULL);
+ remove_mouse();
+ remove_timer();
+ remove_keyboard();
+}
+
+
+void GFX_SETGRAPHICS(void)
+{
+ if (set_gfx_mode(GFX_AUTODETECT,width,height,0,0)<0)
+ GFX_exit(EXIT_FAILURE,"Couldn't re-open graphics screen\n");
+
+ install_keyboard();
+ install_timer();
+ install_mouse();
+ 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_x<dirty_min_x)
+ return;
+
+ dirty_min_x=MAX(0,dirty_min_x);
+ dirty_min_y=MAX(0,dirty_min_y);
+ dirty_max_x=MIN(width,dirty_max_x);
+ dirty_max_y=MIN(height,dirty_max_y);
+
+ show_mouse(NULL);
+
+ blit(bm,screen,dirty_min_x,dirty_min_y,
+ dirty_min_x,dirty_min_y,
+ dirty_max_x-dirty_min_x+1,dirty_max_y-dirty_min_y+1);
+
+ show_mouse(screen);
+
+ dirty_max_x=0;
+ dirty_min_x=width-1;
+ dirty_max_y=0;
+ dirty_min_y=width-1;
+}
+
+
+void GFX_FORCE_REDRAW(void)
+{
+ show_mouse(NULL);
+ blit(bm,screen,0,0,0,0,width,height);
+ show_mouse(screen);
+ dirty_max_x=0;
+ dirty_min_x=width-1;
+ dirty_max_y=0;
+ dirty_min_y=width-1;
+}
+
+
+void GFX_line(int x1,int y1,int x2,int y2,int col)
+{
+ DIRTY(x1,y1);
+ DIRTY(x2,y2);
+ line(bm,x1,y1,x2,y2,ACOL(col));
+}
+
+
+void GFX_plot(int x,int y,int col)
+{
+ DIRTY(x,y);
+ putpixel(bm,x,y,ACOL(col));
+}
+
+
+void GFX_circle(int x,int y,int r,int col)
+{
+ DIRTY(x-r-1,y-r-1);
+ DIRTY(x+r+1,y+r+1);
+ circle(bm,x,y,r,ACOL(col));
+}
+
+
+void GFX_fcircle(int x,int y,int r,int col)
+{
+ DIRTY(x-r-1,y-r-1);
+ DIRTY(x+r+1,y+r+1);
+ circlefill(bm,x,y,r,ACOL(col));
+}
+
+
+void GFX_rect(int x,int y,int w,int h,int col)
+{
+ DIRTY(x,y);
+ DIRTY(x+w,y+h);
+
+ w-=SGN(w);
+ h-=SGN(h);
+
+ rect(bm,x,y,x+w,y+h,ACOL(col));
+}
+
+
+void GFX_frect(int x,int y,int w,int h,int col)
+{
+ DIRTY(x,y);
+ DIRTY(x+w,y+h);
+
+ w-=SGN(w);
+ h-=SGN(h);
+
+ rectfill(bm,x,y,x+w,y+h,ACOL(col));
+}
+
+
+void GFX_set_XOR_mode(void)
+{
+ drawing_mode(DRAW_MODE_XOR,NULL,0,0);
+}
+
+
+void GFX_clear_XOR_mode(void)
+{
+ drawing_mode(DRAW_MODE_SOLID,NULL,0,0);
+}
+
+
+void GFX_print(int x,int y,int col,char *fmt,...)
+{
+ char s[512];
+ va_list va;
+
+ va_start(va,fmt);
+ vsprintf(s,fmt,va);
+ va_end(va);
+
+ DIRTY(x,y);
+ DIRTY(x+text_length(font,s),y+text_height(font));
+
+ text_mode(-1);
+ textout(bm,font,s,x,y,ACOL(col));
+}
+
+
+int GFX_fh(void)
+{
+ return(text_height(font));
+}
+
+
+int GFX_fw(void)
+{
+ return(text_length(font," "));
+}
+
+
+int GFX_mouse_buttons(void)
+{
+ return(mbuttons);
+}
+
+
+int GFX_mouse(int *x,int *y)
+{
+ if (x)
+ *x=mouse_x;
+
+ if (y)
+ *y=mouse_y;
+
+ return(mouse_b);
+}
+
+
+void GFX_waitkey(GFXKey *key)
+{
+ GFXKey dummy;
+
+ while(!keypressed());
+ if (key)
+ GetKey(key);
+ else
+ GetKey(&dummy);
+}
+
+
+int GFX_key(GFXKey *key)
+{
+ if(!keypressed())
+ return(FALSE);
+ else
+ {
+ GetKey(key);
+ return(TRUE);
+ }
+}
+
+
+void GFX_bounce(void)
+{
+ while((keypressed())||(mouse_b))
+ if (keypressed())
+ readkey();
+}
+
+
+void GFX_await_input(GFXEvent *ev)
+{
+ static time_t last_time=0;
+ static int mb;
+
+ /* Assume that a gap of 1-2 seconds means that this is a new await
+ input loop
+ */
+ if (time(NULL)-last_time>1)
+ 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;x<bm->w;x++)
+ for(y=0;y<bm->h;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 */