/* User Extensions */ // Definitions void SDWriteTwo (File file, uint16_t word) { file.write(word & 0xFF); file.write((word >> 8) & 0xFF); } object *fn_savescreen (object *args, object *env) { (void) env; #if defined(sdcardsupport) object *arg = checkstring(first(args)); SDBegin(); File file; char buffer[BUFFERSIZE]; file = SD.open(MakeFilename(arg, buffer), FILE_WRITE); if (!file) error2(PSTR("problem saving to SD card or invalid filename")); uint16_t width = 320, height = 240; file.write('B'); file.write('M'); // BMP SDWriteInt(file, 14+40+width*height*2); // File size in bytes SDWriteInt(file, 0); SDWriteInt(file, 14+40); // Offset to image data from start // Image header: 40 bytes SDWriteInt(file, 40); // Header size SDWriteInt(file, width); // Image width SDWriteInt(file, height); // Image height SDWriteTwo(file, 1); // Planes SDWriteTwo(file, 16); // Bits per pixel SDWriteInt(file, 0); // Compression (none) SDWriteInt(file, 0); // Image size (0 for uncompressed) SDWriteInt(file, 0); // Preferred X resolution (ignore) SDWriteInt(file, 0); // Preferred Y resolution (ignore) SDWriteInt(file, 0); // Colour map entries (ignore) SDWriteInt(file, 0); // Important colours (ignore) // Image data: width * height * 2 bytes for (int y=height-1; y>=0; y--) { int line = y/Leading, row = y%Leading; for (int x=0; x=5 || row>=8) bit = 0; else bit = font[(c & 0x7f)*5 + col] >> row & 1; uint16_t rgb; if (c & 0x80 && row<8) { if (bit) rgb = COLOR_BLACK; else rgb = COLOR_GREEN; } else { if (bit) rgb = COLOR_WHITE; else rgb = COLOR_BLACK; } uint16_t data = (rgb & 0xFFC0)>>1 | (rgb & 0x1F); // Convert to 555 format SDWriteTwo(file, data); } } file.close(); #endif return nil; } void hyperprint (object *form, int lm, pfun_t pfun) { if (atom(form)) { if (isbuiltin(form, NOTHING)) printsymbol(form, pfun); else printobject(form, pfun); } else if (quoted(form)) { pfun('\''); hyperprint(car(cdr(form)), lm + 1, pfun); } else { lm = lm + PPINDENT; bool fits = (subwidth(form, PPWIDTH - lm - PPINDENT) >= 0); int special = 0, extra = 0; bool separate = true; object *arg = car(form); if (symbolp(arg) && builtinp(arg->name)) { uint8_t minmax = getminmax(builtin(arg->name)); if (minmax == 0327 || minmax == 0313) special = 2; // defun, setq, setf, defvar else if (minmax == 0317 || minmax == 0017 || minmax == 0117 || minmax == 0123) special = 1; } while (form != NULL) { if (atom(form)) { pfstring(PSTR(" . "), pfun); printobject(form, pfun); pfun(')'); return; } else if (separate) { pfun('('); separate = false; } else if (special) { pfun(' '); special--; } else if (fits) { pfun(' '); } else { pln(pfun); indent(lm, ' ', pfun); } hyperprint(car(form), lm+extra, pfun); form = cdr(form); } pfun(')'); } } object *fn_sym_def (object *args, object *env) { (void) env; object *obj = first(args); pfun_t pfun = pstreamfun(cdr(args)); #if defined(gfxsupport) if (pfun == gfxwrite) ppwidth = GFXPPWIDTH; #endif object *pair = findvalue(obj, env); object *var = car(pair); object *val = cdr(pair); pln(pfun); if (consp(val) && symbolp(car(val)) && builtin(car(val)->name) == LAMBDA) { hyperprint(cons(bsymbol(DEFUN), cons(var, cdr(val))), 0, pfun); } else { hyperprint(cons(bsymbol(DEFVAR), cons(var, cons(quote(val), NULL))), 0, pfun); } pln(pfun); ppwidth = PPWIDTH; return bsymbol(NOTHING); } // Symbol names const char string_sym_def[] PROGMEM = "symbol-def"; const char stringsavescreen[] PROGMEM = "save-screen"; // Documentation strings const char doc_sym_def[] PROGMEM = "(symbol-def symbol [str])\n" "Prints the definition of a symbol (variable or function) defined in ulisp using the pretty printer." "If str is specified it prints to the specified stream. It returns no value."; // const char docsavescreen[] PROGMEM = "(save-screen filename)\n" "Saves an image of the text screen as a BMP file on the SD card."; // Symbol lookup table const tbl_entry_t lookup_table2[] PROGMEM = { { stringsavescreen, fn_savescreen, 0211, docsavescreen }, { string_sym_def, fn_sym_def, 0212, doc_sym_def } }; // Table cross-reference functions tbl_entry_t *tables[] = {lookup_table, lookup_table2}; const unsigned int tablesizes[] = { arraysize(lookup_table), arraysize(lookup_table2) }; const tbl_entry_t *table (int n) { return tables[n]; } unsigned int tablesize (int n) { return tablesizes[n]; }