void corr_matrix(Data_Obj *dpto,Data_Obj *dpfr) { int had_err=0; float *op1, *op2; float *dest, *dest2; dimension_t i,j; Vec_Args args; if( ! is_real(dpto,"corr_matrix") ) return; if( ! is_real(dpfr,"corr_matrix") ) return; if( OBJ_COLS(dpto) != OBJ_ROWS(dpto) ){ sprintf(ERROR_STRING,"target matrix %s (%dx%d) must be square",OBJ_NAME(dpto), OBJ_ROWS(dpto),OBJ_COLS(dpto)); WARN(ERROR_STRING); had_err++; } if( OBJ_COLS(dpto) != OBJ_ROWS(dpfr) ){ sprintf(ERROR_STRING, "target matrix %s size %d not equal to source matrix %s rows (%d)", OBJ_NAME(dpto),OBJ_COLS(dpto),OBJ_NAME(dpfr),OBJ_ROWS(dpfr)); WARN(ERROR_STRING); had_err++; } if( had_err ) return; if( IS_COMPLEX(dpto) ) args.arg_argstype = COMPLEX_ARGS; else args.arg_argstype = REAL_ARGS; args.arg_inc1 = OBJ_PXL_INC(dpfr); args.arg_inc2 = OBJ_PXL_INC(dpfr); args.arg_n1 = OBJ_COLS(dpfr); args.arg_n2 = OBJ_COLS(dpfr); args.arg_prec1 = OBJ_PREC(dpfr); args.arg_prec2 = OBJ_PREC(dpfr); op1 = OBJ_DATA_PTR(dpfr); for(i=0;i<OBJ_ROWS(dpfr);i++){ dest = dest2 = OBJ_DATA_PTR(dpto); dest += i*OBJ_ROW_INC(dpto); dest += i*OBJ_PXL_INC(dpto); dest2 += i*OBJ_PXL_INC(dpto); dest2 += i*OBJ_ROW_INC(dpto); op2 = OBJ_DATA_PTR(dpfr); op2 += i*OBJ_ROW_INC(dpfr); for(j=i;j<OBJ_ROWS(dpfr);j++){ args.arg_v1 = op1; args.arg_v2 = op2; vdot(&args); *dest2 = *dest; /* symmetric matrix */ op2 += OBJ_ROW_INC(dpfr); dest += OBJ_PXL_INC(dpto); dest2 += OBJ_ROW_INC(dpto); } op1 += OBJ_ROW_INC(dpfr); } } /* end corr_matrix() */
/* Returns the fid of the fruit type; if that type already exists, it * returns the fid of that one; if it does not exist, it adds a new fruit * type to the chain and returns the new one. */ int fruitadd(const char *str) { int i; struct fruit *f; struct fruit *lastf = 0; int highest_fruit_id = 0; char buf[PL_FSIZ], *c; boolean user_specified = (str == pl_fruit); /* if not user-specified, then it's a fruit name for a fruit on a bones level... */ /* Note: every fruit has an id (spe for fruit objects) of at least 1; 0 is an error. */ if (user_specified) { /* disallow naming after other foods (since it'd be impossible to tell the difference) */ boolean found = FALSE, numeric = FALSE; for (i = bases[FOOD_CLASS]; objects[i].oc_class == FOOD_CLASS; i++) { if (i != SLIME_MOLD && !strcmp(OBJ_NAME(objects[i]), pl_fruit)) { found = TRUE; break; } } for (c = pl_fruit; *c >= '0' && *c <= '9'; c++) ; if (isspace(*c) || *c == 0) numeric = TRUE; if (found || numeric || !strncmp(str, "cursed ", 7) || !strncmp(str, "uncursed ", 9) || !strncmp(str, "blessed ", 8) || !strncmp(str, "partly eaten ", 13) || (!strncmp(str, "tin of ", 7) && (!strcmp(str + 7, "spinach") || name_to_mon(str + 7) >= LOW_PM)) || !strcmp(str, "empty tin") || ((!strncmp(str + strlen(str) - 7, " corpse", 7) || !strncmp(str + strlen(str) - 4, " egg", 4)) && name_to_mon(str) >= LOW_PM)) { strcpy(buf, pl_fruit); strcpy(pl_fruit, "candied "); strncat(pl_fruit + 8, buf, PL_FSIZ - 8 - 1); } } for (f = ffruit; f; f = f->nextf) { lastf = f; if (f->fid > highest_fruit_id) highest_fruit_id = f->fid; if (!strncmp(str, f->fname, PL_FSIZ)) goto nonew; } /* if adding another fruit would overflow spe, use a random fruit instead... we've got a lot to choose from. */ if (highest_fruit_id >= 127) return rnd(127); highest_fruit_id++; f = newfruit(); memset(f, 0, sizeof (struct fruit)); if (ffruit) lastf->nextf = f; else ffruit = f; strcpy(f->fname, str); f->fid = highest_fruit_id; f->nextf = 0; nonew: if (user_specified) current_fruit = highest_fruit_id; return f->fid; }
void inner(QSP_ARG_DECL Data_Obj *dpto,Data_Obj *dpfr1,Data_Obj *dpfr2) { //dimension_t _n; /* dot prod len */ dimension_t i,j; Vec_Obj_Args oa1, *oap=&oa1; //Dimension_Set sizes={{1,1,1,1,1}}; Dimension_Set *sizes; index_t dst_indices[N_DIMENSIONS]={0,0,0,0,0}; index_t src1_indices[N_DIMENSIONS]={0,0,0,0,0}; index_t src2_indices[N_DIMENSIONS]={0,0,0,0,0}; Data_Obj *col_dp; sizes=NEW_DIMSET; for(i=0;i<N_DIMENSIONS;i++) SET_DIMENSION(sizes,i,1); #ifdef CAUTIOUS clear_obj_args(oap); #endif /* CAUTIOUS */ /* The types and precisions should be whatever is allowed by vdot, * which is float, double, real and complex... */ if( ! is_good_for_inner(dpto,"inner") ) return; if( ! is_good_for_inner(dpfr1,"inner") ) return; if( ! is_good_for_inner(dpfr2,"inner") ) return; /* we need to make sure that the types and precisions MATCH! */ if( ! prec_and_type_match(dpto,dpfr1,"inner") ) return; if( ! prec_and_type_match(dpto,dpfr2,"inner") ) return; if( OBJ_ROWS(dpto) != OBJ_ROWS(dpfr1) ){ sprintf(DEFAULT_ERROR_STRING, "inner: dpto %s (%d) and first operand %s (%d) must have same # rows", OBJ_NAME(dpto),OBJ_ROWS(dpto),OBJ_NAME(dpfr1),OBJ_ROWS(dpfr1)); NWARN(DEFAULT_ERROR_STRING); return; } if( OBJ_COLS(dpto) != OBJ_COLS(dpfr2) ){ sprintf(DEFAULT_ERROR_STRING, "inner: target %s (%d) and second operand %s (%d) must have same # columns", OBJ_NAME(dpto),OBJ_COLS(dpto),OBJ_NAME(dpfr2),OBJ_COLS(dpfr2)); NWARN(DEFAULT_ERROR_STRING); return; } if( OBJ_COLS(dpfr1) != OBJ_ROWS(dpfr2) ){ sprintf(DEFAULT_ERROR_STRING, "inner: # cols of operand %s (%d) must match # rows of operand %s (%d)", OBJ_NAME(dpfr1),OBJ_COLS(dpfr1),OBJ_NAME(dpfr2),OBJ_ROWS(dpfr2)); NWARN(DEFAULT_ERROR_STRING); return; } //_n=OBJ_COLS(dpfr1); /* the length of each dot product we will compute */ if( IS_COMPLEX(dpto) ) SET_OA_ARGSTYPE(oap,COMPLEX_ARGS); else SET_OA_ARGSTYPE(oap,REAL_ARGS); /* vdot things it's inputs have the same shape, so if we are taking the inner * product of a column vector with a row vector, we have to transpose one of * the inputs... */ if( OBJ_ROWS(dpfr1) > 1 ) SET_OA_SRC1(oap,d_subscript(QSP_ARG dpfr1,0) ); /* subscript first row */ else SET_OA_SRC1(oap,dpfr1); /* object is a row */ if( OBJ_COLS(dpto) > 1 ) col_dp=c_subscript(QSP_ARG dpfr2,0); else col_dp=dpfr2; SET_OA_DEST(oap,mk_subimg(QSP_ARG dpto,0,0,"target pixel",1,1) ); //[sizes setDimensionAtIndex : 1 withValue : OBJ_ROWS(col_dp) ]; SET_DIMENSION(sizes,1,OBJ_ROWS(col_dp)); SET_DIMENSION(sizes,0,OBJ_COMPS(col_dp)); SET_OA_SRC2(oap,make_equivalence(QSP_ARG "_transposed_column", col_dp,sizes,OBJ_PREC_PTR(col_dp)) ); for(i=0;i<OBJ_ROWS(dpto);i++){ src1_indices[2]=i; SET_OBJ_DATA_PTR( OA_SRC1(oap), multiply_indexed_data(dpfr1,src1_indices) ); for(j=0;j<OBJ_COLS(dpto);j++){ dst_indices[2]=i; /* k_th component */ dst_indices[1]=j; /* k_th component */ SET_OBJ_DATA_PTR( OA_DEST(oap), multiply_indexed_data(dpto,dst_indices) ); src2_indices[1]=j; SET_OBJ_DATA_PTR( OA_SRC2(oap), multiply_indexed_data(dpfr2,src2_indices) ); vdot(QSP_ARG oap); } } delvec(QSP_ARG OA_SRC2(oap) ); /* "_transposed_column" */ if( OA_SRC1(oap) != dpfr1 ) delvec(QSP_ARG OA_SRC1(oap) ); if( col_dp != dpfr2 ) delvec(QSP_ARG col_dp); delvec(QSP_ARG OA_DEST(oap) ); }
int xform_chk(Data_Obj *dpto,Data_Obj *dpfr,Data_Obj *xform) { if( dpto==NO_OBJ || dpfr==NO_OBJ || xform==NO_OBJ ) return(-1); if( !IS_IMAGE(xform) ){ sprintf(DEFAULT_ERROR_STRING, "xform_chk: transformation %s must be a matrix (image)", OBJ_NAME(xform)); NWARN(DEFAULT_ERROR_STRING); return(-1); } if( OBJ_COMPS(xform) != 1 ){ sprintf(DEFAULT_ERROR_STRING, "xform_chk: transform matrix %s must have single-component elements",OBJ_NAME(xform)); NWARN(DEFAULT_ERROR_STRING); return(-1); } if( OBJ_COMPS(dpto) != OBJ_ROWS(xform) ){ sprintf(DEFAULT_ERROR_STRING, "xform_chk: target %s component dimension (%d) must match # rows of xform %s (%d)", OBJ_NAME(dpto),OBJ_COMPS(dpto),OBJ_NAME(xform),OBJ_ROWS(xform)); NWARN(DEFAULT_ERROR_STRING); return(-1); } if( OBJ_COMPS(dpfr) != OBJ_COLS(xform) ){ sprintf(DEFAULT_ERROR_STRING, "xform_chk: source %s component dimension (%d) must match # columns of xform %s (%d)", OBJ_NAME(dpto),OBJ_COMPS(dpto),OBJ_NAME(xform),OBJ_ROWS(xform)); NWARN(DEFAULT_ERROR_STRING); return(-1); } if( OBJ_N_TYPE_ELTS(dpto)/OBJ_COMPS(dpto) != OBJ_N_TYPE_ELTS(dpfr)/OBJ_COMPS(dpfr) ){ sprintf(DEFAULT_ERROR_STRING, "xform_chk: target %s (%d/%d) and source %s (%d/%d) must have same # of elements", OBJ_NAME(dpto),OBJ_N_TYPE_ELTS(dpto),OBJ_COMPS(dpto), OBJ_NAME(dpfr),OBJ_N_TYPE_ELTS(dpfr),OBJ_COMPS(dpfr)); NWARN(DEFAULT_ERROR_STRING); return(-1); } /* BUG these contiguity requirements may no longer be necessary... */ if( !is_contiguous(DEFAULT_QSP_ARG dpto) ){ sprintf(DEFAULT_ERROR_STRING, "xform_chk: xform target %s must be contiguous",OBJ_NAME(dpto)); NWARN(DEFAULT_ERROR_STRING); return(-1); } if( !is_contiguous(DEFAULT_QSP_ARG dpfr) ){ sprintf(DEFAULT_ERROR_STRING, "xform_chk: xform source %s must be contiguous",OBJ_NAME(dpfr)); NWARN(DEFAULT_ERROR_STRING); return(-1); } if( !is_contiguous(DEFAULT_QSP_ARG xform) ){ sprintf(DEFAULT_ERROR_STRING, "xform_chk: xform %s must be contiguous",OBJ_NAME(xform)); NWARN(DEFAULT_ERROR_STRING); return(-1); } return(0); } // end xform_chk
// This function allows us to do a different mapping of the image... static void map_cuda_viewer(QSP_ARG_DECL Cuda_Viewer *cvp, Data_Obj *img_dp, Data_Obj *coord_dp) { if( OBJ_PREC(coord_dp) != PREC_SP ){ sprintf(ERROR_STRING, "map_cuda_viewer: coord object %s must have %s precision!?", OBJ_NAME(coord_dp),PREC_NAME(OBJ_PREC_PTR(coord_dp))); WARN(ERROR_STRING); return; } if( ! IS_CONTIGUOUS(coord_dp) ){ sprintf(ERROR_STRING, "map_cuda_viewer: coord object %s must be contiguous!?", OBJ_NAME(coord_dp)); WARN(ERROR_STRING); return; } if( OBJ_COMPS(coord_dp) != 2 ){ sprintf(ERROR_STRING, "map_cuda_viewer: coord object %s must have 2 components!?", OBJ_NAME(coord_dp)); WARN(ERROR_STRING); return; } if( OBJ_COLS(coord_dp) != 2 ){ sprintf(ERROR_STRING, "map_cuda_viewer: coord object %s must have 2 columns!?", OBJ_NAME(coord_dp)); WARN(ERROR_STRING); return; } if( OBJ_ROWS(coord_dp) != 2 ){ sprintf(ERROR_STRING, "map_cuda_viewer: coord object %s must have 2 rows!?", OBJ_NAME(coord_dp)); WARN(ERROR_STRING); return; } #ifdef HAVE_OPENGL float *f; prepare_image_for_mapping(img_dp); f=(float *)OBJ_DATA_PTR(coord_dp); glBegin(GL_QUADS); fprintf(stderr,"first vertex at %f, %f (normally -1, -1)\n",f[0],f[1]); glTexCoord2f(0, 1); glVertex2f( f[0], f[1] ); // -1, -1 fprintf(stderr,"second vertex at %f, %f (normally -1, 1)\n",f[4],f[5]); glTexCoord2f(0, 0); glVertex2f( f[4], f[5] ); // -1, 1 fprintf(stderr,"third vertex at %f, %f (normally 1, 1)\n",f[6],f[7]); glTexCoord2f(1, 0); glVertex2f( f[6], f[7] ); // 1, 1 fprintf(stderr,"fourth vertex at %f, %f (normally 1, -1)\n",f[2],f[3]); glTexCoord2f(1, 1); glVertex2f( f[2], f[3] ); // 1, -1 glEnd(); glBindTexture(GL_TEXTURE_2D, 0); cuda_display_finish(QSP_ARG img_dp); #else // ! HAVE_OPENGL NO_OGL_MSG #endif // ! HAVE_OPENGL }
/* Handles one turn of book reading. Returns 1 if unfinished, 0 if finshed. */ static int learn(void) { int i; short booktype; boolean costly = TRUE; boolean already_known = FALSE; int first_unknown = MAXSPELL; int known_spells = 0; const char *splname; /* JDS: lenses give 50% faster reading; 33% smaller read time */ if (u.uoccupation_progress[tos_book] && ublindf && ublindf->otyp == LENSES && rn2(2)) u.uoccupation_progress[tos_book]++; if (Confusion) { /* became confused while learning */ confused_book(u.utracked[tos_book]); u.utracked[tos_book] = 0; /* no longer studying */ helpless(-u.uoccupation_progress[tos_book], hr_busy, "absorbed in a spellbook", "You're finally able to put the book down."); u.uoccupation_progress[tos_book] = 0; return 0; } booktype = u.utracked[tos_book]->otyp; if (booktype == SPE_BOOK_OF_THE_DEAD) { deadbook(u.utracked[tos_book], FALSE); u.utracked[tos_book] = 0; u.uoccupation_progress[tos_book] = 0; return 0; } /* The book might get cursed while we're reading it. In this case, immediately stop reading it, cancel progress, and apply a few turns of helplessness. (3.4.3 applies negative spellbook effects but lets you memorize the spell anyway; this makes no sense. It destroys the spellbook on the "contact poison" result, which makes even less sense.) */ if (u.utracked[tos_book]->cursed) { pline("This book isn't making sense any more."); helpless(rn1(5,5), hr_busy, "making sense of a spellbook", "You give up trying to make sense of the spellbook."); u.uoccupation_progress[tos_book] = 0; u.utracked[tos_book] = 0; return 0; } if (++u.uoccupation_progress[tos_book] < 0) return 1; /* still busy */ if (ACURR(A_WIS) < 12) exercise(A_WIS, TRUE); /* you're studying. */ splname = msgprintf(objects[booktype].oc_name_known ? "\"%s\"" : "the \"%s\" spell", OBJ_NAME(objects[booktype])); for (i = 0; i < MAXSPELL; i++) { if (spellid(i) == booktype) { already_known = TRUE; if (u.utracked[tos_book]->spestudied > MAX_SPELL_STUDY) { pline("This spellbook is too faint to be read any more."); u.utracked[tos_book]->otyp = booktype = SPE_BLANK_PAPER; } else if (spellknow(i) <= 1000) { pline("Your knowledge of %s is keener.", splname); incrnknow(i); u.utracked[tos_book]->spestudied++; if (ACURR(A_WIS) < 12) exercise(A_WIS, TRUE); /* extra study */ } else { /* 1000 < spellknow(i) <= MAX_SPELL_STUDY */ pline("You know %s quite well already.", splname); if (yn("Do you want to read the book anyway?") == 'y') { pline("You refresh your knowledge of %s.", splname); incrnknow(i); u.utracked[tos_book]->spestudied++; } else costly = FALSE; } /* make book become known even when spell is already known, in case amnesia made you forget the book */ makeknown((int)booktype); break; } else if (spellid(i) == NO_SPELL && (i < first_unknown || i == spellno_from_let(objects[booktype].oc_defletter))) first_unknown = i; else known_spells++; } if (first_unknown == MAXSPELL && !already_known) panic("Too many spells memorized!"); if (!already_known) { spl_book[first_unknown].sp_id = booktype; spl_book[first_unknown].sp_lev = objects[booktype].oc_level; incrnknow(first_unknown); u.utracked[tos_book]->spestudied++; pline(known_spells > 0 ? "You add %s to your repertoire." : "You learn %s.", splname); makeknown((int)booktype); } if (costly) check_unpaid(u.utracked[tos_book]); u.utracked[tos_book] = 0; return 0; }
int dowrite(struct obj *pen, const struct nh_cmd_arg *arg) { struct obj *paper; const char *namebuf, *nm, *bp; struct obj *new_obj; int basecost, actualcost; int curseval; const char *qbuf; int first, last, i; boolean by_descr = FALSE, by_name = FALSE; const char *typeword; if (nohands(youmonst.data)) { pline(msgc_cancelled, "You need hands to be able to write!"); return 0; } else if (slippery_fingers(&youmonst)) { pline(msgc_cancelled1, "%s from your %s.", Tobjnam(pen, "slip"), makeplural(body_part(FINGER))); unwield_silently(pen); dropx(pen); return 1; } /* get paper to write on */ paper = getargobj(arg, write_on, "write on"); if (!paper) return 0; typeword = (paper->oclass == SPBOOK_CLASS) ? "spellbook" : "scroll"; if (Blind && !paper->dknown) { pline(msgc_cancelled1, "You don't know if that %s is blank or not!", typeword); return 1; } paper->dknown = 1; if (paper->otyp != SCR_BLANK_PAPER && paper->otyp != SPE_BLANK_PAPER) { pline(msgc_cancelled1, "That %s is not blank!", typeword); exercise(A_WIS, FALSE); return 1; } /* what to write */ qbuf = msgprintf("What type of %s do you want to write?", typeword); namebuf = getarglin(arg, qbuf); namebuf = msgmungspaces(namebuf); /* remove any excess whitespace */ if (namebuf[0] == '\033' || !namebuf[0]) return 1; nm = namebuf; if (!strncmpi(nm, "scroll ", 7)) nm += 7; else if (!strncmpi(nm, "spellbook ", 10)) nm += 10; if (!strncmpi(nm, "of ", 3)) nm += 3; if ((bp = strstri(nm, " armour")) != 0) nm = msgcat_many(msgchop(nm, bp-nm), " armor", bp+7, NULL); first = bases[(int)paper->oclass]; last = bases[(int)paper->oclass + 1] - 1; for (i = first; i <= last; i++) { /* extra shufflable descr not representing a real object */ if (!OBJ_NAME(objects[i])) continue; if (!strcmpi(OBJ_NAME(objects[i]), nm)) goto found; if (!strcmpi(OBJ_DESCR(objects[i]), nm)) { by_descr = TRUE; goto found; } if (objects[i].oc_uname && !strcmpi(objects[i].oc_uname, nm)) { by_name = TRUE; goto found; } } pline(msgc_cancelled1, "There is no such %s!", typeword); return 1; found: if (i == SCR_BLANK_PAPER || i == SPE_BLANK_PAPER) { pline(msgc_cancelled1, "You can't write that!"); pline(msgc_cancelled1, "It's obscene!"); return 1; } else if (i == SPE_BOOK_OF_THE_DEAD) { pline(msgc_cancelled1, "No mere dungeon adventurer could write that."); return 1; } else if ((by_descr || by_name) && paper->oclass == SPBOOK_CLASS && !objects[i].oc_name_known) { /* can't write unknown spellbooks by description */ pline(msgc_cancelled1, "Unfortunately you don't have enough information to go on."); return 1; } /* KMH, conduct */ break_conduct(conduct_illiterate); new_obj = mksobj(level, i, FALSE, FALSE, rng_main); new_obj->bknown = (paper->bknown && pen->bknown); /* shk imposes a flat rate per use, not based on actual charges used */ check_unpaid(pen); /* see if there's enough ink */ basecost = cost(new_obj); if (pen->spe < basecost / 2) { pline(msgc_failcurse, "Your marker is too dry to write that!"); obfree(new_obj, NULL); return 1; } /* we're really going to write now, so calculate cost no custom RNG used: too much influence from player actions */ actualcost = rn1(basecost / 2, basecost / 2); curseval = bcsign(pen) + bcsign(paper); exercise(A_WIS, TRUE); /* dry out marker */ if (pen->spe < actualcost) { pen->spe = 0; pline(msgc_itemloss, "Your marker dries out!"); /* scrolls disappear, spellbooks don't */ if (paper->oclass == SPBOOK_CLASS) { pline(msgc_failcurse, "The spellbook is left unfinished and your writing fades."); update_inventory(); /* pen charges */ } else { pline(msgc_failcurse, "The scroll is now useless and disappears!"); useup(paper); } obfree(new_obj, NULL); return 1; } pen->spe -= actualcost; /* can't write if we don't know it - unless we're lucky */ if (!(objects[new_obj->otyp].oc_name_known) && (rnl(Role_if(PM_WIZARD) ? 3 : 15))) { pline(msgc_failrandom, "You %s to write that!", by_descr ? "fail" : "don't know how"); /* scrolls disappear, spellbooks don't */ if (paper->oclass == SPBOOK_CLASS) { pline_implied(msgc_failrandom, "You write in your best handwriting: " "\"My Diary\", but it quickly fades."); update_inventory(); /* pen charges */ } else { const char *written; if (by_descr) { written = OBJ_DESCR(objects[new_obj->otyp]); written = eroded_text(written, (6 + MAXULEV - youmonst.m_lev) / 6, 0); } else written = msgprintf("%s was here!", u.uplname); pline_implied(msgc_failrandom, "You write \"%s\" and the scroll disappears.", written); useup(paper); } obfree(new_obj, NULL); return 1; } /* useup old scroll / spellbook */ useup(paper); /* success */ if (new_obj->oclass == SPBOOK_CLASS) { /* acknowledge the change in the object's description... */ pline(msgc_actionok, "The spellbook warps strangely, then turns %s.", OBJ_DESCR(objects[new_obj->otyp])); } new_obj->blessed = (curseval > 0); new_obj->cursed = (curseval < 0); hold_another_object(new_obj, "Oops! %s out of your grasp!", The(aobjnam(new_obj, "slip")), NULL); return 1; }
static Data_Obj *insure_ram_obj(QSP_ARG_DECL Data_Obj *dp) { Data_Obj *tmp_dp; char *tname; Data_Area *save_ap; Data_Obj *c_dp=NULL; if( OBJ_IS_RAM(dp) ) return dp; // This object lives on a different platform. // We create a copy in RAM, and download the data // using the platform download function. save_ap = curr_ap; curr_ap = ram_area_p; tname = getbuf( strlen(OBJ_NAME(dp)) + strlen(DNAME_PREFIX) + 1 ); sprintf(tname,"%s%s",DNAME_PREFIX,OBJ_NAME(dp)); tmp_dp = dup_obj(QSP_ARG dp, tname); givbuf(tname); if( tmp_dp == NO_OBJ ){ // This can happen if the object is subscripted, // as the bracket characters are illegal in names return NO_OBJ; } curr_ap = save_ap; // We can't download if the source data is not contiguous... // // We have a problem with bit precision, because the bits can // be non-contiguous when the long words are - any time the number of columns // is not evenly divided by the bits-per-word if( (! IS_CONTIGUOUS(dp)) && ! HAS_CONTIGUOUS_DATA(dp) ){ Vec_Obj_Args oa1, *oap=&oa1; advise("object is not contiguous, and does not have contiguous data..."); longlist(QSP_ARG dp); save_ap = curr_ap; curr_ap = OBJ_AREA( dp ); tname = getbuf( strlen(OBJ_NAME(dp)) + strlen(CNAME_PREFIX) + 1 ); sprintf(tname,"%s%s",CNAME_PREFIX,OBJ_NAME(dp)); c_dp = dup_obj(QSP_ARG dp, tname ); givbuf(tname); curr_ap = save_ap; // Now do the move... setvarg2(oap,c_dp,dp); if( IS_BITMAP(dp) ){ SET_OA_SBM(oap,dp); SET_OA_SRC1(oap,NO_OBJ); } if( IS_REAL(dp) ) /* BUG case for QUAT too? */ OA_ARGSTYPE(oap) = REAL_ARGS; else if( IS_COMPLEX(dp) ) /* BUG case for QUAT too? */ OA_ARGSTYPE(oap) = COMPLEX_ARGS; else if( IS_QUAT(dp) ) /* BUG case for QUAT too? */ OA_ARGSTYPE(oap) = QUATERNION_ARGS; else //ERROR1("CAUTIOUS: insure_ram_obj: bad argset type!?"); assert( AERROR("insure_ram_obj: bad argset type!?") ); //fprintf(stderr,"insure_ram_obj: moving remote data to a contiguous object\n"); call_vfunc( QSP_ARG FIND_VEC_FUNC(FVMOV), oap ); //fprintf(stderr,"insure_ram_obj: DONE moving remote data to a contiguous object\n"); dp = c_dp; } gen_obj_dnload(QSP_ARG tmp_dp, dp); if( c_dp != NO_OBJ ) delvec(QSP_ARG c_dp); // BUG - when to delete? // We try using the VOLATILE flag. This will work as long as // the input object is not VOLATILE!? SET_OBJ_FLAG_BITS(tmp_dp, DT_VOLATILE ) ; return tmp_dp; }
void multivariate_histo(QSP_ARG_DECL Data_Obj *histo_dp,Data_Obj *data_dp,float *width_array,float *min_array) { dimension_t n_dimensions; dimension_t i,j,k; unsigned int l; float *fbase, *fptr, *f; float *histbuf; incr_t index[MAX_DIMENSIONS]; int n_bins[MAX_DIMENSIONS]; int n_under[MAX_DIMENSIONS], n_over[MAX_DIMENSIONS]; INSIST_RAM_OBJ(histo_dp,compute_histo); INSIST_RAM_OBJ(data_dp,compute_histo); if( OBJ_PREC(histo_dp) != PREC_SP ){ NWARN("2D histogram precision must be float"); return; } if( OBJ_COMPS(histo_dp) != 1 ){ NWARN("2D histogram data must be real"); return; } if( OBJ_PXL_INC(histo_dp) != 1 ){ NWARN("2D histogram data must be contiguous"); return; } n_dimensions = OBJ_COMPS(data_dp); if( n_dimensions > MAX_DIMENSIONS ){ NWARN("Too many 2D histogram dimensions"); return; } if( OBJ_PREC(data_dp) != PREC_SP ){ NWARN("2D data precision must be float"); return; } fbase = (float *) OBJ_DATA_PTR(data_dp); for(l=0;l<n_dimensions;l++){ n_over[l]=0; n_under[l]=0; n_bins[l] = OBJ_TYPE_DIM(histo_dp,l+1); } histbuf = (float *) OBJ_DATA_PTR(histo_dp); zero_dimension(histo_dp,(float *)OBJ_DATA_PTR(histo_dp),n_dimensions,0L); for(l=0;l<MAX_DIMENSIONS;l++) index[l]=0; for(i=0;i<OBJ_FRAMES(data_dp);i++){ fptr = fbase; for(j=0;j<OBJ_ROWS(data_dp);j++){ f=fptr; for(k=0;k<OBJ_COLS(data_dp);k++){ float num[MAX_DIMENSIONS]; for(l=0;l<n_dimensions;l++){ num[l] = f[l]; /* assume cinc=1 */ num[l] -= min_array[l]; num[l] /= width_array[l]; num[l] += 0.5; index[l] = (incr_t)num[l]; /* cast to int */ if( index[l] < 0 ){ index[l]=0; n_under[l]++; } else if( index[l] >= n_bins[l] ){ index[l] = n_bins[l]-1; n_over[l]++; } } histbuf[ index[0] + index[1] * OBJ_ROW_INC(histo_dp) + index[2] * OBJ_FRM_INC(histo_dp) ] += 1.0; f += OBJ_PXL_INC(data_dp); } fptr += OBJ_ROW_INC(data_dp); } fbase += OBJ_FRM_INC(data_dp); } for(l=0;l<n_dimensions;l++){ if( (n_under[l] > 0) || (n_over[l] > 0) ){ sprintf(ERROR_STRING, "Histogram for %s had %d underflows and %d overflows in dimension %d", OBJ_NAME(data_dp),n_under[l],n_over[l],l); advise(ERROR_STRING); } } }
static void test_parport(void) { int n,s; Data_Obj *dp; u_long *lp; FB_Info *fbip; pthread_attr_t attr1; VBoard_Info vbi1; PPort_Info ppti1; u_long l; pthread_attr_init(&attr1); /* initialize to default values */ pthread_attr_setinheritsched(&attr1,PTHREAD_INHERIT_SCHED); fbip = pick_fbi("frame buffer for VSYNC"); dp = pick_obj("data vector for latencies"); if( fbip == NULL || dp == NULL ) return; INSIST_RAM_OBJ(dp,"test_parport") if( OBJ_PREC(dp) != PREC_UDI ){ sprintf(ERROR_STRING,"latency vector %s (%s) should have precision %s", OBJ_NAME(dp),PREC_NAME(OBJ_PREC_PTR(dp)), NAME_FOR_PREC_CODE(PREC_UDI)); WARN(ERROR_STRING); return; } if( OBJ_COMPS(dp) != 2 ){ sprintf(ERROR_STRING,"latency vector %s (%d) should have 2 components", OBJ_NAME(dp),OBJ_COMPS(dp)); WARN(ERROR_STRING); return; } if( ! IS_CONTIGUOUS(dp) ){ sprintf(ERROR_STRING,"latency vector %s should be contiguous",OBJ_NAME(dp)); WARN(ERROR_STRING); return; } n = OBJ_N_MACH_ELTS(dp)/2; lp = (u_long *) OBJ_DATA_PTR(dp); vbi1.vbi_fbip = fbip; vbi1.vbi_buf = lp; vbi1.vbi_count = n; vbi1.vbi_inc = 2; #ifdef THREAD_SAFE_QUERY vbi1.vbi_qsp = THIS_QSP; #endif // THREAD_SAFE_QUERY lp ++; if( the_ppp == NULL ){ the_ppp=open_parport(NULL); /* use default */ if( the_ppp == NULL ) return; } ppti1.ppti_ppp = the_ppp; ppti1.ppti_buf = lp; ppti1.ppti_count = n; ppti1.ppti_inc = 2; tvp = NULL; /* force re-zero */ s=read_til_transition(the_ppp,8); if( s==0 ) s=read_til_transition(the_ppp,8); /* should now be in the one state */ /* this is the end of the (negative) pulse */ l = delta_usecs(); /* zero the clock */ pthread_create(&vboard_thr,&attr1,vboard_daemon,&vbi1); pthread_create(&pport_thr,&attr1,pport_logger,&ppti1); /* should wait for threads here... */ if( pthread_join(vboard_thr,NULL) != 0 ){ perror("pthread_join"); WARN("error joining video board thread"); } if( pthread_join(pport_thr,NULL) != 0 ){ perror("pthread_join"); WARN("error joining parallel port thread"); } }
static COMMAND_FUNC( do_cyplot ) { Data_Obj *dp; Data_Obj *cdp; u_long i, np; /* number of points */ long inc; long cinc; std_type x,y,dx,*yp; char *cp; dp=PICK_OBJ("data vector"); cdp=PICK_OBJ("color vector"); if( dp==NO_OBJ ) return; if( cdp==NO_OBJ ) return; INSIST_RAM_OBJ(dp,"cyplot") INSIST_RAM_OBJ(cdp,"cyplot") if( OBJ_PREC(dp) != PREC_SP ) { WARN("do_cyplot: data vector should be float"); return; } if( OBJ_PREC(cdp) != PREC_BY ) { WARN("color vector should be byte"); return; } if( !dp_same_size(QSP_ARG dp,cdp,"do_cyplot") ) { sprintf(ERROR_STRING,"data vector %s and color vector %s must have identical sizes", OBJ_NAME(dp),OBJ_NAME(cdp)); WARN(ERROR_STRING); return; } if( OBJ_COLS(dp)==1 ) { /* maybe this is a column vector? */ np=OBJ_ROWS(dp); inc = OBJ_ROW_INC(dp); cinc = OBJ_ROW_INC(cdp); } else { np=OBJ_COLS(dp); inc = OBJ_PXL_INC(dp); cinc = OBJ_PXL_INC(cdp); } x=0; dx=1; i=np-1; yp = (std_type *) OBJ_DATA_PTR(dp); cp = (char *) OBJ_DATA_PTR(cdp); xp_fmove(x,*yp); xp_select(*cp); xp_fcont(x,*yp); while(i--) { yp += inc; cp += cinc; x += dx; y = *yp; xp_select(*cp); xp_fcont(x,y); } }