cake
/
libg1m
Archived
1
0
Fork 0

Implemented matrixes and correct CAS type decoding.

This commit is contained in:
Thomas Touhey 2017-03-10 13:32:27 +01:00
parent 795c9638c6
commit a3d708c766
7 changed files with 122 additions and 32 deletions

View File

@ -55,7 +55,7 @@ struct caspro_header {
};
/* ************************************************************************** */
/* Variable/number */
/* Variable */
/* ************************************************************************** */
/* Variable has the following structure (described in a comment):
*
@ -73,6 +73,26 @@ struct caspro_header {
*
* uint8_t checksum;
* The checksum (calculated as for the header). */
/* ************************************************************************** */
/* Matrix/List */
/* ************************************************************************** */
/* The matrix height is stored in `used`, and its width is stored in the low
* byte of `length`. For the list, only the height is used (`used`).
*
* There aren't any imaginary parts in matrixes and lists (and this wasn't made
* possible until CASIOWIN 2.00, so a long time after). Each value (line by
* line) is sent as an independent cell, which has this format: */
struct caspro_cell {
/* coordinates */
uint16_t y, x;
/* the value */
cas_bcd_t val;
/* the checksum */
uint8_t checksum;
};
/* TODO: other file formats */
# pragma pack()

View File

@ -153,6 +153,7 @@ int g1m_decode_cashpart_##NAME(g1m_mcshead_t *head, g1m_mcshead_t *heads, \
G1M_CASFUNC(var)
G1M_CASFUNC(program)
G1M_CASHFUNC(program)
G1M_CASFUNC(matrix)
/* ************************************************************************** */
/* Picture utilities */
/* ************************************************************************** */

View File

@ -82,6 +82,7 @@ typedef struct g1m_mcs_cell_s {
/* mcs file head flags */
# define g1m_mcsflag_unfinished 0x8000 /* is there still parts to read? */
# define g1m_mcsflag_multiple 0x4000 /* is a group */
# define g1m_mcsflag_request 0x2000 /* is a request */
# define g1m_mcsflag_complex 0x0001 /* is a complex variable */
/* mcs file type -- what type of raw information is there
@ -110,7 +111,7 @@ typedef struct g1m_mcshead_s {
unsigned char _group[17], _dirname[9];
/* cas-related raw data */
unsigned char _maintype[4];
unsigned char _appname[4];
unsigned char _datatype[3];
/* the program password */

View File

@ -47,6 +47,8 @@ struct cas_corresp {
static struct cas_corresp cas_types[] = {
{g1m_mcstype_var, FUNC(var), NULL},
{g1m_mcstype_program, FUNC(program), HFUNC(program)},
{g1m_mcstype_matrix, FUNC(matrix), NULL},
{g1m_mcstype_list, FUNC(matrix), NULL},
TTERM
};
@ -115,6 +117,14 @@ static int decode_caspro_head(g1m_mcshead_t *head, struct caspro_header *hd)
/* TODO: id */
head->count = 1;
break;
case g1m_mcstype_matrix:
head->height = hd->used;
head->width = be16toh(hd->length) & 0xFF;
break;
case g1m_mcstype_list:
head->height = hd->used;
head->width = 1;
break;
}
/* TODO */

View File

@ -104,3 +104,41 @@ fail:
*handle = NULL;
return (err);
}
/**
* g1m_decode_caspart_matrix:
* Decode a CAS matrix part.
*
* @arg handle the handle to contribute to.
* @arg buffer the buffer to read from.
* @return the error code (0 if ok).
*/
int g1m_decode_caspart_matrix(g1m_mcsfile_t *handle, g1m_buffer_t *buffer)
{
/* get content */
DREAD(cell, caspro_cell)
/* check the cell */
uint8_t csum = ~g1m_checksum8(&cell, sizeof(struct caspro_cell) - 1) + 1;
if (csum != cell.checksum)
return (g1m_error_checksum);
/* decode */
cell.y = be16toh(cell.y);
cell.x = be16toh(cell.x);
g1m_bcd_t bcd; g1m_bcd_fromcas(&cell.val, &bcd);
handle->cells[cell.y][cell.x] = (g1m_mcs_cell_t){
.real = bcd,
.imgn = {},
.used = 1
};
/* check if its the last cell */
if (cell.y == handle->head.height - 1
&& cell.x == handle->head.width - 1)
handle->head.flags &= ~g1m_mcsflag_unfinished;
/* no error! */
return (0);
}

View File

@ -41,8 +41,12 @@ struct type_corresp {
#define TTERM {NULL, 0, 0}
static struct type_corresp cas_groups[] = {
/* implemented */
{"LT", g1m_mcstype_list, 0}, // list
{"MT", g1m_mcstype_matrix, 0}, // matrix
{"P1", g1m_mcstype_program, 0}, // one program
{"PG", g1m_mcstype_program, 0}, // same than above
{"PZ", g1m_mcstype_program, g1m_mcsflag_multiple}, // set of programs
{"VM", g1m_mcstype_variable, 0}, // one variable
/* not implemented yet */
{"AA", 0, 0}, // dynamic graph functions
@ -54,18 +58,26 @@ static struct type_corresp cas_groups[] = {
{"DD", 0, 0}, // screenshot
{"EN", 0, 0}, // one editor file
{"FN", 0, 0}, // set of editor files
{"FT", 0, 0}, // ??? (cafix)
{"F1", 0, 0}, // one function memory
{"F6", 0, 0}, // set of function memories
{"GA", 0, 0}, // set of graph functions
{"GF", 0, 0}, // graph zoom factor (graph function?)
{"GM", 0, 0}, // gmem (cafix)
{"GR", 0, 0}, // graph range
{"GT", 0, 0}, // function table
{"MA", 0, 0}, // set of matrices
{"PC", 0, 0}, // picture from 9xxx (cafix)
{"PD", 0, 0}, // polynomial equations
{"RF", 0, 0}, // ??? (cafix)
{"RR", 0, 0}, // ??? (cafix)
{"RT", 0, 0}, // recursion table
{"SD", 0, 0}, // simultaneous equations
{"SE", 0, 0}, // equation (cafix)
{"SR", 0, 0}, // linear regression data
{"SS", 0, 0}, // standard deviation data
{"TR", 0, 0}, // ??? (cafix)
{"WD", 0, 0}, // window data (cafix)
/* terminating entry */
TTERM

View File

@ -22,13 +22,15 @@
/* Local types */
/* ************************************************************************** */
/* Correspondance type */
struct type_corresp {
#define flg_type 0x0001 /* if not there, the type is defined by the datatype */
#define flg_flags 0x0002 /* the following value is the flag to OR. */
struct app_corresp {
/* identification */
const char *maintype;
const char *datatype;
const char *name;
/* libg1m MCS file type */
g1m_mcstype_t type;
/* values */
unsigned int flags; /* the internal flags */
unsigned long int value; /* meaning of this depends on the flags */
};
/* ************************************************************************** */
@ -38,12 +40,12 @@ struct type_corresp {
* - Correspondances with a NULL data type means the data type isn't to be
* read. */
#define TTERM {NULL, NULL, 0}
static struct type_corresp cas_types[] = {
{"TXT", "PG", g1m_mcstype_program},
{"VAL", "VM", g1m_mcstype_variable},
{"END", NULL, g1m_mcstype_end},
//{"VAL", "MT", g1m_mcstype_matrix},
#define TTERM {NULL, 0, 0}
static struct app_corresp apps[] = {
{"TXT", 0, 0}, /* editor */
{"VAL", 0, 0}, /* RUN? */
{"REQ", flg_flags, g1m_mcsflag_request}, /* request */
{"END", flg_type, g1m_mcstype_end}, /* end */
/* terminating entry */
TTERM
@ -57,38 +59,44 @@ static struct type_corresp cas_types[] = {
* Get the libg1m MCS type from raw CAS identification data.
*
* @arg head the head to fill.
* @arg maintype the main type string.
* @arg app the app string.
* @arg datatype the data type string.
* @return the error (if any).
*/
int g1m_maketype_caspro(g1m_mcshead_t *head,
const char *maintype, const char *datatype)
const char *app, const char *datatype)
{
/* copy raw information */
memset(head, 0, sizeof(g1m_mcshead_t));
head->flags |= g1m_mcsinfo_caspro;
memcpy(head->_maintype, maintype, 3);
head->_maintype[3] = 0;
memcpy(head->_datatype, datatype, 2);
head->_datatype[2] = 0;
/* look for correspondance */
struct type_corresp *c;
for (c = cas_types; c->datatype; c++) {
if ((!c->maintype || !strncmp(maintype, c->maintype, 4))
&& (!c->datatype || !strncmp(datatype, c->datatype, 3)))
/* look for the app */
struct app_corresp *a;
for (a = apps; a->name; a++) {
if (!strncmp(a->name, app, 3))
break;
}
if (!c->maintype) goto notfound;
if (!a->name) goto notfound;
/* check if we need the datatype */
if (a->flags & flg_type) {
memset(head, 0, sizeof(g1m_mcshead_t));
head->type = a->value;
memcpy(head->_appname, app, 3); head->_appname[3] = 0;
} else {
int err = g1m_maketype_cas(head, datatype);
if (err) return (err);
}
/* copy raw information */
head->flags = (head->flags & ~g1m_mcsmask_info) | g1m_mcsinfo_caspro;
memcpy(head->_appname, app, 3); head->_appname[3] = 0;
if (a->flags & flg_flags)
head->flags |= (unsigned int)a->value;
/* fill in info and return */
head->type = c->type;
return (0);
notfound:
log_info("Type with '%.4s' data string was not implemented or not "
"recognized.", datatype);
log_info("Type with '%.3s' app name and '%.2s' data string was not"
"implemented or recognized.", app, datatype);
head->type = 0;
return (1);
}