Added Main ID distinguishment
This commit is contained in:
parent
2baded1666
commit
b98ca3b0ee
|
@ -0,0 +1,11 @@
|
|||
# TODO in libg1m
|
||||
## Find out what these formats are/how to parse them
|
||||
- G1L (languages for fx calculators?);
|
||||
- G1N (???);
|
||||
- G3L (languages for cg calculators);
|
||||
- G3M (like G1M?);
|
||||
|
||||
## Correct the parsing of these formats
|
||||
- G1M (BCD, other subtypes);
|
||||
- G1A/G3A (addins for fx and cg calculators);
|
||||
- G3P (pictures).
|
|
@ -20,32 +20,7 @@
|
|||
* In fact, there is no name for the general format, only names for the
|
||||
* "subformats" based on this one.
|
||||
*
|
||||
* Here's a complete list of the declinations and corresponding IDs: */
|
||||
|
||||
enum g1m_type {
|
||||
/* fx-CG add-in */
|
||||
g1m_typ_addin_cg = 0x2c,
|
||||
|
||||
/* mcs (main memory) save */
|
||||
g1m_typ_mcs = 0x31,
|
||||
|
||||
/* e-activity (document) */
|
||||
g1m_typ_eact = 0x49,
|
||||
|
||||
/* g1r equivalent */
|
||||
g1m_typ_g2r = 0x62,
|
||||
|
||||
/* g3m (fx-CG program) */
|
||||
g1m_typ_g3m = 0x75,
|
||||
|
||||
/* g3p (fx-CG picture) */
|
||||
g1m_typ_g3p = 0x7d,
|
||||
|
||||
/* add-in (compiled program) */
|
||||
g1m_typ_addin = 0xf3,
|
||||
};
|
||||
|
||||
/* It all starts with a header, called Standard Header by Simon Lothar.
|
||||
* It all starts with a header, called Standard Header by Simon Lothar.
|
||||
* This Standard Header contains the total filesize, the G1M type (add-in,
|
||||
* MCS, e-acts), some data that will be useful for the MCS type, and some
|
||||
* magic and control bytes.
|
||||
|
@ -57,7 +32,7 @@ enum g1m_type {
|
|||
* it can simply be obtained bitwise-AND-ing with 0xff. */
|
||||
|
||||
struct standard_header {
|
||||
/* the file identifier, should be "USBPower". */
|
||||
/* the file identifier - see below */
|
||||
uint8_t main_id[8];
|
||||
|
||||
/* our filetype! */
|
||||
|
@ -90,6 +65,52 @@ struct standard_header {
|
|||
uint16_t number;
|
||||
};
|
||||
|
||||
/* At the beginning, we thought "USBPower" was some magic sequence we would
|
||||
* systematically find in the "main_id" field. But a counter example came:
|
||||
* the G3L, where the main ID was "Ly755 ".
|
||||
*
|
||||
* So here are the known main IDs: */
|
||||
|
||||
enum g1m_main_id {
|
||||
/* "USBPower": the most common one */
|
||||
g1m_mid_usbpower,
|
||||
|
||||
/* "Ly755 ": fx-CG specific types */
|
||||
g1m_mid_ly755,
|
||||
};
|
||||
|
||||
/* Here are USBPower types: */
|
||||
|
||||
enum g1m_usbpower_type {
|
||||
/* fx-CG add-in */
|
||||
g1m_usbpower_type_addin_cg = 0x2c,
|
||||
|
||||
/* mcs (main memory) save */
|
||||
g1m_usbpower_type_mcs = 0x31,
|
||||
|
||||
/* e-activity (document) */
|
||||
g1m_usbpower_type_eact = 0x49,
|
||||
|
||||
/* g1r equivalent */
|
||||
g1m_usbpower_type_g2r = 0x62,
|
||||
|
||||
/* g3m (fx-CG program) */
|
||||
g1m_usbpower_type_g3m = 0x75,
|
||||
|
||||
/* g3p (fx-CG picture) */
|
||||
g1m_usbpower_type_g3p = 0x7d,
|
||||
|
||||
/* add-in (compiled program) */
|
||||
g1m_usbpower_type_addin = 0xf3,
|
||||
};
|
||||
|
||||
/* And here are Ly755 types: */
|
||||
|
||||
enum g1m_ly755_type {
|
||||
/* language file */
|
||||
g1m_ly755_type_lang = 0x2c
|
||||
};
|
||||
|
||||
# pragma pack()
|
||||
|
||||
/* After the Standard Header is read and the G1M type is read, we have parts,
|
||||
|
|
|
@ -55,7 +55,7 @@
|
|||
|
||||
/* Functions prototypes */
|
||||
void g1m_log_mem(const char *prefix, void *m, size_t n);
|
||||
const char *g1m_get_type_string(int code);
|
||||
const char *g1m_get_type_string(int main_id, int type);
|
||||
const char *g1m_get_mcs_ftype_string(int code);
|
||||
const char *g1m_get_eact_ltype_string(int code);
|
||||
|
||||
|
|
|
@ -135,17 +135,25 @@ void g1m_log_mem(const char *prefx, void *m, size_t n)
|
|||
* @return the string.
|
||||
*/
|
||||
|
||||
const char *g1m_get_type_string(int code)
|
||||
const char *g1m_get_type_string(int main_id, int type)
|
||||
{
|
||||
switch (code) {
|
||||
case g1m_typ_addin_cg: return ("fx-CG addin");
|
||||
case g1m_typ_mcs: return ("mcs");
|
||||
case g1m_typ_eact: return ("e-activity");
|
||||
case g1m_typ_g2r: return ("mcs (g2r)");
|
||||
case g1m_typ_g3p: return ("g3p");
|
||||
case g1m_typ_addin: return ("addin");
|
||||
default: return ("unknown");
|
||||
switch (main_id) {
|
||||
case g1m_mid_usbpower:
|
||||
switch (type) {
|
||||
case g1m_usbpower_type_addin_cg: return ("fx-CG addin");
|
||||
case g1m_usbpower_type_mcs: return ("mcs");
|
||||
case g1m_usbpower_type_eact: return ("e-activity");
|
||||
case g1m_usbpower_type_g2r: return ("mcs (g2r)");
|
||||
case g1m_usbpower_type_g3p: return ("g3p");
|
||||
case g1m_usbpower_type_addin: return ("addin");
|
||||
}
|
||||
break;
|
||||
case g1m_mid_ly755:
|
||||
switch (type) {
|
||||
case g1m_ly755_type_lang: return ("fx-CG language file");
|
||||
}
|
||||
}
|
||||
return ("unknown");
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -9,6 +9,23 @@
|
|||
/* ************************************************************************** */
|
||||
#include <libg1m/internals.h>
|
||||
|
||||
/**
|
||||
* get_main_id:
|
||||
* Get numerical main ID based on the main ID string.
|
||||
*
|
||||
* @arg s the 8-bytes buffer containing the ID.
|
||||
* @return the main ID or -1 if the main ID is unknown.
|
||||
*/
|
||||
|
||||
static int get_main_id(unsigned char *s)
|
||||
{
|
||||
if (!memcmp(s, "USBPower", 8))
|
||||
return (g1m_mid_usbpower);
|
||||
if (!memcmp(s, "Ly755 ", 8))
|
||||
return (g1m_mid_ly755);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/**
|
||||
* g1m_parse:
|
||||
* Parse a G1M file.
|
||||
|
@ -50,37 +67,56 @@ int g1m_parse(g1m_t *handle, FILE *stream)
|
|||
return (g1m_error_magic);
|
||||
}
|
||||
|
||||
/* get the main ID */
|
||||
int main_id = get_main_id(hd.main_id);
|
||||
if (main_id < 0) {
|
||||
log_fatal("Main ID is unknown: '%.8s'", hd.main_id);
|
||||
return (g1m_error_magic);
|
||||
}
|
||||
|
||||
/* log some data */
|
||||
log_info("Standard Header Main ID is '%.8s'", hd.main_id);
|
||||
log_info("Standard Header Type is '%s' (0x%02x)",
|
||||
g1m_get_type_string(hd.type), hd.type);
|
||||
g1m_get_type_string(main_id, hd.type), hd.type);
|
||||
log_info("Standard Header filesize is %uo", hd.filesize);
|
||||
log_info("Standard Header num is %d.", hd.number);
|
||||
|
||||
/* subparse. */
|
||||
handle->is_cg = 0;
|
||||
switch (hd.type) {
|
||||
case g1m_typ_addin:
|
||||
switch (main_id) {
|
||||
case g1m_mid_usbpower:
|
||||
switch (hd.type) {
|
||||
case g1m_usbpower_type_addin:
|
||||
handle->type = g1m_type_addin;
|
||||
return (g1m_parse_addin(handle, stream));
|
||||
case g1m_typ_addin_cg:
|
||||
case g1m_usbpower_type_addin_cg:
|
||||
handle->type = g1m_type_addin;
|
||||
handle->is_cg = 1;
|
||||
return (g1m_parse_addin_cg(handle, stream, &hd));
|
||||
case g1m_typ_g2r:
|
||||
case g1m_typ_mcs:
|
||||
case g1m_usbpower_type_g2r:
|
||||
case g1m_usbpower_type_mcs:
|
||||
handle->type = g1m_type_mcs;
|
||||
return (g1m_parse_mcs(handle, stream, hd.number));
|
||||
case g1m_typ_eact:
|
||||
case g1m_usbpower_type_eact:
|
||||
handle->type = g1m_type_eact;
|
||||
return (g1m_parse_eact(handle, stream));
|
||||
case g1m_typ_g3p:
|
||||
case g1m_usbpower_type_g3p:
|
||||
handle->type = g1m_type_pict;
|
||||
handle->is_cg = 1;
|
||||
return (g1m_parse_g3p(handle, stream, &hd));
|
||||
default:
|
||||
log_info("Type not managed (yet?): 0x%02x", hd.type);
|
||||
}
|
||||
break;
|
||||
case g1m_mid_ly755:
|
||||
switch (hd.type) {
|
||||
case g1m_ly755_type_lang:
|
||||
log_info("Lang type isn't managed yet.");
|
||||
break;
|
||||
default:
|
||||
log_info("Type not managed (yet?): 0x%02x", hd.type);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/* no error */
|
||||
|
|
Reference in New Issue