cake
/
libg1m
Archived
1
0
Fork 0
This repository has been archived on 2024-03-16. You can view files and clone it, but cannot push or open issues or pull requests.
libg1m/include/libg1m/format/casemul.h

197 lines
7.0 KiB
C

/* *****************************************************************************
* libg1m/format/casemul.h -- the Casemul file format description.
* 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/>.
* ************************************************************************** */
#ifndef LIBG1M_FORMAT_CASEMUL_H
# define LIBG1M_FORMAT_CASEMUL_H
# include <libg1m/bcd.h>
# pragma pack(1)
/* Casemul files are made of an overall header, a source part and an
* optional compiled part. One thing to know is that every header has an
* internal header, which always has this structure: */
struct casemul_internal_header {
/* this type was made using `MAKELONG`: you have to reverse the bytes in
* each word (e.g. AC-FS -> CA-SF). */
char type[4];
/* version (more or less 0xMMmm, where MM is the major and mm the minor) */
uint32_t version;
/* header size */
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. */
/* ************************************************************************** */
/* Overall, source and compiled headers */
/* ************************************************************************** */
/* The overall header contains information about the other sections, and the
* current state of the file (whether it contains the compiled part or not).
*
* Its internal header ID is "CAFS" (ACFS, used as the magic string).
* The expected version is 1.00. */
# define casemul_compiled 0x80 /* if the compiled program is there */
struct casemul_header {
/* the flags */
uint8_t flags;
/* offset of the sources */
uint32_t source_offset;
/* compiled program offset */
uint32_t compiled_offset;
/* some alignment? */
uint8_t _align[3];
};
/* At the beginning of the source part, we find the source header.
* The source part contains the programs, pictures, matrixes and lists as four
* blocks, uncompiled.
*
* Its internal header ID is "SRCE" (RSEC).
* The expected version is 1.00. */
struct casemul_source_header {
/* number of program records in the program block */
uint8_t programs;
/* number of picture records in the program block */
uint8_t pictures;
/* number of matrix records in the program block */
uint8_t matrixes;
/* number of list records in the list block */
uint8_t lists;
/* program block offset */
uint32_t programs_offset;
/* picture block offset (length of the file before) */
uint32_t pictures_offset;
/* matrix block offset */
uint32_t matrixes_offset;
/* list block offset */
uint32_t list_offset;
/* main program ID */
uint8_t program_id;
/* alignment */
uint8_t _align[3];
};
/* At the beginning of the compiled part, we find the compiled header.
* The compilation process is unknown (yet to read the sources to find out
* what it is).
*
* Its internal header ID is "COMP" (OCPM).
* The expected version is 1.00. */
struct casemul_comp_header {
/* the number of instructions (size of the part) */
uint32_t instructions_count;
};
/* ************************************************************************** */
/* Record */
/* ************************************************************************** */
/* For each element, there is record, with a header and a subheader. The
* record header cannot easily be expressed as a structure, so here it is, in
* the form of a comment:
*
* uint32_t name_length;
* The name length.
* uint8_t name[name_length];
* The name.
* uint32_t length;
* The subheader+data length.
*
* Then expect an internal header, part of the subheader, that expresses the
* type of it (expected version for all of them is 1.00). */
/* ************************************************************************** */
/* Program */
/* ************************************************************************** */
/* A program has type "PROG" (RPGO). Its subheader is the following: */
struct casemul_prog_header {
/* program length after Casemul encoding */
uint32_t length;
};
/* Casemul makes use of tokens instead of FONTCHARACTERs or Unicode - this
* should be documented in the FONTCHARACTER reference. */
/* ************************************************************************** */
/* Picture */
/* ************************************************************************** */
/* A picture has type "PICT" (IPTC), and has the following subheader: */
struct casemul_pict_header {
/* size */
uint8_t w, h;
/* ... aaaaand alignment. (you know, unchecked theory?) */
uint8_t _align[2];
};
/* Also, pixels are organized per _column_; this comes from the original code:
*
* BYTE m_TabPixels[DATAPICTURE_CX][DATAPICTURE_CY];
*
* Notice that DATAPICTURE_CX and DATAPICTURE_CY are actually macros,
* which means there are always 128x64 pixels (or at least that Casemul
* will only be able to open 128x64 pictures)... */
/* ************************************************************************** */
/* Matrix */
/* ************************************************************************** */
/* A matrix has type "MTRX" (TMXR) and its its subheader has the following
* structure: */
struct casemul_mtrx_header {
/* number of lines and columns
* actually int-s in the original code... */
uint32_t lines, columns;
};
/* Then it's simply a tab of `lines*columns` `double` numbers,
* ordered by lines (y). They are the real parts, as the numbers in those
* matrixes have got no imaginary parts. */
/* ************************************************************************** */
/* List */
/* ************************************************************************** */
/* A list has type "LIST" (ILTS) and has the following subheader structure: */
struct casemul_list_header {
/* number of lines
* actually int-s in the original code... */
uint32_t lines;
};
/* Then it's simply a tab of `lines` `double` numbers.
* The numbers in these have no imaginary parts. */
# pragma pack()
#endif /* LIBG1M_FORMAT_CASEMUL_H */