ftp.nice.ch/pub/next/unix/tools/jug.0.7.N.bs.tar.gz#/amiga.c

This is amiga.c in view mode; [Download] [Up]

/*
  (c) 1990 S.Hawtin.
  Permission is granted to copy this file provided
   1) It is not used for commercial gain
   2) This notice is included in all copies
   3) Altered copies are marked as such

  No liability is accepted for the contents of the file.

    amiga.c	within		Jug
*/

/*
  The Amiga interface functions
*/

#define SC_WIDTH 320
#define SC_HEIGHT 200
#define SC_TOP    10
#define X_SCALE 0.10
#define Y_SCALE 0.07
#define X_OFFSET 100
#define Y_OFFSET 148
#define BALL_RADIUS 3
#define RETURN_X (SC_WIDTH/2 - 20)
#define RETURN_Y (SC_HEIGHT - SC_TOP - 15)

int time_x = 20;
int time_y = RETURN_Y;
int ball_offset = 2*BALL_RADIUS/X_SCALE;
double x_scale = X_SCALE;
double y_scale = Y_SCALE;
static int ball_width  = BALL_RADIUS;
static int ball_height = BALL_RADIUS;
static int key_in;
/* Reset this flag if you do not like the animated person */
static int	animate = 1;
static int	animate_mono = 1;

static int fig[32];

#include <stdio.h>
#include <types.h>
#include <math.h>
#include <intuition/intuition.h>
#include <graphics/rastport.h>
#include <graphics/gfx.h>
#include <graphics/view.h>
#include <intuition/screens.h>

#include "jug.h"

extern struct Screen *OpenScreen();
extern struct Window *OpenWindow();
extern struct ViewPort *ViewPortAddress();
extern long OpenLibrary();
extern struct Message *GetMsg();
extern struct ColorMap *GetColorMap();
extern PLANEPTR AllocRaster();
extern long Request();

void tidy_screen();

static UWORD title[128];
static UWORD area1Buffer[25];
static UWORD area2Buffer[25];

/* Get the menustrip data structures */
#include "menustrp.h"

/* Get the requester data structure */
/* #include "requester.h" */

static PLANEPTR myplane1;
static PLANEPTR myplane2;

static struct TmpRas myTmpRas1;
static struct NewWindow init_win;
static struct Window *mywin;
static struct Window *win1,*win2;
static struct NewScreen init_scn;
static struct Screen *myscreen;
static struct AreaInfo myArea1;
static struct AreaInfo myArea2;

/* struct ViewPort *myvport; */

static short colours[16] =
   {0x0000,0x0f00,0x00a0,0x000f,	/* black  red    green  blue   */
    0x0ff0,0x0f0f,0x00cc,0x0fff,	/* yellow violet cyan   white  */
    0x0888,0x0942,0x0f60,0x0ccc,	/* grey   brown  orange grey1  */
    0x0aaa,0x0888,0x0666,0x0444,        /* grey2  grey3  grey4  grey5  */
    };

static void
real_to_screen(x,y,z,screen_x,screen_y)
    int x,y,z;
    int *screen_x;
    int *screen_y;
   {/* Convert from real space to screen space assumes 2D screen !! */
    *screen_x = X_OFFSET + (int)(x_scale * x);
    *screen_y = Y_OFFSET - (int)(y_scale * y);
    }

static void
process_events()
   {
    struct Window *this_win;
    ULONG  class;
    USHORT code;
    USHORT qualifier;
    struct IntuiMessage *my_msg;

    this_win = win1;
    while(this_win)
       {/* process all the waiting events */
        my_msg = (struct IntuiMessage *)GetMsg(this_win->UserPort);
        while(my_msg!=NULL)
           {
            class = my_msg->Class;
            code  = my_msg->Code;
            qualifier = my_msg->Qualifier;
            /* OK now free the message */
            ReplyMsg(my_msg);
            switch(class)
               {case MENUPICK:
                    if(code==MENUNULL)
                        break;
                    switch(MENUNUM(code))
                       {case EDIT_MENU:
                            switch(ITEMNUM(code))
                               {case QUIT_ITEM:
                                    exit(0);
                                case REQ_ITEM:
                                    break;
                                default:
                                    printf("Unknown item %x\n",code);
                                }
                            break;
                        default:
                            printf("Unknown Menu %x\n",code);
                        }
                    break;
                case VANILLAKEY:
                    key_in = process_key(code);
                    break;
                case MOUSEBUTTONS:
                    if(code == 0x68)
                        key_in = 1;
                    break;
                default:
                    printf("Message class %x %x %x\n",class,code,qualifier);
                }
            my_msg = (struct IntuiMessage *)GetMsg(this_win->UserPort);
            }
        if(this_win == win1)
            this_win = win2;
          else
            this_win = NULL;
        }
    }

void
screen_clr()
   {/* Draw the background */

    process_events();

    /* Clear off window */
    SetRast(mywin->RPort,0);
    if(animate)
       {/* Draw the person */
        SetAPen(mywin->RPort,7);
#ifdef NORTHC
        /* NorthC misspells this !! */
        DrawElipse(mywin->RPort,fig[0],fig[1],fig[2],fig[3]);
#else
        DrawEllipse(mywin->RPort,fig[0],fig[1],fig[2],fig[3]);
#endif
        Move(mywin->RPort,fig[4],fig[5]);
        Draw(mywin->RPort,fig[6],fig[7]);
        Move(mywin->RPort,fig[8],fig[9]);
        Draw(mywin->RPort,fig[10],fig[11]);
#ifdef NORTHC
        /* NorthC misspells this !! */
        DrawElipse(mywin->RPort,fig[12],fig[13],fig[14],fig[15]);
#else
        DrawEllipse(mywin->RPort,fig[12],fig[13],fig[14],fig[15]);
#endif
        Move(mywin->RPort,fig[16],fig[17]);
        Draw(mywin->RPort,fig[18],fig[19]);
        Draw(mywin->RPort,fig[20],fig[21]);
#ifdef NORTHC
        /* NorthC misspells this !! */
        DrawElipse(mywin->RPort,fig[22],fig[23],fig[24],fig[25]);
#else
        DrawEllipse(mywin->RPort,fig[22],fig[23],fig[24],fig[25]);
#endif
        Move(mywin->RPort,fig[26],fig[27]);
        Draw(mywin->RPort,fig[28],fig[29]);
        Draw(mywin->RPort,fig[30],fig[31]);
        }
    }

void
screen_flush()
   {
    /* Wait for screen blank */
    WaitBOVP(myscreen->ViewPort);

    /* Copy win1 to win2 */
    ClipBlit(win1->RPort,0,0,win2->RPort,0,0,SC_WIDTH,SC_HEIGHT,0xc0);
    }

void
rescale()
   {/* The obvious bits of rescale are handled by jug.c */
    int x,y,cx,cy,t;

    ball_width = (BALL_RADIUS*x_scale)/X_SCALE;
    ball_height = (BALL_RADIUS*y_scale)/Y_SCALE;

    real_to_screen(100,1000,0,&cx,&cy);
    real_to_screen(300,600,0,&x,&y);
    if(cx > x)
       {t = cx;
        cx = x;
        x = t;
        }
    if(cy > y)
       {t = cy;
        cy = y;
        y = t;
        }
    fig[0] = (cx+x)/2;
    fig[1] = (cy+y)/2;
    fig[2] = (x-cx)/2;
    fig[3] = (y-cy)/2;
    real_to_screen(150,625,0,&fig[4],&fig[5]);
    real_to_screen(-50,550,0,&fig[6],&fig[7]);
    real_to_screen(250,625,0,&fig[8],&fig[9]);
    real_to_screen(450,550,0,&fig[10],&fig[11]);
    real_to_screen(-100,400,0,&cx,&cy);
    real_to_screen(0,550,0,&x,&y);
    if(cx > x)
       {t = cx;
        cx = x;
        x = t;
        }
    if(cy > y)
       {t = cy;
        cy = y;
        y = t;
        }
    fig[12] = (cx+x)/2;
    fig[13] = (cy+y)/2;
    fig[14] = (x-cx)/2;
    fig[15] = (y-cy)/2;
    real_to_screen(-50,400,0,&fig[16],&fig[17]);
    real_to_screen(50,-30,0,&fig[18],&fig[19]);
    real_to_screen(0,-150,0,&fig[20],&fig[21]);
    real_to_screen(500,400,0,&cx,&cy);
    real_to_screen(400,550,0,&x,&y);
    if(cx > x)
       {t = cx;
        cx = x;
        x = t;
        }
    if(cy > y)
       {t = cy;
        cy = y;
        y = t;
        }
    fig[22] = (cx+x)/2;
    fig[23] = (cy+y)/2;
    fig[24] = (x-cx)/2;
    fig[25] = (y-cy)/2;
    real_to_screen(450,400,0,&fig[26],&fig[27]);
    real_to_screen(350,-30,0,&fig[28],&fig[29]);
    real_to_screen(400,-150,0,&fig[30],&fig[31]);
    }

extern int sub_div;
extern int step;
extern int delay;

init_screen()
   {/* Open up the window */
    int i;

    /* Set the defaults to look good on the Amiga */
    sub_div = 6; step = 1; delay = 0;

    /* Set up the figure */
    rescale();
    /* Open the intuition library */
    if(0==OpenLibrary("intuition.library",0L))
       {printf("Unable to open intuition library\n");
	exit(EXIT_FAILURE);
	}
    /* Open the graphics library */
    if(0==OpenLibrary("graphics.library",0L))
       {printf("Unable to open graphics library\n");
	exit(EXIT_FAILURE);
	}
    /* Ensure we tidy up */
    atexit(tidy_screen);
    /* Open my own screen */
    init_scn.LeftEdge  = 0;
    init_scn.TopEdge   = 0;
    init_scn.Width     = SC_WIDTH;
    init_scn.Height    = SC_HEIGHT;
    init_scn.Depth     = 4;
    init_scn.Type      = CUSTOMSCREEN;
    sprintf(title,"Amiga %s %d.%d",NAME,MAJ_VERSION,MIN_VERSION);
    init_scn.DefaultTitle = title;
    init_scn.DetailPen = 15;
    init_scn.BlockPen  = 8;
    myscreen = OpenScreen(&init_scn);
    if(myscreen==NULL)
       {printf("Failed to open screen\n");
	exit(EXIT_FAILURE);
        }

    /* Open the window */
    init_win.LeftEdge = 0;
    init_win.TopEdge  = SC_TOP;
    init_win.Width    = SC_WIDTH;
    init_win.Height   = SC_HEIGHT-SC_TOP;
    /* Window cannot resize so just fix it */
    init_win.MaxWidth = init_win.Width;
    init_win.MaxHeight= init_win.Height;
    init_win.MinWidth = init_win.Width;
    init_win.MinHeight= init_win.Height;

    init_win.DetailPen= 15;
    init_win.BlockPen = 8;
    init_win.Title    = (UBYTE *)"";
    init_win.Screen   = myscreen;
    init_win.Type     = CUSTOMSCREEN;
    init_win.Flags    = BORDERLESS | SMART_REFRESH | ACTIVATE;
    init_win.IDCMPFlags = MENUPICK|GADGETDOWN|GADGETUP|REQCLEAR|REQSET|
                MOUSEBUTTONS|VANILLAKEY;
    /* Now try and open the windows */
    win1 = OpenWindow(&init_win);
    win2 = OpenWindow(&init_win);
    mywin = win1;

    if(win1==NULL || win2==NULL)
       {printf("Failed to open window\n");
	exit(EXIT_FAILURE);
        }

    /* Set up the menu strip */
    SetMenuStrip(win1, &edit_menu );
    SetMenuStrip(win2, &edit_menu );

    /* Set up the areas */
    InitArea(&myArea1,&area1Buffer[0],10L);
    win1->RPort->AreaInfo = &myArea1;
    InitArea(&myArea2,&area2Buffer[0],10L);
    win2->RPort->AreaInfo = &myArea2;

    myplane1 = AllocRaster((long)SC_WIDTH,(long)(SC_HEIGHT-SC_TOP));
    if(myplane1==NULL)
       {printf("Failed to create plane\n");
        exit(EXIT_FAILURE);
        }
    InitTmpRas(&myTmpRas1,myplane1,RASSIZE(SC_WIDTH,SC_HEIGHT-SC_TOP));
    win1->RPort->TmpRas = win2->RPort->TmpRas = &myTmpRas1;

    /* Set the colours to right map */
    LoadRGB4(&myscreen->ViewPort,colours,16L);
    }

int
is_option(num,argv,argc)
    int *num;
    char **argv;
    int argc;
   {/* Process some option for the grapics */
    if(argv[*num][0] == '-')
       {switch(argv[*num][1])
           {case 'a': case 'A':
                animate = 0;
                animate_mono = 0;
                return(1);
            case 'c': case 'C':
                animate_mono = 0;
                return(1);
            }
        }

    /* Not a valid graphics option */

    /* Tell the user the options */
    printf("Graphics options\n");
    printf("          -a -c\n");
    return(0);
    }

void
tidy_screen()
   {/* Close down the graphics window, this function is called 
      when exit() runs or with normal program termination */

    if(myplane1)
       {
        FreeRaster(myplane1,(long)SC_WIDTH,(long)(SC_HEIGHT-SC_TOP));
        myplane1 = NULL;
        }
    if(myplane2)
       {
        FreeRaster(myplane2,(long)SC_WIDTH,(long)(SC_HEIGHT-SC_TOP));
        myplane2 = NULL;
        }
    if(win1)
       {
        ClearMenuStrip(win1);
        CloseWindow(win1);
        win1 = NULL;
        }
    if(win2)
       {
        ClearMenuStrip(win2);
        CloseWindow(win2);
        win2 = NULL;
        }
    if(myscreen)
        CloseScreen(myscreen);
    myscreen = NULL;
    }

out_string(x,y,str)
    int x,y;
    char *str;
   {
    SetAPen(mywin->RPort,7L);
    Move(mywin->RPort,x,y);
    Text(mywin->RPort,str,strlen(str));
    }


/***********************************************************************/

/* This portion converts the current position into an image on the 
   screen */

void
draw_ball(x,y,z,ball)
    int x,y,z;
    Ball *ball;
   {/* Draw a ball ont the pixmap */
    int s_x,s_y;

    real_to_screen(x,y,z,&s_x,&s_y);

    SetAPen(mywin->RPort,ball->ball_num);

    AreaElipse(mywin->RPort,s_x,s_y,ball_width,ball_height);
    AreaEnd(mywin->RPort);
    }

#define FORE_LENGTH 425
#define LOWER_LENGTH 450

static void
draw_arm(x,y,z,hand)
    int x,y,z;
    Hand *hand;
   {/* Draw the arm */
    int x1,y1,z1,x2,y2,z2,d2;
    int cx,cy,dx,dy;

    /* Where is the top of this arm? */
    z1 = -450;y1 = 475;
    if(hand->def_x == 0)
        x1 = -50;
      else
        x1 = 450;
    /* Assume that the complete arm is held in a vertical plane */
    /* There must be a simple way to work out where the elbow is! */

    /* How far away is the hand from the shoulder? */
    d2 = (x - x1)*(x - x1) + (y - y1)*(y - y1) + (z - z1)*(z - z1);
    if(d2 < (FORE_LENGTH-LOWER_LENGTH)*(FORE_LENGTH-LOWER_LENGTH) ||
       d2 > (FORE_LENGTH+LOWER_LENGTH)*(FORE_LENGTH+LOWER_LENGTH))
       {/* The arm cannot reach there !! */
        x2 = x1; y2 = y1; z2 = z1;
        }
      else
       {/* Work out the angles */
        double a1,a2,delta_y,delta_x;

        a1 = asin((double)(y1-y)/sqrt((double)d2));
        a1 += acos((double)(FORE_LENGTH*FORE_LENGTH + d2 - 
                                     LOWER_LENGTH*LOWER_LENGTH)/
                           (2.0*FORE_LENGTH*sqrt((double)d2)));
        delta_y = sin(a1)*FORE_LENGTH;
        delta_x = cos(a1)*FORE_LENGTH;
        y2 = y1 - delta_y;
        x2 = x1 - (int)((delta_x * (x1 - x))/sqrt((double)((x - x1)*(x - x1) + 
                                                           (z - z1)*(z - z1))));
        z2 = z1 - (int)((delta_x * (z1 - z))/sqrt((double)((x - x1)*(x - x1) + 
                                                           (z - z1)*(z - z1))));
        }

    real_to_screen(x-50,y,z,&cx,&cy);
    Move(mywin->RPort,cx,cy);
    real_to_screen(x2-50,y2,z2,&dx,&dy);
    Draw(mywin->RPort,dx,dy);
    real_to_screen(x1-50,y1,z1,&dx,&dy);
    Draw(mywin->RPort,dx,dy);

    real_to_screen(x+50,y,z,&cx,&cy);
    Move(mywin->RPort,cx,cy);
    real_to_screen(x2+50,y2,z2,&dx,&dy);
    Draw(mywin->RPort,dx,dy);
    real_to_screen(x1+50,y1,z1,&dx,&dy);
    Draw(mywin->RPort,dx,dy);
    }

void
draw_hand(x,y,z,hand)
    int x,y,z;
    Hand *hand;
   {/* Draw a hand out */
    int s_x,s_y;

    real_to_screen(x,y,z,&s_x,&s_y);

    if(animate_mono)
        SetAPen(mywin->RPort,7);
      else
        SetAPen(mywin->RPort,hand->hand_num);

    if(animate)
        draw_arm(x,y,z,hand);

    Move(mywin->RPort,s_x-3*ball_width,s_y);
    Draw(mywin->RPort,s_x-3*ball_width,s_y+ball_height);
    Draw(mywin->RPort,s_x+3*ball_width,s_y+ball_height);
    Draw(mywin->RPort,s_x+3*ball_width,s_y);
    }

void
wait_step()
   {/* Wait for the user to do something before going on */
    char next;

    out_string(RETURN_X,RETURN_Y,"press <Return> or <?>");

    /* Now display the screen we have constructed */
    screen_flush();

    /* Wait for a character */
    key_in = 0;
    do {
        process_events();
        } while (!key_in);
    }

These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.