home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Virtual Reality Zone
/
VRZONE.ISO
/
mac
/
PC
/
REND386
/
DEVEL5
/
CURSORS.C
< prev
next >
Wrap
C/C++ Source or Header
|
1992-09-29
|
5KB
|
201 lines
/* 2D and 3D cursor handling */
/* some manipulation routines */
/* Written by Dave Stampe, Aug. 1992 */
/* Copyright 1992 by Bernie Roehl.
May be freely used to write software for release into the public domain;
all commercial endeavours MUST contact Bernie Roehl and Dave Stampe
for permission to incorporate any part of this software into their
products!
*/
#include <stdio.h>
#include <dos.h>
#include "../include/rend386.h"
#include "../include/f3dkitd.h"
#include "../include/intmath.h"
#include "../include/pointer.h"
#include "../include/cursor.h"
#include "../include/segio.h"
#include "../include/plg.h"
extern int redraw;
extern SEGMENT *cursor_seg;
/***************** 2D (screen) cursor handling ************/
static int oldx = 160, oldy = 100;
static int cursor_flag = -1;
static int lastpage;
void cursor_move(int x, int y) /* move cursor if visible */
{
oldx = x;
oldy = y;
if (cursor_flag == 0)
{
set_drawpage(lastpage);
erase_cursor(lastpage);
draw_cursor(x,y,0,lastpage);
}
}
int cursor_hide() /* erase cursor */
{
if (cursor_flag >= 0) erase_cursor(lastpage);
--cursor_flag;
return lastpage;
}
int cursor_forget() /* will be erased by redraw: ignore it! */
{
--cursor_flag;
return lastpage;
}
void cursor_show(int page) /* redisplay cursor */
{
if (++cursor_flag == 0)
{
set_drawpage(page);
lastpage = page;
draw_cursor(oldx, oldy, 0, page);
}
}
int move_2D(PDRIVER *d, int *x, int *y, unsigned *b)
{
int c;
if (d == NULL) return 0;
if (PNEW_POS & (c = mouse_read(d, x, y, b)))
cursor_move(*x, *y);
return c;
}
int move_till_click(PDRIVER *d, unsigned b, int *x, int *y) /* b is button mask */
{
int s;
unsigned c;
if (d == NULL) return -1;
while(1)
{
if (((s = move_2D(d, x, y, &c)) & PNEW_BUT) && (c & b)) break;
}
return s;
}
/* find world coordinates of pointer based on given view */
void pointer_to_world(POINTER *p, VIEW *v, long *x, long *y, long *z)
{
MATRIX n;
*x = p->x;
*y = p->y;
*z = p->z;
view_to_matrix(v,n);
matrix_point(n,x,y,z);
p->wpos[3][0] = *x;
p->wpos[3][1] = *y;
p->wpos[3][2] = *z;
p->wpos_valid = 1;
}
/* rotate data to view alignment */
void rotate_to_view( VIEW *v, long *x, long *y, long *z)
{
MATRIX n;
view_to_matrix(v,n);
matrix_rotate(n,x,y,z);
}
/***************** GLOVE CURSOR SUPPORT *************/
static SEGMENT *wrist_seg; /* wrist-on-body segment */
/* also used to manip. objects */
static SEGMENT *glove_seg; /* wrist twist for presentation */
static SEGMENT *glove_joints[20]; /* joints on hand */
#define Y_GLV_OFFSET 0 /* needed as "body" is at neck level */
#define GLOVE_DIST 1000
#define SELECT_LENGTH 20 /* distance along last index finger segment */
/* to selection point */
int glove_update(PDRIVER *d, POINTER *p) /* read glove, update positions */
{
int c;
c = pointer_read(d, p);
if ((c & (PNEW_POS | PNEW_ROT | PNEW_FLEX)) == 0) return 0;
abs_move_segment(wrist_seg, p->x, p->y + Y_GLV_OFFSET, p->z + GLOVE_DIST);
if (d->pdata->type&P_IS6DG)
abs_rot_segment(wrist_seg, p->rx, p->ry, p->rz, RYXZ);
else
abs_rot_segment(glove_seg, -2000L*p->y, p->ry, -4000L*p->x, RYXZ);
abs_rot_segment(glove_joints[1], 0L,30*65536L+18061L*p->flex[0],0L, RYXZ);
abs_rot_segment(glove_joints[2], -20*65536L,90*65536L,-5*65536L+38700L*p->flex[1], RYZX);
abs_rot_segment(glove_joints[3], 38700*p->flex[2],0L,0L, RYXZ);
abs_rot_segment(glove_joints[4], 38700*p->flex[3],0L,0L, RYXZ);
abs_rot_segment(glove_joints[5], 38700*p->flex[4],0L,0L, RYXZ);
abs_rot_segment(glove_joints[6], 38700*p->flex[5],0L,0L, RYXZ);
abs_rot_segment(glove_joints[7], 38700*p->flex[6],0L,0L, RYXZ);
abs_rot_segment(glove_joints[8], 38700*p->flex[7],0L,0L, RYXZ);
abs_rot_segment(glove_joints[9], 38700*p->flex[8],0L,0L, RYXZ);
abs_rot_segment(glove_joints[10],38700*p->flex[9],0L,0L, RYXZ);
redraw = 1;
return 1;
}
int cursor_update3D(PDRIVER *d, POINTER *p) /* read pointer, update positions */
{
int c;
c = pointer_read(d, p);
if ((c & (PNEW_POS | PNEW_ROT)) == 0) return 0;
abs_move_segment(cursor_seg, p->x, p->y + Y_GLV_OFFSET, p->z + GLOVE_DIST);
abs_rot_segment(cursor_seg, p->rx, p->ry, p->rz, RYXZ);
redraw = 1;
return 1;
}
/************* USED FOR 3D/6D MANIPULATION *************/
extern int have_glove, use_glove, have_ptr;
SEGMENT *manip_data(PDRIVER *d, long *x, long *y, long *z)
{
if (!have_ptr)
{
*x = 0;
*y = 0;
*z = SELECT_LENGTH;
matrix_point(*get_seg_pmatrix(glove_joints[4]), x, y, z);
return wrist_seg;
}
else
{
seg_getposxyz(cursor_seg, x ,y ,z);
return cursor_seg;
}
}