/* ------------------------------------------------------------------ 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 #include #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; iMAX_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; jp[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; inumpoints; 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; inumpoints; 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; inumpoints; 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 */