void save_difficulty() { FILE *fp=fopen("hardness.lsp","wb"); if (!fp) dprintf("Unable to write to file hardness.lsp\n"); else { fprintf(fp,"(setf difficulty '"); if (DEFINEDP(l_difficulty)) { if (symbol_value(l_difficulty)==l_extreme) fprintf(fp,"extreme)\n"); else if (symbol_value(l_difficulty)==l_hard) fprintf(fp,"hard)\n"); else if (symbol_value(l_difficulty)==l_easy) fprintf(fp,"easy)\n"); else fprintf(fp,"medium)\n"); } else fprintf(fp,"medium)\n"); fclose(fp); } }
void status_bar::draw_update() { if (total_weapons && v) { if (DEFINEDP(symbol_value(l_mouse_can_switch)) && symbol_value(l_mouse_can_switch) && mouse_in_area()) { if ((current_level->tick_counter()&4)==0) wm->set_mouse_shape(cache.img(c_mouse1)->copy(),4,4); else wm->set_mouse_shape(cache.img(c_mouse2)->copy(),4,4); changed_cursor=1; } else if (changed_cursor) { if (!(dev&EDIT_MODE)) wm->set_mouse_shape(cache.img(c_target)->copy(),8,8); else wm->set_mouse_shape(cache.img(c_normal)->copy(),1,1); changed_cursor=0; } if (need_rf) redraw(screen); } }
jl_value_t *jl_parse_next() { value_t c = fl_applyn(0, symbol_value(symbol("jl-parser-next"))); if (c == FL_F) return NULL; if (iscons(c)) { value_t a = car_(c); if (isfixnum(a)) { jl_lineno = numval(a); //jl_printf(JL_STDERR, " on line %d\n", jl_lineno); return scm_to_julia(cdr_(c)); } } return scm_to_julia(c); }
void display(LISP_OBJ_PTR objp) { switch (objp->form) { case INT_FORM: fprintf(out_stream, "%d", int_value(objp)); break; case FLOAT_FORM: fprintf(out_stream, "%g", float_value(objp)); break; case CHAR_FORM: fprintf(out_stream, "%c", char_value(objp)); break; case STRING_FORM: fprintf(out_stream, "%s", string_value(objp)); break; case SYMBOL_FORM: fprintf(out_stream, "%s", symbol_value(objp)); break; case PROCEDURE_FORM: fprintf(out_stream, "<PROCEDURE>"); break; case BOOLEAN_FORM: fprintf(out_stream, "#%c", bool_value(objp) ? 't' : 'f'); break; case CONS_FORM: fprintf(out_stream, "("); while (TRUE) { print_lispobj(car(objp)); objp = cdr(objp); if (objp == nil_ptr) break; if (!(is_pair(objp))) { printf(" . "); print_lispobj(objp); break; } fprintf(out_stream, " "); } fprintf(out_stream, ")"); break; case NO_FORM: fprintf(out_stream, "no form, boss"); break; default: fprintf(out_stream, "dunno that form %d", form(objp)); } }
/* * Versions of disk_dump that support it contain the "dump_level" symbol. * Version 1 and later compressed kdump dumpfiles contain the dump level * in an additional field of the sub_header_kdump structure. */ static int get_dump_level(void) { int dump_level; if (DISKDUMP_VALID()) { if (symbol_exists("dump_level") && readmem(symbol_value("dump_level"), KVADDR, &dump_level, sizeof(dump_level), "dump_level", QUIET|RETURN_ON_ERROR)) return dump_level; } else if (KDUMP_CMPRS_VALID()) { if (dd->header->header_version >= 1) return dd->sub_header_kdump->dump_level; } return -1; }
// returns either an expression or a thunk jl_value_t *jl_expand(jl_value_t *expr) { int np = jl_gc_n_preserved_values(); value_t arg = julia_to_scm(expr); value_t e = fl_applyn(1, symbol_value(symbol("jl-expand-to-thunk")), arg); jl_value_t *result; if (e == FL_T || e == FL_F || e == FL_EOF) { result = NULL; } else { result = scm_to_julia(e); } while (jl_gc_n_preserved_values() > np) { jl_gc_unpreserve(); } return result; }
// evaluate form x with lexical bindings a LISPTR eval(LISPTR x) { if (consp(x)) { // evaluate a form LISPTR f = car(x); LISPTR args = cdr(x); x = apply(f, args); } else if (stringp(x) || numberp(x)) { return x; } else if (symbolp(x)) { LISPTR binding = assoc(x, lexvars); if (binding != NIL) { x = cdr(binding); } else { x = symbol_value(x); } } return x; }
DLLEXPORT void jl_init_frontend(void) { fl_init(2*512*1024); value_t img = cvalue(iostreamtype, sizeof(ios_t)); ios_t *pi = value2c(ios_t*, img); ios_static_buffer(pi, flisp_system_image, sizeof(flisp_system_image)); if (fl_load_system_image(img)) { JL_PRINTF(JL_STDERR, "fatal error loading system image\n"); jl_exit(1); } fl_applyn(0, symbol_value(symbol("__init_globals"))); jvtype = define_opaque_type(symbol("julia_value"), sizeof(void*), NULL, NULL); assign_global_builtins(julia_flisp_ast_ext); }
// this is for parsing one expression out of a string, keeping track of // the current position. DLLEXPORT jl_value_t *jl_parse_string(const char *str, int pos0, int greedy) { value_t s = cvalue_static_cstring(str); value_t p = fl_applyn(3, symbol_value(symbol("jl-parse-one-string")), s, fixnum(pos0), greedy?FL_T:FL_F); jl_value_t *expr=NULL, *pos1=NULL; JL_GC_PUSH(&expr, &pos1); value_t e = car_(p); if (e == FL_T || e == FL_F || e == FL_EOF) { expr = (jl_value_t*)jl_null; } else { expr = scm_to_julia(e); } pos1 = jl_box_long(toulong(cdr_(p),"parse")); jl_value_t *result = (jl_value_t*)jl_tuple2(expr, pos1); JL_GC_POP(); return result; }
DLLEXPORT void jl_lisp_prompt(void) { fl_applyn(1, symbol_value(symbol("__start")), fl_cons(FL_NIL,FL_NIL)); }
LISP_OBJ_PTR define(ENVIRONMENT_PTR env, LISP_OBJ_PTR args) { char *var; LISP_OBJ_PTR to_def = car(args); LISP_OBJ_PTR val; LISP_OBJ_PTR fun, params, req_params, opt_params, rest_params; ENVIRONMENT_PTR fun_env; BOOLEAN optional = FALSE, rest = FALSE; switch(form(to_def)) { case SYMBOL_FORM: var = symbol_value(to_def); val = cadr(args); enter_symbol(env, var, val); return to_def; case CONS_FORM: var = symbol_value(car(to_def)); val = cdr(args); params = cdr(to_def); req_params = params; opt_params = nil_ptr; rest_params = nil_ptr; // edge case if (is_pair(params) && !strcmp(symbol_value(car(params)), "&optional")) { req_params = nil_ptr; optional = TRUE; // giving this a try opt_params = cdr(params); cdr(params) = nil_ptr; params = opt_params; } else if (is_pair(params) && !strcmp(symbol_value(car(params)), "&rest")) { req_params = nil_ptr; rest = TRUE; rest_params = cadr(params); } while (params != nil_ptr && !optional && !rest) { if (is_pair(cdr(params)) && !strcmp(symbol_value(cadr(params)), "&optional")) { optional = TRUE; opt_params = cddr(params); cdr(params) = nil_ptr; params = opt_params; break; } else if (is_pair(cdr(params)) && !strcmp(symbol_value(cadr(params)), "&rest")) { rest = TRUE; rest_params = caddr(params); cdr(params) = nil_ptr; params = rest_params; break; } params = cdr(params); } while (optional && params != nil_ptr && !rest) { if (is_pair(cdr(params)) && !strcmp(symbol_value(cadr(params)), "&rest")) { rest = TRUE; rest_params = caddr(params); cdr(params) = nil_ptr; params = rest_params; break; } params = cdr(params); } fun = alloc_obj(); form(fun) = PROCEDURE_FORM; proc_type(fun) = DERIVED; proc_env(fun) = env; proc_reqparams(fun) = req_params; proc_optparams(fun) = opt_params; proc_restparams(fun) = rest_params; proc_body(fun) = val; enter_symbol(env, var, fun); return car(to_def); } }
// parse and eval a whole file, possibly reading from a string (`content`) jl_value_t *jl_parse_eval_all(const char *fname, const char *content, size_t contentlen, jl_module_t *inmodule) { jl_ptls_t ptls = jl_get_ptls_states(); if (ptls->in_pure_callback) jl_error("cannot use include inside a generated function"); jl_ast_context_t *ctx = jl_ast_ctx_enter(); fl_context_t *fl_ctx = &ctx->fl; value_t f, ast, expression; size_t len = strlen(fname); f = cvalue_static_cstrn(fl_ctx, fname, len); fl_gc_handle(fl_ctx, &f); if (content != NULL) { JL_TIMING(PARSING); value_t t = cvalue_static_cstrn(fl_ctx, content, contentlen); fl_gc_handle(fl_ctx, &t); ast = fl_applyn(fl_ctx, 2, symbol_value(symbol(fl_ctx, "jl-parse-string-stream")), t, f); fl_free_gc_handles(fl_ctx, 1); } else { JL_TIMING(PARSING); assert(memchr(fname, 0, len) == NULL); // was checked already in jl_load ast = fl_applyn(fl_ctx, 1, symbol_value(symbol(fl_ctx, "jl-parse-file")), f); } fl_free_gc_handles(fl_ctx, 1); if (ast == fl_ctx->F) { jl_ast_ctx_leave(ctx); jl_errorf("could not open file %s", fname); } fl_gc_handle(fl_ctx, &ast); fl_gc_handle(fl_ctx, &expression); int last_lineno = jl_lineno; const char *last_filename = jl_filename; size_t last_age = jl_get_ptls_states()->world_age; jl_lineno = 0; jl_filename = fname; jl_module_t *old_module = ctx->module; ctx->module = inmodule; jl_value_t *form = NULL; jl_value_t *result = jl_nothing; int err = 0; JL_GC_PUSH2(&form, &result); JL_TRY { assert(iscons(ast) && car_(ast) == symbol(fl_ctx, "toplevel")); ast = cdr_(ast); while (iscons(ast)) { expression = car_(ast); { JL_TIMING(LOWERING); if (fl_ctx->T == fl_applyn(fl_ctx, 1, symbol_value(symbol(fl_ctx, "contains-macrocall")), expression)) { form = scm_to_julia(fl_ctx, expression, inmodule); form = jl_expand_macros(form, inmodule, NULL, 0); expression = julia_to_scm(fl_ctx, form); } // expand non-final expressions in statement position (value unused) expression = fl_applyn(fl_ctx, 1, symbol_value(symbol(fl_ctx, iscons(cdr_(ast)) ? "jl-expand-to-thunk-stmt" : "jl-expand-to-thunk")), expression); } jl_get_ptls_states()->world_age = jl_world_counter; form = scm_to_julia(fl_ctx, expression, inmodule); JL_SIGATOMIC_END(); jl_get_ptls_states()->world_age = jl_world_counter; if (jl_is_linenode(form)) jl_lineno = jl_linenode_line(form); else result = jl_toplevel_eval_flex(inmodule, form, 1, 1); JL_SIGATOMIC_BEGIN(); ast = cdr_(ast); } } JL_CATCH { form = jl_pchar_to_string(fname, len); result = jl_box_long(jl_lineno); err = 1; } jl_get_ptls_states()->world_age = last_age; jl_lineno = last_lineno; jl_filename = last_filename; fl_free_gc_handles(fl_ctx, 2); ctx->module = old_module; jl_ast_ctx_leave(ctx); if (err) { if (jl_loaderror_type == NULL) jl_rethrow(); else jl_rethrow_other(jl_new_struct(jl_loaderror_type, form, result, ptls->exception_in_transit)); } JL_GC_POP(); return result; }
DLLEXPORT int jl_is_operator(char *sym) { return fl_applyn(1, symbol_value(symbol("operator?")), symbol(sym)) == FL_T; }
// label is the backreference we'd like to fix up with this read static value_t do_read_sexpr(value_t label) { value_t v, sym, oldtokval, *head; value_t *pv; u_int32_t t; char c; t = peek(); take(); switch (t) { case TOK_CLOSE: lerror(ParseError, "read: unexpected ')'"); case TOK_CLOSEB: lerror(ParseError, "read: unexpected ']'"); case TOK_DOT: lerror(ParseError, "read: unexpected '.'"); case TOK_SYM: case TOK_NUM: return tokval; case TOK_COMMA: head = &COMMA; goto listwith; case TOK_COMMAAT: head = &COMMAAT; goto listwith; case TOK_COMMADOT: head = &COMMADOT; goto listwith; case TOK_BQ: head = &BACKQUOTE; goto listwith; case TOK_QUOTE: head = "E; listwith: v = cons_reserve(2); car_(v) = *head; cdr_(v) = tagptr(((cons_t*)ptr(v))+1, TAG_CONS); car_(cdr_(v)) = cdr_(cdr_(v)) = NIL; PUSH(v); if (label != UNBOUND) ptrhash_put(&readstate->backrefs, (void*)label, (void*)v); v = do_read_sexpr(UNBOUND); car_(cdr_(Stack[SP-1])) = v; return POP(); case TOK_SHARPQUOTE: // femtoLisp doesn't need symbol-function, so #' does nothing return do_read_sexpr(label); case TOK_OPEN: PUSH(NIL); read_list(&Stack[SP-1], label); return POP(); case TOK_SHARPSYM: sym = tokval; if (sym == tsym || sym == Tsym) return FL_T; else if (sym == fsym || sym == Fsym) return FL_F; // constructor notation c = nextchar(); if (c != '(') { take(); lerrorf(ParseError, "read: expected argument list for %s", symbol_name(tokval)); } PUSH(NIL); read_list(&Stack[SP-1], UNBOUND); if (sym == vu8sym) { sym = arraysym; Stack[SP-1] = fl_cons(uint8sym, Stack[SP-1]); } else if (sym == fnsym) { sym = FUNCTION; } v = symbol_value(sym); if (v == UNBOUND) fl_raise(fl_list2(UnboundError, sym)); return fl_apply(v, POP()); case TOK_OPENB: return read_vector(label, TOK_CLOSEB); case TOK_SHARPOPEN: return read_vector(label, TOK_CLOSE); case TOK_SHARPDOT: // eval-when-read // evaluated expressions can refer to existing backreferences, but they // cannot see pending labels. in other words: // (... #2=#.#0# ... ) OK // (... #2=#.(#2#) ... ) DO NOT WANT sym = do_read_sexpr(UNBOUND); if (issymbol(sym)) { v = symbol_value(sym); if (v == UNBOUND) fl_raise(fl_list2(UnboundError, sym)); return v; } return fl_toplevel_eval(sym); case TOK_LABEL: // create backreference label if (ptrhash_has(&readstate->backrefs, (void*)tokval)) lerrorf(ParseError, "read: label %ld redefined", numval(tokval)); oldtokval = tokval; v = do_read_sexpr(tokval); ptrhash_put(&readstate->backrefs, (void*)oldtokval, (void*)v); return v; case TOK_BACKREF: // look up backreference v = (value_t)ptrhash_get(&readstate->backrefs, (void*)tokval); if (v == (value_t)HT_NOTFOUND) lerrorf(ParseError, "read: undefined label %ld", numval(tokval)); return v; case TOK_GENSYM: pv = (value_t*)ptrhash_bp(&readstate->gensyms, (void*)tokval); if (*pv == (value_t)HT_NOTFOUND) *pv = fl_gensym(NULL, 0); return *pv; case TOK_DOUBLEQUOTE: return read_string(); } return FL_UNSPECIFIED; }
DLLEXPORT void jl_lisp_prompt(void) { if (jvtype==NULL) jl_init_frontend(); fl_applyn(1, symbol_value(symbol("__start")), fl_cons(FL_NIL,FL_NIL)); }
static int jl_parse_deperror(fl_context_t *fl_ctx, int err) { value_t prev = fl_applyn(fl_ctx, 1, symbol_value(symbol(fl_ctx, "jl-parser-deperror")), err ? fl_ctx->T : fl_ctx->F); return prev == fl_ctx->T ? 1 : 0; }
DLLEXPORT int jl_operator_precedence(char *sym) { return numval(fl_applyn(1, symbol_value(symbol("operator-precedence")), symbol(sym))); }
void jl_start_parsing_file(const char *fname) { fl_applyn(1, symbol_value(symbol("jl-parse-file")), cvalue_static_cstring(fname)); }
void main_menu() { int y=yres/2-210; ico_button *list=make_conditional_buttons(xres-51,y); list=make_default_buttons(xres-51,y,list); input_manager *inm=new input_manager(screen,eh,list); inm->allow_no_selections(); inm->clear_current(); time_marker old_time; screen->add_dirty(0,0,xres-1,yres-1); int eoff=0,coff=0; event ev; #ifdef __MAC__ int command = 0; #endif int state=0,stop_menu=0; time_marker start; eh->flush_screen(); do { time_marker new_time; if (eh->event_waiting()) { do { eh->get_event(ev); } while (ev.type==EV_MOUSE_MOVE && eh->event_waiting()); inm->handle_event(ev,NULL,eh); #ifdef __MAC__ if ((ev.type==EV_KEY || ev.type==EV_KEYRELEASE) && ev.key==JK_COMMAND) command = (ev.type == EV_KEY); if (ev.type==EV_KEY && ev.key=='q' && command) eh->push_event(new event(ID_QUIT,NULL)); #else if (ev.type==EV_KEY && ev.key==JK_ESC) eh->push_event(new event(ID_QUIT,NULL)); #endif menu_handler(ev,inm); start.get_time(); eh->flush_screen(); } if (new_time.diff_time(&start)>22) { if (volume_window) start.get_time(); else { if (!current_demo) { void *d=make_find_symbol("demos"); if (DEFINEDP(symbol_value(d))) current_demo=symbol_value(d); } if (current_demo) { demo_man.set_state(demo_manager::PLAYING,lstring_value(CAR(current_demo))); stop_menu=1; current_demo=CDR(current_demo); } } } if (volume_window) stop_menu=0; // can't exit with colume window open else if (main_net_cfg && main_net_cfg->restart_state()) stop_menu=1; else if (the_game->state==RUN_STATE) stop_menu=1; else if (ev.type==EV_MESSAGE) { if (ev.message.id==ID_START_GAME || ev.message.id==ID_RETURN) stop_menu=1; else if (ev.message.id==ID_QUIT) { #ifdef __MAC__ stop_menu=1; #else if (confirm_quit()) stop_menu=1; else { ev.type=EV_SPURIOUS; start.get_time(); } #endif } } } while (!stop_menu); delete inm; if (ev.type==EV_MESSAGE && ev.message.id==ID_QUIT) // propogate the quit message the_game->end_session(); }
ico_button *make_default_buttons(int x,int &y, ico_button *append_list) { int h; int diff_on; if (DEFINEDP(symbol_value(l_difficulty))) { if (symbol_value(l_difficulty)==l_extreme) diff_on=3; else if (symbol_value(l_difficulty)==l_hard) diff_on=2; else if (symbol_value(l_difficulty)==l_easy) diff_on=0; else diff_on=1; } else diff_on=3; ico_button *start; ifield **cur=(ifield **)&start; if (!player_list->next) { *cur=load_icon(0,ID_START_GAME,x,y,h,NULL,"ic_start"); cur=&((*cur)->next); y+=h; } ico_switch_button *set=NULL; if (!main_net_cfg || (main_net_cfg->state!=net_configuration::SERVER && main_net_cfg->state!=net_configuration::CLIENT)) { *cur=new ico_switch_button(x,y,ID_NULL,diff_on, load_icon(3,ID_EASY,x,y,h, load_icon(8,ID_MEDIUM,x,y,h, load_icon(9,ID_HARD,x,y,h, load_icon(10,ID_EXTREME,x,y,h,NULL,"ic_extreme"), "ic_hard"),"ic_medium"),"ic_easy"),NULL); cur=&((*cur)->next); y+=h; } *cur=load_icon(4,ID_LIGHT_OFF,x,y,h,NULL,"ic_gamma"); cur=&((*cur)->next); y+=h; *cur=load_icon(5,ID_VOLUME,x,y,h,NULL,"ic_volume"); cur=&((*cur)->next); y+=h; if (registered && prot) { *cur = load_icon(11,ID_NETWORKING,x,y,h,NULL,"ic_networking"); cur=&((*cur)->next); y+=h; } *cur = load_icon(2,ID_SHOW_SELL,x,y,h,NULL,"ic_sell"); cur=&((*cur)->next); y+=h; *cur = load_icon(12,ID_MACCONF,x,y,h,NULL,"ic_macconf"); cur=&((*cur)->next); y+=h; *cur = load_icon(13,ID_MACKEYS,x,y,h,NULL,"ic_mackeys"); cur=&((*cur)->next); y+=h; *cur=load_icon(6,ID_QUIT,x,y,h,NULL,"ic_quit"); cur=&((*cur)->next); y+=h; ico_button *list=append_list; if (append_list) { while (append_list->next) append_list=(ico_button *)append_list->next; append_list->next=start; } else list=start; return list; }
void show_sell(int abortable) { #if 0 void *ss=make_find_symbol("sell_screens"); if (!DEFINEDP(symbol_value(ss))) { int sp=current_space; current_space=PERM_SPACE; // char *prog="((\"art/help.spe\" . \"sell2\")(\"art/help.spe\" . \"sell4\")(\"art/help.spe\" . \"sell3\")(\"art/endgame.spe\" . \"credit\"))"; char *prog="((\"art/endgame.spe\" . \"credit\") (\"art/help.spe\" . \"sell6\"))"; set_symbol_value(ss,compile(prog)); current_space=sp; } if (DEFINEDP(symbol_value(ss))) { image blank(2,2); blank.clear(); eh->set_mouse_shape(blank.copy(),0,0); // don't show mouse ss=symbol_value(ss); int quit=0; while (ss && !quit) { int im=cash.reg_object("art/help.spe",CAR(ss),SPEC_IMAGE,1); fade_in(cash.img(im),16); event ev; do { eh->flush_screen(); eh->get_event(ev); } while (ev.type!=EV_KEY); if (ev.key==JK_ESC && abortable) quit=1; fade_out(16); ss=CDR(ss); } eh->set_mouse_shape(cash.img(c_normal)->copy(),1,1); } #else image blank(2,2); blank.clear(); eh->set_mouse_shape(blank.copy(),0,0); // don't show mouse screen->clear(); image *im; event ev; int i; im=cash.img(cash.reg("art/endgame.spe","credit",SPEC_IMAGE,1)); char *str=lstring_value(eval(make_find_symbol("thanks_text"))); int dx=(xres+1)/2-im->width()/2,dy=(yres+1)/2-im->height()/2; im->put_image(screen,dx,dy); fade_in(0,16); uchar cmap[32]; for (i=0;i<32;i++) cmap[i]=pal->find_closest(i*256/32,i*256/32,i*256/32); i = 0; int tx = 300, ty = 350, twx = 319, twy = 119; while (eh->event_waiting()) eh->get_event(ev); ev.type = EV_SPURIOUS; time_marker start; int txti = 0; do { im->put_part(screen,dx+tx,dy+ty,tx,ty,tx+twx,ty+twy); txti++; text_draw(twy+5-txti,dx+tx+15,dy+ty,dx+tx+twx-15,dy+ty+twy,str,eh->font(),cmap,eh->bright_color()); eh->flush_screen(); time_marker now; while (now.diff_time(&start)<0.10) now.get_time(); start.get_time(); while (eh->event_waiting() && ev.type!=EV_KEY) eh->get_event(ev); } while (txti<600 && ev.type!=EV_KEY && ev.type!=EV_MOUSE_BUTTON); fade_out(16); if (!abortable || !(ev.type==EV_KEY && ev.key==JK_ESC)) { im=cash.img(cash.reg("art/help.spe","sell6",SPEC_IMAGE,1)); fade_in(im,16); do { eh->flush_screen(); eh->get_event(ev); } while (ev.type!=EV_KEY && ev.type!=EV_MOUSE_BUTTON); fade_out(16); } eh->set_mouse_shape(cash.img(c_normal)->copy(),1,1); #endif }
/* * Initialize the unwind table(s) in the best-case order: * * 1. Use the in-memory kernel and module unwind tables. * 2. Use the in-memory kernel-only .eh_frame data. (possible?) * 3. Use the kernel-only .eh_frame data from the vmlinux file. */ void init_unwind_table(void) { ulong unwind_table_size; void *unwind_table; kt->flags &= ~DWARF_UNWIND; if (gather_in_memory_unwind_tables()) { if (CRASHDEBUG(1)) fprintf(fp, "init_unwind_table: DWARF_UNWIND_MEMORY (%d tables)\n", unwind_tables_cnt); kt->flags |= DWARF_UNWIND_MEMORY; if (unwind_tables_cnt > 1) kt->flags |= DWARF_UNWIND_MODULES; if (!(kt->flags & NO_DWARF_UNWIND)) kt->flags |= DWARF_UNWIND; return; } if (symbol_exists("__start_unwind") && symbol_exists("__end_unwind")) { unwind_table_size = symbol_value("__end_unwind") - symbol_value("__start_unwind"); if (!(unwind_table = malloc(unwind_table_size))) { error(WARNING, "cannot malloc unwind table space\n"); goto try_eh_frame; } if (!readmem(symbol_value("__start_unwind"), KVADDR, unwind_table, unwind_table_size, "unwind table", RETURN_ON_ERROR)) { error(WARNING, "cannot read unwind table data\n"); free(unwind_table); goto try_eh_frame; } kt->flags |= DWARF_UNWIND_MEMORY; if (!(kt->flags & NO_DWARF_UNWIND)) kt->flags |= DWARF_UNWIND; default_unwind_table.size = unwind_table_size; default_unwind_table.address = unwind_table; if (CRASHDEBUG(1)) fprintf(fp, "init_unwind_table: DWARF_UNWIND_MEMORY\n"); return; } try_eh_frame: if (st->dwarf_eh_frame_size || st->dwarf_debug_frame_size) { int fd; int is_ehframe = (!st->dwarf_debug_frame_size && st->dwarf_eh_frame_size); unwind_table_size = is_ehframe ? st->dwarf_eh_frame_size : st->dwarf_debug_frame_size; if (!(unwind_table = malloc(unwind_table_size))) { error(WARNING, "cannot malloc unwind table space\n"); return; } if ((fd = open(pc->namelist, O_RDONLY)) < 0) { error(WARNING, "cannot open %s for %s data\n", pc->namelist, is_ehframe ? ".eh_frame" : ".debug_frame"); free(unwind_table); return; } if (is_ehframe) lseek(fd, st->dwarf_eh_frame_file_offset, SEEK_SET); else lseek(fd, st->dwarf_debug_frame_file_offset, SEEK_SET); if (read(fd, unwind_table, unwind_table_size) != unwind_table_size) { if (CRASHDEBUG(1)) error(WARNING, "cannot read %s data from %s\n", is_ehframe ? ".eh_frame" : ".debug_frame", pc->namelist); free(unwind_table); return; } close(fd); default_unwind_table.size = unwind_table_size; default_unwind_table.address = unwind_table; kt->flags |= DWARF_UNWIND_EH_FRAME; if (!(kt->flags & NO_DWARF_UNWIND)) kt->flags |= DWARF_UNWIND; if (CRASHDEBUG(1)) fprintf(fp, "init_unwind_table: DWARF_UNWIND_EH_FRAME\n"); return; } }
void jl_stop_parsing() { fl_applyn(0, symbol_value(symbol("jl-parser-close-stream"))); }
void status_bar::step() { if (!v) return ; if (!DEFINEDP(symbol_value(l_mouse_can_switch)) || !symbol_value(l_mouse_can_switch)) return ; int sb_w,sb_h; if (sbar>0 && total_weapons) { image *sb=cache.img(sbar); // status bar width & height sb_w=sb->Size().x; sb_h=sb->Size().y; } // see if the mouse is in the sbar region (demo_x already corrected for small_render) int sx1,sy1,sx2,sy2; area(sx1,sy1,sx2,sy2); int view_y2=small_render ? (v->cy2-v->cy1+1)*2+v->cy1 : v->cy2; if (sy1<view_y2) // tell view to shrink if it is overlapping the status bar { v->suggest.send_view=1; v->suggest.cx1=v->cx1; v->suggest.cy1=v->cy1; v->suggest.cx2=v->cx2; v->suggest.cy2=small_render ? (sy1-v->cy1-2)/2+v->cy1 : sy1-2; } if (sbar<=0 || !total_weapons) return ; int mx=small_render ? (last_demo_mx-v->cx1)*2+v->cx1 : last_demo_mx; int my=small_render ? (last_demo_my-v->cy1)*2+v->cy1 : last_demo_my; if (mx>sx1 && my>sy1 && mx<sx2 && my<sy2) { int new_target; mx-=sx1; if (small_render) mx/=2; mx-=47; if (mx<0) new_target=0; else { new_target=mx/33; if (new_target>=TOTAL_WEAPONS) new_target=TOTAL_WEAPONS-1; if (new_target>=total_weapons) new_target=total_weapons-1; } if (v->has_weapon(new_target) && new_target!=icon_in_selection) { icon_in_selection=new_target; need_refresh(); } if (last_demo_mbut==2 && icon_in_selection!=v->current_weapon && icon_in_selection!=-1) // the user requested a weapon change { v->suggest.send_weapon_change=1; v->suggest.new_weapon=icon_in_selection; } } else { if (icon_in_selection!=-1) { icon_in_selection=-1; need_refresh(); } } // see if a new weapon has been selected other than the one // we think is selected, if so redraw the status bar if (currently_selected_weapon!=v->current_weapon) { currently_selected_weapon=v->current_weapon; need_refresh(); } }
void jl_load_file_string(const char *text) { fl_applyn(1, symbol_value(symbol("jl-parse-string-stream")), cvalue_static_cstring(text)); jl_parse_eval_all(""); }
static int jl_parse_depwarn_(fl_context_t *fl_ctx, int warn) { value_t prev = fl_applyn(fl_ctx, 1, symbol_value(symbol(fl_ctx, "jl-parser-depwarn")), warn ? fl_ctx->T : fl_ctx->F); return prev == fl_ctx->T ? 1 : 0; }
static void FFN(Fdefun)(object args) { object name,oname; object body, form; if (endp(args) || endp(MMcdr(args))) FEtoo_few_argumentsF(args); if (MMcadr(args) != Cnil && !consp(MMcadr(args))) FEerror("~S is an illegal lambda-list.", 1, MMcadr(args)); oname=name = MMcar(args); if (type_of(name) != t_symbol) name=ifuncall1(sSfunid_to_sym,name); if (name->s.s_sfdef != NOT_SPECIAL) { if (name->s.s_mflag) { if (symbol_value(sSAinhibit_macro_specialA) != Cnil) name->s.s_sfdef = NOT_SPECIAL; } else if (symbol_value(sSAinhibit_macro_specialA) != Cnil) FEerror("~S, a special form, cannot be redefined.", 1, name); } if (name->s.s_hpack == lisp_package && name->s.s_gfdef != OBJNULL && !raw_image && sLwarn->s.s_gfdef) { vs_push(make_simple_string("~S is being redefined.")); ifuncall2(sLwarn, vs_head, name); vs_popp; } vs_base = vs_top; if (lex_env[0] == Cnil && lex_env[1] == Cnil && lex_env[2] == Cnil) { vs_push(MMcons(sLlambda_block, args)); } else { vs_push(MMcons(lex_env[2], args)); vs_base[0] = MMcons(lex_env[1], vs_base[0]); vs_base[0] = MMcons(lex_env[0], vs_base[0]); vs_base[0] = MMcons(sLlambda_block_closure, vs_base[0]); } {/* object fname; */ vs_base[0]=fSfset_in(name,vs_base[0]); /* object x=alloc_object(t_ifun); */ /* x->ifn.ifn_self=vs_base[0]; */ /* x->ifn.ifn_name=name; */ /* x->ifn.ifn_call=Cnil; */ /* vs_base[0]=x; */ /* fname = clear_compiler_properties(name,vs_base[0]); */ /* fname->s.s_gfdef = vs_base[0]; */ /* fname->s.s_mflag = FALSE; */ } vs_base[0] = oname; for (body = MMcddr(args); !endp(body); body = body->c.c_cdr) { form = macro_expand(body->c.c_car); if (type_of(form) == t_string) { if (endp(body->c.c_cdr)) break; vs_push(form); name->s.s_plist = putf(name->s.s_plist, form, sSfunction_documentation); vs_popp; break; } if (!consp(form) || form->c.c_car != sLdeclare) break; } }
void *ant_ai() { game_object *o=current_object,*b; if (o->hp()==0) // if we are dead return NULL and get deleted { if (o->state==dead) return NULL; else o->set_state(dead); return true_symbol; } if (o->state==flinch_up || o->state==flinch_down) { o->next_picture(); return true_symbol; } switch (o->aistate()) { case ANT_START : { o->set_state((character_state)S_hanging); if (o->lvars[ANT_hide_flag]) o->set_aistate(ANT_HIDING); else o->set_aistate(ANT_HANGING); } break; case ANT_HIDING : { if ((jrand()%128)==0) the_game->play_sound(S_SCARE_SND,127,o->x,o->y); if (o->otype!=S_HIDDEN_ANT) { o->change_type(S_HIDDEN_ANT); // switch types so noone hurts us. o->set_state(stopped); o->set_aistate(ANT_HIDING); } int fall=0; if (o->total_objects()==0) { if (player_list->next) b=current_level->attacker(current_object); else b=player_list->m_focus; if (abs(b->x-o->x)<130 && (o->y<b->y)) fall=1; } else if (o->get_object(0)->aistate()!=0) fall=1; if (fall) { o->change_type(S_ANT_ROOF); o->set_state((character_state)S_falling); o->set_aistate(ANT_FALL_DOWN); o->set_targetable(1); } else o->set_targetable(0); } break; case ANT_HANGING : { int fall=0; if ((jrand()%128)==0) the_game->play_sound(S_SCARE_SND,127,o->x,o->y); if (o->lvars[ANT_hide_flag]) o->set_aistate(ANT_HIDING); else { o->set_state((character_state)S_hanging); if (o->total_objects()) { if (o->get_object(0)->aistate()!=0) fall=1; } else { if (player_list->next) b=current_level->attacker(current_object); else b=player_list->m_focus; if (abs(b->x-o->x)<130 && (o->y<b->y)) fall=1; } if (fall) { o->set_state((character_state)S_fall_start); o->set_aistate(ANT_FALL_DOWN); o->set_targetable(1); } else o->set_targetable(0); } } break; case ANT_FALL_DOWN : { o->set_state((character_state)S_falling); if (player_list->next) b=current_level->attacker(current_object); else b=player_list->m_focus; scream_check(o,b); int ret=o->mover(0,0,0); if ((ret&BLOCKED_DOWN) || !can_see(o,o->x,o->y,o->x,o->y+1)) { o->set_state((character_state)S_landing); the_game->play_sound(S_ALAND_SND,127,o->x,o->y); o->set_aistate(ANT_LANDING); } } break; case ANT_LANDING : { if (!o->next_picture()) { int32_t xv=0,yv=2; o->try_move(o->x,o->y,xv,yv,1); if (yv!=0) { o->set_gravity(1); o->set_aistate(ANT_FALL_DOWN); } else { o->set_state(stopped); o->set_aistate(ANT_RUNNING); return (void *)ant_ai; } } } break; case ANT_RUNNING : { if (player_list->next) b=current_level->attacker(current_object); else b=player_list->m_focus; scream_check(o,b); if ((jrand()%16)==0) o->lvars[ANT_need_to_dodge]=1; if (!ant_dodge(o)) { if ((o->x>b->x && o->direction==-1) || (o->x<b->x && o->direction==1)) { o->next_picture(); if ((jrand()%4)==0 && abs(o->x-b->x)<180 && abs(o->y-b->y)<100 && can_hit_player(o,b)) { o->set_state((character_state)S_weapon_fire); o->set_aistate(ANT_FIRE); } else if (abs(o->x-b->x)<100 && abs(o->y-b->y)<10 && (jrand()%4)==0) o->set_aistate(ANT_POUNCE_WAIT); else if (abs(o->x-b->x)>140 && !ant_congestion(o)) o->set_aistate(ANT_JUMP); else { int32_t xm=o->direction>0 ? get_ability(o->otype,run_top_speed) : -get_ability(o->otype,run_top_speed); int32_t ym=0,new_xm=xm; if (o->state!=running) o->set_state(running); o->try_move(o->x,o->y,new_xm,ym,3); if (new_xm!=xm) // blocked, see if we can climb ramp { new_xm=xm; ym=-abs(xm); o->try_move(o->x,o->y,new_xm,ym,3); if (new_xm==xm) { o->x+=new_xm; o->y+=ym; new_xm=0; ym=abs(xm); // now get back on the ground o->try_move(o->x,o->y,new_xm,ym,3); o->x+=new_xm; o->y+=ym; } else { o->direction=0-o->direction; o->set_aistate(ANT_JUMP); } } else o->x+=new_xm; new_xm=0; ym=10; // see if we should fall o->try_move(o->x,o->y,new_xm,ym,3); if (ym==10) o->set_aistate(ANT_FALL_DOWN); else o->y+=ym; } } else { o->direction=o->x>b->x ? -1 : 1; o->set_aistate(ANT_LANDING); } } } break; case ANT_POUNCE_WAIT : { if (!ant_dodge(o)) { o->set_state((character_state)S_pounce_wait); if (o->aistate_time()>alien_wait_time()) { the_game->play_sound(S_ASLASH_SND,127,o->x,o->y); o->set_state(stopped); o->set_aistate(ANT_JUMP); } } } break; case ANT_JUMP : { o->lvars[ANT_need_to_dodge]=0; if (o->move(o->direction,-1,0)&BLOCKED_DOWN) o->set_aistate(ANT_RUNNING); } break; case ANT_FIRE : { if (!ant_dodge(o)) { if (o->state==S_fire_wait) { if (!o->next_picture() || symbol_value(l_difficulty)==l_extreme) { if (player_list->next) b=current_level->attacker(current_object); else b=player_list->m_focus; fire_at_player(o,b); o->set_state(stopped); o->set_aistate(ANT_RUNNING); } } else o->set_state((character_state)S_fire_wait); } } break; case ANT_JUMP_ROOF : { o->lvars[ANT_need_to_dodge]=0; o->set_state((character_state)S_jump_up); // o->set_yvel(o->yvel()+1); o->set_xacel(0); int32_t xv=0,yv=o->yvel(); o->y-=31; o->try_move(o->x,o->y,xv,yv,1); o->y+=31+yv; if (yv!=o->yvel()) { if (o->yvel()>0) { o->set_state(stopped); o->set_aistate(ANT_RUNNING); } else { o->set_state((character_state)S_top_walk); o->set_aistate(ANT_ROOF_WALK); } o->set_yvel(0); } } break; case ANT_ROOF_WALK : { if (player_list->next) b=current_level->attacker(current_object); else b=player_list->m_focus; scream_check(o,b); if (((jrand()%8)==0 && abs(o->x-b->x)<10 && o->y<b->y) || o->lvars[ANT_need_to_dodge]==1) { o->set_gravity(1); o->set_state(run_jump); o->set_aistate(ANT_JUMP); ant_ai(); } else { if ((o->x>b->x && o->direction>0) || (o->x<b->x && o->direction<0)) o->direction=-o->direction; else if (abs(o->x-b->x)<120 && (jrand()%4)==0) { o->set_state((character_state)S_ceil_fire); o->set_aistate(ANT_CEIL_SHOOT); ant_ai(); } else { int speed=o->direction>0 ? get_ability(o->otype,run_top_speed) : -get_ability(o->otype,run_top_speed); if (can_see(o,o->x,o->y-31,o->x+speed,o->y-31) && !can_see(o,o->x+speed,o->y-31,o->x+speed,o->y-32)) { o->x+=speed; if (!o->next_picture()) o->set_state((character_state)S_top_walk); } else o->set_aistate(ANT_FALL_DOWN); } } } break; case ANT_CEIL_SHOOT : { if (!o->next_picture()) { if (player_list->next) b=current_level->attacker(current_object); else b=player_list->m_focus; fire_at_player(o,b); o->set_state((character_state)S_top_walk); o->set_aistate(ANT_ROOF_WALK); } } break; } return true_symbol; }
struct lisp_object *c_eval(struct lisp_object *obj) { if (!obj) { lisp_error(); return NULL; } if (obj->quoted) { struct lisp_object *new_obj = lisp_object_deep_copy(obj); new_obj->quoted = C_FALSE; return new_obj; } switch (obj->obj_type) { case LIST: { struct lisp_object *ret = make_lisp_object(LIST, NULL); struct lisp_object *head = HEAD(obj); if (!head) { // It already is nil return ret; } struct lisp_object *func = c_eval(head); if (!func) { set_error("Function %s doesn't exist.", TOSTR(head)); return NULL; } if (func->obj_type != BUILTIN && func->obj_type != FUNCTION) { set_error("First object in list is not a function.", SYM_NAME(head)); return NULL; } /* Allocate an object to be used to store the copied arguments list */ struct lisp_object *args = make_lisp_object(LIST, NULL); if (head->next) { struct lisp_object *args_head; if (func->obj_type == BUILTIN && (TOBUILTIN(func)->spec & UNEVAL_ARGS)) { args_head = lisp_object_deep_copy(head->next); } else { args_head = c_eval(head->next); if (!args_head) { return NULL; } } args_head->next = NULL; args_head->prev = NULL; struct lisp_object *current = head->next->next; struct lisp_object *args_current = NULL; struct lisp_object *args_prev = args_head; while (current) { if (func->obj_type == BUILTIN && (TOBUILTIN(func)->spec & UNEVAL_ARGS)) { args_current = lisp_object_deep_copy(current); } else { args_current = c_eval(current); if (!args_current) { return NULL; } } args_current->prev = args_prev; args_current->next = NULL; args_prev->next = args_current; args_prev = args_current; current = current->next; } /* Finish constructing the arguments list */ args->data = args_head; } /* Perform the function call. */ if (func->obj_type == BUILTIN) { int count = list_length(args); struct lisp_builtin *builtin = TOBUILTIN(func); if (builtin->max_params != -1 && count > builtin->max_params) { set_error("Incorrect number of arguments (%d) to function %s!", count, TOSTR(head)); } if (builtin->min_params != -1 && count < builtin->min_params) { set_error("Incorrect number of arguments (%d) to function %s!", count, TOSTR(head)); } return builtin->func(args); } else if (func->obj_type == FUNCTION) { struct lisp_function *func_obj = TOFUNC(func); int count = list_length(args); char *func_name = head->obj_type == SYMBOL ? TOSTR(head) : "<unnamed lambda>"; if (count != func_obj->numparams) { set_error("Incorrect number of arguments (%d) to function %s!", count, func_name); return NULL; } int i = 0; struct lisp_object *params_current = HEAD(func_obj->params); struct lisp_object *args_current = HEAD(args); struct symbol *syms = malloc(sizeof(struct symbol)*count); while (params_current) { syms[i].symbol_name = SYM_NAME(params_current); syms[i].value = args_current; i++; params_current = params_current->next; args_current = args_current->next; } set_local_symbols(syms, count); struct lisp_object *form_current = func_obj->forms; struct lisp_object *sub = nil; while (form_current) { sub = c_eval(form_current); if (!sub) { return NULL; } // Keep track of the return value ret = sub; form_current = form_current->next; } unset_local_symbols(); free(syms); return ret; } } case SYMBOL: { /* Do a lookup of the symbol and return the value. */ struct lisp_object *value = symbol_value(SYM_NAME(obj)); if (!value) { set_error("Symbol %s does not exist!", SYM_NAME(obj)); } return value; } default: { return lisp_object_deep_copy(obj); } } }
void load_data(int argc, char **argv) { total_objects=0; total_weapons=0; weapon_types=NULL; figures=NULL; nforetiles=nbacktiles=0; foretiles=NULL; backtiles=NULL; pal=NULL; color_table=NULL; # if 0 int should_save_sd_cache = 0; char *cachepath; cachepath = (char *)malloc( strlen( get_save_filename_prefix() ) + 12 + 1 ); sprintf( cachepath, "%ssd_cache.tmp", get_save_filename_prefix() ); bFILE *load = open_file( cachepath, "rb" ); if( !load->open_failure() ) { sd_cache.load( load ); } else { should_save_sd_cache = 1; } delete load; #endif // don't let them specify a startup file we are connect elsewhere if (!net_start()) { for (int i=1; i<argc; i++) { if (!strcmp(argv[i],"-lsf")) { i++; strcpy(lsf,argv[i]); } if (!strcmp(argv[i],"-a")) { i++; snprintf(lsf, sizeof(lsf), "addon/%s/%s.lsp", argv[i], argv[i]); } } } else if (!get_remote_lsf(net_server,lsf)) { dprintf("Unable to get remote lsf from %s\n",net_server); exit(0); } char prog[100]; char const *cs; c_mouse1=cache.reg("art/dev.spe","c_mouse1",SPEC_IMAGE,0); c_mouse2=cache.reg("art/dev.spe","c_mouse2",SPEC_IMAGE,0); c_normal=cache.reg("art/dev.spe","c_normal",SPEC_IMAGE,0); c_target=cache.reg("art/dev.spe","c_target",SPEC_IMAGE,0); snprintf(prog, sizeof(prog), "(load \"%s\")\n", lsf); cs=prog; if (!LObject::Compile(cs)->Eval()) { printf("unable to open file '%s'\n",lsf); exit(0); } compiled_init(); LSpace::Tmp.Clear(); dprintf("Engine : Registering base graphics\n"); for (int z=0; z<=11; z++) { char nm[10]; snprintf(nm, sizeof(nm), "l%d", z); light_buttons[z]=cache.reg("art/dev.spe",nm,SPEC_IMAGE,0); } image *tmp_image = new image(ivec2(192, 104), fnt6x13); big_font=new JCFont(tmp_image); delete tmp_image; char const *ff; // FIXME: unnecessary duplicate call if (DEFINEDP(LSymbol::FindOrCreate("frame_file")->GetValue())) ff = lstring_value(LSymbol::FindOrCreate("frame_file")->GetValue()); else ff = "art/frame.spe"; ok_button = cache.reg(ff,"dev_ok",SPEC_IMAGE); cancel_button = cache.reg(ff,"cancel",SPEC_IMAGE); // clouds = cache.reg(ff,"clouds",SPEC_IMAGE); lower_volume= cache.reg(ff,"lower_volume",SPEC_IMAGE); raise_volume= cache.reg(ff,"raise_volume",SPEC_IMAGE); music_button= cache.reg(ff,"music",SPEC_IMAGE); sfx_button= cache.reg(ff,"sound_fx",SPEC_IMAGE); record_button= cache.reg(ff,"record",SPEC_IMAGE); play_button= cache.reg(ff,"play",SPEC_IMAGE); window_colors= cache.reg(ff,"window_colors",SPEC_IMAGE); pause_image= cache.reg(ff,"pause_image",SPEC_IMAGE); vmm_image= cache.reg(ff,"vmm",SPEC_IMAGE); border_tile= cache.reg(ff,"border_tile",SPEC_IMAGE); window_texture= cache.reg(ff,"window_texture",SPEC_IMAGE); help_screens=NULL; total_help_screens=0; if (DEFINEDP(symbol_value(l_help_screens))) { void *v=symbol_value(l_help_screens); char *ff=lstring_value(CAR(v)); v=CDR(v); total_help_screens=0; while (v) { total_help_screens++; v=CDR(v); } if (total_help_screens) { help_screens=(int *)malloc(sizeof(int)*total_help_screens); v=CDR(symbol_value(l_help_screens)); int i=0; for (; v; v=CDR(v),i++) help_screens[i]=cache.reg(ff,lstring_value(CAR(v)),SPEC_IMAGE); } else dprintf("Warning no help images following filename\n"); } int i; for (i=1; i<argc; i++) { if (!strcmp(argv[i],"-ec")) l_empty_cache->SetValue(true_symbol); if (!strcmp(argv[i],"-t")) { i++; insert_tiles(argv[i]); } } if (DEFINEDP(symbol_value(l_title_screen))) title_screen=cache.reg_object(NULL,(LObject *)symbol_value(l_title_screen),SPEC_IMAGE,1); else title_screen=-1; if (DEFINEDP(symbol_value(l_cdc_logo))) cdc_logo=cache.reg_object(NULL,(LObject *)symbol_value(l_cdc_logo),SPEC_IMAGE,1); else cdc_logo=-1; start_position_type=0xffff; for(i=0; i<total_objects; i++) if (!strcmp(object_names[i],"START")) start_position_type=i; if (start_position_type==0xffff) { printf("No object named START, cannot start game.\n"); exit(0); } sbar.load(); load_number_icons(); ERROR(nbacktiles,"No background tiles defined!"); ERROR(nforetiles,"No foreground tiles defined!"); ERROR(foretiles[0]>=0,"No black (0) foreground tile defined!"); ERROR(backtiles[0]>=0,"No black (0) background tile defined!"); ERROR(big_font_pict!=-1 || small_font_pict!=-1, "No font loaded (use load_big_font or load_small_font)!"); f_wid=cache.foret(foretiles[0])->im->Size().x; f_hi=cache.foret(foretiles[0])->im->Size().y; b_wid=cache.backt(backtiles[0])->im->Size().x; b_hi=cache.backt(backtiles[0])->im->Size().y; #if 0 if( should_save_sd_cache ) { bFILE *save = open_file( cachepath, "wb" ); if( !save->open_failure() ) { sd_cache.save( save ); } delete save; } #endif sd_cache.clear(); past_startup = 1; #if 0 free( cachepath ); #endif }