cake
/
libg1m
Archived
1
0
Fork 0

Corrected MCS head management.

This commit is contained in:
Thomas Touhey 2017-03-03 17:02:24 +01:00
parent 931e14f1fd
commit 23f40d1695
10 changed files with 95 additions and 90 deletions

View File

@ -2,8 +2,9 @@
Copyright (C) 2017 Thomas "Cakeisalie5" Touhey <thomas@touhey.fr>
The documentation comes from a lot of places in the CASIO community, but mainly
from **Casiopeia** (mainly with Simon Lothar's documentation) and **Cemetech**
(Prizm-related formats).
from **Casiopeia** (mainly with Simon Lothar's documentation), **Cemetech**
(Prizm-related formats) and the **Casetta project documentation**
(reunion of five to twenty years old documentation).
Thanks to Simon Lothar, Teamfx and KermMartian for their help!
Thanks to the people on **Planète Casio** for their support!

View File

@ -85,21 +85,28 @@ int g1m_fopen(g1m_t **handle, const char *path, FILE *stream,
g1m_type_t expected_type);
#endif
/* open MCS head/file */
/* open MCS head for decoding, correct it for encoding */
int g1m_decode_mcsfile_head(g1m_mcshead_t *head,
int raw_type, const unsigned char *groupname,
const unsigned char *dirname, const unsigned char *filename,
uint_fast32_t filesize);
int g1m_mcstype_correct(g1m_mcshead_t *head);
/* open and decode MCS file */
int g1m_decode_mcsfile(g1m_mcsfile_t **handle,
const g1m_mcshead_t *head, g1m_buffer_t *buffer);
int g1m_decode_mcsfile_data(g1m_mcsfile_t **handle,
const g1m_mcshead_t *head, const unsigned char *data, size_t size);
/* open CAS head/file */
/* open CAS head for decoding (TODO: correct it for encoding) */
int g1m_decode_casfile_head(g1m_mcshead_t *head,
const char *datatype, const char *filename, const char *specific);
/* open and decode CAS file */
int g1m_decode_casfile(g1m_mcsfile_t **handle,
const g1m_mcshead_t *head, g1m_buffer_t *buffer);
int g1m_decode_casfile_data(g1m_mcsfile_t **handle,
const g1m_mcshead_t *head, const unsigned char *data, size_t size);
/* free handles */
void g1m_free(g1m_t *handle);

View File

@ -37,9 +37,20 @@ struct casemul_internal_header {
uint32_t size;
};
/* The multi-byte values are always little-endian, expected from the
* values made with `MAKELONG` (like the internal header type, which, in the
* source, is a DWORD), because its funnier. */
/* The multi-byte values do not have a defined endianness! The Casemul files
* are generated from C++ classes, so when one is generated, the host's
* endianness is used. Also, there is no setting anywhere in the file to say
* whether the host was big endian or little endian.
*
* Actually, there is a way to guess using the magic, which is made using
* `MAKELONG`, which concatenates two words ('CA' and 'FS', 'AC' and 'SF' in
* little endian). That means if it is "CASF", then the file was generated on
* a big endian platform, and if it is "ACFS", it was generated on a little
* endian platform.
*
* The libg1m implementation just supposes the file was generated on a
* little-endian platform, as CasEmul was used when Microsoft Windows was
* only implemented on x86-like platforms (little endian). */
/* ************************************************************************** */
/* Overall, source and compiled headers */
/* ************************************************************************** */

View File

@ -37,8 +37,6 @@ int g1m_get_type_info(const char *path,
/* get mcs type data */
int g1m_mcstype_get(const char *groupname, const char *filename,
unsigned int rawtype, unsigned int *type, int *id);
int g1m_mcstype_toraw(unsigned int type, int id,
char *name, char *dirname, char *groupname);
/* get cas type data */
int g1m_castype_get(const char *datatype, unsigned int *type);

View File

@ -71,7 +71,7 @@ typedef struct g1m_mcs_cell_s {
/* Main structures */
/* ************************************************************************** */
/* mcs file head flags */
# define g1m_mcshead_complex 0x0001 /* is a complex variable */
# define g1m_mcsflag_complex 0x0001 /* is a complex variable */
/* mcs file head */
typedef struct g1m_mcshead_s {
@ -83,9 +83,12 @@ typedef struct g1m_mcshead_s {
/* content size */
uint_fast32_t size;
/* raw data */
/* mcs-related raw data */
unsigned int _rawtype;
unsigned char _group[17], _dirname[9];
/* cas-related raw data */
unsigned char _data[3];
} g1m_mcshead_t;
/* mcs file */

View File

@ -22,7 +22,7 @@
#include <libg1m/internals.h>
/* ************************************************************************** */
/* Direct subfile decoding functions */
/* Head decoding function */
/* ************************************************************************** */
/**
* g1m_decode_casfile_head:
@ -61,7 +61,11 @@ int g1m_decode_casfile_head(g1m_mcshead_t *head, const char *datatype,
return (0);
}
/* ************************************************************************** */
/* File decoding functions */
/* ************************************************************************** */
/* TODO: g1m_decode_casfile */
/* TODO: g1m_decode_casfile_data */
/* ************************************************************************** */
/* File decoding function */
@ -92,6 +96,7 @@ int g1m_decode_cas(g1m_t *handle, g1m_buffer_t *buffer,
(char*)hd.filename, (char*)hd._specific)))
return (err);
/* TODO: decode it */
/* everything went fine :) */
return (0);
return (g1m_error_wrong_type);
}

View File

@ -1,25 +0,0 @@
/* *****************************************************************************
* decode/cat.c -- decode a CAT file.
* Copyright (C) 2017 Thomas "Cakeisalie5" Touhey <thomas@touhey.fr>
*
* This file is part of libg1m.
* libg1m is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 3.0 of the License,
* or (at your option) any later version.
*
* libg1m is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with libg1m; if not, see <http://www.gnu.org/licenses/>.
*
* CAT is a proprietary format by CASIO. It is a text-based format.
* A description of it is available in the Casetta project documentation:
* https://casetta.tuxfamily.org/formats/cat
* ************************************************************************** */
#include <libg1m/internals.h>
/* TODO */

View File

@ -71,7 +71,7 @@ static mcs_decode_func_t lookup_mcsfile_decode(unsigned int type)
}
/* ************************************************************************** */
/* Public file functions */
/* Head decoding function */
/* ************************************************************************** */
/**
* g1m_decode_mcsfile_head:
@ -121,6 +121,9 @@ int g1m_decode_mcsfile_head(g1m_mcshead_t *head,
return (0);
}
/* ************************************************************************** */
/* File decoding functions */
/* ************************************************************************** */
/**
* g1m_decode_mcsfile:
* Decode MCS file content.

View File

@ -71,12 +71,12 @@ static g1m_mcsfile_t *find_space_for_file(g1m_t *handle,
found:;
/* don't forget to copy basic things */
g1m_mcsfile_t *file = *pfile;
if (name) strncpy(file->head.name, name, 8);
if (name) sprintf(file->head.name, "%.8s", name);
file->head.type = type;
file->head.id = id;
/* and use mcstype utilities to copy other info */
g1m_mcstype_toraw(type, id, file->head.name,
(char*)file->head._dirname, (char*)file->head._group);
g1m_mcstype_correct(&file->head);
/* return it */
return (file);

View File

@ -21,23 +21,25 @@
/* ************************************************************************** */
/* Local types */
/* ************************************************************************** */
/* Type flags */
#define noarg 0x0000
#define arg 0x0001
#define arg_is_num 0x0002
#define arg_is_let 0x0000
#define weight_by_gid 0x0004
/* Correspondance type */
#define noarg 0
#define arg 1
#define arg_is_num 2
#define arg_is_let 0
#define weight_by_gid 4
struct type_corresp {
/* identification */
unsigned int rawtype;
const char *name; /* NULL: don't check */
unsigned int flags;
unsigned int flags; /* TODO: move */
/* information for logging and re-constituting information */
const char *dirname;
const char *info;
/* libg1m MCS file type */
/* libg1m information */
unsigned int type;
};
@ -295,79 +297,79 @@ notfound:
}
/**
* g1m_mcstype_toraw:
* Get raw information for writing.
* g1m_mcstype_correct:
* Correct information.
*
* @arg type the libg1m type.
* @arg id the ID.
* @arg name the name buffer.
* @arg dirname the directory name buffer.
* @arg groupname the groupname buffer.
* @arg head the mcs head to correct.
* @return if an error was encountered.
*/
int g1m_mcstype_toraw(unsigned int type, int id,
char *name, char *dirname, char *groupname)
int g1m_mcstype_correct(g1m_mcshead_t *head)
{
/* check if there is a type */
if (!head || !head->type)
return (0);
/* find the group/type */
struct group_corresp *g;
struct type_corresp *t;
for (g = mcs_groups; g->types; g++) for (t = g->types; t->dirname; t++) {
/* check if the libg1m type corresponds */
if (t->type != head->type) continue;
for (g = mcs_groups; g->types; g++) {
for (t = g->types; t->dirname; t++) {
/* check if the libg1m type corresponds */
if (t->type != type)
/* check if id is weighted by major */
if (g1m_get_id_major(head->id)) {
if (~t->flags & weight_by_gid)
continue;
/* check if id is weighted by major */
if (g1m_get_id_major(id)) {
if (~t->flags & weight_by_gid)
continue;
} else if (t->flags & weight_by_gid)
continue;
/* we found the entry! */
goto found;
}
} else
continue;
/* we have found the entry! */
goto found;
}
/* not found */
return (1);
/* not found... */
return (g1m_error_unknown);
found:
found:;
/* put the group name */
strcpy(groupname, g->name);
char *gr = (char*)head->_group;
if (g->flags & arg) {
int grid = g1m_get_id_major(id);
int grid = g1m_get_id_major(head->id);
if ((t->flags & arg) && ~t->flags & weight_by_gid)
grid = g1m_get_id_minor(id);
grid = g1m_get_id_minor(head->id);
if (grid == g1m_ans)
sprintf(groupname, "%sAns", g->name);
sprintf(gr, "%sAns", g->name);
else if (grid == g1m_theta)
sprintf(groupname, "%s\xCE", g->name);
sprintf(gr, "%s\xCE", g->name);
else if (grid == g1m_r)
sprintf(groupname, "%s\xCD", g->name);
sprintf(gr, "%s\xCD", g->name);
else if (g->flags & arg_is_num)
sprintf(groupname, "%s%d", g->name, grid);
sprintf(gr, "%s%d", g->name, grid);
else
sprintf(groupname, "%s%c", g->name, grid + 'A' - 1);
}
sprintf(gr, "%s%c", g->name, grid + 'A' - 1);
} else
strcpy(gr, g->name);
/* put the directory name */
strcpy(dirname, t->dirname);
strcpy((char*)head->_dirname, t->dirname);
/* put the filename */
char *nm = (char*)head->name;
if (t->flags & arg) {
int namid = g1m_get_id_minor(id);
int namid = g1m_get_id_minor(head->id);
if (namid == g1m_ans)
sprintf(name, "%sAns", t->name);
sprintf(nm, "%sAns", t->name);
else if (namid == g1m_theta)
sprintf(name, "%s\xCE", t->name);
sprintf(nm, "%s\xCE", t->name);
else if (namid == g1m_r)
sprintf(name, "%s\xCD", t->name);
sprintf(nm, "%s\xCD", t->name);
else if (t->flags & arg_is_num)
sprintf(name, "%s%d", t->name, namid);
sprintf(nm, "%s%d", t->name, namid);
else
sprintf(name, "%s%c", t->name, g1m_get_id_minor(id) + 'A' - 1);
sprintf(nm, "%s%c", t->name, namid + 'A' - 1);
}
/* no error */