home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Virtual Reality Madness
/
VRMAD96_ONE.ISO
/
virtek
/
examples
/
show3d.c
< prev
Wrap
C/C++ Source or Header
|
1995-08-24
|
19KB
|
768 lines
// ┌─────────────────────────────────────────────────────────────┐
// │ │
// │ Filename: show3d.c │
// │ Author: Various │
// │ <support@virtek.com> │
// │ Creation date: 30th October 1994 │
// │ │
// │ Compiled using: Borland C++ V3.1 │
// │ │
// │ Tested by: CKD, PBA, NAJ │
// │ │
// │ │
// │ Purpose: A small program to load a 3D-Ware │
// │ world file and use a mouse to control │
// │ flight throughout the world. │
// │ │
// └─────────────────────────────────────────────────────────────┘
#include <stdio.h>
#include <conio.h>
#include <dos.h>
#include <dir.h>
#include <io.h>
#include <alloc.h>
#include <string.h>
#include <stdlib.h>
#include "..\3d-ware\dddware.h"
#define ALLOC_THRESHOLD 50
#define SHIFT (dddkeypressed [_L_SHIFT] || dddkeypressed [_R_SHIFT])
enum { FALSE,TRUE };
/************/
/* typedefs */
/************/
typedef struct shapename_s {
char *name;
long size;
} shapename;
/**************/
/* prototypes */
/**************/
void ContinuousRotation(void);
void MouseControlsViewer(void);
void MouseControlsObject(void);
void Finish(void);
void NextControlMethod(void);
void ToggleHoriFade(void);
void ToggleHorizon(void);
void ToggleInfo(void);
void ToggleSame(void);
void ToggleLine(void);
void KeyHelp(void);
void IncSem(void);
void DecSem(void);
void ZeroSem(void);
void ToggleSem1(void);
void ToggleSem2(void);
void ToggleSem3(void);
void ToggleSem4(void);
void ToggleSem5(void);
void ToggleSem6(void);
void ToggleSem7(void);
void ToggleSem8(void);
void main(int ,char **);
char IsFullPath(char *);
void TryDrawUsing(void);
void GetBits(unsigned short,char);
void ResetViewer(void);
void ReadShape(char *);
void GrabScreen(void);
void ToggleDrawModes();
void NewMessage(char *message);
void DisplayInfo(void);
/********/
/* vars */
/********/
char bobsem = 0;
char msgcol = 11;
char xlook = 0;
short back_screen = 0;
char sameon = 0; // same on/off flag
char outline = 0; // outline on/off flag
short mouse = 0; // mouse control select
char timing = 0; // timing on/off flag
char done = 0;
char showinfo = 0;
char dohorizon = 0;
char doHoriFade = 0;
char far shape_directory[MAXPATH];
char current_directory[MAXPATH];
struct ffblk dta;
long lastime; // frame comp values for continuous rot'n
long thistime;
short x,y,z;
char buff[80];
char work[80];
short vz,vx,vy,vdist;
short vpage;
short far mx,my;
short thiskey;
char control_num = 0;
void (*control_route)(void);
short shapeno = 0;
short numshapes = 0;
shapename *shapelist;
char *thisfile;
char target_toggle=0;
short grab_screen_flag=0;
short temp1_shape;
char temp1_flags;
short temp1_ax;
short temp1_ay;
short temp1_az;
char temp1_draw;
char fade_shift = 9;
char far *flags = &temp1_flags;
char bitstring[17];
short Xrotspeed=0x80;
short Yrotspeed=0x120;
short Zrotspeed=0;
char message_string[80];
short message_countdown;
void (*control_table[])(void) =
{
MouseControlsViewer,
ContinuousRotation,
0
};
struct {
short key;
char *name;
void (*route)(void);
char *help;
} keytable[] = {
{ _ESC, "ESC", Finish, "Exit" }, // Ok.
{ _F1, "F1", KeyHelp, "Help" }, // Ok.
{ _F2, "F2", ToggleInfo, "Toggle info display" }, // Ok.
{ _F3, "F3", ToggleHorizon, "Toggle horizon routines" },
{ _F4, "F4", ToggleDrawModes, "Toggle draw routines" },
{ _F5, "F5", NextControlMethod, "Toggle spin" }, // Ok.
{ _C, "C", ResetViewer, "Reset the viewer" },
{ _G, "G", GrabScreen, "Grab the current screen" },
{ _0, "0", ZeroSem, "Zero SEM flags" },
{ _1, "1", ToggleSem1, "Toggle SEM1" },
{ _2, "2", ToggleSem2, "Toggle SEM2" },
{ _3, "3", ToggleSem3, "Toggle SEM3" },
{ _4, "4", ToggleSem4, "Toggle SEM4" },
{ _5, "5", ToggleSem5, "Toggle SEM5" },
{ _6, "6", ToggleSem6, "Toggle SEM6" },
{ _7, "7", ToggleSem7, "Toggle SEM7" },
{ _8, "8", ToggleSem8, "Toggle SEM8" },
{ _K_PLUS, "PLUS", IncSem, "Increment SEM flags" },
{ _K_MINUS, "MINUS", DecSem, "Decrement SEM flags" },
{ 0, "?", 0, 0 } };
void (*key[128])(void);
//════════════════════════════════════════════════════════════════════════
// MAIN PROGRAM
//════════════════════════════════════════════════════════════════════════
void main(int argc,char **argv)
{
char *s;
shapename *p;
long filesize;
short i;
void (*action)(void);
char tempname[80];
printf("\nShow3D. Simple 3D shape viewer. Version 1.0\n\n"); // Say hello.
mouse = dddInitMouse(); // Initialise the mouse.
if(mouse)
{
dddMouseHidePointer();
}
shapelist = (shapename *)0;
filesize = 0L;
if(argc < 2) // Is a 3D file specified ?
{
printf("** ERROR ** No .3D file specified\n");
return;
}
strupr(argv[1]);
filesize = dddGetFileSize(argv[1]); // Get the size of the .3D file.
if(filesize==0)
{
printf("** ERROR ** couldn't find %s\n",argv[1]);
return;
}
if(filesize > 16000)
{
printf("** ERROR ** file is too large\n");
return;
}
control_route = control_table[0];
dddSelectEmmAmount(100); // 100k of EMM is ample.
dddInit3d();
dddInitVideo();
dddLoadColors("default.col");
dddSetPal(dddstandardpal);
temp1_draw = DRW_MOBILE;
temp1_shape = dddShapeLoad(argv[1]);
temp1_ax = 0;
temp1_ay = 0;
temp1_az = 0;
vx = 0;
vy = 0;
vz = 0;
vpage = 0;
vdist = 1000;
x = y = z = 0;
dddInitKeybd(); // Initialise Keyboard reading.
memset(key, 0, sizeof(key));
i = 0;
do {
key[keytable[i].key] = keytable[i].route;
strupr(keytable[i].name);
strupr(keytable[i].help);
} while(keytable[++i].key);
do {
control_route();
if(dddkeypressed [_Q]) temp1_ax += 0x100;
if(dddkeypressed [_W]) temp1_ay += 0x100;
if(dddkeypressed [_E]) temp1_az += 0x100;
if(dddkeypressed [_A]) temp1_ax -= 0x100;
if(dddkeypressed [_S]) temp1_ay -= 0x100;
if(dddkeypressed [_D]) temp1_az -= 0x100;
if(dddkeypressed [_LF_ARROW]) vz -= 0x100;
if(dddkeypressed [_RT_ARROW]) vz += 0x100;
if(dddkeypressed [_UP_ARROW]) z += 0x50;
if(dddkeypressed [_DN_ARROW]) z -= 0x50;
if(dddkeypressed [_R]) z += 0x8;
if(dddkeypressed [_F]) z -= 0x8;
if(dddkeypressed [_X]&& dddkeypressed [_K_0]) Xrotspeed=0;
if(dddkeypressed [_Y]&& dddkeypressed [_K_0]) Yrotspeed=0;
if(dddkeypressed [_Z]&& dddkeypressed [_K_0]) Zrotspeed=0;
if(dddkeypressed [_X]&& dddkeypressed [_K_PLUS]) Xrotspeed+=0x5;
if(dddkeypressed [_Y]&& dddkeypressed [_K_PLUS]) Yrotspeed+=0x5;
if(dddkeypressed [_Z]&& dddkeypressed [_K_PLUS]) Zrotspeed+=0x5;
if(dddkeypressed [_X]&& dddkeypressed [_K_MINUS]) Xrotspeed-=0x5;
if(dddkeypressed [_Y]&& dddkeypressed [_K_MINUS]) Yrotspeed-=0x5;
if(dddkeypressed [_Z]&& dddkeypressed [_K_MINUS]) Zrotspeed-=0x5;
if(dddkeycode)
{
action = key[ dddkeycode ];
dddkeycode = 0;
if(action)
{
action();
}
}
dddClearObjects();
dddInsertObject16(temp1_draw,temp1_shape,temp1_flags,x,y,z,temp1_ax,temp1_ay,temp1_az);
if (message_countdown>0)
{
message_countdown--;
dddPrint7(12,10,180,message_string);
}
if (target_toggle)
{
dddDrawLine(msgcol,154,97,164,97); // Draw horizontal first.
dddDrawLine(msgcol,159,92,159,102); // Draw vertical last.
dddPlot(0,159,97);
}
dddScreenSwap();
if(back_screen)
{
dddCopyScreenBuffer2Logbase();
}
else
{
if(dohorizon)
{
dddHorizon(vx,vz);
dddDotGrid();
}
else
if(doHoriFade)
{
dddHoriFade(vx,vz);
}
else
{
dddCls();
}
}
dddDrawObjects();
if(showinfo)
{
DisplayInfo();
}
}while(!done);
dddClose3d();
dddRestoreKeybd();
dddRestoreVideo();
}
void DisplayInfo(void)
{
// ┌─────────────────────────────────────────────────────────────────┐
// │ │
// │ Print the shape's position. │
// │ │
// └─────────────────────────────────────────────────────────────────┘
sprintf(work,"SHAPE POSN: X=%d Y=%d Z=%d",x,y,z);
dddGamePrint5(msgcol,0,0,work);
// ┌─────────────────────────────────────────────────────────────────┐
// │ │
// │ Print the camera's Z distance. │
// │ │
// └─────────────────────────────────────────────────────────────────┘
sprintf(work,"CAMERA DIST = %d",vdist);
dddGamePrint5(msgcol,19,191,work);
// ┌─────────────────────────────────────────────────────────────────┐
// │ │
// │ Print the current Semaphore values. │
// │ │
// └─────────────────────────────────────────────────────────────────┘
GetBits(temp1_flags,8);
sprintf(work,"SEMS = %s %3d",bitstring,temp1_flags);
dddGamePrint5(msgcol,180,10,work);
}
//─────────────────────────────────────────────────────────────────────────
// GetBits
//─────────────────────────────────────────────────────────────────────────
void GetBits(unsigned short n,char bits)
{
char *p;
p = &bitstring[bits];
*p-- = 0;
while(bits)
{
*p-- = (n & 1) ? '*' : '.';
n >>= 1;
--bits;
}
}
//─────────────────────────────────────────────────────────────────────────
// Is Full Path -- return true if filename is a full path
//─────────────────────────────────────────────────────────────────────────
char IsFullPath(char *fname)
{
char drive[_MAX_DRIVE];
char dir[_MAX_DIR];
char file[_MAX_FNAME];
char ext[_MAX_EXT];
_splitpath(fname,drive,dir,file,ext);
if(drive[0] || dir[0])
{
return(TRUE);
}
return(FALSE);
}
//─────────────────────────────────────────────────────────────────────────
// Continuous Rotation
//─────────────────────────────────────────────────────────────────────────
void ContinuousRotation()
{
vx += Xrotspeed;
vy += Yrotspeed;
vz += Zrotspeed;
dddMouseGetRelPointerXy(&mx,&my);
if(dddMouseGetButtons() & 1)
{
vx += my << 4;
vy += mx << 4;
}
else
{
vdist += my;
}
dddLookAt16(x,y,z,vx,vy,vz,vdist);
}
//─────────────────────────────────────────────────────────────────────────
// mouse controls viewer
//─────────────────────────────────────────────────────────────────────────
void MouseControlsViewer()
{
dddMouseGetRelPointerXy(&mx,&my);
if(dddMouseGetButtons() & 2)
{
x += mx>>2;
y += my>>2;
dddLookAt16(0,0,0,vx,vy,vz,vdist);
}
else
{
if(dddMouseGetButtons() & 1)
{
vx += my << 6;
vy += mx << 6;
}
else
{
vdist += my;
}
dddLookAt16(0,0,0,vx,vy,vz,vdist);
}
}
//─────────────────────────────────────────────────────────────────────────
// mouse controls object
//─────────────────────────────────────────────────────────────────────────
void MouseControlsObject()
{
int b;
dddMouseGetRelPointerXy(&mx,&my);
b = dddMouseGetButtons();
if(b)
{
if(b & 1)
{
x += mx << 4;
y -= my << 4;
}
else
{
z += my << 4;
}
}
else
{
temp1_ax += my << 4;
temp1_ay += mx << 4;
}
dddSetViewAngles(0,0,0);
dddSetViewPos16(0,0,0);
}
//─────────────────────────────────────────────────────────────────────────
// Finish
//─────────────────────────────────────────────────────────────────────────
void Finish()
{
done = 1;
}
//─────────────────────────────────────────────────────────────────────────
// NextControlMethod
//─────────────────────────────────────────────────────────────────────────
void NextControlMethod()
{
NewMessage("CONTINUOUS ROTATION ON");
if(!control_table[++control_num])
{
control_num = 0;
NewMessage("CONTINUOUS ROTATION OFF");
}
control_route = control_table[control_num];
}
//─────────────────────────────────────────────────────────────────────────
// ToggleHorizon
//─────────────────────────────────────────────────────────────────────────
void ToggleHorizon()
{
if (doHoriFade)
{
doHoriFade = ~doHoriFade;
NewMessage("HORIZON OFF");
}
else
{
if (!dohorizon)
{
dohorizon = ~dohorizon;
NewMessage("NORMAL HORIZON ON");
}
else
{
doHoriFade = ~doHoriFade;
dohorizon = ~dohorizon;
NewMessage("BANDED HORIZON ON");
}
}
}
//─────────────────────────────────────────────────────────────────────────
// ToggleInfo
//─────────────────────────────────────────────────────────────────────────
void ToggleInfo()
{
showinfo = ~showinfo;
}
//─────────────────────────────────────────────────────────────────────────
// GrabScreen -- grab the current screen + use as a backdrop
//─────────────────────────────────────────────────────────────────────────
void GrabScreen(void)
{
if (grab_screen_flag==0)
{
if(!back_screen)
{
back_screen = ~back_screen;
}
grab_screen_flag=1;
}
dddCopyLogbase2ScreenBuffer();
dddSetLogbase2ScreenBuffer();
}
//─────────────────────────────────────────────────────────────────────────
// ToggleDrawModes -- toggle same color /line color /normal
//─────────────────────────────────────────────────────────────────────────
void ToggleDrawModes()
{
if (sameon)
{
sameon = ~sameon;
dddLineOff();
dddSameOff();
NewMessage("NORMAL DRAWING MODES");
}
else
{
if (!outline)
{
outline = ~outline;
dddSameOff();
dddLineOn(msgcol);
NewMessage("LINE DRAWING ON");
}
else
{
sameon = ~sameon;
outline = ~outline;
dddLineOff();
dddSameOn(255);
NewMessage("MASK DRAWING ON");
}
}
}
//─────────────────────────────────────────────────────────────────────────
// ToggleSame -- toggle same color on/off
//─────────────────────────────────────────────────────────────────────────
void ToggleSame()
{
if((sameon = ~sameon) != 0)
dddSameOn(255);
else
dddSameOff();
}
//─────────────────────────────────────────────────────────────────────────
// ToggleLine -- toggle line on/off
//─────────────────────────────────────────────────────────────────────────
void ToggleLine()
{
if((outline = ~outline) != 0)
dddLineOn(msgcol);
else
dddLineOff();
}
//─────────────────────────────────────────────────────────────────────────
// Display key help
//─────────────────────────────────────────────────────────────────────────
void KeyHelp()
{
int i,j;
i = 0;
do{
j = 0;
dddCls();
do{
dddPrint7(msgcol,5,j<<3,keytable[i].name);
dddGamePrint5(msgcol,90,j<<3,keytable[i].help);
}while(keytable[++i].key && ((++j) < 25));
dddScreenSwap();
dddkeycode = 0;
while( dddkeycode ==0); // wait for key before continuing
dddkeycode = 0;
}while(keytable[i].key && j>=25);
}
//─────────────────────────────────────────────────────────────────────────
// ToggleSem
//─────────────────────────────────────────────────────────────────────────
void ZeroSem()
{
*flags = 0;
}
void IncSem()
{
(*flags)++;
}
void DecSem()
{
(*flags)--;
}
void ToggleSem1()
{
*flags ^= 1;
}
void ToggleSem2()
{
*flags ^= 2;
}
void ToggleSem3()
{
*flags ^= 4;
}
void ToggleSem4()
{
*flags ^= 8;
}
void ToggleSem5()
{
*flags ^= 16;
}
void ToggleSem6()
{
*flags ^= 32;
}
void ToggleSem7()
{
*flags ^= 64;
}
void ToggleSem8()
{
*flags ^= 128;
}
//─────────────────────────────────────────────────────────────────────────
// ResetViewer -- Reset the viewed shape to the centre pos and angles
//─────────────────────────────────────────────────────────────────────────
void ResetViewer(void)
{
vx=0;
vy=0;
x=0;
y=0;
temp1_ax = 0;
temp1_ay = 0;
temp1_az = 0;
vz = 0;
z = 0;
vdist = 1000;
Xrotspeed=0x80;
Yrotspeed=0x120;
Zrotspeed=0;
}
// ┌──────────────────────────────────────┐
// │ NewMessage │
// │ │
// │ Displays the new message for │
// │ 50 frames. │
// │ │
// └──────────────────────────────────────┘
void NewMessage(char *message)
{
strcpy(message_string,message);
message_countdown=50;
}