static int recv_screen (CalcHandle* handle, CalcScreenCoord* sc, uint8_t** bitmap) { uint32_t size = 0; uint8_t cmd, *data; int retval; int type; CalcInfos infos; // First of all, we have to identify the Nspire model. retval = get_version(handle, &infos); if (!retval) { if (infos.bits_per_pixel == 4) { // Nspire (CAS) Clickpad or Touchpad. type = 0; } else if (infos.bits_per_pixel == 16) { // Nspire (CAS) CX. type = 1; } else { ticalcs_critical(_("Unknown calculator model with %d bpp\n"), infos.bits_per_pixel); return ERR_UNSUPPORTED; // THIS RETURNS ! } // Do screenshot TRYF(nsp_session_open(handle, SID_SCREEN_RLE)); TRYF(nsp_cmd_s_screen_rle(handle, 0)); TRYF(nsp_cmd_r_screen_rle(handle, &cmd, &size, &data)); sc->width = sc->clipped_width = (data[8] << 8) | data[9]; sc->height = sc->clipped_height = (data[10] << 8) | data[11]; //size = GUINT32_FROM_BE(*((uint32_t *)(data))); size = ( (((uint32_t)data[0]) << 24) | (((uint32_t)data[1]) << 16) | (((uint32_t)data[2]) << 8) | (((uint32_t)data[3]) )); TRYF(nsp_cmd_r_screen_rle(handle, &cmd, &size, &data)); TRYF(nsp_session_close(handle)); *bitmap = rle_uncompress(sc, data, size, type); g_free(data); if(*bitmap == NULL) { return ERR_MALLOC; } retval = 0; } return retval; }
static DECL_SYMBOL_ACTION(emulate_set_mem) { char *str, *typ; int addr; char hexstr[256]; char memtyp[4]; mem_domain dmn; u8 vector[64]; u8 rle[64]; int vectorlen, rlelen, idx; bool force; if (task == csa_READ) { static int saveaddr; u8 verify[64]; /* Write memory to a hex string, CPU RAM followed by VDP RAM */ if (!iter) saveaddr = 0; addr = saveaddr; // spit out 64 bytes at a time if (addr < 65536) { /* Note: this may not seem right, when we could have a * MemoryEntry for a MEMENT_STORED RAM block covering * this area already, but this preserves the state of * that RAM at the time of the session being saved. */ mrstruct *mrarea; while (!HAS_RAM_ACCESS(md_cpu, addr)) addr = (addr & ~4095) + 4096; dmn = md_cpu; mrarea = THE_AREA(md_cpu, addr); memtyp[0] = 'C'; memtyp[1] = 0; // not compressed memtyp[2] = 0; } else if (addr < 65536 + 16384) { addr -= 65536; memtyp[0] = 'V'; memtyp[1] = 0; // not compressed memtyp[2] = 0; dmn = md_video; } else { return 0; } command_arg_set_num(sym->args->next, addr); /* Read 64 bytes from memory */ vectorlen = 0; do { vector[vectorlen++] = domain_read_byte(dmn, addr); addr++; } while (addr & 63); /* RLE compress the vector */ rlelen = rle_compress(vector, vectorlen, rle, sizeof(rle)); /* Returns zero if it couldn't compress any */ if (rlelen) { memtyp[1] = '*'; // compressed rle_uncompress(rle, rlelen, verify, sizeof(verify)); if (memcmp(vector, verify, vectorlen)) { command_logger(_L|LOG_ABORT, _("Mismatched on RLE compress:\n" "In : %s\n" "Out: %s\n" "Ver: %s\n"), emulate_bin2hex(vector, 0L, vectorlen), emulate_bin2hex(rle, 0L, rlelen), emulate_bin2hex(verify, 0L, sizeof(verify))); } } else { rlelen = vectorlen; memcpy(rle, vector, rlelen); } str = hexstr; idx = 0; while (idx < rlelen) { u8 byt; byt = rle[idx++]; *str++ = NUMHEX(byt>>4); *str++ = NUMHEX(byt&0xf); } *str = 0; saveaddr = addr + (dmn == md_video ? 65536 : 0); command_arg_set_string(sym->args, memtyp); command_arg_set_string(sym->args->next->next, hexstr); return 1; } // write memory command_arg_get_string(sym->args, &typ); command_arg_get_num(sym->args->next, &addr); addr &= 0xffff; command_arg_get_string(sym->args->next->next, &str); // get memory type dmn = emulate_parse_mem_type(typ, &force); if ((int)dmn < 0) return 0; // decode string, assuming it's rle-encoded rlelen = 0; while (*str) { u8 byt = (HEXNUM(*str) << 4) + HEXNUM(*(str+1)); rle[rlelen++] = byt; str+=2; } // second char of memory type indicates compression if (typ[1] && typ[1] == '*') { vectorlen = rle_uncompress(rle, rlelen, vector, sizeof(vector)); } else { memcpy(vector, rle, rlelen); vectorlen = rlelen; } idx = 0; while (idx < vectorlen) { domain_write_byte(dmn, addr, vector[idx++]); addr++; } return 1; }