← Back to contents
C source, ASCII text
— 11K bytes
— 1994-01-01
/*
------------------------------------------------------------------
Black Nebula
File : 3d.c
Programmer: Colin Adams
Date: 4/3/91
Last Modified : 10/6/91
------------------------------------------------------------------
+y
|
|
|
|
|
|
|
|
|
------------ +x
/
/
/
/
/
+z
*/
/* ---------------------------------------------------------------
Defines/Includes
---------------------------------------------------------------
*/
#define MAINCODE
#define AMIGA_INCLUDES
#include "3d.h"
#include <hardware/custom.h>
#include <hardware/cia.h>
#define CIAAPRA 0xBFE001
#define FIRE 1
#define RIGHT 2
#define LEFT 4
#define DOWN 8
#define UP 16
extern struct Custom far custom;
struct CIA *cia = (struct CIA *) CIAAPRA;
extern struct RastPort my_rast_port, back_rast_port;
extern struct View my_view, back_view;
extern struct Screen *screen;
extern struct Window *window1;
extern void build_table(void), SetUpExplosions(void);
extern short U_rot, W_rot;
/* ------------------------------------------------------------------
General Variables
------------------------------------------------------------------
*/
char filename[80];
object myship;
short swapflag = 1;
/* ------------------------------------------------------------------
Amiga Variables
------------------------------------------------------------------
*/
UWORD Palette2[] =
{
0x0000,
0x000F,
0x00D7,
0x0098,
0x0078,
0x0047,
0x0016,
0x0024,
0x0FF0,
0x0FB1,
0x0F72,
0x0C21,
0x0803,
0x0503,
0x0F0F,
0x0847
};
/* ------------------------------------------------------------------
EXTERNAL ROUTINES
------------------------------------------------------------------
*/
extern object *CreateObject();
/* ------------------------------------------------------------------
START OF ROUTINES
------------------------------------------------------------------
*/
void CleanUpandExit(void)
/*
Frees resources and quits. Unfortunately fails to free some memory
somewhere, if the OS was done properly wouldn't be a problem, but I'll
try and track it down sometime.
*/
{
EndSound();
if(window1)
CloseWindow(window1);
if(screen)
CloseScreen(screen);
if(IntuitionBase)
CloseLibrary(IntuitionBase);
if(GfxBase)
CloseLibrary((struct Library *) GfxBase);
exit(1);
}
UBYTE Joystick(void)
/*
Reads the joystick port. Goes straight to the metal...
All flames will be ignored.
*/
{
UBYTE data = 0;
UWORD joy;
joy = custom.joy1dat;
data += !( cia->ciapra & 0x0080 ) ? FIRE : 0;
data += joy & 0x0002 ? RIGHT : 0;
data += joy & 0x0200 ? LEFT : 0;
data += (joy >> 1 ^ joy) & 0x0001 ? DOWN : 0;
data += (joy >> 1 ^ joy) & 0x0100 ? UP : 0;
return data;
}
UBYTE Keyboard(void)
/*
Returns the keycode of a key pressed. Goes straight to the
hardware, which isn't very nice to the OS, but is fast.
*/
{
UBYTE code;
code = cia->ciasdr ^ 0xFF;
code = code & 0x01 ? (code>>1)+0x80 : code>>1;
return code;
}
void get2d(short px, short py, short pz)
/*
Converts a point onto a 2d plane from 3d. This code is optimized
to be fast, not readable. The details of the algorithm are in
3d.h. Though naturally you should be able to understand this :-)
*/
{
register int temp;
register int rx, ry, rz;
rx = px - ex;
ry = py - ey;
rz = pz - ez;
d = getmultC(ux, rx) + getmultC(uy, ry) + getmultC(uz,rz);
temp = getmultC(vx, rx) + getmultC(vy, ry) + getmultC(vz,rz);
y = d ? - (temp*571) / d : 0;
temp = getmultC(wx, rx) + getmultC(wy, ry) + getmultC(wz,rz);
x = (G/2) + (d ? (temp*571) / d : 0);
}
void SetUp3d(void)
/* must initialize viewing vectors */
{
k.numer = 571; /* this variable is not used, just here for reference */
k.denom = 1; /* because this is 1, it simplifies the calculations */
ex = 4000; /* eye location */
ey = 500;
ez = 1000;
setconst(vx,0); /* top of skull unit vector */
setconst(vy,1);
setconst(vz,0);
setconst(wy,0); /* out of right ear vector */
SetFixed(wx, 1000,1000);
SetFixed(wz, 0, 1000);
setconst(uy,0); /* view vector */
SetFixed(ux, 0, 1000);
SetFixed(uz, -1000, 1000);
view_mode = 0;
View_Angle = 270;
U_rot = 270; W_rot = 180;
}
/* ------------------------------------------------------------------
Routines for allowing objects to be defined
------------------------------------------------------------------
*/
void EnterObject(void)
{
object *obj;
polygon *pg;
int sides, i;
int convert;
int x,y,z;
obj = CreateObject();
printf("ENTER:\n");
printf("Enter the name of the object : ");
scanf("%s",filename);
strcat(filename, ".object");
fflush(stdin);
printf("Object Types:\n");
printf("Enter the type of object : ");
scanf("%d",&convert);
obj->type = convert;
printf("How many points comprise the object ? ");
scanf("%d",&sides); /* get number points in object */
obj->numpoints = sides;
for(i=1; i<=sides; i++)
{
printf("Enter point %d: x, y, z = ",i);
scanf("%d %d %d",&x,&y,&z);
obj->objpoints[i].x = x;
obj->objpoints[i].y = y;
obj->objpoints[i].z = z;
}
printf("Enter the centre point of the object (x,y,z) ? ");
scanf("%d %d %d",&x, &y, &z);
obj->start_x = x;
obj->start_y = y;
obj->start_z = z;
printf("Enter the approx. radius squared of the object ? ");
scanf("%d",&x);
obj->radius = x;
printf("Enter the number of polygons : ");
scanf("%d",&sides);
for(i=0; i<sides; i++)
{
int numpoints, j;
printf("Enter data for polygon %d :\n",i+1);
do
{
printf("How many points are in this polygon ? ");
scanf("%d",&numpoints);
} while(numpoints>MAX_POINTS);
pg = (polygon *) malloc(sizeof(polygon));
printf("Colours :\n");
printf("0-black, 1-blue, 2-green, 3-lt.green 4-grey, 5-med.blue\n");
printf("6-matt.blue,7-blue/black,8-yellow,9-lt.orange,10-orange\n");
printf("11-red,12-d.red,13-v.d.red,14-d.laven,15-lavender\n");
printf("What colour is it ? ");
scanf("%d", &j);
pg->colour = j;
printf("Enter %d Point Numbers : ", numpoints);
for(j=0; j<numpoints; j++)
{
scanf("%d",&convert);
pg->p[j] = convert;
}
printf("Enter the centre of the polygon (x,y,z) ? ");
scanf("%d %d %d",&x, &y, &z);
pg->centre.x = x;
pg->centre.y = y;
pg->centre.z = z;
pg->numpoints = numpoints;
AddPoly(obj, pg);
}
Save_Object(obj, filename);
Destroy_Object(obj);
}
void ChangeObjectFile(void)
{
object *obj;
polygon *p;
int i, count = 1;
int x,y,z;
printf("CHANGE :\n");
printf("Enter the object name (NO .object) - ");
scanf("%s",filename);
printf("\nObject - %s\n",filename);
strcat(filename,".object");
obj = CreateObject();
if(!(Load_Object(obj, filename)))
return;
printf("What would you like to change ?\n");
printf("(2=details, 1=point, 0=poly) ?");
scanf("%d",&i);
if(i==2)
{
printf("Current values :\n");
printf("Type = %d\n",obj->type);
printf("Numpoints = %d\n",obj->numpoints);
printf("Radius = %d\n",obj->radius);
printf("\nEnter type : ");
scanf("%d", &i);
obj->type = i;
printf("Enter numpoints : ");
scanf("%d",&i);
obj->numpoints = i;
printf("Enter radius^2 : ");
scanf("%d",&i);
obj->radius = i;
printf("Ok.\n");
Save_Object(obj, filename);
Destroy_Object(obj);
return;
}
if(i)
{
printf("Enter point to change (max is %d) ?",obj->numpoints);
scanf("%d", &i);
printf("Enter new value for point (x,y,z) ? ");
scanf("%d %d %d", &x, &y, &z);
obj->objpoints[i].x = x;
obj->objpoints[i].y = y;
obj->objpoints[i].z = z;
printf("Ok.\n");
Save_Object(obj, filename);
Destroy_Object(obj);
return;
}
printf("Enter number of polygon to change ? ");
scanf("%d",&i);
p = obj->poly;
while(p && count!=i)
{
p = (polygon *) p->next;
count++;
}
if(!p)
{
printf("That polygon doesn't exist!\n");
Destroy_Object(obj);
return;
}
printf("Old Values :\n");
printf(" Number of points - %d\n",p->numpoints);
printf(" Colour - %d\n",p->colour);
printf(" Centre %d %d %d\n",p->centre.x,p->centre.y,
p->centre.z);
for(i=0; i<p->numpoints; i++)
printf(" Point %d : %d\n",i+1,p->p[i]);
printf("Enter no. of points in polygon ?");
scanf("%d", &i);
p->numpoints = i;
printf("Colours :\n");
printf("0-black, 1-blue, 2-green, 3-lt.green 4-grey, 5-med.blue\n");
printf("6-matt.blue,7-blue/black,8-yellow,9-lt.orange,10-orange\n");
printf("11-red,12-d.red,13-v.d.red,14-d.laven,15-lavender\n");
printf("What colour is it ? ");
scanf("%d", &i);
p->colour = i;
printf("Enter the centre of the polygon (x,y,z) ? ");
scanf("%d %d %d", &x, &y, &z);
p->centre.x = x;
p->centre.y = y;
p->centre.z = z;
printf("Enter the points : ");
for(i=0; i<p->numpoints; i++)
{
scanf("%d", &x);
p->p[i] = x;
}
printf("Object Changed.\n");
Save_Object(obj, filename);
Destroy_Object(obj);
}
void PrintObjValues(void)
{
object *obj;
polygon *p;
int i, counter = 1;
printf("PRINT :\n");
printf("Enter the object name (NO .object) - ");
scanf("%s",filename);
printf("\nObject - %s\n",filename);
strcat(filename,".object");
obj = CreateObject();
if(!(Load_Object(obj, filename)))
return;
printf("Type - %d\n",obj->type);
p = obj->poly;
printf("Centre - %d %d %d\n",obj->start_x, obj->start_y,
obj->start_z);
printf("Radius - %d\n", obj->radius);
printf("Points :\n");
for(i=1; i<=obj->numpoints; i++)
{
printf("Point %d = %d, %d, %d\n",i,obj->objpoints[i].x,
obj->objpoints[i].y, obj->objpoints[i].z);
}
while(p)
{
printf("Polygon %d :\n",counter++);
printf(" Number of points - %d\n",p->numpoints);
printf(" Colour - %d\n",p->colour);
printf(" Centre %d %d %d\n",p->centre.x,p->centre.y,
p->centre.z);
for(i=0; i<p->numpoints; i++)
printf(" Point %d : %d\n",i+1,p->p[i]);
p = (polygon *) p->next;
}
Destroy_Object(obj);
}
void OptionMenu(void)
{
int c;
while(1)
{
printf("\nF-79 OBJECT CREATION\n");
printf("Options :\n");
printf("1 - Enter an Object\n");
printf("2 - List Objects\n");
printf("3 - Change Object\n");
printf("4 - Print Object values\n");
printf("5 - Exit\n");
printf("Enter option : ");
fflush(stdin);
scanf("%d",&c);
printf("\n");
switch(c)
{
case 1: EnterObject(); break;
case 2: system("dir #?.object"); break;
case 3: ChangeObjectFile(); break;
case 4: PrintObjValues(); break;
case 5: CleanUpandExit(); break;
default: printf("Unknown Option!\n");
}
}
}
int main(char argc, char *argv[])
{
IntuitionBase = (struct IntutionBase *)
OpenLibrary("intuition.library",0);
if(IntuitionBase==NULL)
exit(FALSE);
GfxBase = (struct GfxBase *)
OpenLibrary("graphics.library",0);
if(GfxBase==NULL)
CleanUpandExit();
TrigSetUp(); /* set up fast sin/cos table */
build_table(); /* set up fast square root table */
Setupangles(); /* set up fast asin table */
if(argc>=2)
OptionMenu();
else
{
SoundSetUp(); /* load sound effects */
SetRandom();
SetUpExplosions();
DoIntro();
}
CleanUpandExit();
}
/* end of module 3d.c */