home *** CD-ROM | disk | FTP | other *** search
- /* Tesseract ©1991, Jerry D. Hedden, All Rights Reserved
-
- The Tesseract program, source code, documenation, and icon imagery are
- freely redistributable, but may not be modified in any way, or used in part
- or in whole without the express written consent of the author. Images
- generated by the Tesseract program may be used for any purpose provided
- credit is given to the program's author.
-
- Jerry D. Hedden
- 28 Windemere Dr.
- Sicklerville, NJ 08081
- Phone: (609)629-3975
- Email: Hedden@ESDSDF.DNet.GE.com
-
- ===========================================================================
-
- This source code REQUIRES Aztec 'C' v3.6a. It probably cannot be handled
- by any other compiler because of the assumed register usage within the
- embedded assembly code. Make with the following:
-
- as startup
- cc +x3 -e500 -z10000 tess
- ln -m -o Tesseract startup.o tess.o -lc
-
- ===========================================================================
-
- The following copyright notice accompanied the source code for Palette
- Requester which was used as a model for this program's Color Requester.
-
- Palette Requester -- (c) Copyright 1989 Jonathan Potter
- This program is freely redistributable, although all rights to it remain
- with the author. It may be used freely in any program as long as this
- notice remains intact, however, if you do this, please mention the author
- in the program. If you wish to use this in a commercial program of any
- kind, you must register with a $15 donation.
- Please send donations, bug reports, comments and suggestions to :
- Jonathan Potter
- 3 William Street
- Clarence Park 5034
- South Australia
- Australia
-
- ===========================================================================
-
- History:
-
- v1.00 - 10 Aug 1991
- Initial release
-
- **************************************************************************/
-
- #include <intuition/intuition.h>
-
- /* corrects <exec/memory.h> long integer problems */
- #define CLEARED_CHIP 0x00010002L
-
- /* required libraries */
- struct Library *IntuitionBase, *GfxBase, *MathBase, *MathTransBase,
- *_OpenLibrary();
-
- /* Motorola FFP math routines */
- long SPFix(), SPTst();
- float SPFlt(), SPAdd(), SPSub(), SPMul();
- float SPSincos(), SPSqrt();
-
- /* arrays for holding pre-computed, converted "floating point" values */
- short cos[720], sin[720];
-
- /* circle constants */
- #define PI (float)3.1415926535897932384626433832795
- #define HALF_DEG (float)(PI/360.0)
-
- /* rotation constants */
- #define RESTART -1
- #define STOPPED 0
- #define TEN_DEGREES 20
- #define NINETY_DEGREES 180
- #define THREE_SIXTY 720
-
- /* the 4 coordinates */
- #define X 0L
- #define Y 1L
- #define Z 2L
- #define W 3L
-
- /* viewing angles */
- short cos_theta,sin_theta,cos_phi,sin_phi;
-
- /* objects plotted by this program */
- #define TESSERACT 0
- short t4d[33][4], tseq[33] =
- {0,1,3,2,0,8,9,11,10,8,12,14,10,2,6,4,5,7,6,14,15,11,3,7,15,13,9,1,5,13,12,4,0};
-
- #define OCTAHEDRON 1
- short o4d[25][4], oseq[25] =
- {0,2,1,3,0,4,1,5,2,4,3,5,0,6,1,7,2,6,3,7,4,6,5,7,0};
-
- #define PYRAMID 2
- short p4d[11][4], pseq[11] = {0,1,2,3,4,1,3,0,2,4,0};
-
- /* information for display and graphics */
- #define WIDTH 656L
- #define HEIGHT 430L
- #define PLANES 1
- #define PLANESIZE (long)((WIDTH>>3)*HEIGHT)
- /* used in mapping to screen */
- #asm
- H_HEIGHT equ 215
- H_WIDTH equ 328
- ; SCALE_X = SCALE_Y * 7/8
- SCALE_X equ 65
- SCALE_Y equ 75
- #endasm
-
- struct Screen *screen, *OpenScreen();
- struct ViewPort *vp;
- struct Window *window, *OpenWindow();
- struct RastPort *rp;
- short *pointer;
- struct IntuiMessage *_GetMsg();
- PLANEPTR buffer1[PLANES], buffer2[PLANES], _AllocMem();
-
- struct NewScreen MyScreen = {
- 0,0, WIDTH,HEIGHT,PLANES, 0,1, HIRES|LACE,CUSTOMSCREEN,
- NULL,(UBYTE *)"Tesseract",NULL,NULL
- };
-
- struct NewWindow MyWindow = {
- 0,0, WIDTH,HEIGHT, 0,1, RAWKEY|MOUSEMOVE,
- NOCAREREFRESH|BORDERLESS|ACTIVATE|SIMPLE_REFRESH|RMBTRAP|REPORTMOUSE,
- NULL,NULL,NULL,NULL,NULL, WIDTH,HEIGHT, WIDTH,HEIGHT, CUSTOMSCREEN
- };
-
- /* colors */
- #define BLACK 0L
- #define WHITE 1L
-
- UWORD ColorTables[3][1<<PLANES] = {
- {0x0000,0x0079},
- {0x0FFF,0x0000},
- /* used by color requester */
- {0x0000,0x0079}
- };
-
-
- /* sets up the pre-computed, converted "floating point" arrays */
- Initialize()
- {
- register long i;
- register float fsin;
- float fcos;
-
- initial_pos();
-
- for (i=0; i<720; i++) {
- fsin = SPSincos(&fcos,SPMul(HALF_DEG,SPFlt(i)));
- cos[i] = (SPTst(fcos) >= 0) ? SPFix(SPAdd(0.5,SPMul(fcos,8192.0))) :
- SPFix(SPSub(0.5,SPMul(fcos,8192.0)));
- sin[i] = (SPTst(fsin) >= 0) ? SPFix(SPAdd(0.5,SPMul(fsin,8192.0))) :
- SPFix(SPSub(0.5,SPMul(fsin,8192.0)));
- }
- }
-
-
- #define SCALE_O 14500
- #define SCALE_P 3000.0
-
- /* sets the objects to their "starting positions" */
- initial_pos()
- {
- register long i;
-
- for (i=0; i<33; i++) {
- t4d[i][X] = (((tseq[i]<<1)&2)-1)<<13;
- t4d[i][Y] = (((tseq[i] )&2)-1)<<13;
- t4d[i][Z] = (((tseq[i]>>1)&2)-1)<<13;
- t4d[i][W] = (((tseq[i]>>2)&2)-1)<<13;
- }
- for (i=0; i<25; i++) {
- o4d[i][X] = (oseq[i]==0 || oseq[i]==1) ? ((oseq[i]&1) ? SCALE_O : -SCALE_O) : 0;
- o4d[i][Y] = (oseq[i]==2 || oseq[i]==3) ? ((oseq[i]&1) ? SCALE_O : -SCALE_O) : 0;
- o4d[i][Z] = (oseq[i]==4 || oseq[i]==5) ? ((oseq[i]&1) ? SCALE_O : -SCALE_O) : 0;
- o4d[i][W] = (oseq[i]==6 || oseq[i]==7) ? ((oseq[i]&1) ? SCALE_O : -SCALE_O) : 0;
- }
- for (i=0; i<11; i++) {
- p4d[i][X] = (pseq[i] < 2) ? ((pseq[i] == 1) ?
- SPFix(SPMul(SCALE_P,SPMul( 3.0,SPSqrt(2.0)))) :
- SPFix(SPMul(SCALE_P,SPMul(-3.0,SPSqrt(2.0)))) ) : 0;
- p4d[i][Y] = (pseq[i] < 3) ? ((pseq[i] == 2) ?
- SPFix(SPMul(SCALE_P,SPMul( 2.0,SPSqrt(6.0)))) :
- SPFix(SPMul(SCALE_P,SPMul(-1.0,SPSqrt(6.0)))) ) : 0;
- p4d[i][Z] = (pseq[i] < 4) ? ((pseq[i] == 3) ?
- SPFix(SPMul(SCALE_P,SPMul( 3.0,SPSqrt(3.0)))) :
- SPFix(SPMul(SCALE_P,SPMul(-1.0,SPSqrt(3.0)))) ) : 0;
- p4d[i][W] = (pseq[i] == 4) ?
- SPFix(SPMul(SCALE_P,SPMul( 2.4,SPSqrt(5.0)))) :
- SPFix(SPMul(SCALE_P,SPMul(-0.6,SPSqrt(5.0)))) ;
- }
- }
-
-
- /* rotates the four-dimensional objects */
- rotate_4d(dir1,dir2,angle)
- long dir1,dir2;
- short angle;
- {
- register short cangle, sangle;
- register short *rega2, *rega3;
- register long i;
-
- if (angle == RESTART) {
- initial_pos();
- return;
- }
-
- cangle = cos[angle]; sangle = sin[angle];
-
- rega2 = &t4d[0][dir1]; rega3 = &t4d[0][dir2];
- for (i=0; i<33; i++) {
- #asm
- bsr.s rotate
- #endasm
- }
-
- rega2 = &o4d[0][dir1]; rega3 = &o4d[0][dir2];
- for (i=0; i<25; i++) {
- #asm
- bsr.s rotate
- #endasm
- }
-
- rega2 = &p4d[0][dir1]; rega3 = &p4d[0][dir2];
- for (i=0; i<11; i++) {
- #asm
- bsr.s rotate
- #endasm
- }
- return;
-
- #asm
- rotate: move.w (a2),d0 ; d1' = d1*cos - d2*sin
- muls d4,d0
- move.w (a3),d2
- muls d5,d2
- sub.l d2,d0
- move.w (a2),d1 ; d2' = d1*sin + d2*cos
- muls d5,d1
- move.w (a3),d2
- muls d4,d2
- add.l d2,d1
- moveq #13,d3 ; normalize
- asr.l d3,d0
- asr.l d3,d1
- move.w d0,(a2)
- move.w d1,(a3)
- addq.l #8,a2
- addq.l #8,a3
- rts
- #endasm
- }
-
-
- plot_object(object)
- short object;
- {
- register long i, size;
- short plot_buf[66];
- register short *obj_ptr, *buf_ptr = plot_buf;
-
- if (object == TESSERACT) {
- obj_ptr = &t4d[0][X]; size = 33;
- } else if (object == OCTAHEDRON) {
- obj_ptr = &o4d[0][X]; size = 25;
- } else { /* PYRAMID */
- obj_ptr = &p4d[0][X]; size = 11;
- }
-
- for (i=0; i<size; i++) {
- #asm
- move.w (a2),d0 ; x' = x*cos_theta - z*sin_theta
- muls _cos_theta,d0
- move.w 4(a2),d2
- muls _sin_theta,d2
- sub.l d2,d0
-
- move.w (a2),d1 ; z' = x*sin_theta + z*cos_theta
- muls _sin_theta,d1
- move.w 4(a2),d2
- muls _cos_theta,d2
- add.l d2,d1
-
- moveq #13,d3 ; normalize z'
- asr.l d3,d1
-
- move.w 2(a2),d2 ; y' = y*cos_phi - z'*sin_phi
- muls _cos_phi,d2
- muls _sin_phi,d1
- sub.l d1,d2
-
- asr.l d3,d0 ; normalize x' and y'
- asr.l d3,d2
-
- divs #SCALE_X,d0 ; screen_x = WIDTH/2 + x'/SCALE_X
- add.w #H_WIDTH,d0
- divs #-SCALE_Y,d2 ; screen_y = HEIGHT/2 - y'/SCALE_Y
- add.w #H_HEIGHT,d2
-
- move.w d0,(a3)+ ; store in plotting buffer
- move.w d2,(a3)+
- addq.l #8,a2 ; move to next point
- #endasm
- }
-
- SetBuffer();
- Move(rp,(long)plot_buf[0],(long)plot_buf[1]);
- PolyDraw(rp,size,plot_buf);
- DisplayBuffer();
- }
-
-
- /* for double buffering */
- SetBuffer()
- {
- register long i;
-
- if (rp->BitMap->Planes[0] == buffer1[0])
- for (i=0; i<PLANES; i++)
- rp->BitMap->Planes[i] = buffer2[i];
- else
- for (i=0; i<PLANES; i++)
- rp->BitMap->Planes[i] = buffer1[i];
- SetRast(rp,BLACK);
- }
-
-
- DisplayBuffer()
- {
- WaitBOVP(vp);
- WaitTOF();
- ScrollVPort(vp);
- RethinkDisplay();
- }
-
-
- #define ONE_KEY 1
- #define ZERO_KEY 10
- #define ESCAPE 69
- #define SPACE 64
- #define RKEY 19
- #define TKEY 20
- #define IKEY 23
- #define OKEY 24
- #define PKEY 25
- #define DKEY 34
- #define XKEY 50
- #define CKEY 51
- #define KP8 62
- #define KP2 30
- #define KP4 45
- #define KP6 47
- #define UPARROW 76
- #define DOWNARROW 77
- #define LEFTARROW 79
- #define RIGHTARROW 78
- #define HELP 95
-
- #define IMAGINARY 0
- #define REAL 1
-
- #define STILL 0
- #define MOVED 1
-
- MainLoop()
- {
- register struct IntuiMessage *msg;
- register ULONG class;
- register USHORT code;
- register USHORT qualifier;
- register short mouse = MOVED;
- short plot_it, mode;
- short object = TESSERACT;
- short step_rate = 5;
- short ColorSet = BLACK;
-
- struct {
- long axis1, axis2;
- short angle;
- } rot[2];
-
- Initialize();
- goto reset;
-
- for (;;) {
- if (rot[0].angle != STOPPED) {
- rotate_4d(rot[0].axis1,rot[0].axis2,rot[0].angle);
- if (rot[0].angle != step_rate && rot[0].angle != THREE_SIXTY-step_rate)
- rot[0].angle = STOPPED;
- else if (rot[1].angle != STOPPED)
- rotate_4d(rot[1].axis1,rot[1].axis2,rot[1].angle);
- plot_it = TRUE;
- }
- if (plot_it) {
- plot_object(object);
- plot_it = FALSE;
- }
- if (rot[0].angle == STOPPED)
- _WaitPort(window->UserPort);
- while (msg = _GetMsg(window->UserPort)) {
- class = msg->Class; code = msg->Code; qualifier = msg->Qualifier;
- _ReplyMsg(msg);
- if (class == MOUSEMOVE) {
- mouse = MOVED;
- } else if (class == RAWKEY) {
- switch (code) {
- case TKEY:
- object = TESSERACT; plot_it = TRUE;
- break;
- case OKEY:
- object = OCTAHEDRON; plot_it = TRUE;
- break;
- case PKEY:
- object = PYRAMID; plot_it = TRUE;
- break;
- case RKEY:
- mode = REAL;
- break;
- case IKEY:
- mode = IMAGINARY;
- break;
- case DKEY:
- if (qualifier & (IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT)) {
- rot[1].angle = STOPPED;
- } else {
- rot[1] = rot[0];
- rot[0].angle = STOPPED;
- }
- break;
- case XKEY:
- reset:
- mode = REAL;
- rot[0].axis1 = X; rot[0].axis2 = Z; rot[0].angle = RESTART;
- rot[1].angle = STOPPED;
- plot_it = TRUE;
- break;
- case CKEY:
- if (qualifier & (IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT)) {
- ColorRequester(ColorSet);
- plot_it = TRUE;
- } else {
- if (ColorSet = 1 - ColorSet)
- SetRGB4(vp,17L,0L,0L,0L);
- else
- SetRGB4(vp,17L,15L,15L,15L);
- LoadRGB4(vp, &ColorTables[ColorSet][0], 1L<<PLANES);
- }
- break;
- case SPACE:
- rot[0].angle = STOPPED;
- break;
- case KP4:
- case KP6:
- rot[0].axis1 = X; rot[0].axis2 = (mode) ? Z : W;
- goto calc_angle;
- case KP8:
- case KP2:
- rot[0].axis1 = Y; rot[0].axis2 = (mode) ? Z : W;
- goto calc_angle;
- case LEFTARROW:
- case RIGHTARROW:
- mode = REAL; rot[0].axis1 = X; rot[0].axis2 = Y;
- goto calc_angle;
- case UPARROW:
- case DOWNARROW:
- mode = IMAGINARY; rot[0].axis1 = Z; rot[0].axis2 = W;
- calc_angle:
- if (qualifier & (IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT))
- rot[0].angle = TEN_DEGREES;
- else if (qualifier & IEQUALIFIER_CONTROL)
- rot[0].angle = NINETY_DEGREES;
- else
- rot[0].angle = step_rate;
- if (code == KP8 || code == RIGHTARROW ||
- code == KP6 || code == UPARROW)
- rot[0].angle = THREE_SIXTY - rot[0].angle;
- break;
- case ESCAPE:
- cleanup(0L);
- case HELP:
- LoadRGB4(vp, &ColorTables[0][0], 1L<<PLANES);
- info();
- LoadRGB4(vp, &ColorTables[ColorSet][0], 1L<<PLANES);
- plot_it = TRUE;
- break;
- default:
- if (code >= ONE_KEY && code <= ZERO_KEY) {
- if (rot[0].angle != STOPPED)
- if (rot[0].angle == step_rate)
- rot[0].angle = code;
- else
- rot[0].angle = THREE_SIXTY - code;
- step_rate = code;
- }
- }
- }
- }
- if (mouse) {
- short x,y;
- x = (screen->MouseX*45)/41; /* CAUTION: these factors are */
- y = (screen->MouseY*36)/43; /* highly screen-dependent */
- if (x > 719) x = 719;
- cos_theta = (-cos[x]); sin_theta = sin[x];
- cos_phi = sin[y]; sin_phi = (-cos[y]);
- mouse = STILL; plot_it = TRUE;
- }
- }
- }
-
-
- main()
- {
- long i;
-
- if (IntuitionBase = _OpenLibrary("intuition.library", 0L))
- if (GfxBase = _OpenLibrary("graphics.library", 0L))
- if (MathBase = _OpenLibrary("mathffp.library", 0L))
- if (MathTransBase = _OpenLibrary("mathtrans.library", 0L))
- if (screen = OpenScreen(&MyScreen)) {
- vp = &screen->ViewPort;
- LoadRGB4(vp,&ColorTables[0][0],1L<<PLANES);
- MyWindow.Screen = screen;
- if (window = OpenWindow(&MyWindow)) {
- rp = window->RPort;
- SetDrMd(rp,(long)JAM1);
- SetAPen(rp,WHITE);
- for (i=0; i<PLANES; i++) {
- buffer1[i] = rp->BitMap->Planes[i];
- if (!(buffer2[i] = _AllocMem(PLANESIZE,CLEARED_CHIP)))
- cleanup(101L);
- }
- if (pointer = (short *)_AllocMem(16L,CLEARED_CHIP))
- /* set a white one-pixel pointer */
- pointer[2] = 0x8000;
- SetRGB4(vp,17L,15L,15L,15L);
- SetPointer(window,pointer,1L,1L,0L,0L);
- MainLoop(); /* terminates via cleanup() */
- }
- }
- cleanup(100L); /* no direct indication of what went wrong above */
- }
-
-
- cleanup(code)
- long code;
- {
- long i;
-
- if (pointer) {
- ClearPointer(window);
- _FreeMem(pointer,16L);
- }
- if (window) {
- if (rp->BitMap->Planes[0] == buffer2[0]) {
- SetBuffer();
- DisplayBuffer();
- }
- CloseWindow(window);
- }
- for (i=0; i<PLANES; i++)
- if (buffer2[i]) _FreeMem(buffer2[i],PLANESIZE);
- if (screen) CloseScreen(screen);
- if (MathTransBase) _CloseLibrary(MathTransBase);
- if (MathBase) _CloseLibrary(MathBase);
- if (GfxBase) _CloseLibrary(GfxBase);
- if (IntuitionBase) _CloseLibrary(IntuitionBase);
- exit(code);
- }
-
-
- /*** Info function ***/
-
- struct TextAttr InfoFont =
- {(UBYTE *)"topaz.font",8,FS_NORMAL,FPF_ROMFONT|FPF_DESIGNED};
- struct IntuiText Text = {1,0,JAM2,0,0,&InfoFont,NULL,NULL};
-
- #define TEXT_MARGIN 14L
- #define TEXT_START 22L
-
- char *InfoTitle =
- " Tesseract v1.00 \2511991, Jerry D. Hedden, All Rights Reserved";
- char *InfoText[] = {
- "You are viewing the three-dimensional projection of a four-dimensional object.",
- "You can select amoung the objects supported by this program by pressing 't'",
- "for the tesseract (a hyper-cube), 'o' for a hyper-octahedron or 'p' for a",
- "hyper-tetrahedron (think [incorrectly] of a pyramid). To quit, press 'esc'.",
- "",
- "With the mouse pointer in the center of the screen, the x-axis is horizontal",
- "to the screen, y is vertical, and z extends outward. (The fourth-dimensional",
- "w-axis cannot be 'seen', of course.) The mouse moves these axes; allowing",
- "views of the object from any angle.",
- "",
- "You can rotate the object in four-dimensional space using the arrow and keypad",
- "keys. Rotations in the x-y, x-z and y-z planes are referred to as REAL",
- "because they result in rotations of the object in 3D. For the x-w, y-w and",
- "z-w planes, rotations are IMAGINARY; occuring only in four-dimensional space.",
- "The keypad 8, 2, 4 and 6 represent the up, down, left and right directions.",
- "Pressing 'r' sets the keypad to perform REAL rotations on the object; 'i' sets",
- "IMAGINARY rotations. These correspond to rotations in the x-z plane (REAL",
- "4/6), y-z plane (REAL 8/2), x-w plane (IMAGINARY 4/6) and y-w plane (IMAGINARY",
- "8/2). The left/right arrows perform REAL rotations counterclockwise/clockwise",
- "in x-y plane. The up/down arrows perform IMAGINARY rotations in the z-w plane.",
- "",
- "Pressing an arrow/keypad key alone causes its action to repeat continuously.",
- "Press 'space' to stop. The change between frames can be set from 0.5\260 to 5\260",
- "using the keyboard 1 thru 0. 'Shift-' arrow/keypad keys cause a single 10\260",
- "change; 'ctrl-' causes a 90\260 change.",
- "",
- "The object can be rotated in two planes at once. Set up a rotation, either",
- "REAL or IMAGINARY and at the desired rate, and press 'd' (for dual). The",
- "object will stop which indicates that the settings have been entered for the",
- "dual rotation. Subsequent continuous rotations of the object will have the",
- "dual superimposed on it. 'Shift-d' will erase the dual rotation setting.",
- "",
- "Pressing 'x' will reset the object to its initial position in 4D, and cancel",
- "all rotations.",
- "",
- "Press 'c' to toggle between two color sets (the 'white' set is intended for",
- "printing). 'Shift-c' brings up a color requester.",
- "",
- "The Tesseract program's source code is a combination of 'C' and assembly",
- "using Manx Aztec 'C' v3.6a. The source contains examples of double-",
- "buffering, fixed- and floating-point math, and in-line assembly code. I also",
- "used some of the code from Jonathan Potter's color requester. Send $5.00 to",
- "obtain a disk containing source code and updated program.",
- "",
- " Comments, Jerry D. Hedden",
- " Questions, \\\\ 28 Windemere Dr.",
- " Bug reports, >>>>>> Sicklerville, NJ 08081",
- " Source requests, // Phone: (609)629-3975",
- " etc. Email: Hedden@ESDSDF.DNet.GE.com",
- NULL
- };
-
-
- info()
- {
- register long line;
- register struct Window *info_window;
- register struct IntuiMessage *msg;
- register ULONG class;
- register short all_done;
-
- MyWindow.IDCMPFlags = CLOSEWINDOW;
- MyWindow.Flags = SIMPLE_REFRESH|NOCAREREFRESH|ACTIVATE|WINDOWCLOSE;
- MyWindow.Title = (UBYTE *)InfoTitle;
-
- if (!(info_window = OpenWindow(&MyWindow))) return;
-
- for (line = 0; Text.IText = (UBYTE *)InfoText[line]; line++)
- PrintIText(info_window->RPort,&Text,TEXT_MARGIN,TEXT_START+(line<<3));
-
- for (all_done=0; !all_done; ) {
- _WaitPort(info_window->UserPort);
- while (msg = _GetMsg(info_window->UserPort)) {
- class = msg->Class;
- _ReplyMsg(msg);
- if (class == CLOSEWINDOW) all_done = 1;
- }
- }
- CloseWindow(info_window);
- }
-
-
- /*** common requester stuff ***/
-
- #define RESET 41
- #define CANCEL 42
- #define OKAY 43
-
- short border_xy[] = {0,0, 115,0, 115,10, 0,10, 0,0};
- struct Border MyBorder = {-1,-1,1,0,JAM1,5,border_xy,NULL};
-
- struct IntuiText
- OkayText = {1,0,JAM1, 41,1,NULL,(UBYTE *)"OKAY", NULL},
- ResetText = {1,0,JAM1, 37,1,NULL,(UBYTE *)"RESET", NULL},
- CancelText = {1,0,JAM1, 33,1,NULL,(UBYTE *)"CANCEL",NULL};
-
- struct Image PropImage1, PropImage2, PropImage3;
-
- struct Window *ReqWindow;
-
-
- /*** Color Requester ***/
-
- #define RED 31
- #define GREEN 32
- #define BLUE 33
-
- struct IntuiText
- RedText = {1,0,JAM1,-14,2,NULL,(UBYTE *)"R",NULL},
- GreenText = {1,0,JAM1,-14,2,NULL,(UBYTE *)"G",NULL},
- BlueText = {1,0,JAM1,-14,2,NULL,(UBYTE *)"B",NULL},
- ValuesText = {0,1,JAM2, 0,0,NULL,(UBYTE *)"RGB",NULL};
-
- struct PropInfo
- RedProp = {AUTOKNOB|FREEHORIZ,0,0,0x1000},
- GreenProp = {AUTOKNOB|FREEHORIZ,0,0,0x1000},
- BlueProp = {AUTOKNOB|FREEHORIZ,0,0,0x1000};
-
- struct Image CurColorImage = {0,0,235,8,1,NULL,0,1,NULL};
-
- struct Gadget
- RedCGadg = {NULL,24,54,100,11,
- GADGHNONE|GADGIMAGE,RELVERIFY|GADGIMMEDIATE,PROPGADGET,
- (APTR)&PropImage1,NULL,&RedText,NULL,(APTR)&RedProp,RED,NULL},
- GreenCGadg = {&RedCGadg,24,66,100,11,
- GADGHNONE|GADGIMAGE,RELVERIFY|GADGIMMEDIATE,PROPGADGET,
- (APTR)&PropImage2,NULL,&GreenText,NULL,(APTR)&GreenProp,GREEN,NULL},
- BlueCGadg = {&GreenCGadg,24,78,100,11,
- GADGHNONE|GADGIMAGE,RELVERIFY|GADGIMMEDIATE,PROPGADGET,
- (APTR)&PropImage3,NULL,&BlueText,NULL,(APTR)&BlueProp,BLUE,NULL},
- OkayCGadg = {&BlueCGadg,130,79,114,9,GADGHCOMP,RELVERIFY,BOOLGADGET,
- (APTR)&MyBorder,NULL,&OkayText,NULL,NULL,OKAY,NULL},
- ResetCGadg = {&OkayCGadg,130,67,114,9,GADGHCOMP,RELVERIFY,BOOLGADGET,
- (APTR)&MyBorder,NULL,&ResetText,NULL,NULL,RESET,NULL},
- CancelCGadg = {&ResetCGadg,130,55,114,9,GADGHCOMP,RELVERIFY,BOOLGADGET,
- (APTR)&MyBorder,NULL,&CancelText,NULL,NULL,CANCEL,NULL};
-
- struct NewWindow ColorNewWindow={
- 40,23,255,93,0,1,GADGETUP|GADGETDOWN|MOUSEBUTTONS|RAWKEY,
- ACTIVATE|SIMPLE_REFRESH|NOCAREREFRESH|RMBTRAP,
- &CancelCGadg,NULL,(UBYTE *)" Tesseract's Color Requester",
- NULL,NULL,0,0,0,0,CUSTOMSCREEN};
-
- long CurColor;
-
-
- ColorRequester(ColorSet)
- short ColorSet;
- {
- register long i;
- register ULONG Class;
- register USHORT Code, GadgetID;
- register struct IntuiMessage *msg;
-
- ColorNewWindow.Screen = screen;
- if (!(ReqWindow = OpenWindow(&ColorNewWindow))) return;
-
- for (i=0; i < (1<<PLANES); i++)
- ColorTables[2][i] = ColorTables[ColorSet][i];
-
- DrawPalette(PLANES);
- CurColorImage.PlaneOnOff = CurColor = 1;
- ValuesText.FrontPen = CurColor^((1<<PLANES)-1);
- ValuesText.BackPen = 1;
- DrawImage(ReqWindow->RPort,&CurColorImage,10L,45L);
- SetRGBProps();
-
- FOREVER {
- _WaitPort(ReqWindow->UserPort);
- while (msg = _GetMsg(ReqWindow->UserPort)) {
- Class = msg->Class; Code = msg->Code;
- if (Class == GADGETUP || Class == GADGETDOWN)
- GadgetID = ((struct Gadget *)msg->IAddress)->GadgetID;
- _ReplyMsg(msg);
- switch (Class) {
- case MOUSEBUTTONS: {
- long x,y;
- long NewColor, ReadPixel();
- if (Code != SELECTDOWN) break;
- x=ReqWindow->MouseX; y=ReqWindow->MouseY;
- if (x<12 || x>243 || y<15 || y>40) break;
- if (CurColor == (NewColor = ReadPixel(ReqWindow->RPort,x,y))) break;
- CurColorImage.PlaneOnOff = CurColor = NewColor;
- DrawImage(ReqWindow->RPort,&CurColorImage,10L,45L);
- SetRGBProps();
- break;
- }
- case GADGETDOWN:
- if (GadgetID >= RED && GadgetID <= BLUE) {
- do {
- ReadRGBProps();
- } while (!(msg = _GetMsg(ReqWindow->UserPort)));
- _ReplyMsg(msg);
- ReadRGBProps();
- }
- break;
- case RAWKEY:
- if (Code != ESCAPE) break;
- GadgetID = RESET;
- case GADGETUP:
- switch (GadgetID) {
- case RESET:
- for (i=0; i < (1<<PLANES); i++)
- ColorTables[2][i] = ColorTables[ColorSet][i];
- LoadRGB4(vp, &ColorTables[2][0], 1L<<PLANES);
- SetRGBProps();
- break;
- case OKAY:
- for (i=0; i < (1<<PLANES); i++)
- ColorTables[ColorSet][i] = ColorTables[2][i];
- case CANCEL:
- LoadRGB4(vp, &ColorTables[ColorSet][0], 1L<<PLANES);
- while (msg = _GetMsg(ReqWindow->UserPort)) _ReplyMsg(msg);
- CloseWindow(ReqWindow);
- return;
- }
- }
- }
- }
- }
-
-
- SetRGBProps()
- {
- register UWORD cval = ColorTables[2][CurColor];
- NewModifyProp(&RedCGadg, ReqWindow,0L,(long)(FREEHORIZ|AUTOKNOB),
- (long)(((cval>>8)&0xf)*0x1111),0L,0x1000L,0L,1L);
- NewModifyProp(&GreenCGadg,ReqWindow,0L,(long)(FREEHORIZ|AUTOKNOB),
- (long)(((cval>>4)&0xf)*0x1111),0L,0x1000L,0L,1L);
- NewModifyProp(&BlueCGadg, ReqWindow,0L,(long)(FREEHORIZ|AUTOKNOB),
- (long)((cval&0xf)*0x1111),0L,0x1000L,0L,1L);
- ShowRGBValues();
- }
-
-
- ReadRGBProps()
- {
- register long re,gr,bl;
-
- re = RedProp. HorizPot >> 12;
- gr = GreenProp.HorizPot >> 12;
- bl = BlueProp. HorizPot >> 12;
- ColorTables[2][CurColor] = (re<<8)|(gr<<4)|bl;
- SetRGB4(vp,CurColor,re,gr,bl);
- ShowRGBValues();
- }
-
-
- char *hex = "0123456789ABCDEF";
-
- ShowRGBValues()
- {
- register UWORD cval = ColorTables[2][CurColor];
- ValuesText.IText[0] = hex[(cval>>8)&0xf];
- ValuesText.IText[1] = hex[(cval>>4)&0xf];
- ValuesText.IText[2] = hex[ cval &0xf];
- ValuesText.FrontPen = CurColor^((1<<PLANES)-1);
- ValuesText.BackPen = CurColor;
- PrintIText(ReqWindow->RPort,&ValuesText,115L,45L);
- }
-
-
- DrawPalette(depth)
- int depth;
- {
- long w,h,ox,x,y,i;
-
- #if PLANES>3
- if (depth==4)
- { w=29; h=12; ox=13; }
- else if (depth==5)
- { w=14; h=12; ox=17; }
- else
- #endif
- { w=235/(1<<depth); h=25; ox=12; }
- i=0; x=ox; y=15;
- for (i=0; i<(1<<depth); i++) {
- SetAPen(ReqWindow->RPort,i);
- RectFill(ReqWindow->RPort,x,y,x+w,y+h);
- #if PLANES>3
- if (depth>3 && i==(1<<(depth-1))-1) {
- x=ox; y+=h;
- } else
- #endif
- x+=w;
- }
- }
-
-
- #asm
- ; Stubs for accessing the math libraries
-
- public _MathBase
-
- _LVOSPMul equ -78
- _LVOSPSub equ -72
- _LVOSPAdd equ -66
- _LVOSPTst equ -48
- _LVOSPFlt equ -36
- _LVOSPFix equ -30
-
- public _SPFix
- _SPFix
- move.l 4(sp),d0
- move.l _MathBase,a6
- jmp _LVOSPFix(a6)
-
- public _SPFlt
- _SPFlt
- move.l 4(sp),d0
- move.l _MathBase,a6
- jmp _LVOSPFlt(a6)
-
- public _SPAdd
- _SPAdd
- move.l 4(sp),d1
- move.l 12(sp),d0
- move.l _MathBase,a6
- jmp _LVOSPAdd(a6)
-
- public _SPSub
- _SPSub
- move.l 4(sp),d1
- move.l 12(sp),d0
- move.l _MathBase,a6
- jmp _LVOSPSub(a6)
-
- public _SPMul
- _SPMul
- move.l 4(sp),d1
- move.l 12(sp),d0
- move.l _MathBase,a6
- jmp _LVOSPMul(a6)
-
- public _SPTst
- _SPTst
- move.l 4(sp),d1
- move.l _MathBase,a6
- jmp _LVOSPTst(a6)
-
-
- public _MathTransBase
- _LVOSPSincos equ -54
- _LVOSPSqrt equ -96
-
- public _SPSincos
- _SPSincos
- move.l 4(sp),d1
- move.l 8(sp),d0
- move.l _MathTransBase,a6
- jmp _LVOSPSincos(a6)
-
- public _SPSqrt
- _SPSqrt
- move.l 4(sp),d0
- move.l _MathTransBase,a6
- jmp _LVOSPSqrt(a6)
- #endasm
-