/* ***************************************************************************** * libg1m/format/lang.h -- the G1M language file format description. * Copyright (C) 2017 Thomas "Cakeisalie5" Touhey * * 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 . * ************************************************************************** */ #ifndef LIBG1M_FORMAT_LANG_H # define LIBG1M_FORMAT_LANG_H # include # pragma pack(1) /* ************************************************************************** */ /* G1L - Language files for fx calculators */ /* ************************************************************************** */ /* It all starts with a header: */ struct g1l_subheader { /* identifier: is "PowerUSB" on original things */ uint8_t identifier[8]; /* OS information (raw binary format), e.g. 0x02,0x09 for 2.09. */ uint8_t os_major; uint8_t os_minor; /* unknown bytes */ uint8_t _unknown[2]; /* message count */ uint16_t message_count; }; /* Then comes a list of offsets, and the messages. * * Each element of the offsets list is 16-bytes long. * It is relative to the first element (which starts right after the * offsets list - no alignment). * * The messages are null-terminated - once you get the offsets, you get * them completely. */ /* ************************************************************************** */ /* G3L - Language files for Prizm */ /* ************************************************************************** */ /* Thanks to amazonka for his (minimalist) description of the G3L format * at Cemetech. So the G3L format starts off with a header: */ struct g3l_subheader { /* a checksum */ uint32_t checksum; /* magic: * - 0x04, 0x01, 0x00, 0x00 for language files; * - 0x02, 0x01, 0x00, 0x00 for function key files. */ uint8_t magic[4]; /* lol */ uint8_t undocumented[14]; /* size of the message zone size - unreliable (valid could have zero) */ uint32_t message_zone_size; /* undocumented, again */ uint8_t undocumented5[6]; /* name of the language */ uint8_t language_name2[28]; /* size of the entire file */ uint32_t filesize; /* size of the entire file - starts with an '@' */ uint8_t internal_name[8]; /* undocumented */ uint8_t undocumented2[200]; /* version number string: "XX.XX.XXXX" */ uint8_t version[10]; /* unused */ uint8_t unused2[2]; /* creation time: "YYYY.MMDD.HHMM" */ uint8_t datetime[14]; /* big undocumented thing */ uint8_t undocumented3[3410]; /* language name (zero terminated) */ uint8_t language_name[16]; /* language salutation (zero terminated) */ uint8_t language_salutation[16]; /* filename (extension included) */ uint8_t g3l_filename[16]; /* undocumented */ uint8_t undocumented4[308]; }; /* Then there is something amazonka names the "executable code section". * This is in fact the message zone. */ struct g3l_lang_header { /* sequence: '4C 59 37 35 35 00 00 00 02' (LY755 ) */ uint8_t sequence[9]; /* unused byte. */ uint8_t unused; /* number of messages ("possibly 0 base indexed") */ uint32_t num; /* unused bytes */ uint8_t unused2[2]; }; /* Then we have offsets of all messages (4 bytes each), * then messages themselves, zero-terminated. * * The four last bytes of the files are a little footer, which is: */ struct g3l_footer { /* copy of the first checksum in the subheader */ uint32_t checksum; }; /* This footer is not counted as part of the file. */ # pragma pack() #endif /* LIBG1M_FORMAT_LANG_H */