home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Virtual Reality Zone
/
VRZONE.ISO
/
mac
/
PC
/
PCGLOVE
/
GLOVE
/
OBJGLV.ZIP
/
SRC
/
DEMO4B
/
KEYBOARD.CPP
< prev
next >
Wrap
C/C++ Source or Header
|
1993-05-02
|
29KB
|
1,320 lines
/* Keyboard routines */
/* Written by Bernie Roehl, July 1992 */
/* Copyright 1992 by Dave Stampe and 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 <time.h> /* time(), ctime() */
#include <string.h>
#include <math.h>
#include <bios.h>
#include <ctype.h>
#include <stdlib.h>
#include <conio.h>
#include "rend386.hpp"
#include "intmath.h"
#include "plg.h"
#include "pointer.hpp"
#include "userint.hpp"
#include "splits.hpp"
#include "cursor.hpp"
#include "render.hpp"
#include "demo4.hpp"
#include "world.hpp"
#include "keyboard.hpp"
#include "segio.hpp"
extern STEREO default_stereo;
extern manip_2D_avail;
extern int sl_xflip, sl_xoff;
extern long sl_left, sl_top, sl_right, sl_bottom;
extern int sr_xflip, sr_xoff;
extern long sr_left, sr_top, sr_right, sr_bottom;
extern float sl_xrot, sr_xrot;
int use_old_keys = 0;
extern long latitude,longitude,center_roll;
extern long center_x,center_y,center_z,center_d;
extern char *progname;
extern OBJECT *where_split_screen_pt(int *pol, int *vert, int x, int y);
extern int redraw, review, reframe, running, do_horizon;
extern OBJLIST *objlist;
extern long spacestep;
extern int stereo_type;
extern int fancy_background, reflection_pool, show_logo, do_screen_clear;
extern VIEW default_view, orig_view, *current_view;
extern STEREO default_stereo;
extern SPLIT *split_tree;
extern unsigned lastkey, nextolastkey;
extern unsigned paint;
extern int show_location, show_compass, show_framerate;
#define to_rad(a) ((a) * 3.14159262 / 180.0)
#define sine(x) sin(to_rad(x/65536L))
#define cosine(x) cos(to_rad(x/65536L))
#define F1 0x3B00
#define F2 0x3C00
#define F3 0x3D00
#define F4 0x3E00
#define F5 0x3F00
#define F6 0x4000
#define F7 0x4100
#define F8 0x4200
#define F9 0x4300
#define F10 0x4400
#define HOME 0x4700
#define END 0x4F00
#define PGUP 0x4900
#define PGDN 0x5100
#define KEY_LEFT 0x4B00
#define KEY_RIGHT 0x4D00
#define UP 0x4800
#define DOWN 0x5000
#define SHLEFT 0x4B01
#define SHRIGHT 0x4D01
#define SHUP 0x4801
#define SHDOWN 0x5001
#define SHPGUP 0x4901
#define SHPGDN 0x5101
#define CTRLLEFT 0x7300
#define CTRLRIGHT 0x7400
#define CTRLHOME 0x7700
#define CTRLEND 0x7500
#define CTRLPGUP 0x8400
#define CTRLPGDN 0x7600
#define ESC 0x001B
unsigned getkey()
{
unsigned c;
union REGS regs;
int shifted;
regs.h.ah = 2;
int86(0x16, ®s, ®s);
shifted = (regs.h.al & 3);
if ((c = bioskey(0)) & 0xFF) c &= 0xFF;
else if (shifted) c |= 1;
return c;
}
char *helptext[] = {
" HELP",
"ARROWS move around horizonally",
"Pgup/Pgdn move up/down",
"CTRL+ARROWS twist head, U u-turns",
"CTRL PgUp/CTRL PgDn tilt head up/down",
"+ and - keys zoom in and out",
"G go to specified x,y,z location",
"R repeats last move 100x",
"I gives information O sets options",
"0-9 set step size (0 = 10)",
"* resets to default view",
"Q quits, ? shows help",
"V resizes view, ^ saves PCX file",
"C changes hither/yon clipping",
"D displays status information",
"L loads, S saves PLG files",
"M loads multi-resolution PLG files",
"F loads figure files",
"P displays color palette",
"Z does object manipulation",
"X invokes extra features",
NULL
};
static char *featmenu[] = {
"Select Surface type",
"Choose Color",
"Paint Polys",
NULL
};
static char *surfmenu[] = {
"Absolute",
"Cosine-lit",
"Metal",
"Glass",
NULL
};
void disp_palette()
{
int i, j, page;
page = cursor_hide();
for (i = 0; i < 16; i++)
for (j = 0; j < 16; j++)
user_box(j*10,i*8,j*10+9,i*8+8,i*16+j);
cursor_show(page);
reframe = 1;
}
static int stepsize = 5;
static long anglestep = 2L * 65536L;
FILE *save_file = NULL;
int nsaved = 0;
void save_it(OBJECT *obj)
{
if (get_obj_flags(obj) & OBJ_HIGHLIGHTED)
{
char buff[100];
save_plg(obj, save_file);
sprintf(buff, "%d object%s saved", ++nsaved,
(nsaved > 1) ? "s" : "");
refresh_display();
popmsg(buff);
reframe = 1;
}
}
do_key(unsigned c)
{
void joystick_calibration(), *what_area();
char buff[100];
FILE *in, *out;
long x, y, z;
int i, j;
MATRIX m,n;
long av, bv, cv, dv; /* used for 'A' */
if (check_key(c)) return 0;
switch (c)
{
#ifdef NFF_SAVE /* not in this release... */
case 'N':
case 'n':
nextolastkey = 0;
askfor("File to save? ", buff, 15);
if (buff[0] == '\0') {
redraw = 1;
break;
}
if ((out = fopen(buff, "w")) == NULL) {
popmsg("Could not save file");
getkey();
}
else {
save_nff(out);
fclose(out);
}
reframe = redraw = 1;
break;
#endif
case 'M':
case 'm':
nextolastkey = 0;
askfor("File to load? ", buff, 15);
if (buff[0] == '\0') {
redraw = 1;
break;
}
if ((in = fopen(buff, "r")) == NULL) {
popmsg("Could not load file");
getkey();
}
else {
OBJECT *obj;
SEGMENT *s;
set_loadplg_offset(0,0,0);
set_loadplg_scale(1,1,1);
obj = load_multi_plg(in);
select_representation(obj, 0L);
add_obj_to_split_area(split_tree, obj);
if ((s = new_seg(NULL)) == NULL) {
popmsg("Warning -- out of memory!");
getkey();
}
else {
seg_set_object(s, obj);
set_object_owner(obj, s);
update_segment(s);
}
if (spacestep < get_object_bounds(obj, &x, &y, &z)/5L)
spacestep = get_object_bounds(obj, &x, &y, &z)/5L;
fclose(in);
}
reframe = redraw = 1;
break;
case 'G':
case 'g':
nextolastkey = 0;
askfor("X,Y,Z: ", buff, 15);
if (buff[0])
sscanf(buff, "%ld,%ld,%ld", ¤t_view->ex, ¤t_view->ey, ¤t_view->ez);
reframe = review = redraw = 1;
break;
case KEY_LEFT:
if (use_old_keys)
latitude -= stepsize * anglestep;
else
current_view->pan -= stepsize * anglestep;
review = redraw = 1;
break;
case KEY_RIGHT:
if (use_old_keys)
latitude += stepsize * anglestep;
else
current_view->pan += stepsize * anglestep;
longitude -= stepsize * anglestep;
review = redraw = 1;
break;
case UP:
if (use_old_keys)
longitude += stepsize * anglestep;
else
{
current_view->ex += (stepsize * spacestep) * sine(current_view->pan);
current_view->ez += (stepsize * spacestep) * cosine(current_view->pan);
}
review = redraw = 1;
break;
case DOWN:
if (use_old_keys)
longitude -= stepsize * anglestep;
else
{
current_view->ex -= (stepsize * spacestep) * sine(current_view->pan);
current_view->ez -= (stepsize * spacestep) * cosine(current_view->pan);
}
review = redraw = 1;
break;
case PGUP:
if (use_old_keys)
center_d += (stepsize * spacestep);
else
current_view->tilt += (stepsize * anglestep);
review = redraw = 1;
break;
case PGDN:
if (use_old_keys)
center_d -= (stepsize * spacestep);
else
current_view->tilt -= (stepsize * anglestep);
review = redraw = 1;
break;
case CTRLLEFT:
if (use_old_keys)
center_roll -= stepsize * anglestep;
else
{
current_view->ex -= (stepsize * spacestep) * cosine(current_view->pan);
current_view->ez += (stepsize * spacestep) * sine(current_view->pan);
}
review = redraw = 1;
break;
case CTRLRIGHT:
if (use_old_keys)
center_roll += stepsize * anglestep;
else
{
current_view->ex += (stepsize * spacestep) * cosine(current_view->pan);
current_view->ez -= (stepsize * spacestep) * sine(current_view->pan);
}
review = redraw = 1;
break;
case CTRLPGUP:
if (use_old_keys)
current_view->zoom += stepsize * 65536L/10;
else
current_view->ey += (stepsize * spacestep);
review = redraw = 1;
break;
case CTRLPGDN:
if (use_old_keys)
current_view->zoom -= stepsize * 65536L/10;
else
current_view->ey -= (stepsize * spacestep);
review = redraw = 1;
break;
case CTRLHOME:
current_view->roll -= (stepsize * anglestep);
review = redraw = 1;
break;
case CTRLEND:
current_view->roll += (stepsize * anglestep);
review = redraw = 1;
break;
case '+':
if (stereo_type == MONOSCOPIC)
current_view->zoom *= 1.1;
else
default_stereo.world_scaling *= 1.1;
review = redraw = 1;
break;
case '-':
if (stereo_type == MONOSCOPIC)
current_view->zoom /= 1.1;
else {
default_stereo.world_scaling /= 1.1;
if (default_stereo.world_scaling <= 10)
default_stereo.world_scaling = 11;
}
review = redraw = 1;
break;
case 'U':
case 'u':
current_view->pan += 180*65536L;
nextolastkey = 0;
review = redraw = 1;
break;
case '*':
nextolastkey = 0;
if (use_old_keys)
{
current_view = &default_view;
center_d = 10000;
center_x = 0;
center_y = 0;
center_z = 0;
latitude = 0;
longitude = 0;
center_roll = 0;
}
else
default_view = orig_view;
review = redraw = 1;
break;
case SHLEFT:
x = stepsize*spacestep/10;
y = 0;
review = redraw = 1;
goto fixcenter; /* save some code (Dave) */
case SHRIGHT:
x = -stepsize*spacestep/10 ;
y = 0;
review = redraw = 1;
goto fixcenter; /* save some code (Dave) */
case SHUP:
y = -stepsize*spacestep/10;
x = 0;
review = redraw = 1;
goto fixcenter; /* save some code (Dave) */
case SHDOWN:
y = stepsize*spacestep/10;
x = 0;
review = redraw = 1;
fixcenter:
z = 0;
std_matrix(n,longitude,latitude,center_roll,0,0,0);
matrix_point(n,&x,&y,&z);
center_x += x;
center_y += y;
center_d -= z;
break;
case SHPGUP:
center_z += stepsize*spacestep/10;
review = redraw = 1;
break;
case SHPGDN:
center_z -= stepsize*spacestep/10;
review = redraw = 1;
break;
case '[':
nextolastkey = 0;
if (sl_xflip) sl_xoff++; else sl_xoff--;
if (sr_xflip) sr_xoff--; else sr_xoff++;
review = redraw = 1;
goto stereo_recompute; /* save some code (Dave) */
case ']':
nextolastkey = 0;
if (sl_xflip) sl_xoff--; else sl_xoff++;
if (sr_xflip) sr_xoff++; else sr_xoff--;
review = redraw = 1;
goto stereo_recompute; /* save some code (Dave) */
case '{':
nextolastkey = 0;
default_stereo.phys_screen_width++;
review = redraw = 1;
goto stereo_recompute; /* save some code (Dave) */
case '}':
nextolastkey = 0;
default_stereo.phys_screen_width--;
review = redraw = 1;
stereo_recompute:
if (stereo_type != MONOSCOPIC)
{
compute_stereo_data(&default_stereo, LEFT_EYE, sl_xflip, sl_xoff, 65536.0*sl_xrot,
sl_left, sl_top, sl_right, sl_bottom);
compute_stereo_data(&default_stereo, RIGHT_EYE, sr_xflip, sr_xoff, 65536.0*sr_xrot,
sr_left, sr_top, sr_right, sr_bottom);
}
break;
case '0':
nextolastkey = 0;
stepsize = 10;
break;
case '1': case '2': case '3': case '4': case '5':
case '6': case '7': case '8': case '9':
nextolastkey = 0;
stepsize = c - '0';
break;
case 'Q':
case 'q':
case ESC:
nextolastkey = 0;
// popmsg("Really quit?");
// if (toupper(getkey()) == 'Y')
running = 0;
// else reframe = redraw = 1;
break;
case 'R':
case 'r':
nextolastkey = lastkey;
if (lastkey)
for (i = 0; i < 100; i++) {
do_key(lastkey);
refresh_display();
}
break;
case 'C':
case 'c':
nextolastkey = 0;
popmsg("Change Hither or Yon?");
switch (toupper(getkey()))
{
case 'H':
askfor("Enter hither value:", buff, 10);
if (buff[0])
current_view->hither = atof(buff);
if (current_view->hither < 1) current_view->hither = 1;
review = 1;
break;
case 'Y':
askfor("Enter yon value:", buff, 10);
if (buff[0]) current_view->yon = atof(buff);
review = 1;
break;
default:
break;
}
reframe = redraw = 1;
break;
case 'D':
case 'd':
nextolastkey = 0;
disp_status(current_view);
reframe = redraw = 1;
break;
case 'L':
case 'l':
nextolastkey = 0;
askfor("File to load? ", buff, 15);
if (buff[0] == '\0') {
redraw = 1;
break;
}
if ((in = fopen(buff, "r")) == NULL) {
popmsg("Could not load file");
getkey();
}
else {
OBJECT *obj;
set_loadplg_offset(0,0,0);
set_loadplg_scale(1,1,1);
while ((obj = load_plg(in)) != NULL) {
SEGMENT *s;
add_obj_to_split_area(split_tree, obj);
if ((s = new_seg(NULL)) == NULL) {
popmsg("Warning -- out of memory!");
getkey();
}
else {
seg_set_object(s, obj);
set_object_owner(obj, s);
update_segment(s);
}
/* if (spacestep < get_object_bounds(obj, &x, &y, &z)/5L)
spacestep = get_object_bounds(obj, &x, &y, &z)/5L; */
}
fclose(in);
}
reframe = redraw = 1;
break;
case 'S':
case 's':
nextolastkey = 0;
askfor("File to save? ", buff, 15);
if (buff[0] == '\0') {
redraw = 1;
break;
}
if ((save_file = fopen(buff, "w")) == NULL) {
popmsg("Could not open file");
getkey();
}
else {
nsaved = 0;
walk_split_tree(split_tree, save_it);
fclose(save_file);
}
reframe = redraw = 1;
break;
case 'Z':
case 'z':
nextolastkey = 0;
advanced();
while (bioskey(1)) bioskey(0); /* flush keyboard buffer */
reframe = redraw = 1;
break;
case 'I':
case 'i':
nextolastkey = 0;
disp_info();
reframe = redraw = 1;
break;
case 'P':
case 'p':
nextolastkey = 0;
disp_palette();
getkey();
reframe = redraw = 1;
break;
case 'F':
case 'f':
nextolastkey = 0;
askfor("Figure file to read? ", buff, 15);
if (buff[0] == '\0') {
reframe = redraw = 1;
break;
}
if ((in = fopen(buff, "r")) == NULL) {
popmsg("Could not load figure file");
getkey();
}
else {
SEGMENT *s;
int c;
while ((c = getc(in)) != '{')
if (c == EOF) {
popmsg("Early EOF!");
getkey();
break;
}
set_readseg_objlist(objlist);
if ((s = readseg(in, NULL)) == NULL) {
popmsg("Error reading figure file");
getkey();
}
else
update_segment(s);
}
reframe = redraw = 1;
break;
case 'H':
case 'h':
case '?':
nextolastkey = 0;
poptext(helptext);
getkey();
reframe = redraw = 1;
break;
case 'O':
case 'o':
nextolastkey = 0;
set_options();
reframe = redraw = 1;
break;
#ifdef RESIZE_IMPLEMENTED
case 'V':
case 'v':
nextolastkey = 0;
resize_viewport();
reframe = review = redraw = 1;
break;
#endif
case 'X':
case 'x':
nextolastkey = 0;
new_features();
while (bioskey(1)) bioskey(0); /* flush keyboard buffer */
reframe = review = redraw = 1;
break;
case '^':
nextolastkey = 0;
save_pcx_file();
default:
break;
}
return 0;
}
extern long last_render_time;
do_joy(joystick_data *joy)
{
return do_joy_move(joy->x, joy->y, joy->buttons);
}
do_joy_move(int x, int y, int buttons)
{
long dist = spacestep*stepsize;
float cosvalue, sinvalue;
int sscale = last_render_time;
if (abs(x) < 10 && abs(y) < 10) return 0;
if (x > 10) x -= 10;
else
{
if (x > -10) x = 0;
else x += 10;
}
if (y > 10) y -= 10;
else
{
if (y > -10) y = 0;
else y += 10;
}
cosvalue = cosine(current_view->pan);
sinvalue = sine(current_view->pan);
switch (buttons)
{
case 0:/* no buttons down */
current_view->pan += (x * anglestep*stepsize)/1200*sscale;
current_view->ex -= (y * dist * sinvalue)/100*sscale ;
current_view->ez -= (y * dist * cosvalue)/100*sscale ;
review = redraw = 1;
break;
case 1:/* first button down */
current_view->tilt -= (y * anglestep*stepsize)/2000*sscale;
current_view->ex -= (x * dist * cosvalue)/400*sscale ;
current_view->ez += (x * dist * sinvalue)/400*sscale ;
review = redraw = 1;
break;
case 2:/* second button down */
current_view->ex -= (x * dist * cosvalue)/400*sscale ;
current_view->ez += (x * dist * sinvalue)/400*sscale ;
current_view->ey -= (y * spacestep*stepsize)/400*sscale ;
review = redraw = 1;
break;
case 3:/* both buttons down */
current_view->roll += (x * anglestep*stepsize)/400*sscale;
current_view->zoom += (y*65536L) /4000*sscale;
review = redraw = 1;
break;
default:
break;
}
return 0;
}
static char *adv_menu[] = {
"Move",
"Rotate",
"Twirl",
"Alter",
"Paint",
"Info",
"Save",
"Delete",
"Unselect",
"Hack off",
"Join to",
"Figure...",
"Next rep",
NULL
};
POINTER pointer;
static char *surface_menu[] = {
"Normal", "Cosine-lit", "Metal", "Glass", NULL };
static char *figure_menu[] = {
"Figure select",
"Delete",
"Save",
"Copy",
"Info",
NULL
};
void select_tree(SEGMENT *s)
{
SEGMENT *p;
OBJECT *obj;
if ((obj = (OBJECT *)seg_get_object(s)) != NULL) highlight_obj(obj);
for (p = child_segment(s); p; p = sibling_segment(p))
select_tree(p);
}
void count_tree(SEGMENT *s, int *nsegs, int *nverts, int *npolys)
{
SEGMENT *p;
OBJECT *obj;
++*nsegs;
if ((obj = (OBJECT *)seg_get_object(s)) != NULL) {
int nv, np;
get_obj_info(obj, &nv, &np);
*nverts += nv;
*npolys += np;
}
for (p = child_segment(s); p; p = sibling_segment(p))
count_tree(p, nsegs, nverts, npolys);
}
static void zap_obj(OBJECT *obj)
{
remove_from_objlist(obj);
delete_obj(obj);
}
int nselected = 0;
void count_selected(OBJECT *obj)
{
if (get_obj_flags(obj) & OBJ_HIGHLIGHTED)
++nselected;
}
int nobjs = 0, nverts = 0, npolys = 0;
void gather_info(OBJECT *obj)
{
if (get_obj_flags(obj) & OBJ_HIGHLIGHTED)
{
int nv, np;
++nobjs;
get_obj_info(obj, &nv, &np);
nverts += nv;
npolys += np;
}
}
long ptx, pty, ptz;
long oldx, oldy, oldz, oldcx, oldcy, oldcz, dx, dy, dz;
void move_it(OBJECT *obj)
{
if (get_obj_flags(obj) & OBJ_HIGHLIGHTED)
{
SEGMENT *s;
if ((s = (SEGMENT *)get_object_owner(obj)) != NULL)
{
rel_move_segment(s, ptx - oldx, pty - oldy, ptz - oldz);
update_segment(s);
}
}
}
void rot_it(OBJECT *obj)
{
int i;
if (get_obj_flags(obj) & OBJ_HIGHLIGHTED)
{
SEGMENT *s;
if ((s = (SEGMENT *)get_object_owner(obj)) != NULL)
{
rel_rot_segment(s, ptx, pty, ptz, RYXZ);
update_segment(s);
}
}
}
unsigned surf;
void surf_it(OBJECT *obj)
{
if (get_obj_flags(obj) & OBJ_HIGHLIGHTED) {
int nv, np, i;
get_obj_info(obj, &nv, &np);
for (i = 0; i < np; ++i) {
unsigned color;
get_poly_info(obj, i, &color, &nv, NULL, 0);
set_poly_color(obj, i, (color & 0xCFFF) | surf);
}
}
}
void color_it(OBJECT *obj)
{
if (get_obj_flags(obj) & OBJ_HIGHLIGHTED) {
int nv, np, i;
get_obj_info(obj, &nv, &np);
for (i = 0; i < np; ++i)
set_poly_color(obj, i, 0x8000 | paint);
}
}
void unhi_it(OBJECT *obj)
{
set_obj_flags(obj, get_obj_flags(obj) & ~OBJ_HIGHLIGHTED);
unhighlight_obj(obj);
}
void hack_it(OBJECT *obj)
{
SEGMENT *s;
if ((get_obj_flags(obj) & OBJ_HIGHLIGHTED) && (s = (SEGMENT *)get_object_owner(obj)) != NULL) {
detach_segment(s);
update_segment(s);
}
}
SEGMENT *newparent = NULL;
void join_it(OBJECT *obj)
{
SEGMENT *s;
if ((get_obj_flags(obj) & OBJ_HIGHLIGHTED) &&
(s = (SEGMENT *)get_object_owner(obj)) != NULL)
{
attach_segment(s, newparent);
update_segment(s);
}
}
void nuke_it(OBJECT *obj)
{
if ((get_obj_flags(obj) & OBJ_HIGHLIGHTED)) {
SEGMENT *s;
if ((s = (SEGMENT *)get_object_owner(obj)) != NULL)
seg_set_object(s, NULL);
remove_from_objlist(obj);
delete_obj(obj);
}
}
void next_it(OBJECT *obj)
{
next_rep(obj);
}
extern PDRIVER *cursor_device;
advanced()
{
SEGMENT *s;
OBJECT *obj;
int nsegs = 0;
char buff[100], *p;
FILE *out;
char c, d;
unsigned char oldflags;
int mx, my;
unsigned buttons;
time_t now;
int click = 0;
init_pointer(&pointer);
nselected = 0;
walk_split_tree(split_tree, count_selected);
if (nselected == 0)
{
popmsg("No objects selected!");
delay(600);
return 0;
}
poptext(adv_menu);
switch (c = toupper(getkey()))
{
case 'N':
walk_split_tree(split_tree, next_it);
break;
case 'S':
refresh_display();
if (askfor("Enter filename: ", buff, 20) == 0x1B) break;
if (buff[0] == '\0') {
reframe = redraw = 1;
break;
}
nobjs = 0;
if ((save_file = fopen(buff, "w")) == NULL)
{
popmsg("Could not create file");
reframe = 1;
getkey();
break;
}
nsaved = 0;
walk_split_tree(split_tree, save_it);
fclose(save_file);
save_file = NULL;
refresh_display();
sprintf(buff, "Saved %d object%s", nobjs, (nobjs > 1) ? "s" : "");
popmsg(buff);
getkey();
fclose(out);
break;
case 'I':
refresh_display();
nobjs = nverts = npolys = 0;
walk_split_tree(split_tree, gather_info);
sprintf(buff, "%d obj%s, %d vertice%s, %d polygon%s", nobjs, (nobjs == 1) ? "" : "s", nverts, (nverts == 1) ? "" : "s", npolys, (npolys == 1) ? "" : "s");
popmsg(buff);
getkey();
break;
case 'M':
refresh_display();
if (!manip_2D_avail) break;
pointer_read(cursor_device, &pointer);
pointer_to_world(&pointer, current_view, &ptx, &pty, &ptz);
click = 0;
while (click == 0)
{
refresh_display();
oldx = ptx;
oldy = pty;
oldz = ptz;
click = PNEW_BUT & pointer_read(cursor_device, &pointer);
if (!(pointer.buttons & 1)) click = 0;
pointer_to_world(&pointer, current_view, &ptx, &pty, &ptz);
walk_split_tree(split_tree, move_it);
}
refresh_display();
break;
case 'R':
case 'T':
refresh_display();
if (!manip_2D_avail) break;
pointer_read(cursor_device, &pointer);
oldcx = oldx = pointer.x;
oldcy = oldy = pointer.y;
oldcz = oldz = pointer.z;
while ((pointer.buttons & 0x01) == 0)
{
if (c == 'R')
{
ptx = 32768L*(pointer.y - oldy);
pty = -32768L*(pointer.x - oldx);
ptz = -32768L*(pointer.z - oldz);
}
else
{
ptx = 3270L*(pointer.y - oldcy);
pty = -3270L*(pointer.x - oldcx);
ptz = -3270L*(pointer.z - oldcz);
}
rotate_to_view(current_view, &ptx, &pty, &ptz);
walk_split_tree(split_tree, rot_it);
oldx = pointer.x;
oldy = pointer.y;
oldz = pointer.z;
refresh_display();
pointer_read(cursor_device, &pointer);
}
while (pointer.buttons & 0x01) pointer_read(cursor_device, &pointer);
refresh_display();
break;
case 'A':
refresh_display();
poptext(surface_menu);
switch (toupper(getkey())) {
case 'N':
surf = 0x0000;
break;
case 'C':
surf = 0x1000;
break;
case 'M':
surf = 0x2000;
break;
case 'G':
surf = 0x3000;
break;
default:
return 0;
}
walk_split_tree(split_tree, surf_it);
refresh_display();
break;
case 'P':
walk_split_tree(split_tree, color_it);
refresh_display();
break;
case 'D':
refresh_display();
sprintf(buff, "Delete %d object%s! Are you sure?", nselected, (nselected > 1) ? "s" : "");
popmsg(buff);
reframe = 1;
if (toupper(getkey()) != 'Y') break;
refresh_display();
walk_split_tree(split_tree, nuke_it);
refresh_display();
break;
case 'U':
walk_split_tree(split_tree, unhi_it);
refresh_display();
break;
case 'H':
refresh_display();
walk_split_tree(split_tree, hack_it);
break;
case 'J':
if (!can_point_2D()) break;
if (!manip_2D_avail) break;
refresh_display();
popmsg("Click on new parent");
reframe = 1;
refresh_display();
newparent = NULL;
do {
OBJECT *newobj;
move_till_click(cursor_device, 1, &mx, &my);
newobj = where_split_screen_pt(NULL, NULL, mx, my);
if (newobj)
if ((get_obj_flags(newobj) & OBJ_HIGHLIGHTED) == 0)
newparent = (SEGMENT *)get_object_owner(newobj);
}
while (newparent == NULL);
walk_split_tree(split_tree, join_it);
break;
case 'F':
refresh_display();
poptext(figure_menu);
for (obj = first_in_objlist(objlist); obj; obj = next_in_objlist(obj))
if ((get_obj_flags(obj) & OBJ_HIGHLIGHTED) && (s = (SEGMENT *)get_object_owner(obj)) != NULL)
break;
if (obj == NULL || s == NULL) {
popmsg("No objects selected!");
getkey();
return 0;
}
switch (toupper(getkey())) {
case 'F':
select_tree(find_root_segment(s)); /* and down again */
break;
case 'D':
refresh_display();
popmsg("Delete entire figure! Are you sure?");
if (toupper(getkey()) != 'Y') break;
refresh_display();
delete_segment(find_root_segment(s), zap_obj);
break;
case 'I':
count_tree(find_root_segment(s), &nsegs, &nverts, &npolys);
sprintf(buff, "%d segs, %d verts, %d polys", nsegs, nverts, npolys);
popmsg(buff);
getkey();
break;
case 'S':
refresh_display();
askfor("Filename: ", buff, 20);
if (buff[0] == '\0') break;
refresh_display();
if ((out = fopen(buff, "w")) == NULL) {
popmsg("Could not create file");
getkey();
break;
}
askfor("Comment: ", buff, 20);
if ((p = strchr(buff, ';')) != NULL) *p = '\0';
fprintf(out, "Comment = %s;\n", buff);
time(&now);
strcpy(buff, ctime(&now));
if ((p = strchr(buff, '\n')) != NULL) *p = '\0';
fprintf(out, "Comment = Saved from %s %s;\n", progname, buff);
writeseg(out, find_root_segment(s), 0);
fclose(out);
break;
default:
return 0;
}
break;
default:
break;
}
return 0;
}
static char *optmenu[] = {
"Background",
"Reflection",
"Logo",
"Screen clear",
"Ambient light",
"Directional light",
"Horizon",
"Motion step size",
"Keyboard mode",
"Position display",
"Compass display",
"Frame rate display",
NULL };
set_options()
{
char buff[20];
poptext(optmenu);
switch (toupper(getkey())) {
case 'B':
fancy_background = !fancy_background;
break;
case 'R':
reflection_pool = !reflection_pool;
current_view->bottom = reflection_pool ? 160 : 199;
break;
case 'L':
show_logo = !show_logo;
if (!show_logo) reset_screens();
break;
case 'S':
do_screen_clear = !do_screen_clear;
popmsg(do_screen_clear ? "Will clear" : "Won't clear");
delay(600);
break;
case 'D':
current_view->directional = !current_view->directional;
popmsg(current_view->directional ? "Spotlight" : "Point Source");
delay(600);
break;
case 'H':
do_horizon = !do_horizon;
if (!do_horizon) reset_screens();
popmsg(do_horizon ? "Horizon" : "No Horizon");
delay(600);
break;
case 'A':
askfor("Ambient light: ", buff, 15);
current_view->ambient = atoi(buff) & 0xFF;
break;
case 'M':
popmsg("Space or Angle?");
switch (toupper(getkey())) {
case 'S':
askfor("New space step: ", buff, 15);
if (buff[0]) spacestep = atoi(buff);
break;
case 'A':
askfor("New angle step: ", buff, 15);
if (buff[0]) anglestep = atof(buff) * 65536L;
break;
default:
break;
}
break;
case 'K':
use_old_keys = !use_old_keys;
review = 1;
break;
case 'P':
show_location = !show_location;
if (!show_location) reset_screens();
break;
case 'C':
show_compass = !show_compass;
if (!show_compass) reset_screens();
break;
case 'F':
show_framerate = !show_framerate;
if (!show_framerate) reset_screens();
break;
default:
break;
}
return 0;
}
static unsigned stype[] = {
0, 0x1000, 0x2000, 0x3000 };
unsigned paint = 1;
static unsigned surface = 0x1000;
static unsigned paintcolor = 1;
new_features()
{
int x, y, c, i;
unsigned buttons;
char buff[100];
if (!can_point_2D()) return 3;
poptext(featmenu);
reframe = 1;
c = toupper(getkey());
switch (c)
{
case 'S':/* select surface */
poptext(surfmenu);
reframe = 1;
switch (toupper(getkey())) {
case 'N':
surface = stype[0];
break;
case 'C':
surface = stype[1];
break;
case 'M':
surface = stype[2];
break;
case 'G':
surface = stype[3];
break;
}
if (surface == 0)
paint = paintcolor;
else
paint = (surface | ((paintcolor << 4) & 0x0FF0) + 10); /* hue, brightness *16 */
refresh_display();
break;
case 'C':/* select color */
if (!manip_2D_avail) break;
disp_palette();
disp_palette();
reframe = 1;
do {
move_till_click(cursor_device, 1, &x, &y);
}
while (y>128 || x>160);
paintcolor = 16*(y/8) + x/10;
if (surface == 0)
paint = paintcolor;
else
paint = (surface | ((paintcolor << 4) & 0x0FF0) + 10); /* hue, brightness *16 */
refresh_display();
break;
case 'P':
refresh_display();
do {
if (kbhit()) break;
while (move_2D(cursor_device, &x, &y, &buttons) == 0 && !kbhit());
if (buttons & 0x01) {
OBJECT *obj;
int poly;
obj = where_split_screen_pt(&poly, NULL, x, y);
if (obj) {
set_poly_color(obj, poly, paint);
refresh_display();
}
}
}
while (!(buttons & 0x02));
break;
default:
break;
}
return 0;
}