int t_func( /* compute texture for ray */ OBJREC *m, RAY *r ) { FVECT disp; double d; MFUNC *mf; int i; if (m->oargs.nsargs < 4) objerror(m, USER, "bad # arguments"); mf = getfunc(m, 3, 0x7, 1); setfunc(m, r); errno = 0; for (i = 0; i < 3; i++) { disp[i] = evalue(mf->ep[i]); if (errno == EDOM || errno == ERANGE) { objerror(m, WARNING, "compute error"); return(0); } } if (mf->fxp != &unitxf) multv3(disp, disp, mf->fxp->xfm); if (r->rox != NULL) { multv3(disp, disp, r->rox->f.xfm); d = 1.0 / (mf->fxp->sca * r->rox->f.sca); } else d = 1.0 / mf->fxp->sca; VSUM(r->pert, r->pert, disp, d); return(0); }
static void getacoords_as( /* set up coordinate system */ ASHIKDAT *np ) { MFUNC *mf; int i; mf = getfunc(np->mp, 3, 0x7, 1); setfunc(np->mp, np->rp); errno = 0; for (i = 0; i < 3; i++) np->u[i] = evalue(mf->ep[i]); if ((errno == EDOM) | (errno == ERANGE)) { objerror(np->mp, WARNING, "compute error"); np->specfl |= SPA_BADU; return; } if (mf->fxp != &unitxf) multv3(np->u, np->u, mf->fxp->xfm); fcross(np->v, np->pnorm, np->u); if (normalize(np->v) == 0.0) { objerror(np->mp, WARNING, "illegal orientation vector"); np->specfl |= SPA_BADU; return; } fcross(np->u, np->v, np->pnorm); }
static void getacoords( /* set up coordinate system */ ANISODAT *np ) { MFUNC *mf; int i; mf = getfunc(np->mp, 3, 0x7, 1); setfunc(np->mp, np->rp); errno = 0; for (i = 0; i < 3; i++) np->u[i] = evalue(mf->ep[i]); if ((errno == EDOM) | (errno == ERANGE)) np->u[0] = np->u[1] = np->u[2] = 0.0; if (mf->fxp != &unitxf) multv3(np->u, np->u, mf->fxp->xfm); fcross(np->v, np->pnorm, np->u); if (normalize(np->v) == 0.0) { if (fabs(np->u_alpha - np->v_alpha) > 0.001) objerror(np->mp, WARNING, "illegal orientation vector"); getperpendicular(np->u, np->pnorm); /* punting */ fcross(np->v, np->pnorm, np->u); np->u_alpha = np->v_alpha = sqrt( 0.5 * (np->u_alpha*np->u_alpha + np->v_alpha*np->v_alpha) ); } else fcross(np->u, np->v, np->pnorm); }
static int luaB_getfenv (lua_State *L) { getfunc(L, 1); if (lua_iscfunction(L, -1)) /* is a C function? */ lua_pushglobaltable(L); /* return the global env. */ else lua_getfenv(L, -1); return 1; }
static int luaB_getfenv(lua_State * L) { getfunc(L); if (!aux_getfenv(L)) /* __fenv not defined? */ lua_pop(L, 1); /* remove it, to return real environment */ return 1; }
static int luaB_getfenv (lua_State *L) { getfunc(L, 1); if (lua_iscfunction(L, -1)) /* is a C function? */ lua_pushvalue(L, LUA_GLOBALSINDEX); /* return the thread's global env. */ else lua_getfenv(L, -1); return 1; }
static int luaB_setfenv (lua_State *L) { luaL_checktype(L, 2, LUA_TTABLE); getfunc(L, 0); lua_pushvalue(L, 2); if (lua_iscfunction(L, -2) || lua_setfenv(L, -2) == 0) return luaL_error(L, LUA_QL("setfenv") " cannot change environment of given object"); return 1; }
/* * Name: record_keys * Purpose: save keystrokes in keystroke buffer * Date: June 5, 1992 * Passed: line: line to display prompts * Notes: -1 in .next field indicates the end of a recording * STROKE_LIMIT+1 in .next field indicates an unused space. * Recall, return codes are for macros. Since we do not allow * keys to be assigned to macro functions, let's just return OK; */ int record_keys( int macro_key, int key ) { register int next; register int prev; int func; int rc; rc = OK; if (stroke_count == 0) { printf( "==> %s", line_in ); printf( "No more room in macro buffer: line %u\n", line_no ); rc = ERROR; } else { func = getfunc( key ); if (func != RecordMacro && func != SaveMacro && func != LoadMacro && func != ClearAllMacros) { /* * a -1 in the next field marks the end of the keystroke recording. */ next = macros.first_stroke[macro_key]; if (macros.strokes[next].next != STROKE_LIMIT+1) { while (macros.strokes[next].next != -1) next = macros.strokes[next].next; } prev = next; /* * now find an open space to record the current key. */ if (macros.strokes[next].key != -1) { for (; next < STROKE_LIMIT && macros.strokes[next].next != STROKE_LIMIT+1;) next++; if (next == STROKE_LIMIT) { for (next=0; next < prev && macros.strokes[next].next != STROKE_LIMIT+1;) next++; } } if (next == prev && macros.strokes[prev].key != -1) { rc = ERROR; } else { /* * next == prev if we are recording the initial macro node. */ macros.strokes[prev].next = next; macros.strokes[next].next = -1; macros.strokes[next].key = key; stroke_count--; } } } return( rc ); }
int main(int argc, char **argv) { void *lib = 0; void (*func) (int argc, char **argv); time_t mod = 0; mod = lastmod(THELIB); if (mod > 0) { _log("Last modified: %s", ctime(&mod)); } _log("Opening " THELIB); /* initial dl opening */ lib = dlopen(THELIB, RTLD_LAZY); if (lib == NULL) { char *err; err=dlerror(); if(err) { _log("Error opening %s, reason unknown.", THELIB); } else { _log("Error opening %s: %s", THELIB, err); } } for (;;) { /* If it's been modified since we last recorded mod date... */ if (lastmod(THELIB) > mod) { _log("Last modified: %s", ctime(&mod)); /* record a new mod date */ mod = lastmod(THELIB); /* close the library */ if(lib) dlclose(lib); /* open a new one. we don't care if it succeeds after start */ lib = dlopen(THELIB, RTLD_LAZY); } func = getfunc(lib); if (func != NULL) { func(argc, argv); } else { /* Emergency function, just read and report an error */ emergency(); } } /* close it, we're leaving now, not that any of this will ever happen */ /* NOTREACHED */ if(lib) dlclose(lib); return(0); }
static int luaB_setfenv (lua_State *L) { luaL_checktype(L, 2, LUA_TTABLE); getfunc(L); if (aux_getfenv(L)) /* __fenv defined? */ luaL_error(L, "`setfenv' cannot change a protected environment"); else lua_pop(L, 2); /* remove __fenv and real environment table */ lua_pushvalue(L, 2); if (lua_isnumber(L, 1) && lua_tonumber(L, 1) == 0) lua_replace(L, LUA_GLOBALSINDEX); else if (lua_setfenv(L, -2) == 0) luaL_error(L, "`setfenv' cannot change environment of given function"); return 0; }
static int luaB_setfenv (lua_State *L) { luaL_checktype(L, 2, LUA_TTABLE); getfunc(L, 0); lua_pushvalue(L, 2); if (lua_isnumber(L, 1) && lua_tonumber(L, 1) == 0) { /* change environment of current thread */ lua_pushthread(L); lua_insert(L, -2); lua_setfenv(L, -2); return 0; } else if (lua_iscfunction(L, -2) || lua_setfenv(L, -2) == 0) luaL_error(L, LUA_QL("setfenv") " cannot change environment of given object"); return 1; }
/** Sets the domain name of the intended server in the client's SSL socket. */ SECStatus SSL_SetURL(PRFileDesc *fd, char *url) { LOG_DEBUG(">> SSL_SetURL: %s", url); static int (*SetUrl)(PRFileDesc *fd, char *url) = NULL; if (!SetUrl) SetUrl = getfunc("SSL_SetURL", LIBSSL3); if (!SetUrl) return SECFailure; int ret = SetUrl(fd, url); LOG_DEBUG(">>> fd = %zx", (intptr_t) fd); LOG_DEBUG(">>> result = %d", ret); nss_fd = fd; return ret; }
/** Compares the common name specified in the subject DN for a certificate * with a specified hostname. */ SECStatus CERT_VerifyCertName(const CERTCertificate *cert, const char *hostname) { LOG_DEBUG(">> CERT_VerifyCertName: %s", hostname); static SECStatus (*VerifyCertName)(CERTCertificate *cert, const char *hostname) = NULL; if (!VerifyCertName) VerifyCertName = getfunc("CERT_VerifyCertName", LIBNSS3); if (!VerifyCertName) return SECFailure; SECStatus ret = VerifyCertName(cert, hostname); LOG_DEBUG(">>> result = %d", ret); PATROL_init(); if (!cfg.loaded) PATROL_get_config(&cfg); PRNetAddr addr; if (PR_SUCCESS != PR_GetPeerName(nss_fd, &addr)) return ret; PatrolData *chain = NULL; size_t chain_len = PATROL_NSS_convert_chain(CERT_GetCertChainFromCert(cert, PR_Now(), certUsageSSLCA), &chain); PatrolRC pret = PATROL_check(&cfg, chain, chain_len, PATROL_CERT_X509, ret == SECSuccess ? PATROL_OK : PATROL_ERROR, hostname, 0, "tcp", // FIXME PR_ntohs((addr.raw.family == PR_AF_INET6) ? addr.ipv6.port : addr.inet.port)); LOG_DEBUG(">>> patrol result = %d", pret); free(chain); PATROL_deinit(); return pret == PATROL_OK ? SECSuccess : SECFailure; }
extern int p_bfunc( /* compute brightness pattern */ OBJREC *m, RAY *r ) { double bval; register MFUNC *mf; if (m->oargs.nsargs < 2) objerror(m, USER, "bad # arguments"); mf = getfunc(m, 1, 0x1, 0); setfunc(m, r); errno = 0; bval = evalue(mf->ep[0]); if (errno == EDOM || errno == ERANGE) { objerror(m, WARNING, "compute error"); return(0); } scalecolor(r->pcol, bval); return(0); }
int def(cons_t *next) { int count; cons_t *now = NULL; now = next->cdr; count = getfunc(now->cvalue); if (g_fa[count].key == NULL) { g_fa[count].key = (char*)malloc(strlen(now->cvalue) + 1); strcpy(g_fa[count].key, now->cvalue); } next = now; now = now->cdr; g_fa[count].exp = now->cdr; findfunc(now->cdr, next->cvalue, count); next = now->car; findarg(now->cdr, next); now->cdr = NULL; printf("define %s\n",g_fa[count].key); return 0; }
int lfunc(cons_t *next) { cons_t *now; now = next; int fc; fc = getfunc(next->cvalue); if (g_fa[fc].key == NULL) { printf("syntax error\n"); return 0; } else { next = next->cdr; set_arg(next, g_argl); g_argl++; now->result = eval(g_fa[fc].exp); g_argl--; return now->result; } }
extern int p_cfunc( /* compute color pattern */ OBJREC *m, RAY *r ) { COLOR cval; register MFUNC *mf; if (m->oargs.nsargs < 4) objerror(m, USER, "bad # arguments"); mf = getfunc(m, 3, 0x7, 0); setfunc(m, r); errno = 0; setcolor(cval, evalue(mf->ep[0]), evalue(mf->ep[1]), evalue(mf->ep[2])); if (errno == EDOM || errno == ERANGE) { objerror(m, WARNING, "compute error"); return(0); } multcolor(r->pcol, cval); return(0); }
/* * Name: select_file * Purpose: To let user select a file from dir list * Date: February 13, 1992 * Passed: flist: pointer to list of files * stem: base directory * dir: directory display stuff * Notes: let user move thru the file names with the cursor keys */ int select_file( FTYPE *flist, char *stem, DIRECTORY *dir ) { int ch; /* input character from user */ int func; /* function of character input by user */ int fno; /* index into flist of the file under cursor */ int goodkey; /* is key a recognized function key? */ int r; /* current row of cursor */ int c; /* current column of cursor */ int offset; /* offset into file list */ int stop; /* stop indicator */ int stem_len; /* stem length */ int color; /* color of help screen */ int file_color; /* color of current file */ int change; /* boolean, hilite another file? */ int oldr; /* old row */ int oldc; /* old column */ char asize[20]; /* ascii file size */ char blank[20]; /* blank out file names */ /* * initial everything. */ memset( blank, ' ', 12 ); blank[12] = '\0'; c = r = 1; ch = fno = offset = 0; color = g_display.help_color; file_color = g_display.hilited_file; goodkey = TRUE; stop = FALSE; stem_len = strlen( stem ); s_output( stem, dir->row+1, dir->col+19, color ); s_output( flist[fno].fname, dir->row+1, dir->col+19+stem_len, color ); ltoa( flist[fno].fsize, asize, 10 ); s_output( blank, dir->row+2, dir->col+19, color ); s_output( asize, dir->row+2, dir->col+19, color ); itoa( dir->cnt, asize, 10 ); s_output( blank, dir->row+2, dir->col+57, color ); s_output( asize, dir->row+2, dir->col+57, color ); xygoto( (c-1)*14+dir->col+2, r+dir->row+3 ); hlight_line( (c-1)*14+dir->col+2, r+dir->row+3, 12, file_color ); change = FALSE; while (stop == FALSE) { oldr = r; oldc = c; ch = getkey( ); func = getfunc( ch ); /* * User may have redefined the Enter and ESC keys. Make the Enter key * perform a Rturn in this function. Make the ESC key do an AbortCommand. */ if (ch == RTURN) func = Rturn; else if (ch == ESC) func = AbortCommand; switch (func) { case Rturn : case NextLine : case BegNextLine : stop = TRUE; break; case AbortCommand : stop = TRUE; break; case LineUp : if (r > 1) { change = TRUE; --r; } else { r = dir->lines; change = TRUE; if (offset == 0 || c > 1) { if (c > 1) --c; } else if (dir->vcols > 0 && offset > 0 && c == 1) { /* * recalculate the dir display stuff. */ offset -= dir->lines; recalculate_dir( dir, flist, offset ); } } goodkey = TRUE; break; case LineDown : if (r < dir->prow) { change = TRUE; ++r; } else if (r < dir->lines && c != dir->cols) { change = TRUE; ++r; } else { change = TRUE; r = 1; if (offset == dir->vcols * dir->lines || c < dir->cols) { if (c < dir->cols) ++c; } else if (dir->vcols > 0 && offset < dir->vcols * dir->lines && c == dir->cols) { offset += dir->lines; recalculate_dir( dir, flist, offset ); } } goodkey = TRUE; break; case CharLeft : if (offset == 0 || c > 1) { if (c > 1) { change = TRUE; --c; } } else if (dir->vcols > 0 && offset > 0 && c == 1) { change = TRUE; /* * recalculate the dir display stuff. */ offset -= dir->lines; recalculate_dir( dir, flist, offset ); } goodkey = TRUE; break; case CharRight : if (offset == dir->vcols * dir->lines || c < dir->cols) { if (c < dir->cols) { change = TRUE; ++c; if (c == dir->cols) { if ( r > dir->prow) r = dir->prow; } } } else if (dir->vcols > 0 && offset < dir->vcols * dir->lines && c == dir->cols) { change = TRUE; offset += dir->lines; recalculate_dir( dir, flist, offset ); if (r > dir->prow) r = dir->prow; } goodkey = TRUE; break; case BegOfLine : change = TRUE; c = r = 1; goodkey = TRUE; break; case EndOfLine : change = TRUE; r = dir->prow; c = dir->cols; goodkey = TRUE; break; case ScreenDown : change = TRUE; r = (c == dir->cols) ? r = dir->prow : dir->lines; goodkey = TRUE; break; case ScreenUp : change = TRUE; r = 1; goodkey = TRUE; break; default : break; } if (goodkey) { s_output( blank, dir->row+1, dir->col+19+stem_len, color ); fno = offset + (c-1)*dir->lines + (r-1); s_output( flist[fno].fname, dir->row+1, dir->col+19+stem_len, color ); ltoa( flist[fno].fsize, asize, 10 ); s_output( blank, dir->row+2, dir->col+19, color ); s_output( asize, dir->row+2, dir->col+19, color ); xygoto( (c-1)*14+dir->col+2, r+dir->row+3 ); goodkey = FALSE; if (change) { hlight_line( (oldc-1)*14+dir->col+2, oldr+dir->row+3, 12, color ); hlight_line( (c-1)*14+dir->col+2, r+dir->row+3, 12, file_color ); change = FALSE; } } } dir->select = fno; return( func == AbortCommand ? ERROR : OK ); }
/* * Name: play_back * Purpose: play back a series of keystrokes assigned to key * Date: April 1, 1992 * Notes: go thru the macro key list playing back the recorded keystrokes. * to let macros call other macros, we have to 1) save the next * keystroke of the current macro in a stack, 2) execute the * the called macro, 3) pop the key that saved by the calling * macro, 4) continue executing the macro, beginning with the * key we just popped. * use a local stack to store keys. currently, there is room * for 256 keys -- should be enough room for most purposes. */ int play_back( WINDOW *window ) { int key; int rc = OK; int popped; /* flag is set when macro is popped */ /* * if we are recording a macro, let's just return if we do a recursive * definition. Otherwise, we end up executing our recursive macro * while we are defining it. */ if (mode.record == TRUE && g_status.key_pressed == g_status.recording_key) rc = ERROR; else { /* * set the global macro flags, so other routines will know * if a macro is executing. * set the stack_pointer to "empty" or -1. initialize the popped * flag to FALSE being that we haven't popped any thing off the stack, * yet. */ g_status.macro_executing = TRUE; g_status.mstack_pointer = -1; popped = FALSE; rc = OK; while (rc == OK) { /* * the first time thru the loop, popped is FALSE. some lint * utilities may complain about key being used but not defined. */ if (popped == FALSE) { /* * find the first keystroke in the macro. when we pop the stack, * all this stuff is reset by the pop -- do not reset it again. */ g_status.macro_next = macro.first_stroke[g_status.key_pressed-256]; g_status.current_macro = g_status.key_pressed; key = macro.strokes[g_status.macro_next].key; } popped = FALSE; if (key != MAX_KEYS+1 && key != -1) { do { /* * set up all editor variables as if we were entering * keys from the keyboard. */ window = g_status.current_window; display_dirty_windows( window ); ceh.flag = OK; g_status.key_pressed = macro.strokes[g_status.macro_next].key; g_status.command = getfunc( g_status.key_pressed ); if (g_status.wrapped || g_status.key_pending) { g_status.key_pending = FALSE; g_status.wrapped = FALSE; show_search_message( CLR_SEARCH, g_display.mode_color ); } /* * while there are no errors or Control-Breaks, let's keep on * executing a macro. g_status.control_break is a global * editor flag that is set in our Control-Break interrupt * handler routine. */ if (g_status.control_break == TRUE) { rc = ERROR; break; } /* * we haven't called any editor function yet. we need * to look at the editor command that is to be executed. * if the command is PlayBack, we need to break out of * this inner do loop and start executing the macro * from the beginning (the outer do loop). * * if we don't break out now from a recursive macro, we will * recursively call PlayBack and we will likely overflow * the main (as opposed to the macro_stack) stack. */ if (g_status.command == PlayBack) { /* * recursive macros are handled differently from * macros that call other macros. * recursive macros - break out of this inner loop * and begin executing the macro from the beg of macro. * standard macros - save the next instruction of this * macro on the stack and begin executing the called macro. */ if (g_status.current_macro != g_status.key_pressed) { if (push_macro_stack( macro.strokes[g_status.macro_next].next ) != OK) { error( WARNING, window->bottom_line, ed16 ); rc = ERROR; } g_status.macro_next = macro.first_stroke[g_status.key_pressed-256]; g_status.current_macro = g_status.key_pressed; key = macro.strokes[g_status.macro_next].key; /* * execute called macro at beginning of this do loop. */ continue; } else /* * recursive macro - break out of this inner loop * or else we may overflow the stack(s). */ break; } /* * just as we assert before the main editor routine, let's * assert in the macro function to make sure everything * is everything. */ #if defined( __MSC__ ) assert( window != NULL ); assert( window->file_info != NULL ); assert( window->file_info->line_list != NULL ); assert( window->file_info->line_list_end != NULL ); assert( window->file_info->line_list_end->len == EOF ); assert( window->visible == TRUE ); assert( window->rline >= 0 ); assert( window->rline <= window->file_info->length + 1 ); assert( window->rcol >= 0 ); assert( window->rcol < MAX_LINE_LENGTH ); assert( window->ccol >= window->start_col ); assert( window->ccol <= window->end_col ); assert( window->bcol >= 0 ); assert( window->bcol < MAX_LINE_LENGTH ); assert( window->bcol == window->rcol-(window->ccol - window->start_col) ); assert( window->start_col >= 0 ); assert( window->start_col < window->end_col ); assert( window->end_col < g_display.ncols ); assert( window->cline >= window->top_line ); assert( window->cline <= window->bottom_line ); assert( window->top_line > 0 ); assert( window->top_line <= window->bottom_line ); assert( window->bottom_line < MAX_LINES ); assert( window->bin_offset >= 0 ); if (window->ll->next == NULL) assert( window->ll->len == EOF ); else assert( window->ll->len >= 0 ); assert( window->ll->len < MAX_LINE_LENGTH ); #endif if (g_status.command >= 0 && g_status.command < NUM_FUNCS) rc = (*do_it[g_status.command])( window ); g_status.macro_next = macro.strokes[g_status.macro_next].next; } while (rc == OK && g_status.macro_next != -1); /* * if we have come the end of a macro definition and there * are no keys saved on the stack, we have finished our * macro. get out. */ if (g_status.macro_next == -1 && g_status.mstack_pointer < 0) rc = ERROR; else if (rc != ERROR && g_status.mstack_pointer >= 0) { /* * if this is a recursive macro, don't pop the stack * because we didn't push. * for a standard macro, get back the next key in the * calling macro. */ if (g_status.current_macro != g_status.key_pressed) { if (pop_macro_stack( &g_status.macro_next ) != OK) { error( WARNING, window->bottom_line, ed17 ); rc = ERROR; } else { popped = TRUE; key = macro.strokes[g_status.macro_next].key; } } } } } g_status.macro_executing = FALSE; } return( OK ); }
/* * Name: record_on_off * Purpose: save keystrokes in keystroke buffer * Date: April 1, 1992 * Passed: window: pointer to current window * Notes: -1 in .next field indicates the end of a recording * -1 in .key field indicates the initial, unassigned macro key * STROKE_LIMIT+1 in .next field indicates an unused space. */ int record_on_off( WINDOW *window ) { register int next; int prev; int line; int key; int func; char line_buff[(MAX_COLS+2)*2]; /* buffer for char and attribute */ mode.record = !mode.record; if (mode.record == TRUE) { line = window->bottom_line; show_avail_strokes( ); save_screen_line( 0, line, line_buff ); /* * press key that will play back recording */ set_prompt( main11, line ); /* * get the candidate macro key and look up the function assigned to it. */ key = getkey( ); func = getfunc( key ); /* * the key must be an unused, recognized function key or a function * key assigned to a previously defined macro. we also need room * in the macro structure. */ if (key <= 256 || (func != 0 && func != PlayBack)) { /* * cannot assign a recording to this key */ error( WARNING, line, main12 ); mode.record = FALSE; } else if (g_status.stroke_count == 0) { /* * no more room in recording buffer */ error( WARNING, line, main13 ); mode.record = FALSE; } else { /* * everything is everything so far, just check for a prev macro */ prev = OK; if (func == PlayBack) { /* * overwrite recording (y/n)? */ set_prompt( main14, line ); if (get_yn( ) == A_NO) { prev = ERROR; mode.record = FALSE; } } if (prev == OK) { g_status.recording_key = key; next = macro.first_stroke[key-256]; /* * if key has already been assigned to a macro, clear macro def. */ if (next != STROKE_LIMIT+1) { do { prev = next; next = macro.strokes[next].next; macro.strokes[prev].key = MAX_KEYS+1; macro.strokes[prev].next = STROKE_LIMIT+1; ++g_status.stroke_count; } while (next != -1); show_avail_strokes( ); } /* * find the first open space and initialize */ for (next=0; macro.strokes[next].next != STROKE_LIMIT+1;) next++; macro.first_stroke[key-256] = next; macro.strokes[next].key = -1; macro.strokes[next].next = -1; key_func.key[key-256] = PlayBack; /* * recording */ s_output( main15, g_display.mode_line, 22, g_display.mode_color | 0x80 ); } } restore_screen_line( 0, line, line_buff ); } /* * the flashing "Recording" and the stroke count write over the modes. * when we get thru defining a macro, redisplay the modes. */ if (mode.record == FALSE) { memset( line_buff, ' ', 36 ); line_buff[36] = '\0'; s_output( line_buff, g_display.mode_line, 22, g_display.mode_color ); show_tab_modes( ); show_indent_mode( ); show_sync_mode( ); show_search_case( ); show_wordwrap_mode( ); /* * let's look at the macro. if the first .key of the macro is * still -1, which is the initial unassigned key in a macro, reset * the macro so other keys may be assigned to this node. */ key = g_status.recording_key; if (key != 0) { next = macro.first_stroke[key-256]; if (macro.strokes[next].key == -1) { macro.strokes[next].key = MAX_KEYS+1; macro.strokes[next].next = STROKE_LIMIT+1; macro.first_stroke[key-256] = STROKE_LIMIT+1; if (getfunc( key ) == PlayBack) key_func.key[key-256] = 0; } } g_status.recording_key = 0; } return( OK ); }
/* * 作用: 把键盘命令放到缓存中 * 参数: line: 要提示显示的行 * 注意: 如果next值是-1,表明到了记录的末尾; * 如果next值是STROKE_LIMIT+1表示空间已经用完 */ void record_keys( int line ) { register int next; register int prev; int key; int func; if (mode.record == TRUE) { if (g_status.stroke_count == 0) /* * 宏记录已经没有空间记录更多的操作 */ error( WARNING, line, main13 ); else { key = g_status.key_pressed; func = getfunc( key ); if (func != RecordMacro && func != SaveMacro && func != LoadMacro && func != ClearAllMacros) { /* * 如果next值是-1,表明到了记录的末尾 */ next = macro.first_stroke[g_status.recording_key - 256]; if (macro.strokes[next].next != STROKE_LIMIT+1) { while (macro.strokes[next].next != -1) next = macro.strokes[next].next; } prev = next; /* * 找到一个空间来记录当前的操作 */ if (macro.strokes[next].key != -1) { for (; next < STROKE_LIMIT && macro.strokes[next].next != STROKE_LIMIT+1;) next++; if (next == STROKE_LIMIT) { for (next=0; next < prev && macro.strokes[next].next != STROKE_LIMIT+1;) next++; } } if (next == prev && macro.strokes[prev].key != -1) /* * 记录缓存没有记录 */ error( WARNING, line, main13 ); else { /* * 如果我们正在记录第一个宏节点,那么next == prev */ macro.strokes[prev].next = next; macro.strokes[next].next = -1; macro.strokes[next].key = key; g_status.stroke_count--; show_avail_strokes( ); } } } } }
/* * Name: finish * Purpose: To remove the current window and terminate the program if no * more windows are left. * Date: June 5, 1991 * Passed: window: pointer to current window * Notes: Order of deciding which window becomes current window: * 1) If any invisible window with same top and bottom line, * and start_col and end_col, then first invisible one becomes * current window. * 2) window above if it exists becomes current window * 3) window below if it exists becomes current window * 4) window right if it exists becomes current window * 5) window left if it exists becomes current window * 6) first available invisible window becomes current window. * When I added vertical windows, this routine became a LOT * more complicated. To keep things reasonably sane, let's * only close windows that have three common edges, eg. * * ÚÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄ¿ * ³ ³ no ³ * ³ ÃÄÄÄÄÄÂÄÄÄÄ´ * ³ ³yes1 ³yes1³ * ³ no ÃÄÄÄÄÄÁÄÄÄÄ´ * ³ ³ yes2 ³ * ³ ÃÄÄÄÄÄÄÄÄÄÄ´ * ³ ³ yes2 ³ * ÀÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÙ * * Windows with 'no' cannot be closed. Windows with 'yes' can * be combined with windows that have the same yes number. */ void finish( WINDOW *window ) { register WINDOW *wp; /* for scanning other windows */ register WINDOW *win; /* register pointer for window */ file_infos *file, *fp; /* for scanning other files */ int poof; int cline; int top; int bottom; int start_col; int end_col; int max_letter; int file_change = FALSE; line_list_ptr ll; line_list_ptr temp_ll; win = window; entab_linebuff( ); if (un_copy_line( win->ll, win, TRUE ) == ERROR) return; file = win->file_info; /* * remove all hidden windows that point to same file */ file = win->file_info; for (wp=g_status.window_list; wp != NULL; wp=wp->next) { if (wp->file_info == file) { if (!wp->visible) { if (wp->prev == NULL) { if (wp->next == NULL) g_status.stop = TRUE; else g_status.window_list = wp->next; } else wp->prev->next = wp->next; if (wp->next) wp->next->prev = wp->prev; --wp->file_info->ref_count; free( wp ); --g_status.window_count; } } } if (win->prev == NULL && win->next == NULL) g_status.stop = TRUE; poof = FALSE; if (g_status.stop != TRUE) { /* * see if there are any invisible windows with same top and bottom, * lines, and start_col and end_col as this window. start looking at * end of window list. */ top = win->top_line; bottom = win->bottom_line; start_col = win->start_col; end_col = win->end_col; wp = g_status.window_list; if (wp != NULL) { while (wp->next != NULL) wp = wp->next; } while (wp != NULL && poof == FALSE) { if (wp->top_line == top && wp->bottom_line == bottom && wp->start_col == start_col && wp->end_col == end_col && !wp->visible) poof = TRUE; else wp = wp->prev; } if (poof == FALSE) { /* * see if there are any windows above */ wp = g_status.window_list; while (wp != NULL && poof == FALSE) { if (wp->bottom_line+2 == win->top_line && wp->start_col == win->start_col && wp->end_col == win->end_col && wp->visible) { poof = TRUE; top = wp->top_line; } else wp = wp->next; } if (poof == FALSE) { /* * see if there are any windows below */ wp = g_status.window_list; while (wp != NULL && poof == FALSE) { if (wp->top_line-2 == win->bottom_line && wp->start_col == win->start_col && wp->end_col == win->end_col && wp->visible) { poof = TRUE; bottom = wp->bottom_line; } else wp = wp->next; } } if (poof == FALSE) { /* * see if there are any windows right */ wp = g_status.window_list; while (wp != NULL && poof == FALSE) { if (wp->top_line == win->top_line && wp->bottom_line == win->bottom_line && wp->start_col-2 == win->end_col && wp->visible) { poof = TRUE; end_col = wp->end_col; } else wp = wp->next; } } if (poof == FALSE) { /* * see if there are any windows left */ wp = g_status.window_list; while (wp != NULL && poof == FALSE) { if (wp->top_line == win->top_line && wp->bottom_line == win->bottom_line && wp->end_col+2 == win->start_col && wp->visible) { poof = TRUE; start_col = wp->start_col; } else wp = wp->next; } } if (poof == FALSE) { /* * see if there are any other invisible windows. start looking * at the end of the window list. */ wp = g_status.window_list; if (wp != NULL) { while (wp->next != NULL) wp = wp->next; } while (wp != NULL && poof == FALSE) { if (!wp->visible) poof = TRUE; else wp = wp->prev; } } } if (poof) { wp->visible = TRUE; cline = wp->cline - (wp->top_line+wp->ruler); wp->top_line = top; wp->bottom_line = bottom; wp->cline = (wp->top_line+wp->ruler) + cline; if (wp->cline > wp->bottom_line) wp->cline = wp->top_line+wp->ruler; wp->start_col = start_col; wp->end_col = end_col; if (start_col == 0 && end_col == g_display.ncols - 1) wp->vertical = FALSE; else wp->vertical = TRUE; check_virtual_col( wp, wp->rcol, wp->ccol ); setup_window( wp ); show_window_header( wp ); if (wp->vertical) show_vertical_separator( wp ); /* * The window above, below, or previously invisible becomes the new * current window. */ g_status.current_window = wp; } } if (!poof && g_status.stop != TRUE) /* * cannot close current window */ error( WARNING, win->bottom_line, win7 ); else { /* * free unused file memory if necessary */ if (--file->ref_count == 0) { /* * if a block is marked, unmark it */ if (file == g_status.marked_file) { g_status.marked = FALSE; g_status.marked_file = NULL; } for (fp=g_status.file_list; fp != NULL; fp=fp->next) { if (fp->file_no > file->file_no) fp->file_no--; } file_change = file->file_no; /* * no window now refers to this file, so remove file from the list */ if (file->prev == NULL) g_status.file_list = file->next; else file->prev->next = file->next; if (file->next) file->next->prev = file->prev; /* * free the line pointers, linked list of line pointers, and * file struc. */ ll = file->undo_top; while (ll != NULL) { temp_ll = ll->next; if (ll->line != NULL) my_free( ll->line ); my_free( ll ); ll = temp_ll; } ll = file->line_list; while (ll != NULL) { temp_ll = ll->next; if (ll->line != NULL) my_free( ll->line ); my_free( ll ); ll = temp_ll; } #if defined( __MSC__ ) _fheapmin( ); #endif free( file ); if (--g_status.file_count) { show_file_count( g_status.file_count ); show_avail_mem( ); } } /* * remove the current window from the window list */ if (win->prev == NULL) g_status.window_list = win->next; else win->prev->next = win->next; if (win->next) win->next->prev = win->prev; if (diff.defined && (diff.w1 == win || diff.w2 == win)) diff.defined = FALSE; /* * free the memory taken by the window structure */ free( win ); --g_status.window_count; if (g_status.stop == FALSE) { g_status.current_file = wp->file_info; wp->file_info->dirty = LOCAL; make_ruler( wp ); show_ruler( wp ); show_window_count( g_status.window_count ); if (file_change) { for (wp=g_status.window_list; wp!=NULL; wp=wp->next) if (wp->visible) show_window_number_letter( wp ); } else { max_letter = 'a'; for (wp=g_status.window_list; wp!=NULL; wp=wp->next) { if (wp->file_info == file && wp->letter > max_letter) max_letter = wp->letter; } if (max_letter < file->next_letter - 1) file->next_letter = max_letter + 1; } } } if (g_status.stop == TRUE) { if (g_status.sas_defined && g_status.sas_arg < g_status.sas_argc) { show_avail_mem( ); for (bottom=0; bottom <= g_display.nlines; bottom++) eol_clear( 0, bottom, g_display.text_color ); bottom = g_display.nlines; set_prompt( win18, bottom ); top = getkey( ); top = getfunc( top ); eol_clear( 0, bottom, g_display.text_color ); if (top == RepeatGrep) { g_status.command = RepeatGrep; g_status.window_list = g_status.current_window = NULL; if (search_and_seize( g_status.window_list ) != ERROR) g_status.stop = FALSE; } } } }
/* * Name: size_window * Purpose: To change the size of the current and one other window. * Date: June 5, 1991 * Passed: window: pointer to current window * Notes: Use the Up and Down arrow keys to make the current window * bigger or smaller. The window above will either grow * or contract accordingly. */ int size_window( WINDOW *window ) { char line_buff[(MAX_COLS+1)*2]; /* buffer for char and attribute */ int func; int c; int resize; int show_above_ruler; int old_bottom_line; int old_top_line; int new_bottom_line; int new_top_line; register WINDOW *above; register WINDOW *win; win = window; if (win->top_line != 1 && !win->vertical) { entab_linebuff( ); un_copy_line( win->ll, win, TRUE ); save_screen_line( 0, win->bottom_line, line_buff ); /* * press up or down to change window size */ set_prompt( win4, win->bottom_line ); /* * resizing only affects current window and above visible window */ above = g_status.window_list; while (above->bottom_line + 2 != win->top_line || !above->visible) above = above->next; if (above->vertical) /* * cannot resize vertical window */ error( WARNING, win->bottom_line, win5 ); else { old_top_line = win->top_line; old_bottom_line = above->bottom_line; show_above_ruler = FALSE; for (func=0; func != AbortCommand && func != Rturn; ) { /* * If user has redined the ESC and Return keys, make them Rturn and * AbortCommand in this function. */ c = getkey( ); func = getfunc( c ); if (c == RTURN || func == NextLine || func == BegNextLine) func = Rturn; else if (c == ESC) func = AbortCommand; resize = FALSE; /* * if LineUp, make current window top line grow and bottom line * of above window shrink. if window movement covers up current * line of window then we must adjust logical line and real line. */ if (func == LineUp) { if (above->bottom_line > above->top_line + above->ruler) { if (win->rline == (win->cline - (win->top_line+win->ruler-1))) --win->cline; --win->top_line; if (above->cline == above->bottom_line) --above->cline; --above->bottom_line; resize = TRUE; if (mode.ruler) { if (win->ruler == FALSE) { if (win->cline == win->top_line) ++win->cline; if (win->cline > win->bottom_line) win->cline = win->bottom_line; win->ruler = TRUE; } } } /* * if LineDown, make current window top line shrink and bottom line * of above window grow. if window movement covers up current * line of window then we must adjust logical line and real line. */ } else if (func == LineDown) { if (win->bottom_line > win->top_line + win->ruler) { if (win->cline == win->top_line + win->ruler) ++win->cline; ++win->top_line; ++above->bottom_line; resize = TRUE; if (mode.ruler) { if (above->ruler == FALSE) { if (above->cline == above->top_line) ++above->cline; if (above->cline > above->bottom_line) above->cline = above->bottom_line; above->ruler = TRUE; make_ruler( above ); show_above_ruler = TRUE; } } } } /* * if we resize a window, then update window size and current and * real lines if needed. */ if (resize == TRUE) { setup_window( above ); display_current_window( above ); if (show_above_ruler) { show_ruler( above ); show_ruler_pointer( above ); show_above_ruler = FALSE; } setup_window( win ); show_window_header( win ); win->ruler = mode.ruler; make_ruler( win ); show_ruler( win ); show_ruler_pointer( win ); display_current_window( win ); save_screen_line( 0, win->bottom_line, line_buff ); /* * press up or down to change window size */ set_prompt( win4, win->bottom_line ); } } new_top_line = win->top_line; new_bottom_line = above->bottom_line; for (above=g_status.window_list; above != NULL; above=above->next) { if (!above->visible) { if (above->bottom_line == old_bottom_line) { above->bottom_line = new_bottom_line; if (above->cline < new_bottom_line) above->cline = new_bottom_line; setup_window( above ); } else if (above->top_line == old_top_line) { above->top_line = new_top_line; if (above->cline < new_top_line) above->cline = new_top_line; if ((long)(above->cline+1L - (above->top_line+above->ruler)) > above->rline) above->cline = (int)above->rline + above->top_line + above->ruler - 1; setup_window( above ); } } } } restore_screen_line( 0, win->bottom_line, line_buff ); } else { if (win->vertical) /* * cannot resize vertical window */ error( WARNING, win->bottom_line, win5 ); else /* * cannot resize top window */ error( WARNING, win->bottom_line, win6 ); } return( OK ); }
void init_builtin_functions(struct tc_globals *tg) { struct tc_func *head = calloc(1, sizeof(struct tc_func)); head->returntype = malloc(sizeof(struct type)); head->returntype->type = T_WORD; head->returntype->pm_name = "t"; head->returntype->accept_empty_list = 0; // ? head->name = "head"; head->args = malloc(sizeof(struct func_arg)); head->args->name = "list"; head->args->type = malloc(sizeof(struct type)); head->args->type->type = '['; head->args->type->list_type = malloc(sizeof(struct type)); head->args->type->list_type->type = T_WORD; head->args->type->list_type->pm_name = "t"; head->args->type->list_type->accept_empty_list = 0; // ? head->args->farg = 0; head->args->next = NULL; head->decls = NULL; head->func = getfunc(); head->nargs = 1; head->nlocals = 0; head->next = NULL; builtin_head = head->func; *tg->funcs_last = head; tg->funcs_last = &head->next; struct tc_func *tail = calloc(1, sizeof(struct tc_func)); tail->returntype = malloc(sizeof(struct type)); tail->returntype->type = '['; tail->returntype->list_type = malloc(sizeof(struct type)); tail->returntype->list_type->type = T_WORD; tail->returntype->list_type->pm_name = "t"; tail->returntype->list_type->accept_empty_list = 0; // ? tail->name = "tail"; tail->args = malloc(sizeof(struct func_arg)); tail->args->name = "list"; tail->args->type = malloc(sizeof(struct type)); tail->args->type->type = '['; tail->args->type->list_type = malloc(sizeof(struct type)); tail->args->type->list_type->type = T_WORD; tail->args->type->list_type->pm_name = "t"; tail->args->type->list_type->accept_empty_list = 0; // ? tail->args->farg = 0; tail->args->next = NULL; tail->decls = NULL; tail->func = getfunc(); tail->nargs = 1; tail->nlocals = 0; tail->next = NULL; builtin_tail = tail->func; *tg->funcs_last = tail; tg->funcs_last = &tail->next; struct tc_func *isempty = calloc(1, sizeof(struct tc_func)); isempty->returntype = malloc(sizeof(struct type)); isempty->returntype->type = T_BOOL; isempty->name = "isempty"; isempty->args = malloc(sizeof(struct func_arg)); isempty->args->name = "list"; isempty->args->type = malloc(sizeof(struct type)); isempty->args->type->type = '['; isempty->args->type->list_type = malloc(sizeof(struct type)); isempty->args->type->list_type->type = T_WORD; isempty->args->type->list_type->pm_name = "t"; isempty->args->type->list_type->accept_empty_list = 0; // ? isempty->args->farg = 0; isempty->args->next = NULL; isempty->decls = NULL; isempty->func = getfunc(); isempty->nargs = 1; isempty->nlocals = 0; isempty->next = NULL; builtin_isempty = isempty->func; *tg->funcs_last = isempty; tg->funcs_last = &isempty->next; struct tc_func *fst = calloc(1, sizeof(struct tc_func)); fst->returntype = malloc(sizeof(struct type)); fst->returntype->type = T_WORD; fst->returntype->pm_name = "f"; fst->returntype->accept_empty_list = 0; fst->name = "fst"; fst->args = malloc(sizeof(struct func_arg)); fst->args->name = "tuple"; fst->args->type = malloc(sizeof(struct type)); fst->args->type->type = '('; fst->args->type->fst_type = malloc(sizeof(struct type)); fst->args->type->fst_type->type = T_WORD; fst->args->type->fst_type->pm_name = "f"; fst->args->type->fst_type->accept_empty_list = 0; fst->args->type->snd_type = malloc(sizeof(struct type)); fst->args->type->snd_type->type = T_WORD; fst->args->type->snd_type->pm_name = "s"; fst->args->type->snd_type->accept_empty_list = 0; fst->args->farg = 0; fst->args->next = NULL; fst->decls = NULL; fst->func = getfunc(); fst->nargs = 1; fst->nlocals = 0; fst->next = NULL; builtin_fst = fst->func; *tg->funcs_last = fst; tg->funcs_last = &fst->next; struct tc_func *snd = calloc(1, sizeof(struct tc_func)); snd->returntype = malloc(sizeof(struct type)); snd->returntype->type = T_WORD; snd->returntype->pm_name = "s"; snd->returntype->accept_empty_list = 0; snd->name = "snd"; snd->args = malloc(sizeof(struct func_arg)); snd->args->name = "tuple"; snd->args->type = malloc(sizeof(struct type)); snd->args->type->type = '('; snd->args->type->fst_type = malloc(sizeof(struct type)); snd->args->type->fst_type->type = T_WORD; snd->args->type->fst_type->pm_name = "f"; snd->args->type->fst_type->accept_empty_list = 0; snd->args->type->snd_type = malloc(sizeof(struct type)); snd->args->type->snd_type->type = T_WORD; snd->args->type->snd_type->pm_name = "s"; snd->args->type->snd_type->accept_empty_list = 0; snd->args->farg = 0; snd->args->next = NULL; snd->decls = NULL; snd->func = getfunc(); snd->nargs = 1; snd->nlocals = 0; snd->next = NULL; builtin_snd = snd->func; *tg->funcs_last = snd; tg->funcs_last = &snd->next; }
int m_brdf2( /* color a ray that hit a BRDF material */ OBJREC *m, RAY *r ) { BRDFDAT nd; COLOR ctmp; FVECT vtmp; double dtmp; /* always a shadow */ if (r->crtype & SHADOW) return(1); /* check arguments */ if ((m->oargs.nsargs < (hasdata(m->otype)?4:2)) | (m->oargs.nfargs < ((m->otype==MAT_TFUNC)|(m->otype==MAT_TDATA)?6:4))) objerror(m, USER, "bad # arguments"); /* check for back side */ if (r->rod < 0.0) { if (!backvis) { raytrans(r); return(1); } raytexture(r, m->omod); flipsurface(r); /* reorient if backvis */ } else raytexture(r, m->omod); nd.mp = m; nd.pr = r; /* get material color */ setcolor(nd.mcolor, m->oargs.farg[0], m->oargs.farg[1], m->oargs.farg[2]); /* get specular component */ nd.rspec = m->oargs.farg[3]; /* compute transmittance */ if ((m->otype == MAT_TFUNC) | (m->otype == MAT_TDATA)) { nd.trans = m->oargs.farg[4]*(1.0 - nd.rspec); nd.tspec = nd.trans * m->oargs.farg[5]; dtmp = nd.trans - nd.tspec; setcolor(nd.tdiff, dtmp, dtmp, dtmp); } else { nd.tspec = nd.trans = 0.0; setcolor(nd.tdiff, 0.0, 0.0, 0.0); } /* compute reflectance */ dtmp = 1.0 - nd.trans - nd.rspec; setcolor(nd.rdiff, dtmp, dtmp, dtmp); nd.pdot = raynormal(nd.pnorm, r); /* perturb normal */ multcolor(nd.mcolor, r->pcol); /* modify material color */ multcolor(nd.rdiff, nd.mcolor); multcolor(nd.tdiff, nd.mcolor); /* load auxiliary files */ if (hasdata(m->otype)) { nd.dp = getdata(m->oargs.sarg[1]); getfunc(m, 2, 0, 0); } else { nd.dp = NULL; getfunc(m, 1, 0, 0); } /* compute ambient */ if (nd.trans < 1.0-FTINY) { copycolor(ctmp, nd.mcolor); /* modified by material color */ scalecolor(ctmp, 1.0-nd.trans); multambient(ctmp, r, nd.pnorm); addcolor(r->rcol, ctmp); /* add to returned color */ } if (nd.trans > FTINY) { /* from other side */ flipsurface(r); vtmp[0] = -nd.pnorm[0]; vtmp[1] = -nd.pnorm[1]; vtmp[2] = -nd.pnorm[2]; copycolor(ctmp, nd.mcolor); scalecolor(ctmp, nd.trans); multambient(ctmp, r, vtmp); addcolor(r->rcol, ctmp); flipsurface(r); } /* add direct component */ direct(r, dirbrdf, &nd); return(1); }
int m_brdf( /* color a ray that hit a BRDTfunc material */ OBJREC *m, RAY *r ) { int hitfront = 1; BRDFDAT nd; RAY sr; double mirtest=0, mirdist=0; double transtest=0, transdist=0; int hasrefl, hastrans; int hastexture; COLOR ctmp; FVECT vtmp; double d; MFUNC *mf; int i; /* check arguments */ if ((m->oargs.nsargs < 10) | (m->oargs.nfargs < 9)) objerror(m, USER, "bad # arguments"); nd.mp = m; nd.pr = r; /* dummy values */ nd.rspec = nd.tspec = 1.0; nd.trans = 0.5; /* diffuse reflectance */ if (r->rod > 0.0) setcolor(nd.rdiff, m->oargs.farg[0], m->oargs.farg[1], m->oargs.farg[2]); else setcolor(nd.rdiff, m->oargs.farg[3], m->oargs.farg[4], m->oargs.farg[5]); /* diffuse transmittance */ setcolor(nd.tdiff, m->oargs.farg[6], m->oargs.farg[7], m->oargs.farg[8]); /* get modifiers */ raytexture(r, m->omod); hastexture = DOT(r->pert,r->pert) > FTINY*FTINY; if (hastexture) { /* perturb normal */ nd.pdot = raynormal(nd.pnorm, r); } else { VCOPY(nd.pnorm, r->ron); nd.pdot = r->rod; } if (r->rod < 0.0) { /* orient perturbed values */ nd.pdot = -nd.pdot; for (i = 0; i < 3; i++) { nd.pnorm[i] = -nd.pnorm[i]; r->pert[i] = -r->pert[i]; } hitfront = 0; } copycolor(nd.mcolor, r->pcol); /* get pattern color */ multcolor(nd.rdiff, nd.mcolor); /* modify diffuse values */ multcolor(nd.tdiff, nd.mcolor); hasrefl = bright(nd.rdiff) > FTINY; hastrans = bright(nd.tdiff) > FTINY; /* load cal file */ nd.dp = NULL; mf = getfunc(m, 9, 0x3f, 0); /* compute transmitted ray */ setbrdfunc(&nd); errno = 0; setcolor(ctmp, evalue(mf->ep[3]), evalue(mf->ep[4]), evalue(mf->ep[5])); if ((errno == EDOM) | (errno == ERANGE)) objerror(m, WARNING, "compute error"); else if (rayorigin(&sr, TRANS, r, ctmp) == 0) { if (!(r->crtype & SHADOW) && hastexture) { /* perturb direction */ VSUM(sr.rdir, r->rdir, r->pert, -.75); if (normalize(sr.rdir) == 0.0) { objerror(m, WARNING, "illegal perturbation"); VCOPY(sr.rdir, r->rdir); } } else { VCOPY(sr.rdir, r->rdir); } rayvalue(&sr); multcolor(sr.rcol, sr.rcoef); addcolor(r->rcol, sr.rcol); if (!hastexture) { transtest = 2.0*bright(sr.rcol); transdist = r->rot + sr.rt; } } if (r->crtype & SHADOW) /* the rest is shadow */ return(1); /* compute reflected ray */ setbrdfunc(&nd); errno = 0; setcolor(ctmp, evalue(mf->ep[0]), evalue(mf->ep[1]), evalue(mf->ep[2])); if ((errno == EDOM) | (errno == ERANGE)) objerror(m, WARNING, "compute error"); else if (rayorigin(&sr, REFLECTED, r, ctmp) == 0) { VSUM(sr.rdir, r->rdir, nd.pnorm, 2.*nd.pdot); checknorm(sr.rdir); rayvalue(&sr); multcolor(sr.rcol, sr.rcoef); addcolor(r->rcol, sr.rcol); if (!hastexture && r->ro != NULL && isflat(r->ro->otype)) { mirtest = 2.0*bright(sr.rcol); mirdist = r->rot + sr.rt; } } /* compute ambient */ if (hasrefl) { if (!hitfront) flipsurface(r); copycolor(ctmp, nd.rdiff); multambient(ctmp, r, nd.pnorm); addcolor(r->rcol, ctmp); /* add to returned color */ if (!hitfront) flipsurface(r); } if (hastrans) { /* from other side */ if (hitfront) flipsurface(r); vtmp[0] = -nd.pnorm[0]; vtmp[1] = -nd.pnorm[1]; vtmp[2] = -nd.pnorm[2]; copycolor(ctmp, nd.tdiff); multambient(ctmp, r, vtmp); addcolor(r->rcol, ctmp); if (hitfront) flipsurface(r); } if (hasrefl | hastrans || m->oargs.sarg[6][0] != '0') direct(r, dirbrdf, &nd); /* add direct component */ d = bright(r->rcol); /* set effective distance */ if (transtest > d) r->rt = transdist; else if (mirtest > d) r->rt = mirdist; return(1); }
extern int load_os( /* load associated data for object */ register OBJREC *op ) { DATARRAY *dp; switch (op->otype) { case OBJ_FACE: /* polygon */ getface(op); return(1); case OBJ_CONE: /* cone */ case OBJ_RING: /* disk */ case OBJ_CYLINDER: /* cylinder */ case OBJ_CUP: /* inverted cone */ case OBJ_TUBE: /* inverted cylinder */ getcone(op, 1); return(1); case OBJ_INSTANCE: /* octree instance */ getinstance(op, IO_ALL); return(1); case OBJ_MESH: /* mesh instance */ getmeshinst(op, IO_ALL); return(1); case PAT_CPICT: /* color picture */ if (op->oargs.nsargs < 4) goto sargerr; getpict(op->oargs.sarg[3]); getfunc(op, 4, 0x3<<5, 0); return(1); case PAT_CDATA: /* color data */ dp = getdata(op->oargs.sarg[3]); getdata(op->oargs.sarg[4]); getdata(op->oargs.sarg[5]); getfunc(op, 6, ((1<<dp->nd)-1)<<7, 0); return(1); case PAT_BDATA: /* brightness data */ if (op->oargs.nsargs < 2) goto sargerr; dp = getdata(op->oargs.sarg[1]); getfunc(op, 2, ((1<<dp->nd)-1)<<3, 0); return(1); case PAT_BFUNC: /* brightness function */ getfunc(op, 1, 0x1, 0); return(1); case PAT_CFUNC: /* color function */ getfunc(op, 3, 0x7, 0); return(1); case TEX_DATA: /* texture data */ if (op->oargs.nsargs < 6) goto sargerr; dp = getdata(op->oargs.sarg[3]); getdata(op->oargs.sarg[4]); getdata(op->oargs.sarg[5]); getfunc(op, 6, ((1<<dp->nd)-1)<<7, 1); return(1); case TEX_FUNC: /* texture function */ getfunc(op, 3, 0x7, 1); return(1); case MIX_DATA: /* mixture data */ dp = getdata(op->oargs.sarg[3]); getfunc(op, 4, ((1<<dp->nd)-1)<<5, 0); return(1); case MIX_PICT: /* mixture picture */ getpict(op->oargs.sarg[3]); getfunc(op, 4, 0x3<<5, 0); return(1); case MIX_FUNC: /* mixture function */ getfunc(op, 3, 0x4, 0); return(1); case MAT_PLASTIC2: /* anisotropic plastic */ case MAT_METAL2: /* anisotropic metal */ getfunc(op, 3, 0x7, 1); return(1); case MAT_BRTDF: /* BRDTfunc material */ getfunc(op, 9, 0x3f, 0); return(1); case MAT_BSDF: /* BSDF material */ if (op->oargs.nsargs < 6) goto sargerr; getfunc(op, 5, 0x1d, 1); loadBSDF(op->oargs.sarg[1]); return(1); case MAT_PDATA: /* plastic BRDF data */ case MAT_MDATA: /* metal BRDF data */ case MAT_TDATA: /* trans BRDF data */ if (op->oargs.nsargs < 2) goto sargerr; getdata(op->oargs.sarg[1]); getfunc(op, 2, 0, 0); return(1); case MAT_PFUNC: /* plastic BRDF func */ case MAT_MFUNC: /* metal BRDF func */ case MAT_TFUNC: /* trans BRDF func */ getfunc(op, 1, 0, 0); return(1); case MAT_DIRECT1: /* prism1 material */ getfunc(op, 4, 0xf, 1); return(1); case MAT_DIRECT2: /* prism2 material */ getfunc(op, 8, 0xff, 1); return(1); } /* nothing to load for the remaining types */ return(0); sargerr: objerror(op, USER, "too few string arguments"); return 0; /* pro forma return */ }