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.