home *** CD-ROM | disk | FTP | other *** search
- /*************************************************************************
- * Version 0.0 MULTIDIM.C - Multi-dimensional rotation 12-Mar-86 *
- * Commodore Amiga Main Module MULTIDIM.C *
- *************************************************************************
- * Copyright (c) 1986, Robert S. French *
- * --------------------------------------------------------------------- *
- * This program has been placed in the public domain. A limited *
- * license is hereby granted for the unlimited use and distribution of *
- * this program, provided it is not used for commercial or profit- *
- * making purposes. Thank you. *
- *************************************************************************
- * Author information: | Disclaimer: *
- * | *
- * Name: Robert S. French | The author takes no responsibil- *
- * USnail: 2740 Frankfort Avenue | ity for damages incurred during *
- * Louisville, KY 40206 | the use of this program. *
- * Phone: (502) 897-5096 \-----------------------------------*
- * ARPA: French#Robert%d@LLL-MFE UUCP: ihnp4!ptsfa!well!french *
- *************************************************************************
- * Please send any comments, suggestions, or bugs to one of the above *
- * addresses. *
- *************************************************************************
- * Comments *
- * ======== *
- * *
- * Please note that I have very little background in multi-dimensional *
- * theory. This program is not meant to be a scientific representation *
- * of higher universes, just something kinda neat to look at. I'm sure *
- * that there are mathematical problems, such as rotational direction *
- * in the higher planes. "A" etc. are used for lack of better names. *
- * Hold the joystick right and press the button to end, or left and *
- * press for automatic demo. Feel free to hack this program up as much *
- * as you like. One of the things I'd like to add is double-buffering. *
- *************************************************************************/
-
- /* Lots of include files! */
-
- #include <exec/types.h>
- #include <exec/tasks.h>
- #include <exec/libraries.h>
- #include <exec/devices.h>
- #include <devices/keymap.h>
- #include <devices/gameport.h>
- #include <devices/inputevent.h>
- #include <graphics/copper.h>
- #include <graphics/display.h>
- #include <graphics/gfxbase.h>
- #include <graphics/text.h>
- #include <graphics/view.h>
- #include <graphics/gels.h>
- #include <graphics/regions.h>
- #include <hardware/blit.h>
- #include <intuition/intuition.h>
- #include <intuition/intuitionbase.h>
- #include <stdio.h>
-
- /* Some definitions... */
-
- #define MAXDIM 6
- #define MAXPOINTS 64
- #define MAXEDGES 250
- #define XSCALE 145
- #define YSCALE 60
- #define XCENTER 320
- #define YCENTER 100
-
- /* Fast-Floating-Point Definitions... */
-
- extern int SPFix();
- extern int SPFlt();
- extern int SPCmp();
- extern int SPTst();
- extern int SPAbs();
- extern int SPNeg();
- extern int SPAdd();
- extern int SPSub();
- extern int SPMul();
- extern int SPDiv();
-
- extern int SPAtan();
- extern int SPSin();
- extern int SPCos();
- extern int SPTan();
- extern int SPSincos();
- extern int SPSinh();
- extern int SPCosh();
- extern int SPTanh();
- extern int SPExp();
- extern int SPLog();
- extern int SPPow();
- extern int SPSqrt();
- extern int SPTieee();
- extern int SPFieee();
-
- /* Other external functions... */
-
- extern struct MsgPort *CreatePort();
- extern struct IOStdReq *CreateStdIO();
-
- /* And some global graphics stuff... */
-
- struct GfxBase *GfxBase = NULL;
- struct IntuitionBase *IntuitionBase = NULL;
-
- struct Screen *scrn = NULL;
- struct NewScreen newscreen;
- struct RastPort *rp = NULL;
- struct ViewPort *vp = NULL;
-
- /* And some more global stuff... */
-
- int MathBase = NULL, MathTransBase = NULL;
-
- struct IOStdReq *joystick_io_request = NULL;
- struct InputEvent joystick_data;
-
- union kludge {
- float f;
- int i;
- } points[MAXPOINTS][MAXDIM], xscale, yscale, sqrt2, const2, const15,
- recip2sqrt2;
-
- int st_edge[MAXEDGES], end_edge[MAXEDGES], xpoints[MAXPOINTS],
- ypoints[MAXPOINTS];
-
- int num_points,num_edges,num_dim,alldim;
-
- /* And the real thing... */
-
- main(argc,argv)
- int argc;
- char *argv[];
- {
- int i,j,k,num_change,axis1,axis2,autorot,autocount;
- union kludge angle,nangle,pi;
- char *s;
-
- if (argc < 2)
- abort("Usage: multidim n {D} where n is the number of dimensions");
-
- num_dim = atoi(argv[1]);
- if (num_dim < 2 || num_dim > MAXDIM)
- abort("Illegal number of dimensions");
- alldim = 1;
- if (argc == 3 && toupper(argv[2][0]) == 'D')
- alldim = 0;
-
- if ((MathBase = OpenLibrary("mathffp.library")) == NULL)
- abort("Can't open mathffp.library!");
- if ((MathTransBase = OpenLibrary("mathtrans.library")) == NULL)
- abort("Can't open mathtrans.library!");
-
- xscale.i = SPFlt(XSCALE);
- yscale.i = SPFlt(YSCALE);
- const2.i = SPFlt(2);
- const15.i = SPDiv(SPFlt(2),SPFlt(3));
- sqrt2.i = SPSqrt(const2.i);
- recip2sqrt2.i = SPDiv(SPMul(SPFlt(2),sqrt2.i),SPFlt(1));
-
- num_points = 1 << num_dim;
-
- /* Figure out vertices of n-dimensional "cube" */
-
- for (i=0;i<num_points;i++)
- for (j=0;j<num_dim;j++)
- if (i & (1 << j))
- points[i][j].i = SPFlt(1);
- else
- points[i][j].i = SPFlt(-1);
-
- /* Figure out edges */
-
- num_edges = 0;
-
- for (i=0;i<num_points-1;i++)
- for (j=i+1;j<num_points;j++) {
- num_change = 0;
- for (k=0;k<num_dim;k++)
- if (points[i][k].i != points[j][k].i)
- num_change++;
- if (num_change == 1) {
- st_edge[num_edges] = i;
- end_edge[num_edges] = j;
- num_edges++;
- }
- }
-
- if ((IntuitionBase = (struct IntuitionBase *)
- OpenLibrary("intuition.library", 0)) == NULL)
- abort("Can't open Intuition.Library!\n");
- if ((GfxBase = (struct GfxBase *)
- OpenLibrary("graphics.library", 0)) == NULL)
- abort("Can't open Graphics.Library!\n");
-
- open_joystick();
-
- /* values for new screen */
-
- newscreen.LeftEdge = 0;
- newscreen.TopEdge = 0;
- newscreen.Width = 640;
- newscreen.Height = 200;
- newscreen.Depth = 1;
- newscreen.DetailPen = 0;
- newscreen.BlockPen = 1;
- newscreen.ViewModes = HIRES;
- newscreen.Type = CUSTOMSCREEN;
- newscreen.Font = NULL;
- newscreen.DefaultTitle = "";
- newscreen.Gadgets = NULL;
-
- scrn = (struct Screen *)OpenScreen(&newscreen);
- if (scrn == 0)
- abort("Can't open new screen!\n");
-
- vp = &(scrn->ViewPort);
- rp = &(scrn->RastPort);
-
- SetAPen(rp,0);
- RectFill(rp,0,0,639,199);
-
- SetRGB4(vp,0,0,0,0);
- SetRGB4(vp,1,0xb,0,0);
-
- SetAPen(rp,1);
- SetBPen(rp,0);
- SetDrMd(rp,JAM2);
- Move(rp,0,9);
- Text(rp,"Plane: X Y",10);
- Move(rp,550,9);
- Text(rp,"R. French",9);
-
- pi.f = 3.1415926535;
- pi.i = SPFieee(pi.i);
-
- angle.i = SPMul(SPDiv(SPFlt(180),pi.i),SPFlt(5));
- nangle.i = SPNeg(angle.i);
-
- axis1 = 0;
- axis2 = 1;
- autorot = autocount = 0;
- s = " ";
-
- draw();
- while(1) {
- DoIO(joystick_io_request);
- if (joystick_data.ie_Y == 1 && !autorot) {
- rotate(axis1,axis2,nangle.i);
- draw();
- }
- else if (joystick_data.ie_Y == -1 || autorot) {
- rotate(axis1,axis2,angle.i);
- draw();
- }
- if (autorot) autocount = (autocount + 1) % 33;
- if (joystick_data.ie_Code == IECODE_LBUTTON || autocount == 32) {
- if (joystick_data.ie_Code == IECODE_LBUTTON)
- autorot = autocount = 0;
- if (joystick_data.ie_X == 1)
- abort("All done!");
- if (joystick_data.ie_X == -1)
- autorot = 1;
- axis2++;
- if (axis2 > num_dim-1) {
- axis1++;
- if (axis1 > num_dim-2)
- axis1 = 0;
- axis2 = axis1 + 1;
- }
- SetAPen(rp,0);
- RectFill(rp,56,0,85,9);
- SetAPen(rp,1);
- Move(rp,56,9);
- s[0] = (axis1 < 3) ? 'X'+axis1 : 'A'+axis1-3;
- s[2] = (axis2 < 3) ? 'X'+axis2 : 'A'+axis2-3;
- Text(rp,s,3);
- }
- }
- }
-
- abort(s)
- char *s;
- {
- puts(s);
- if (joystick_io_request) close_joystick();
- if (scrn) CloseScreen(scrn);
- if (GfxBase) CloseLibrary(GfxBase);
- if (IntuitionBase) CloseLibrary(IntuitionBase);
- if (MathTransBase) CloseLibrary(MathTransBase);
- if (MathBase) CloseLibrary(MathBase);
- exit(20);
- }
-
- draw()
- {
- int i,dim;
- union kludge z;
-
- for (i=0;i<num_points;i++) {
- z.i = SPFlt(1);
-
- if (num_dim > 2)
- if (alldim)
- for (dim=num_dim-1;dim>=2;--dim)
- z.i = SPMul(SPAdd(SPMul(points[i][dim].i,recip2sqrt2.i),
- const15.i),z.i);
- else
- z.i = SPAdd(SPMul(points[i][num_dim-1].i,recip2sqrt2.i),
- const15.i);
-
- xpoints[i] = SPFix(SPMul(SPDiv(z.i,points[i][0].i),xscale.i))+XCENTER;
- ypoints[i] = SPFix(SPMul(SPDiv(z.i,points[i][1].i),yscale.i))+YCENTER;
- }
-
- SetAPen(rp,0);
- RectFill(rp,0,10,639,199);
-
- SetAPen(rp,1);
- SetDrMd(rp,JAM1);
-
- for (i=0;i<num_edges;i++) {
- Move(rp,xpoints[st_edge[i]],ypoints[st_edge[i]]);
- Draw(rp,xpoints[end_edge[i]],ypoints[end_edge[i]]);
- }
- }
-
- rotate(p1,p2,a)
- int p1,p2,a;
- {
- int i;
- union kludge ang,thesin,thecos,temp1,temp2;
-
- ang.i = a;
-
- thesin.i = SPSin(ang.i);
- thecos.i = SPCos(ang.i);
-
- for (i=0;i<num_points;i++) {
- temp1.i = SPSub(SPMul(points[i][p2].i,thesin.i),
- SPMul(points[i][p1].i,thecos.i));
- temp2.i = SPAdd(SPMul(points[i][p2].i,thecos.i),
- SPMul(points[i][p1].i,thesin.i));
- points[i][p1].i = temp1.i;
- points[i][p2].i = temp2.i;
- }
- }
-
- open_joystick()
- {
- struct MsgPort *joystick_msg_port;
-
- /* provide a port for the IO request/response */
-
- joystick_msg_port = CreatePort("thejoystickport",0);
-
- if(joystick_msg_port == 0)
- abort("Can't create joystick port");
-
- /* make an io request block for communicating with the joystick device */
-
- joystick_io_request = CreateStdIO(joystick_msg_port);
-
- if(joystick_io_request == 0)
- abort("Can't create joystick I/O request block");
-
- /* open the gameport device for access, unit 1 is right port */
-
- if(OpenDevice("gameport.device",1,joystick_io_request,0))
- abort("Can't open joystick device");
-
- /* set the device type to absolute joystick */
-
- if (set_controller_type(GPCT_ABSJOYSTICK) != 0)
- abort("Can't set controller type");
-
- /* trigger on button-down, button-up, front, back, left, right, center */
-
- if (set_controller_trigger(GPTF_UPKEYS+GPTF_DOWNKEYS,1,1,1) != 0)
- abort("Can't set controller trigger");
-
- /* SETUP THE IO MESSAGE BLOCK FOR THE ACTUAL DATA READ */
-
- /* gameport.device replies to this task */
- joystick_io_request->io_Message.mn_ReplyPort = joystick_msg_port;
-
- /* from now on, just read input events */
- joystick_io_request->io_Command = GPD_READEVENT;
-
- /* into the input buffer, one at a time. */
- joystick_io_request->io_Data = (APTR)&joystick_data;
-
- /* read num events each time we go back to the joystickport */
- joystick_io_request->io_Length = sizeof(joystick_data);
- }
-
- close_joystick()
- {
-
- /* close up joystick device */
-
- CloseDevice(joystick_io_request);
-
- /* clean up */
-
- DeletePort(joystick_io_request->io_Message.mn_ReplyPort);
- DeleteStdIO(joystick_io_request);
- }
-
- int set_controller_type(type)
- BYTE type;
- {
- joystick_io_request->io_Command = GPD_SETCTYPE;
- joystick_io_request->io_Length = 1;
-
- /* set type of controller to "type" */
- joystick_io_request->io_Data = (APTR)&type;
-
- return(DoIO(joystick_io_request));
- }
-
- int set_controller_trigger(keys,timeout,xdelta,ydelta)
- UWORD keys,timeout,xdelta,ydelta;
- {
- struct GamePortTrigger gpt;
-
- joystick_io_request->io_Command = GPD_SETTRIGGER;
- joystick_io_request->io_Length = sizeof(gpt);
- joystick_io_request->io_Data = (APTR)&gpt;
- gpt.gpt_Keys = keys;
- gpt.gpt_Timeout = timeout;
- gpt.gpt_XDelta = xdelta;
- gpt.gpt_YDelta = ydelta;
-
- return(DoIO(joystick_io_request));
- }
-