int r_sph( /* put out a sphere */ int ac, char **av ) { static int nsphs; char *mat; double rad; C_VERTEX *cv; FVECT cent; int inv; /* check argument count and type */ if (ac != 3) return(MG_EARGC); if (!isflt(av[2])) return(MG_ETYPE); if ((cv = c_getvert(av[1])) == NULL) /* get center vertex */ return(MG_EUNDEF); xf_xfmpoint(cent, cv->p); /* transform center */ rad = xf_scale(atof(av[2])); /* scale radius */ if ((inv = rad < 0.)) /* check for inversion */ rad = -rad; if ((mat = material()) == NULL) /* get material */ return(MG_EBADMAT); /* spit out primitive */ printf("\n%s %s %ss%d\n", mat, inv ? "bubble" : "sphere", object(), ++nsphs); printf("0\n0\n4 %18.12g %18.12g %18.12g %18.12g\n", cent[0], cent[1], cent[2], rad); return(MG_OK); }
/* Get a vector from stdin */ int getvec(FVECT vec) { float vf[3]; double vd[3]; char buf[32]; int i; switch (inpfmt) { case 'a': /* ascii */ for (i = 0; i < 3; i++) { if (fgetword(buf, sizeof(buf), stdin) == NULL || !isflt(buf)) return(-1); vec[i] = atof(buf); } break; case 'f': /* binary float */ if (fread((char *)vf, sizeof(float), 3, stdin) != 3) return(-1); VCOPY(vec, vf); break; case 'd': /* binary double */ if (fread((char *)vd, sizeof(double), 3, stdin) != 3) return(-1); VCOPY(vec, vd); break; default: error(CONSISTENCY, "botched input format"); } return(0); }
int i_sph( /* translate sphere description */ int ac, char **av ) { register C_VERTEX *cent; if (ac != 3) return(MG_EARGC); flush_cache(); /* flush vertex cache */ printf("%sSeparator {\n", tabs); indent(1); /* put out current material */ if (put_material() < 0) return(MG_EBADMAT); /* get center */ if ((cent = c_getvert(av[1])) == NULL) return(MG_EUNDEF); /* get radius */ if (!isflt(av[2])) return(MG_ETYPE); printf("%sTranslation { translation %13.9g %13.9g %13.9g }\n", tabs, cent->p[0], cent->p[1], cent->p[2]); printf("%sSphere { radius %s }\n", tabs, av[2]); indent(0); printf("%s}\n", tabs); return(MG_OK); }
int r_cone( /* put out a cone */ int ac, char **av ) { static int ncones; char *mat; double r1, r2; C_VERTEX *cv1, *cv2; FVECT p1, p2; int inv; /* check argument count and type */ if (ac != 5) return(MG_EARGC); if (!isflt(av[2]) || !isflt(av[4])) return(MG_ETYPE); /* get the endpoint vertices */ if ((cv1 = c_getvert(av[1])) == NULL || (cv2 = c_getvert(av[3])) == NULL) return(MG_EUNDEF); xf_xfmpoint(p1, cv1->p); /* transform endpoints */ xf_xfmpoint(p2, cv2->p); r1 = xf_scale(atof(av[2])); /* scale radii */ r2 = xf_scale(atof(av[4])); inv = r1 < 0.; /* check for inverted cone */ if (r1 == 0.) { /* check for illegal radii */ if (r2 == 0.) return(MG_EILL); inv = r2 < 0.; } else if (r2 != 0. && inv ^ (r2 < 0.)) return(MG_EILL); if (inv) { r1 = -r1; r2 = -r2; } if ((mat = material()) == NULL) /* get material */ return(MG_EBADMAT); /* spit the sucker out */ printf("\n%s %s %sc%d\n", mat, inv ? "cup" : "cone", object(), ++ncones); printf("0\n0\n8\n"); putv(p1); putv(p2); printf("%18.12g %18.12g\n", r1, r2); return(MG_OK); }
int arch_is_register_parm(cinv_callconv_t callingconvention, int index, int num_params, cinv_type_t types[]) { int numints = 0, numflts = 0; int i; for (i = 0; i <= index; i++) { if (isflt(types[i])) { numflts++; if (types[i] == CINV_T_FLOAT) numints++; else numints += 2; } else if (types[i] == CINV_T_EXTRALONG) numints += 2; else numints++; } return (isflt(types[index]) && numflts <= 13) || (numints <= 8); }
int r_ring( /* put out a ring */ int ac, char **av ) { static int nrings; char *mat; double r1, r2; C_VERTEX *cv; FVECT cent, norm; /* check argument count and type */ if (ac != 4) return(MG_EARGC); if (!isflt(av[2]) || !isflt(av[3])) return(MG_ETYPE); if ((cv = c_getvert(av[1])) == NULL) /* get center vertex */ return(MG_EUNDEF); if (is0vect(cv->n)) /* make sure we have normal */ return(MG_EILL); xf_xfmpoint(cent, cv->p); /* transform center */ xf_rotvect(norm, cv->n); /* rotate normal */ r1 = xf_scale(atof(av[2])); /* scale radii */ r2 = xf_scale(atof(av[3])); if ((r1 < 0.) | (r2 <= r1)) return(MG_EILL); if ((mat = material()) == NULL) /* get material */ return(MG_EBADMAT); /* spit out primitive */ printf("\n%s ring %sr%d\n", mat, object(), ++nrings); printf("0\n0\n8\n"); putv(cent); putv(norm); printf("%18.12g %18.12g\n", r1, r2); return(MG_OK); }
int i_cyl( /* translate a cylinder description */ int ac, char **av ) { register C_VERTEX *v1, *v2; FVECT va; double length, angle; if (ac != 4) return(MG_EARGC); flush_cache(); /* flush vertex cache */ printf("%sSeparator {\n", tabs); indent(1); /* put out current material */ if (put_material() < 0) return(MG_EBADMAT); /* get endpoints */ if (((v1 = c_getvert(av[1])) == NULL) | ((v2 = c_getvert(av[3])) == NULL)) return(MG_EUNDEF); /* get radius */ if (!isflt(av[2])) return(MG_ETYPE); /* compute transform */ va[0] = v2->p[0] - v1->p[0]; va[1] = v2->p[1] - v1->p[1]; va[2] = v2->p[2] - v1->p[2]; length = VLEN(va); angle = Acos(va[1]/length); printf("%sTranslation { translation %13.9g %13.9g %13.9g }\n", tabs, .5*(v1->p[0]+v2->p[0]), .5*(v1->p[1]+v2->p[1]), .5*(v1->p[2]+v2->p[2])); printf("%sRotation { rotation %.9g %.9g %.9g %.9g }\n", tabs, va[2], 0., -va[0], angle); /* open-ended */ printf("%sCylinder { parts SIDES height %13.9g radius %s }\n", tabs, length, av[2]); indent(0); printf("%s}\n", tabs); return(MG_OK); }
int r_cyl( /* put out a cylinder */ int ac, char **av ) { static int ncyls; char *mat; double rad; C_VERTEX *cv1, *cv2; FVECT p1, p2; int inv; /* check argument count and type */ if (ac != 4) return(MG_EARGC); if (!isflt(av[2])) return(MG_ETYPE); /* get the endpoint vertices */ if ((cv1 = c_getvert(av[1])) == NULL || (cv2 = c_getvert(av[3])) == NULL) return(MG_EUNDEF); xf_xfmpoint(p1, cv1->p); /* transform endpoints */ xf_xfmpoint(p2, cv2->p); rad = xf_scale(atof(av[2])); /* scale radius */ if ((inv = rad < 0.)) /* check for inverted cylinder */ rad = -rad; if ((mat = material()) == NULL) /* get material */ return(MG_EBADMAT); /* spit out the primitive */ printf("\n%s %s %scy%d\n", mat, inv ? "tube" : "cylinder", object(), ++ncyls); printf("0\n0\n7\n"); putv(p1); putv(p2); printf("%18.12g\n", rad); return(MG_OK); }
int r_ies( /* convert an IES luminaire file */ int ac, char **av ) { int xa0 = 2; char combuf[128]; char fname[48]; char *oname; register char *op; register int i; /* check argument count */ if (ac < 2) return(MG_EARGC); /* construct output file name */ if ((op = strrchr(av[1], '/')) != NULL) op++; else op = av[1]; (void)strcpy(fname, op); if ((op = strrchr(fname, '.')) == NULL) op = fname + strlen(fname); (void)strcpy(op, ".rad"); /* see if we need to run ies2rad */ if (access(fname, 0) == -1) { (void)strcpy(combuf, "ies2rad");/* build ies2rad command */ op = combuf + 7; /* get -m option (first) */ if (ac-xa0 >= 2 && !strcmp(av[xa0], "-m")) { if (!isflt(av[xa0+1])) return(MG_ETYPE); op = addarg(addarg(op, "-m"), av[xa0+1]); xa0 += 2; } *op++ = ' '; /* build IES filename */ i = 0; if (mg_file != NULL && (oname = strrchr(mg_file->fname,'/')) != NULL) { i = oname - mg_file->fname + 1; (void)strcpy(op, mg_file->fname); } (void)strcpy(op+i, av[1]); if (access(op, 0) == -1) /* check for file existence */ return(MG_ENOFILE); system(combuf); /* run ies2rad */ if (access(fname, 0) == -1) /* check success */ return(MG_EINCL); } printf("\n!xform"); /* put out xform command */ oname = object(); if (*oname) { printf(" -n "); for (op = oname; op[1]; op++) /* remove trailing separator */ putchar(*op); } for (i = xa0; i < ac; i++) printf(" %s", av[i]); if (ac > xa0 && xf_argc > 0) printf(" -i 1"); for (i = 0; i < xf_argc; i++) printf(" %s", xf_argv[i]); printf(" %s\n", fname); return(MG_OK); }
char *arch_callback_stub(void *functionp, void *param, short stacksize, cinv_callconv_t cc, cinv_type_t types[], int numparams) { short functionphi = ((int)functionp >> 16); short functionplo = ((int)functionp & 0xFFFF); short paramhi = ((int)param >> 16); short paramlo = ((int)param & 0xFFFF); int needscopy = 0, i, numints = 0; for (i = 0; i < numparams; i++) { if (isflt(types[i])) { if (types[i] == CINV_T_FLOAT) numints++; else numints += 2; } else { if (types[i] == CINV_T_EXTRALONG) numints += 2; else numints ++; } if (numints == 9 && types[i] == CINV_T_EXTRALONG) { needscopy = 1; break; } } char *ret = mmap(0, LEN, PROT_EXEC|PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, -1, 0); if (ret == MAP_FAILED) return NULL; if (!needscopy) { //void f() { // __asm("mr r2, r3" ::: "r2"); // ((void (*)(void *))0xAAAABBBB)((void *)0xCCCCDDDD); //} memcpy(ret, "\x7c\x08\x02\xa6\xbf\xc1\xff\xf8" "\x90\x01\x00\x08\x94\x21\xff\xb0" "\x7c\x3e\x0b\x78\x7c\x62\x1b\x78" "\x3c\x00\xaa\xaa\x60\x00\xbb\xbb" "\x3c\x60\xcc\xcc\x60\x63\xdd\xdd" "\x7c\x0c\x03\x78\x7d\x89\x03\xa6" "\x4e\x80\x04\x21\x80\x21\x00\x00" "\x80\x01\x00\x08\x7c\x08\x03\xa6" "\xbb\xc1\xff\xf8\x4e\x80\x00\x20", 72); memcpy(ret + 26, &functionphi, 2); memcpy(ret + 30, &functionplo, 2); memcpy(ret + 34, ¶mhi, 2); memcpy(ret + 38, ¶mlo, 2); } else { short offset = 80 + ARCH_STACK_SKIPTOP + (7 * 4); offset &= 0x7FF; //void f2() { // __asm("lwz r10 3822(r1)"); // 0xEEE // __asm("mr r2, r3" ::: "r2"); // ((void (*)(void *))0xAAAABBBB)((void *)0xCCCCDDDD); //} memcpy(ret, "\x7c\x08\x02\xa6\xbf\xc1\xff\xf8" "\x90\x01\x00\x08\x94\x21\xff\xb0" "\x7c\x3e\x0b\x78\x91\x41\x0e\xee" "\x7c\x62\x1b\x78\x3c\x00\xaa\xaa" "\x60\x00\xbb\xbb\x3c\x60\xcc\xcc" "\x60\x63\xdd\xdd\x7c\x0c\x03\x78" "\x7d\x89\x03\xa6\x4e\x80\x04\x21" "\x80\x21\x00\x00\x80\x01\x00\x08" "\x7c\x08\x03\xa6\xbb\xc1\xff\xf8" "\x4e\x80\x00\x20", 76); memcpy(ret + 22, &offset, 2); memcpy(ret + 30, &functionphi, 2); memcpy(ret + 34, &functionplo, 2); memcpy(ret + 38, ¶mhi, 2); memcpy(ret + 42, ¶mlo, 2); } // the following block is a ppc oddity which is neccessary due to // the instruction cache and data cache not being linked. in // order to modify and execute code on ppc we have to flush it out // of the data cache, then invalidate the instruction cache. this // will ensure that when the code is executed it is running our fresh // copy from memory. Much praise to H D Moore for pointing this out @ // http://www.uninformed.org/?v=1&a=1&t=pdf. int *c = (int *)ret; for (i = 0; i < 76; i++) { __asm("lwz r2, %0" :: "m" (c) : "r2"); __asm("dcbf 0, r2"); __asm("sync"); __asm("icbi 0, r2"); __asm("isync"); c++; } return ret; }