1 /*
2 
3 Copyright (C) 2019 Shockolate Project
4 
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
9 
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 GNU General Public License for more details.
14 
15 You should have received a copy of the GNU General Public License
16 along with this program.  If not, see <http://www.gnu.org/licenses/>.
17 
18 */
19 #if !defined(RESFORMAT_H)
20 #define RESFORMAT_H
21 
22 // Types of resource field within a resfile.
23 typedef int ResFileFieldType;
24 #define RFFT_PAD    0  // not decoded, skip 'offset' bytes
25 #define RFFT_UINT8  1  // 8-bit integer
26 #define RFFT_UINT16 2  // 16-bit integer
27 #define RFFT_UINT32 3  // 32-bit integer
28 #define RFFT_INTPTR 4  // 32 bits on disc, 32 or 64 bits in memory.
29 #define RFFT_RAW    5  // raw data, copy 'offset' bytes or rest of resource if 0
30 #define RFFT_END    6  // mark end of table
31 #define RFFT_BIN_BASE 0x100
32 
33 #define RFFT_BIN(x) (RFFT_BIN_BASE+(x))
34 
35 // Describes the layout of a resource structure.
36 typedef struct {
37     ResFileFieldType type;   // type of field
38     size_t offset;           // offset in memory
39 } ResField;
40 
41 typedef struct {
42     size_t dsize;        // size of resource on disc
43     size_t msize;        // size of resource in memory
44     uint32_t flags;      // misc. info.
45     ResField fields[];
46 } ResLayout;
47 
48 // Indicates that multiple records exist within a resource, each of 'dsize'
49 // bytes, up to the resource size.
50 #define LAYOUT_FLAG_ARRAY            0x01
51 // Indicates that raw data (e.g. bitmap data) follows a header in the resource.
52 // The header is decoded according to the layout and the raw data is copied to
53 // immediately following it.
54 #define LAYOUT_FLAG_RAW_DATA_FOLLOWS 0x02
55 
56 // User data for a resource decoding function.
57 typedef intptr_t UserDecodeData;
58 // Function to decode a resource loaded from disc. Takes raw data, size of raw
59 // data and user data. Returns decoded data. Default is to free decoded data
60 // using free() but the caller can supply a custom free function.
61 typedef void *(*ResDecodeFunc)(void*, size_t*, UserDecodeData);
62 // Encoder function. Same signature as decoder; takes cooked data and returns
63 // raw data for file, violating the laws of thermodynamics but allowing portable
64 // saving. Encoded data is always freed using free().
65 typedef void *(*ResEncodeFunc)(void*, size_t*, UserDecodeData);
66 // Function to free decoded data, if free() won't cut it.
67 typedef void (*ResFreeFunc)(void*);
68 
69 // Decode a resource using a ResLayout. Prototyped as a decode function.
70 void *ResDecode(void *raw, size_t *size, UserDecodeData layout);
71 // Encode a resource using a ResLayout.
72 void *ResEncode(void *raw, size_t *size, UserDecodeData layout);
73 
74 // Describes the format of a resource for serialisation and deserialisation to
75 // and from disc file.
76 typedef struct {
77     ResDecodeFunc decoder; // deserialise data from disc.
78     ResEncodeFunc encoder; // serialise data to disc.
79     UserDecodeData data;   // aux data, typically a pointer to a layout struct.
80     ResFreeFunc freer;     // free cooked (only) data.
81 } ResourceFormat;
82 
83 // An empty ResourceFormat struct means no translation is needed.
84 extern const ResourceFormat RawFormat;
85 #define FORMAT_RAW (&RawFormat)
86 
87 // Make a format out of a layout.
88 #define RES_FORMAT(layout) \
89     { ResDecode, ResEncode, (UserDecodeData)&layout, NULL }
90 
91 extern const ResourceFormat RefTableFormat;
92 #define FORMAT_REFTABLE (&RefTableFormat)
93 
94 #endif // !defined(RESFORMAT_H)
95