/************************************************************************
 *	TITLE:			GL_ODRAW.C				*
 *	PROJECT:		JAGUAR					*
 *	FUNCTION:		GEM like Library			*
 *	PROGRAMMER:		Cary Gee, Hans-Martin Krober, Andreas Binner		*
 *	DATE:			1/95					*
 *									*
 *              COPYRIGHT 1993,1994 Atari U.S. Corporation              *
 *          UNATHORIZED REPRODUCTION, ADAPTATION, DISTRIBUTION,         *
 *          PERFORMANCE OR DISPLAY OF THIS COMPUTER PROGRAM OR          *
 *        THE ASSOCIATED AUDIOVISUAL WORK IS STRICTLY PROHIBITED.       *
 *                            ALL RIGHTS RESERVED.                      *
 *									*
 ************************************************************************/

#include <stdarg.h>
#include "portab.h"
#include "glib.h"
#include "gemlib.h"
#include "joypad.h"
#include "alloc.h"
#include "slibc.h"
#include "timetab.h"

WORD	parser(VOID);

/* ===========================================================================
 * INTERNAL PROTOTYPES 
 */

/*
 *	Object Library
 */

VOID	ob_draw(OBJECT *tree, WORD obj, WORD depth);
WORD	ob_varargs(OBJECT *, ...);
WORD	alpha_char2ix(BYTE *, BYTE *, BYTE *);
WORD	get_par(OBJECT *tree, WORD obj);
VOID	everyobj(OBJECT *tree, WORD this, WORD last, 
		WORD startx, WORD starty, WORD maxdep);
VOID	just_draw(OBJECT *tree, WORD obj, WORD sx, WORD sy);
VOID	draw_alphaslider(SLALPHINFO *, OBJECT *, WORD, WORD, WORD);
VOID	draw_fltslider(SLFLTINFO *, OBJECT *, WORD, WORD, WORD);
VOID	draw_intslider(SLINTINFO *, OBJECT *, WORD, WORD, WORD);
VOID	draw_txtslider(SLTXTINFO *, OBJECT *, WORD, WORD, WORD);
VOID	draw_list(OBJECT *, WORD, WORD);
VOID	show_list(OBJECT *, WORD, WORD);
VOID	dn_list(OBJECT *, WORD);
VOID	up_list(OBJECT *, WORD);

BYTE	ob_sst(OBJECT *tree, WORD obj, LONG *pspec, WORD *pstate,
		WORD *ptype, WORD *pflags, GRECT *pt, WORD *pth);
VOID	gr_crack(UWORD color, WORD *pbc, WORD *ptc, WORD *pip, 
		WORD *pic, WORD *pmd);
VOID point2scrn(GRECT *r,LONG t,LONG a,WORD *x,WORD *y);


/* ===========================================================================
 * DEFINES
 */

#define ADJ3DPIX	3
#define ADJOUTLPIX	3
#define ADJSHADPIX	SHADOW
#define LLOWD(x) 	((UWORD)(x))
#define LLOBT(x) 	((BYTE)(x))
#define LBYTE2(x) 	(*((x)+1))
#define LBYTE3(x) 	(*(x))
#define LWGET(x) 	((WORD) *((WORD *)(x)))
#define TED_THICKNESS	22
#define LHIBT(x) 	((BYTE)(x >> 8))
#define	XADJ3DPIX	2

/* ===========================================================================
 * EXTERNALS
 */

EXTERN LONG _levels;
EXTERN LONG _edges;
EXTERN VOID _readpad(VOID);

EXTERN WORD *v_bas_ad;

EXTERN VOID voices_off(VOID);

/* ===========================================================================
 * GLOBALS
 */

WORD	_ap_id;

WORD	gl_wchar;
WORD	gl_hchar;


LONG sl_table[] = {	/* Ramping values for slider code */
	0L,                       
	1L,
	10L,
	100L,
	1000L,
	10000L,
	100000L,
	1000000L,
	10000000L,
	100000000L,
	1000000000L
};

EXTERN BYTE	MenuBuffer[];

/*
 *	This one does the real object drawing work
 */

VOID v_dark_tree(OBJECT *tree)
{
	LONG x1,y1,x2,y2;
	
	x1=tree[0].ob_x;
	y1=tree[0].ob_y;
	x2=x1+tree[0].ob_width;
	y2=y1+tree[0].ob_height;

	v_darken(x1,y1,x2,y2);
}

draw_arrow(LONG type,LONG *pts)
{
	LONG xy[4];
			
	xy[0]=pts[2];
	xy[1]=pts[3];
	switch(type)
	{
		case 0:
			xy[2]=xy[0]-9;
			xy[3]=xy[1]-5;
			v_line(xy);
			xy[2]=xy[0]-9;
			xy[3]=xy[1]+5;
			v_line(xy);
		break;
		case 1:
			xy[2]=xy[0]+9;
			xy[3]=xy[1]-5;
			v_line(xy);
			xy[2]=xy[0]+9;
			xy[3]=xy[1]+5;
			v_line(xy);
		break;
		case 2:
			xy[2]=xy[0]-5;
			xy[3]=xy[1]-9;
			v_line(xy);
			xy[2]=xy[0]+5;
			xy[3]=xy[1]-9;
			v_line(xy);
		break;
		case 3:
			xy[2]=xy[0]-5;
			xy[3]=xy[1]+9;
			v_line(xy);
			xy[2]=xy[0]+5;
			xy[3]=xy[1]+9;
			v_line(xy);
		break;
		case 4:
			xy[2]=xy[0]-10;
			xy[3]=xy[1]-3;
			v_line(xy);
			xy[2]=xy[0]-3;
			xy[3]=xy[1]-10;
			v_line(xy);
		break;
		case 5:
			xy[2]=xy[0]+10;
			xy[3]=xy[1]+3;
			v_line(xy);
			xy[2]=xy[0]+3;
			xy[3]=xy[1]+10;
			v_line(xy);
		break;
		case 6:
			xy[2]=xy[0]+3;
			xy[3]=xy[1]-10;
			v_line(xy);
			xy[2]=xy[0]+10;
			xy[3]=xy[1]-3;
			v_line(xy);
		break;
		case 7:
			xy[2]=xy[0]-10;
			xy[3]=xy[1]+3;
			v_line(xy);
			xy[2]=xy[0]-3;
			xy[3]=xy[1]+10;
			v_line(xy);
		break;
	}
}

SetGRECT(GRECT *r,WORD x,WORD y,WORD w,WORD h)
{
	r->g_x=x;
	r->g_y=y;
	r->g_w=w;
	r->g_h=h;
}

VOID point2scrn(GRECT *r,LONG t,LONG a,WORD *x,WORD *y)
{
	WORD y_scale,x_scale,d;
	
	a>>=15;
	y_scale=32767/r->g_h;
	*y=r->g_y+r->g_h-a/y_scale;


	x_scale=256/r->g_w;
	d=0;
	while (t>timetab[d].time && d<256)
		d++;

	d/=x_scale;

	*x=r->g_x+d;
}


	VOID
just_draw(OBJECT *tree, WORD obj, WORD sx, WORD sy)
{
	UWORD  type,f,d;
	UWORD  state;
	UWORD  flag;
	LONG	w,t,ct;
	WORD	pty,len,ab,ty;
	WORD	bx,by,bb,bh;
	LONG	ma,mi,cu,mask;
	OBJECT *curtree;
	GRECT  pt,r;
	LONG pts[4],xy[4];
	WORD font_w[]={6,8,8};
	WORD font_h[]={6,8,16};
	BYTE *str,temp[255],*text;
	XOBJECT		*xobp;
	EXTERN LONG vdiColorTable[];
	BYTE sstr[10];
	BYTE dummystr[4];
	
	curtree = (OBJECT *) &tree[obj];
	type    = ObType(obj);
	state   = ObState(obj);
	flag    = ObFlags(obj);

	if (flag & HIDETREE)
		return;

	if (state & DISABLED)
	{
		vdiColorTable[0]=0x7bde7bde;	
		vdiColorTable[1]=0x7bde7bde;	
	}
	vsf_color(LWHITE);

	xobp = &(curtree->ob_spec.common->ex_ob);

	switch (type) {

	case G_XTEXTEDIT:
		strcpy(sstr,"%00ld");
		d=curtree->ob_spec.textedit->maxsize;
		if (d>9)
			d=9;
		sstr[2]='0'+d;
		SetGRECT(&r,sx,sy,ObW(obj),ObH(obj));	

		vsf_color(LWHITE);
		if (flag&IS3DOBJ)
			vr_bar3d(&r,0L);
		else
			vr_bar(&r,0L);
		f=curtree->ob_spec.textedit->fontid;
		str=curtree->ob_spec.textedit->slname;
		text=curtree->ob_spec.textedit->data;
		if (curtree->ob_spec.textedit->usage)
			sprintf(text,sstr,curtree->ob_spec.textedit->value);
		bb=curtree->ob_spec.textedit->maxsize*font_w[f];
		ty=sy+10;
		xobp->num_zones=1;
		xobp->zones[0].rect.g_x=sx+(ObW(obj)-bb)/2-2;
		xobp->zones[0].rect.g_y=ty-2;
		xobp->zones[0].rect.g_w=bb+4;
		xobp->zones[0].rect.g_h=font_h[f]+4;
		xobp->zones[0].joyval=OPTION+FIRE_A+FIRE_B+FIRE_C;
		vst_font(0);
		vst_color(BLACK);
		v_gtext(sx+CenterString(str,ObW(obj),0),ty-9,str);
		vsf_color(WHITE);
		vst_font(f);
		vr_bar(&(xobp->zones[0].rect),0L);
		v_gtext(xobp->zones[0].rect.g_x+2,xobp->zones[0].rect.g_y+2,text);		
		vsl_color(BLACK);
		vr_frame(&(xobp->zones[0].rect));
	break;

	case G_XENVELOPE:
		SetGRECT(&r,sx,sy,ObW(obj),ObH(obj));
		v_Ibar3d(sx,sy,ObW(obj),ObH(obj));
		xobp->num_zones=curtree->ob_spec.env->points;
		bx=by=0;
		f=0;
		if (ObW(obj)<256)
			f=1;
							
		vst_color(LWHITE);
		vst_font(0);
		vst_wrmode(1);
		for (d=0;d<xobp->num_zones;d++)
		{
			pts[0]=bx;
			pts[1]=by;
			point2scrn(&r,curtree->ob_spec.env->time[d],curtree->ob_spec.env->ampl[d],&bx,&by);
			xobp->zones[d].rect.g_x=bx-2;
			xobp->zones[d].rect.g_y=by-2;
			xobp->zones[d].rect.g_w=4;
			xobp->zones[d].rect.g_h=4;
			xobp->zones[d].joyval=d+1;
			if (d==curtree->ob_spec.env->curr_point)
				vsl_color(CYAN);
			else
				vsl_color(RED);
			if (!f)
				vr_frame(&xobp->zones[d].rect);
			if (d==xobp->num_zones-2)
			{
				w=curtree->ob_spec.env->time[d];
				vsl_color(GREEN);
				xy[1]=r.g_y;
				xy[3]=r.g_y+r.g_h-1;
				xy[0]=xy[2]=bx;
				v_line(xy);
				if (!f)
					v_gtext(bx+2,r.g_y+r.g_h-7,"0");
			}
			if (d)
			{
				vsl_color(WHITE);
				pts[2]=bx;
				pts[3]=by;
				v_line(pts);
			}
		
		}
		if (f)
			break;
		vst_color(LWHITE);
		vst_font(0);
		vst_wrmode(1);
		vsl_color(LWHITE);
		pts[1]=r.g_y;
		pts[3]=r.g_y+r.g_h-1;
		t=0x8000;	/* 1 ms */
		do
		{
			point2scrn(&r,t,0,&bx,&by);
			if (bx>r.g_x && bx<r.g_x+r.g_w)
			{
				pts[0]=pts[2]=bx;
				v_line(pts);
				if (t>=0x1f40000)
					sprintf(temp,"%lds",t/0x1f40000);
				else
					sprintf(temp,"%ldms",t/0x8000);
				v_gtext(bx+1,r.g_y+1,temp);

				if (t>w)
				{
					ct=t-w;
					if (ct>=0x1f40000)
						sprintf(temp,"%lds",ct/0x1f40000);
					else
						sprintf(temp,"%ldms",ct/0x8000);
					v_gtext(bx+2,r.g_y+r.g_h-7,temp);
				}
			}
			t*=10;
		} while (bx>=r.g_x && bx<r.g_x+r.g_w);
		
	break;

	case G_XREALSLIDER:
		SetGRECT(&r,sx,sy,ObW(obj),ObH(obj));
		vsf_color(LWHITE);
		vst_font(0);
		vst_color(BLACK);
		vst_wrmode(1);
		ab=curtree->ob_spec.slider->flags;
		if (!(ab&1))
		{
			if (flag&IS3DOBJ)
				vr_bar3d(&r,0L);
			else
				vr_bar(&r,0L);
		}
		
		bx=sx+(ObW(obj)-8)/2;
		by=sy+12;
		bb=8;
		bh=ObH(obj)-24;
		v_Ibar3d(bx, by, bb, bh);
		ma=curtree->ob_spec.slider->max;
		mi=curtree->ob_spec.slider->min;
		cu=curtree->ob_spec.slider->curr;
		f=curtree->ob_spec.slider->frac;
		if (ma == mi)
			ty=by+bh-bb;
		else
			ty=by+bh-bb-(WORD)((LONG)(bh-bb)*(cu-mi)/(ma-mi));
		xobp->num_zones=2;
		xobp->zones[0].rect.g_x=bx;
		xobp->zones[0].rect.g_y=ty;
		xobp->zones[0].rect.g_w=bb;
		xobp->zones[0].rect.g_h=bb;
		xobp->zones[0].joyval=FIRE_A;
		vst_color(BLACK);
		/* this is to keep the stupid PC version of GCC happy: */
		dummystr[0] = (unsigned char) 0xf0;
		dummystr[1] = (unsigned char) 0x00;

		vr_bar3d(&(xobp->zones[0].rect), dummystr);
		vst_color(WHITE);
		v_gtext(bx+1,ty+2, dummystr);
		vst_color(BLACK);
		if (f)
		{
			mask=(0xffffffff<<f)^0xffffffff;
			sprintf(temp,"%ld:%ld",cu>>f,cu&mask);
		}
		else
		{
			if (cu>=0)
				sprintf(temp,"%ld",cu);
			else
				sprintf(temp,"-%ld",-cu);
		}
		
		if (ab&1)
			v_bar(sx+1,sy+1,ObW(obj)-2,9);
			
		xobp->zones[1].rect.g_x=sx+CenterString(temp,ObW(obj),0);
		xobp->zones[1].rect.g_y=sy+2;
		xobp->zones[1].rect.g_w=6*strlen(temp);
		xobp->zones[1].rect.g_h=6;
		xobp->zones[1].joyval=OPTION;
		v_gtext(sx+CenterString(temp,ObW(obj),0),sy+2,temp);
		if (!(ab&1))
		{
			str=curtree->ob_spec.slider->slname;
			v_gtext(sx+CenterString(str,ObW(obj),0),by+bh+4,str);
		}
		curtree->ob_spec.slider->flags&=~1;
	break;

	case G_XPOPUP:
		pty=curtree->ob_spec.popup->type;
		SetGRECT(&r,sx,sy,ObW(obj),ObH(obj));	

		vsf_color(LWHITE);
		if (flag&IS3DOBJ)
			vr_bar3d(&r,0L);
		else
			vr_bar(&r,0L);
		f=curtree->ob_spec.popup->fontid;
		str=curtree->ob_spec.popup->slname;
		d=curtree->ob_spec.popup->index;
		GetPopItem(curtree->ob_spec.popup->data,d,temp);
		vst_color(BLACK);
		vst_wrmode(1);

		xobp->num_zones=1;
		if (pty&ACTION_BUTTON)
			ab=16;
		else
			ab=0;
		if (pty&LEFT_TITLE)
		{
			len=(strlen(str)+1)*font_w[0];
			if (len>=ObW(obj))
				break;
			vst_font(0);
			ty=sy+2;
			v_gtext(sx,ty+(font_h[f]-6)/2+1,str);
			xobp->zones[0].rect.g_x=sx+len;
			xobp->zones[0].rect.g_y=ty;
			xobp->zones[0].rect.g_w=ObW(obj)-len-ab;
			xobp->zones[0].rect.g_h=font_h[f]+2;						
		}
		else
		{
			ty=sy+10;
			xobp->zones[0].rect.g_x=sx+1;
			xobp->zones[0].rect.g_y=ty;
			xobp->zones[0].rect.g_w=ObW(obj)-ab-2;
			xobp->zones[0].rect.g_h=font_h[f]+2;
			vst_font(0);
			v_gtext(sx+CenterString(str,ObW(obj),0),ty-9,str);
		}
		xobp->zones[0].joyval=FIRE_A;

		vst_font(f);
		vr_bar_shadow(&(xobp->zones[0].rect),temp);		

		if (ab)
		{
			xobp->num_zones=2;
			xobp->zones[1].joyval=FIRE_C;
			xobp->zones[1].rect.g_x=sx+ObW(obj)-10;
			xobp->zones[1].rect.g_y=ty+1;
			xobp->zones[1].rect.g_w=font_h[f]+1;
			xobp->zones[1].rect.g_h=font_h[f]+1;
			vr_bar3d(&(xobp->zones[1].rect),"\177");		
		}

	break;

	case G_XARROW:
		w=(LONG)ObW(obj);
		switch((LONG)tree[obj].ob_spec.value)
		{
			case 0:
				pts[0]=(LONG)sx;			
				pts[1]=(LONG)sy;			
				pts[2]=(LONG)sx+w;			
				pts[3]=(LONG)sy;			
			break;
			
			case 1:
				pts[0]=(LONG)sx+w;			
				pts[1]=(LONG)sy;			
				pts[2]=(LONG)sx;			
				pts[3]=(LONG)sy;			
			break;
			
			case 2:
				pts[0]=(LONG)sx;			
				pts[1]=(LONG)sy;			
				pts[2]=(LONG)sx;			
				pts[3]=(LONG)sy+w;			
			break;
			
			case 3:
				pts[0]=(LONG)sx;			
				pts[1]=(LONG)sy+w;			
				pts[2]=(LONG)sx;			
				pts[3]=(LONG)sy;			
			break;
			
			case 4:
				pts[0]=(LONG)sx;			
				pts[1]=(LONG)sy;			
				pts[2]=(LONG)sx+w;			
				pts[3]=(LONG)sy+w;			
			break;
			
			case 5:
				pts[0]=(LONG)sx+w;			
				pts[1]=(LONG)sy+w;			
				pts[2]=(LONG)sx;			
				pts[3]=(LONG)sy;			
			break;
			
			case 6:
				pts[0]=(LONG)sx;			
				pts[1]=(LONG)sy;			
				pts[2]=(LONG)sx-w;			
				pts[3]=(LONG)sy+w;			
			break;
			
			case 7:
				pts[0]=(LONG)sx-w;			
				pts[1]=(LONG)sy+w;			
				pts[2]=(LONG)sx;			
				pts[3]=(LONG)sy;			
			break;		
		}
		
		vsl_color(LBLACK);
		v_line(pts);
		draw_arrow((LONG)tree[obj].ob_spec.value,pts);
		pts[0]++;
		pts[1]++;
		pts[2]++;
		pts[3]++;
		vsl_color(WHITE);
		v_line(pts);
		draw_arrow((LONG)tree[obj].ob_spec.value,pts);
	break;
	
  	case G_BOX:
	case G_XBAR:
		if (flag&FRAME)
			v_frame3d( sx, sy, ObW( obj ), ObH( obj ) );
		else
		{
			if (flag&IS3DOBJ)
			{
				if (tree[obj].ob_state & SELECTED)
					v_Ibar3d( sx, sy, ObW( obj ), ObH( obj ) );
				else
					v_bar3d( sx, sy, ObW( obj ), ObH( obj ) );
			}
			else
				v_bar( sx, sy, ObW( obj ), ObH( obj ) );
		}
		break;
	case G_STRING:
		pt.g_x = sx;
		pt.g_y = sy;
		pt.g_w = tree[obj].ob_width;
		pt.g_h = tree[obj].ob_height;

		gtext_attr(1, 0x0001, 0, 1);
		gr_gtext(TE_LEFT, (BYTE *) tree[obj].ob_spec.value, &pt, 0);
		break;

	case G_XBUTTON:  
		{
		  BTTNINFO *bttn = tree[obj].ob_spec.button;
				
			xobp->num_zones=1;
			xobp->zones[0].rect.g_x=sx;
			xobp->zones[0].rect.g_y=sy;
			xobp->zones[0].rect.g_w=ObW(obj);
			xobp->zones[0].rect.g_h=ObH(obj);
			xobp->zones[0].joyval=FIRE_A;
		  if (flag&CHECKBOX)
		  {
		  		vsf_color(LWHITE);
		  		d=font_h[bttn->bt_fontid];
			  	if (tree[obj].ob_flags & IS3DOBJ)
					v_bar3d(sx, sy, ObW(obj), ObH(obj));
				else
					v_bar(sx, sy, ObW(obj), ObH(obj));
				sx+=3;
				sy+=3;
				v_Ibar3d(sx,sy,d,d);
				vsl_color(WHITE);
				if (state&SELECTED)
				{
					pts[0]=sx;
					pts[1]=sy;
					pts[2]=sx+d-1;
					pts[3]=sy+d-1;
					v_line(pts);
					pts[0]=pts[2];
					pts[2]=sx;
					v_line(pts);
				}
				vst_font(bttn->bt_fontid);
				vst_color(bttn->bt_txtcolor);
				v_gtext(sx+12,sy,bttn->bt_text);
		  }
		  else
		  {
			  if (tree[obj].ob_state & SELECTED)
				v_Ibar3d(sx, sy, ObW(obj), ObH(obj));
			  else
				v_bar3d(sx, sy, ObW(obj), ObH(obj));
			  pt.g_x = sx;
			  pt.g_y = sy;
			  pt.g_w = tree[obj].ob_width;
			  pt.g_h = tree[obj].ob_height;
	
			  if (bttn != NULL) {
				gtext_attr(bttn->bt_fontid, bttn->bt_txtcolor, 0, 1);
				gr_gtext(TE_CNTR, bttn->bt_text, &pt, 0);
		
				vst_font(FNT_SMALL);	/* set font type */
				pt.g_x = sx + pt.g_w - 7;
				pt.g_y = sy + 1;

				v_bltchr(pt.g_x, pt.g_y, bttn->bt_smchar);
			}
		  }
		}
		break;

	case G_XBOXTEXT:
		{
		  BOXTXTINFO *box = tree[obj].ob_spec.boxtext;

		   if (tree[obj].ob_flags & IS3DOBJ) {
			  if (tree[obj].ob_state & SELECTED)
				v_Ibar3d(sx, sy, ObW(obj), ObH(obj));
			  else
				v_bar3d(sx, sy, ObW(obj), ObH(obj));
		   } else
			v_bar3d(sx, sy, ObW(obj), ObH(obj));

		  pt.g_x = sx;
		  pt.g_y = sy;
		  pt.g_w = tree[obj].ob_width;
		  pt.g_h = tree[obj].ob_height;

		  gtext_attr(box->bx_fontid, box->bx_txtcolor, 0, 1);
		  gr_gtext(box->bx_align, box->bx_text, &pt, 0);

		}
		break;

	case G_XTEXT:
		{
		  BOXTXTINFO *box = tree[obj].ob_spec.boxtext;

		  pt.g_x = sx;
		  pt.g_y = sy;
		  pt.g_w = tree[obj].ob_width;
		  pt.g_h = tree[obj].ob_height;

		  gtext_attr(box->bx_fontid, box->bx_txtcolor, 0, 1);
		  gr_gtext(box->bx_align, box->bx_text, &pt, 0);

		}
		break;
#if 1
	case G_XALPHSLIDER:  
		xobp->num_zones=2;
		xobp->zones[0].rect.g_x=sx+ObW(obj)-12;
		xobp->zones[0].rect.g_y=sy+12;
		xobp->zones[0].rect.g_w=12;
		xobp->zones[0].rect.g_h=20;
		xobp->zones[0].joyval=JOY_UP;
		xobp->zones[1].rect.g_x=sx;
		xobp->zones[1].rect.g_y=sy+12;
		xobp->zones[1].rect.g_w=12;
		xobp->zones[1].rect.g_h=20;
		xobp->zones[1].joyval=JOY_DOWN;
		
		draw_alphaslider(curtree->ob_spec.alphaslider, tree, obj, sx, sy);
		break;	
	case G_XFLTSLIDER:  
		xobp->num_zones=2;
		xobp->zones[0].rect.g_x=sx+ObW(obj)-12;
		xobp->zones[0].rect.g_y=sy+12;
		xobp->zones[0].rect.g_w=12;
		xobp->zones[0].rect.g_h=20;
		xobp->zones[0].joyval=JOY_UP|FIRE_A;
		xobp->zones[1].rect.g_x=sx;
		xobp->zones[1].rect.g_y=sy+12;
		xobp->zones[1].rect.g_w=12;
		xobp->zones[1].rect.g_h=20;
		xobp->zones[1].joyval=JOY_DOWN|FIRE_A;

		draw_fltslider(curtree->ob_spec.floatslider, tree, obj, sx, sy);
		break;	

	case G_XTXTSLIDER:  
		xobp->num_zones=2;
		xobp->zones[0].rect.g_x=sx+ObW(obj)-12;
		xobp->zones[0].rect.g_y=sy+12;
		xobp->zones[0].rect.g_w=12;
		xobp->zones[0].rect.g_h=20;
		xobp->zones[0].joyval=JOY_UP;
		xobp->zones[1].rect.g_x=sx;
		xobp->zones[1].rect.g_y=sy+12;
		xobp->zones[1].rect.g_w=12;
		xobp->zones[1].rect.g_h=20;
		xobp->zones[1].joyval=JOY_DOWN;

		draw_txtslider(curtree->ob_spec.textslider, tree, obj, sx, sy);
		break;	

	case G_XINTSLIDER:  
		xobp->num_zones=2;
		xobp->zones[0].rect.g_x=sx+ObW(obj)-12;
		xobp->zones[0].rect.g_y=sy+12;
		xobp->zones[0].rect.g_w=12;
		xobp->zones[0].rect.g_h=20;
		xobp->zones[0].joyval=JOY_UP|FIRE_A;
		xobp->zones[1].rect.g_x=sx;
		xobp->zones[1].rect.g_y=sy+12;
		xobp->zones[1].rect.g_w=12;
		xobp->zones[1].rect.g_h=20;
		xobp->zones[1].joyval=JOY_DOWN|FIRE_A;

		draw_intslider(curtree->ob_spec.intslider, tree, obj, sx, sy);
		break;	 	
	case G_XLIST:  
		xobp->num_zones=3;
		xobp->zones[0].rect.g_x=sx+ObW(obj)-12;
		xobp->zones[0].rect.g_y=sy+14;
		xobp->zones[0].rect.g_w=12;
		xobp->zones[0].rect.g_h=12;
		xobp->zones[0].joyval=JOY_UP;
		xobp->zones[1].rect.g_x=sx+ObW(obj)-12;
		xobp->zones[1].rect.g_y=sy+ObH(obj)-12;
		xobp->zones[1].rect.g_w=12;
		xobp->zones[1].rect.g_h=12;
		xobp->zones[1].joyval=JOY_DOWN;
/*		xobp->zones[2].rect.g_x=sx;
		xobp->zones[2].rect.g_y=sy+ObH(obj)/2+7;
		xobp->zones[2].rect.g_w=ObW(obj)-12;
		xobp->zones[2].rect.g_h=8;
		xobp->zones[2].joyval=FIRE_A;*/
		xobp->zones[2].rect.g_x=sx;
		xobp->zones[2].rect.g_y=sy+18;
		xobp->zones[2].rect.g_w=ObW(obj)-12;
		xobp->zones[2].rect.g_h=ObH(obj)-10;
		xobp->zones[2].joyval=FIRE_A+OPTION;

		draw_list(&tree[obj], sx, sy);
		show_list(&tree[obj], sx, sy);
		break;	 	
#endif
	case G_XBOXCHAR:
		if (tree[obj].ob_state & SELECTED)
			v_Ibar3d(sx, sy, ObW(obj), ObH(obj));
		else
			v_bar3d(sx, sy, ObW(obj), ObH(obj));

		pt.g_x = sx;
		pt.g_y = sy;
		pt.g_w = tree[obj].ob_width;
		pt.g_h = tree[obj].ob_height;

		gtext_attr(1, 0x0001, 0, 1);
		gr_gtext(TE_CNTR, (BYTE *) tree[obj].ob_spec.value, &pt, 0);
		break;
	default:
		break;
     } /* switch */

	vdiColorTable[0]=0xfffefffe;	
	vdiColorTable[1]=0L;	

} /* just_draw */


/*
 *	Draw a alpha numeric slider
 */
	VOID
draw_alphaslider(slinfo, tree, obj, sx, sy)
	SLALPHINFO *slinfo;
	OBJECT 	*tree;
	WORD	obj;
	WORD	sx, sy;
{
	WORD	slwidth, slheight;
	WORD	boxx, boxy;
	WORD	intx, fracx, texty;
	WORD	titlex;

	vst_bgcolor(LWHITE);

	slinfo->sliderx = sx;
	slinfo->slidery = sy;

	slwidth = (slinfo->mainspaces + slinfo->extspaces + 5) * 
		slinfo->charwidth;
	slheight = 2 * slinfo->charheight;
	boxx = slinfo->sliderx;
	boxy = slinfo->slidery + ((slinfo->charheight == 6) ?
		slinfo->charheight + 3 : slinfo->charheight);
	intx = boxx + 2 * slinfo->charwidth;
	fracx = intx + (slinfo->mainspaces * slinfo->charwidth) + 
		slinfo->charwidth;
	texty = boxy + (slinfo->charheight / 2);

	v_bar3d(boxx, slinfo->slidery, slwidth, 4 * slinfo->charheight);


	v_bar3d(boxx, boxy, slinfo->charwidth, slheight);
	v_bar3d(boxx + ( 2 * slinfo->charwidth), boxy,
			slwidth - (4 * slinfo->charwidth),
			slheight);
	v_bar3d(boxx + slwidth - slinfo->charwidth,
			boxy,
			slinfo->charwidth,
			slheight);


	titlex = (boxx + (slwidth / 2))-
	      (((strlen(slinfo->slname)) * 6) / 2);  /* assume 6x6 font */

	vst_color(LGREEN);
	vst_font(FNT_SMALL);
	vst_wrmode(1);

	v_gtext(titlex, slinfo->slidery + 1, slinfo->slname);

	vst_color(BLACK);
	vst_font(slinfo->fontid);
	vst_wrmode(0);


	v_bltchr(slinfo->sliderx, texty, 2);
    	v_bltchr(slinfo->sliderx + slwidth - slinfo->charwidth, texty, 1);

	v_gtext(intx, texty, slinfo->mainstr);
	if (slinfo->extflag) {
		v_gtext(fracx - slinfo->charwidth, texty, ".");
		v_gtext(fracx, texty, slinfo->extstr);
	}
}

/*
 *	Draw a floating point number slider
 */
	VOID
draw_fltslider(slinfo, tree, obj, sx, sy)
	SLFLTINFO *slinfo;
	OBJECT 	*tree;
	WORD	obj;
	WORD	sx, sy;
{
	WORD	slwidth, slheight;
	BYTE	intstr[10];
	BYTE	fracstr[10];
	WORD	boxx, boxy;
	WORD	intx, fracx, texty;
	WORD	titlex;

	vst_bgcolor(LWHITE);

	slinfo->sliderx = sx;
	slinfo->slidery = sy;

	slwidth = (slinfo->intspaces + slinfo->fracspaces + 5) * 
		slinfo->charwidth;
	slheight = 2 * slinfo->charheight;
	boxx = slinfo->sliderx;
	boxy = slinfo->slidery + ((slinfo->charheight == 6) ?
		slinfo->charheight + 3 : slinfo->charheight);
	intx = boxx + 2 * slinfo->charwidth;
	fracx = intx + (slinfo->intspaces * slinfo->charwidth) + 
		slinfo->charwidth;
	texty = boxy + (slinfo->charheight / 2);

	v_bar3d(boxx, slinfo->slidery, slwidth, 4 * slinfo->charheight);


	v_bar3d(boxx, boxy, slinfo->charwidth, slheight);
	v_bar3d(boxx + ( 2 * slinfo->charwidth), boxy,
			slwidth - (4 * slinfo->charwidth),
			slheight);
	v_bar3d(boxx + slwidth - slinfo->charwidth,
			boxy,
			slinfo->charwidth,
			slheight);


	titlex = (boxx + (slwidth / 2))-
	      (((strlen(slinfo->slname)) * 6) / 2);  /* assume 6x6 font */

	vst_color(LGREEN);
	vst_font(FNT_SMALL);
	vst_wrmode(1);

	v_gtext(titlex, slinfo->slidery + 1, slinfo->slname);

	vst_color(BLACK);
	vst_font(slinfo->fontid);
	vst_wrmode(0);

	ltoa(slinfo->intval,  slinfo->intspaces, intstr);
	ltoa(slinfo->fracval, slinfo->fracspaces, fracstr);

	v_bltchr(slinfo->sliderx, texty, 2);
    	v_bltchr(slinfo->sliderx + slwidth - slinfo->charwidth, texty, 1);

	v_gtext(intx, texty, intstr);
	v_gtext(fracx - slinfo->charwidth, texty, ":");
	v_gtext(fracx, texty, fracstr);
}



/*
 *	Draw an integer number slider
 */

	VOID
draw_intslider(slinfo, tree, obj, sx, sy)
	SLINTINFO *slinfo;
	OBJECT 	*tree;
	WORD	obj;
	WORD	sx, sy;
{
	WORD	slwidth, slheight;
	BYTE	intstr[15];
	WORD	boxx, boxy;
	WORD	intx, texty;
	WORD	titlex;

	vst_bgcolor(LWHITE);

	slinfo->sliderx = sx; /* tree[obj].ob_x; */
	slinfo->slidery = sy; /* tree[obj].ob_y; */

	slwidth = (slinfo->intspaces + 5) * slinfo->charwidth;
	/* slwidth = slinfo->slwidth; */
	slheight = 2 * slinfo->charheight;
	boxx = slinfo->sliderx;
	boxy = slinfo->slidery + ((slinfo->charheight == 6) ?
		slinfo->charheight + 3 : slinfo->charheight);
/*	intx = boxx + 2 * slinfo->charwidth; */
	intx = (boxx + (slwidth / 2)) - 
		((slinfo->intspaces * slinfo->charwidth) / 2);
	texty = boxy + (slinfo->charheight / 2);

	v_bar3d(boxx, slinfo->slidery, slwidth, 4 * slinfo->charheight);
	tree[obj].ob_width=slwidth;
	tree[obj].ob_height=4 * slinfo->charheight;
	
	v_bar3d(boxx, boxy, slinfo->charwidth, slheight);
	v_bar3d(intx, boxy, slinfo->intspaces * slinfo->charwidth, slheight);
	v_bar3d(boxx + slwidth - slinfo->charwidth, boxy,
		slinfo->charwidth, slheight);

	titlex = boxx + (slwidth / 2) -
		((strlen(slinfo->slname) * 6) / 2);  /* assume 6x6 font */

	vst_color(LGREEN);
	vst_font(FNT_SMALL);
	vst_wrmode(1);

	v_gtext(titlex, slinfo->slidery + 1, slinfo->slname);
	
	vst_color(BLACK);

	vst_font(slinfo->fontid);
    	vst_wrmode(0);

	if (slinfo->signextend)
		ltoa(slinfo->intval, (WORD)slinfo->intspaces, intstr);
	else
		ltoa(slinfo->intval, (WORD)slinfo->intspaces, intstr);

	v_bltchr(slinfo->sliderx, texty, 2);
	v_bltchr(slinfo->sliderx + slwidth - slinfo->charwidth, texty, 1);

    	v_gtext(intx, texty, intstr);
}

/*
 *	Draw Text Slider
 */
	VOID
draw_txtslider(slinfo, tree, obj, sx, sy)
	SLTXTINFO *slinfo;
	OBJECT 	*tree;
	WORD	obj;
	WORD	sx, sy;
{
	WORD	slwidth, slheight;
	WORD	boxx, boxy;
	WORD	xpos, ypos;
	WORD	titlex;

	vst_bgcolor(LWHITE);

	slinfo->sliderx = sx; /* tree[obj].ob_x; */
	slinfo->slidery = sy; /* tree[obj].ob_y; */

	slwidth = (slinfo->maxlength + 5) * slinfo->charwidth;
	slheight = 2 * slinfo->charheight;
	boxx = slinfo->sliderx;
	boxy = slinfo->slidery + ((slinfo->charheight == 6) ?
		slinfo->charheight + 3 : slinfo->charheight);

/*	xpos = boxx + 2 * slinfo->charwidth; */
	xpos = (boxx + (slwidth / 2)) - 
		((slinfo->maxlength * slinfo->charwidth) / 2);
	ypos = boxy + (slinfo->charheight / 2);

	v_bar3d(boxx, slinfo->slidery, slwidth, 4 *slinfo->charheight);

	v_bar3d(boxx, boxy, slinfo->charwidth, slheight);
	v_bar3d(boxx + (2 * slinfo->charwidth), boxy,
			slwidth - (4 * slinfo->charwidth),
			slheight);
	v_bar3d(boxx + slwidth - slinfo->charwidth,
			boxy,
			slinfo->charwidth,
			slheight);

	titlex = (boxx + (slwidth / 2)) -
		((strlen(slinfo->slname) * 6 ) / 2);  /* assume 6x6 font */
	vst_color(LGREEN);
	vst_font(FNT_SMALL);
	vst_wrmode(1);
	
	v_gtext(titlex, slinfo->slidery + 1, slinfo->slname);

	vst_color(BLACK);
	vst_font(slinfo->fontid);
    	vst_wrmode(0);

	v_bltchr(slinfo->sliderx, ypos, 2);
	v_bltchr(slinfo->sliderx + slwidth - slinfo->charwidth, ypos, 1);

	v_gtext(xpos, ypos, (BYTE*)(slinfo->table[slinfo->index]));
}

/*
 *	draw list object
 */
	VOID
draw_list(obj, sx, sy)
	OBJECT *obj;
	WORD	sx, sy;
{
	WORD x, y, w, h;
	GRECT pt;
	REG LISTINFO *li = obj->ob_spec.list;
	REG WORD i, n;

	/* Main Box	 */
	vsf_color(LWHITE);
	v_bar3d(sx, sy, obj->ob_width, obj->ob_height);

	
	/* Scroll Bar 	*/
	vst_color(WHITE);
	sx += 2;
	sy += 2;
	x = sx + obj->ob_width - 12;
	y = sy + 12;
	v_bar3d(x, y, 10, obj->ob_height - 14);
	vst_font(FNT_MEDIUM);
	v_bltchr(x+1, y, '\001');
	v_bltchr(x+1, y + obj->ob_height - 12 - 10, '\002');


	/* Name Box	*/
	v_bar3d(sx-2, sy-2, obj->ob_width, 10);
	pt.g_x = sx - 2;
	pt.g_y = sy - 2;
	pt.g_w = obj->ob_width;
	pt.g_h = 10;
	gtext_attr(1, 0x0001, 0, 1);
	gr_gtext(TE_CNTR, (BYTE *) li->name, &pt, 0);

	vst_color(LGREEN);
	vst_font(li->fontid);

	/* Columns: Boxes + Titels	*/
	n = li->ncols;
	x = sx - 2 + li->cx[0];
	y = sy + 12;
	h = obj->ob_height - 14;
	for (i = 0; i < (n-1); i++) {
		x = sx - 2 + li->cx[i];
		w = li->cx[i+1] - li->cx[i] - 2;
		v_bar3d(x, y, w, h);
		v_gtext(x+1, y+2, li->titles[i]);
	}
	x = sx - 2 + li->cx[i];
	w = obj->ob_width - li->cx[i] - 14;
	v_bar3d(x, y, w, h);
	v_gtext(x+1, y+2, li->titles[i]);
	
}


	VOID
show_list(obj, sx, sy)
	OBJECT 	*obj;
	WORD	sx, sy;	
{
	REG LISTINFO *list   =  obj->ob_spec.list;
	REG BYTE     **data  = (BYTE **) list->data;
	REG WORD     i, j, l;
	WORD	     n;
	WORD	     current;
	WORD	     x, y, dy;
	WORD	     ix;

	current = list->index;
	if ((list->maxitems <= 0) || (current < 0))
		return;

	vst_color(BLACK);
	vst_font(list->fontid);

	dy = list->charheight + 2;

	y = sy + list->cy;
	x = sx;
	n = list->visitems / 2;
	i = current - n;
	i = (i < 0) ? 0 : i;
	l = i + list->visitems;
	l = (l > (list->maxitems - 1)) ? (list->maxitems - 1) : l;

	if ((current - i) < n) {
		for (j = 0; j < (n - (current - i)); j++)
			y += dy;
		if ((l - i + j) > list->visitems)	
			l = list->visitems + i - j;  
	}	
	n  = list->ncols;
	ix = list->ncols * i;
	for (; i <= l; i++, y += dy) {
		if (i == current) {
			vst_color(BLUE);
			list->cly = y;
		}
		for (j = 0; j < n; j++) {
			x = sx + list->cx[j];
			v_gtext(x+2, y, data[ix++]);
		}
		if (i == current) {
			vst_color(BLACK);
		}
	}
}
#if 0
	REG T_WAVEINFO *wi = *pwi;
	REG WORD	i, l, j;
	WORD 		current = wi->current;
	BYTE 		buf[32];
	BYTE 		buf1[32];
	BYTE 		buf2[32];
	BYTE 		buf3[32];
	WORD		index;
	BYTE		nr[8];
	LONG		f;

	if ((wi->end == -1) || (wi->current == -1))
		return;



	TxtSFont(0);
	TxtSColor(0x001f);

	ltoa((LONG)wi->current, 2, nr);
	STxtBlt(wi->x + 2, wi->y + 3, nr);
 
	TxtSColor(0x0001);
	sy = wi->sy_row;
	i = current - 4;
	i = (i < 0) ? 0 : i;
	l = i + 9;
	l = (l > wi->end) ? wi->end : l;

 	buf[0]  = ' ';
 	buf1[0] = ' ';
 	buf2[0] = ' ';
 	buf3[0] = ' ';
	wbp = &wi->wavebuf[wi->index[i]];

#if 0					/* NOT working */
	if (((j = (l - i)) < 9)) {
		WORD k;

		k = (9 - j) >> 1;
		for (j = 0; j < k; j++)
			sy += 8;
	}
#else					/* SEEMS to work */
	if ((current - i) < 4) {
		for (j = 0; j < (4 - (current - i)); j++)
			sy += 8;
/*
		if (l > j)
			l -= j;  
*/
		if ((l - i + j) > 9)	
			l = 9 + i - j;  
	}	
#endif
	for (; i <= l; i++, sy += 8) {
		if (i == current) {
			TxtSColor(0x001f);
		}

		STxtBlt(wi->sx_col1 + 6, sy, 
			wtable[index = FindWave((ULONG)wbp->sample)]);

		ltoa(wbp->time, 5, &buf[1]);
		STxtBlt(wi->sx_col2, sy, buf);	

		f = wbp->fade_v >> 14L;
		ltoa(f, 6, &buf1[1]);
		STxtBlt(wi->sx_col3, sy, buf1);

		f = wbp->fade_v & 0x3fffL;
		ltoa(f, 5, &buf2[1]);
		buf2[0] = ':';
		STxtBlt(wi->sx_col3 + 42, sy, buf2);
		/*buf2[0] = ' ';*/

		ltoa(-(wbp->fade_l), 4, &buf3[1]);	/* CS 11/17/93 */
		STxtBlt(wi->sx_col4, sy, buf3);	

		if (i == current) {
			TxtSColor(0x0001);
			wi->c_y = sy;
			wi->c_wave = index;
			strcpy(wi->c_time, buf);
			strcpy(wi->c_fd_vi, buf1);
			strcpy(wi->c_fd_vf, buf2);
			strcpy(wi->c_fd_l, buf3);			
		}

		if ((wbp = wbp->next) == (T_WAVEBUF *) -1L)
			break;
	}
}

#endif
