1 /* 2 3 Copyright (C) 2015-2018 Night Dive Studios, LLC. 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 // Res.H Resource Manager header file 20 // Rex E. Bradford (REX) 21 /* 22 * $Header: n:/project/lib/src/res/rcs/res.h 1.9 1994/06/16 11:56:34 rex Exp $ 23 * $Log: res.h $ 24 * Revision 1.9 1994/06/16 11:56:34 rex 25 * Got rid of RDF_NODROP 26 * 27 * Revision 1.8 1994/05/26 13:54:27 rex 28 * Added prototype ResInstallPager() 29 * 30 * Revision 1.7 1994/03/09 19:31:48 jak 31 * Res\RefExtractInBlocks transfers a variable/length 32 * block of data in each pass. The user/defined function 33 * returns the amount that should be passed in NEXT time. 34 * 35 * Revision 1.6 1994/02/17 11:25:02 rex 36 * Massive overhaul, moved some private stuff out to res_.h 37 * 38 * Revision 1.5 1993/09/01 16:02:10 rex 39 * Added prototype for ResExtractRefTable(). 40 * 41 * Revision 1.4 1993/05/13 10:38:44 rex 42 * Added prototype for ResUnmake() 43 * 44 * Revision 1.3 1993/05/13 10:30:56 rex 45 * Added Extract routines and macros 46 * 47 * Revision 1.2 1993/03/08 10:06:12 rex 48 * Changed resource directory entry format (reduced from 12 to 10 bytes) 49 * 50 * Revision 1.1 1993/03/04 18:47:58 rex 51 * Initial revision 52 * 53 * Revision 1.6 1993/03/02 18:42:21 rex 54 * Major revision, new system 55 * 56 */ 57 58 #ifndef __RES_H 59 #define __RES_H 60 61 //��� For now 62 //#define DBG_ON 1 63 64 #include <stdbool.h> 65 #include <stddef.h> 66 #include <stdint.h> 67 #include <stdio.h> // for FILE* 68 #include <stdlib.h> 69 70 #include "lg.h" 71 72 //#ifndef DATAPATH_H 73 //#include <datapath.h> 74 //#endif 75 76 #ifndef __RESTYPES_H 77 #include "restypes.h" 78 #endif 79 80 #include "resformat.h" 81 82 #pragma pack(push,2) 83 84 // --------------------------------------------------------- 85 // ID AND REF DEFINITIONS AND MACROS 86 // --------------------------------------------------------- 87 88 // Id's refer to resources, Ref's refer to items in compound resources 89 90 typedef uint16_t Id; // ID of a resource 91 typedef uint32_t Ref; // high word is ID, low word is index 92 typedef uint16_t RefIndex; // index part of ref 93 94 // Here's how you get parts of a ref, or make a ref 95 96 #define REFID(ref) (uint16_t)((ref) >> 16u) // get id from ref 97 #define REFINDEX(ref) (uint16_t)((ref) & 0xFFFFu) // get index from ref 98 #define MKREF(id, index) ((((uint32_t)id) << 16u) | (uint16_t)(index)) // make ref 99 100 #define ID_NULL 0 // null resource id 101 #define ID_HEAD 1 // holds head ptr for LRU chain 102 #define ID_TAIL 2 // holds tail ptr for LRU chain 103 #define ID_MIN 3 // id's from 3 and up are valid 104 105 // --------------------------------------------------------- 106 // ACCESS TO RESOURCES (ID'S) (resacc.c) 107 // --------------------------------------------------------- 108 109 void *ResLock(Id id); // lock resource & get ptr 110 void ResUnlock(Id id); // unlock resource 111 void *ResGet(Id id); // get ptr to resource (dangerous!) 112 void *ResExtract(Id id, const ResourceFormat *format, void *buffer); // extract resource into buffer 113 void ResDrop(Id id); // drop resource from immediate use 114 void ResDelete(Id id); // delete resource forever 115 116 // ------------------------------------------------------------ 117 // ACCESS TO ITEMS IN COMPOUND RESOURCES (REF'S) (refacc.c) 118 // ------------------------------------------------------------ 119 120 // Each compound resource starts with a Ref Table. When loaded into memory, a 121 // ref table entry has a size, an offset into the raw resource (if loaded) and a 122 // pointer to the decoded ref (freed when the compound resource is unloaded). 123 typedef struct { 124 uint32_t size; 125 uint32_t offset; 126 void *decoded_data; 127 } RefTableEntry; 128 129 typedef struct { 130 RefIndex numRefs; // # items in compound resource 131 void *raw_data; // resource data if loaded. 132 RefTableEntry entries[]; // numRefs table entries 133 } RefTable; 134 135 // Decode raw ref table from file and return a RefTable. 136 void *ResDecodeRefTable(void *raw, size_t *size, UserDecodeData); 137 138 void *RefLock(Ref ref); // lock compound res, get ptr to item 139 #define RefUnlock(ref) ResUnlock(REFID(ref)) // unlock compound res item 140 void *RefGet(Ref ref); // get ptr to item in comp. res (dangerous!) 141 142 RefTable *ResReadRefTable(Id id); // alloc & read ref table 143 void ResFreeRefTable(void *ptr); // free ref table 144 int32_t ResExtractRefTable(Id id, RefTable *prt, 145 int32_t size); // extract reftable 146 147 #define RefIndexValid(prt, index) ((index) < (prt)->numRefs) 148 149 // returns the number of refs in a resource, extracting if necessary. 150 int32_t ResNumRefs(Id id); 151 152 #define REFTABLESIZE(numrefs) (offsetof(RefTable, entries) + ((numrefs) * sizeof(RefTableEntry))) 153 154 /* 155 // ----------------------------------------------------------- 156 // BLOCK-AT-A-TIME ACCESS TO RESOURCES (resexblk.c) 157 // ----------------------------------------------------------- 158 159 void ResExtractInBlocks(Id id, void *buff, int32_t blockSize, 160 int32_t (*f_ProcBlock)(void *buff, int32_t numBytes, int32_t iblock)); 161 void RefExtractInBlocks(RefTable *prt, Ref ref, void *buff, int32_t blockSize, 162 int32_t (*f_ProcBlock)(void *buff, int32_t numBytes, int32_t iblock)); 163 164 #define REBF_FIRST 0x01 // set for 1st block passed to f_ProcBlock 165 #define REBF_LAST 0x02 // set for last block (may also be first!) 166 */ 167 168 // ----------------------------------------------------------- 169 // IN-MEMORY RESOURCE DESCRIPTORS, AND INFORMATION ROUTINES 170 // ----------------------------------------------------------- 171 // For Mac version, keep a handle (rather than ptr). Most ResDesc info not 172 // needed because the Mac Resource Mgr takes care of it. 173 174 // Each resource id gets one of these resource descriptors 175 176 /*typedef struct 177 { 178 //Handle hdl; // Mac resource handle. 179 NULL if not in memory (on disk) int32_t filenum; // Mac 180 resource file number uint8_t lock; // lock count uint8_t 181 flags; // misc flags (RDF_XXX, see below) uint8_t type; 182 // resource type (RTYPE_XXX, see restypes.h) uint32_t offset; uint32_t 183 size; 184 185 void* ptr; 186 Id next; 187 Id prev; 188 } ResDesc;*/ 189 190 typedef struct { 191 void *ptr; // ptr to resource in memory 192 uint32_t lock; // lock count 193 uint32_t fsize; // size of resource in bytes (1 Mb max) 194 uint32_t msize; // size in memory (where used; not for compound) 195 uint32_t filenum; // file number 0-31 196 uint32_t offset; // offset in file 197 Id next; // next resource in LRU order 198 Id prev; // previous resource in LRU order 199 //uint32_t flags; // resource management flags 200 /*uint16_t type : 8;*/ // resource type (RTYPE_XXX, see restypes.h) 201 const ResourceFormat *format;// format of resource 202 } ResDesc; 203 204 typedef struct { 205 uint16_t flags : 8; // misc flags (RDF_XXX, see below) 206 uint16_t type : 8; // resource type (RTYPE_XXX, see restypes.h) 207 } ResDesc2; 208 209 #define RESDESC(id) (&gResDesc[id]) // convert id to resource desc ptr 210 #define RESDESC_ID(prd) ((prd)-gResDesc) // convert resdesc ptr to id 211 212 #define RESDESC2(id) (&gResDesc2[id]) // convert id to rd2 ptr 213 #define RESDESC2_ID(prd) ((prd)-gResDesc2) // convert rd2 ptr to id 214 215 #define RDF_LZW 0x01 // if 1, LZW compressed 216 #define RDF_COMPOUND 0x02 // if 1, compound resource 217 #define RDF_RESERVED 0x04 // reserved 218 #define RDF_LOADONOPEN 0x08 // if 1, load block when open file 219 220 #define RES_MAXLOCK 255 // max locks on a resource 221 222 // ptr to big array of ResDesc's 223 extern ResDesc *gResDesc; 224 // ptr to array of ResDesc2 (shared buff with resdesc) 225 extern ResDesc2 *gResDesc2; 226 227 extern Id resDescMax; // max id in res desc 228 229 // Information about resources 230 #define ResInUse(id) (gResDesc[id].offset) 231 #define ResPtr(id) (gResDesc[id].ptr) 232 #define ResSize(id) (gResDesc[id].msize) 233 #define ResLocked(id) (gResDesc[id].lock) 234 #define ResFilenum(id) (gResDesc[id].filenum) 235 #define ResType(id) (gResDesc2[id].type) 236 #define ResFlags(id) (gResDesc2[id].flags) 237 #define ResCompressed(id) (gResDesc2[id].flags & RDF_LZW) 238 #define ResIsCompound(id) (gResDesc2[id].flags & RDF_COMPOUND) 239 //#define ResZipped(id) (gResDesc2[id].flags & RDF_PKZIP) 240 241 //#define MaxSizeRsrc(theResource) GetMaxResourceSize(theResource) 242 243 // ------------------------------------------------------------ 244 // RESOURCE MANAGER GENERAL ROUTINES (res.c) 245 // ------------------------------------------------------------ 246 247 void ResInit(); // init Res, allocate initial ResDesc[] 248 void ResTerm(); // term Res (done auto via atexit) 249 250 // ------------------------------------------------------------ 251 // RESOURCE FILE ACCESS (resfile.c) 252 // ------------------------------------------------------------ 253 254 typedef enum { 255 ROM_READ, // open for reading only 256 ROM_EDIT, // open for editing (r/w) only 257 ROM_EDITCREATE, // open for editing, create if not found 258 ROM_CREATE // open for creation (deletes existing) 259 } ResOpenMode; 260 261 void ResAddPath(char *path); // add search path for resfiles 262 int32_t ResOpenResFile(const char *fname, ResOpenMode mode, bool auxinfo); 263 void ResCloseFile(int32_t filenum); // close res file 264 265 #define ResOpenFile(fname) ResOpenResFile(fname, ROM_READ, FALSE) 266 #define ResEditFile(fname, creat) ResOpenResFile(fname, (creat) ? ROM_EDITCREATE : ROM_EDIT, TRUE) 267 #define ResCreateFile(fname) ResOpenResFile(fname, ROM_CREATE, TRUE) 268 269 #define MAX_RESFILENUM 31 // maximum file number 270 271 // extern Datapath gDatapath; // res system's datapath (others may use) 272 /* 273 // --------------------------------------------------------- 274 // RESOURCE MEMORY MANAGMENT ROUTINES (resmem.c) 275 // --------------------------------------------------------- 276 277 void *ResMalloc(size_t size); 278 void *ResRealloc(void *p, size_t newsize); 279 void ResFree(void *p); 280 void *ResPage(int32_t size); 281 282 void ResInstallPager(void *f(int32_t size)); 283 284 // --------------------------------------------------------- 285 // RESOURCE STATS - ACCESSIBLE AT ANY TIME 286 // --------------------------------------------------------- 287 288 typedef struct { 289 uint16_t numLoaded; // # resources 290 loaded in ram uint16_t numLocked; // # 291 resources locked int32_t totMemAlloc; // total 292 memory alloted to resources } ResStat; 293 294 extern ResStat resStat; // stats computed if 295 proper DBG bit set 296 */ 297 298 // ---------------------------------------------------------- 299 // PUBLIC INTERFACE FOR CREATORS OF RESOURCES 300 // ---------------------------------------------------------- 301 302 // ---------------------------------------------------------- 303 // RESOURCE MAKING (resmake.c) 304 // ---------------------------------------------------------- 305 306 // make resource from data block 307 void ResMake(Id id, void *ptr, size_t size, uint8_t type, int32_t filenum, uint8_t flags, const ResourceFormat *format); 308 // make empty compound resource 309 void ResMakeCompound(Id id, uint8_t type, int32_t filenum, uint8_t flags); 310 // add item to compound 311 void ResAddRef(Ref ref, void *pitem, int32_t itemSize); 312 // unmake a resource 313 void ResUnmake(Id id); 314 315 // ---------------------------------------------------------- 316 // RESOURCE FILE LAYOUT 317 // ---------------------------------------------------------- 318 319 // Resource-file disk format: header, data, dir 320 321 typedef struct { 322 char signature[16]; // "LG ResFile v2.0\n", 323 char comment[96]; // user comment, terminated with '\z' 324 uint8_t reserved[12]; // reserved for future use, must be 0 325 int32_t dirOffset; // file offset of directory 326 } ResFileHeader; // total 128 bytes (why not?) 327 328 typedef struct { 329 uint16_t numEntries; // # items referred to by directory 330 int32_t dataOffset; // file offset at which data resides 331 // directory entries follow immediately 332 // (numEntries of them) 333 } ResDirHeader; 334 335 typedef struct { 336 Id id; // resource id (if 0, entry is deleted) 337 uint32_t size : 24; // uncompressed size (size in ram) 338 uint32_t flags : 8; // resource flags (RDF_XXX) 339 uint32_t csize : 24; // compressed size (size on disk) 340 // (this size is valid disk size even if not comp.) 341 uint32_t type : 8; // resource type 342 } ResDirEntry; 343 344 // Active resource file table 345 346 typedef struct { 347 uint16_t flags; // RFF_XXX 348 ResFileHeader hdr; // file header 349 ResDirHeader *pdir; // ptr to resource directory 350 uint16_t numAllocDir; // # dir entries allocated 351 int32_t currDataOffset; // current data offset in file 352 } ResEditInfo; 353 354 typedef struct { 355 FILE *fd; // file descriptor (from open()) 356 ResEditInfo *pedit; // editing info, or NULL if read-only file 357 } ResFile; 358 359 #define RFF_NEEDSPACK 0x0001 // resfile has holes, needs packing 360 #define RFF_AUTOPACK 0x0002 // resfile auto-packs (default TRUE) 361 362 extern ResFile resFile[MAX_RESFILENUM + 1]; 363 364 // Macros to get ptr to resfile's directory, & iterate across entries 365 366 #define RESFILE_HASDIR(filenum) (resFile[filenum].pedit) 367 #define RESFILE_DIRPTR(filenum) (resFile[filenum].pedit->pdir) 368 #define RESFILE_DIRENTRY(pdir, n) ((ResDirEntry *)((pdir) + 1) + (n)) 369 #define RESFILE_FORALLINDIR(pdir, pde) \ 370 for (pde = RESFILE_DIRENTRY(pdir, 0); pde < RESFILE_DIRENTRY(pdir, pdir->numEntries); pde++) 371 372 extern char resFileSignature[16]; // magic header 373 374 // -------------------------------------------------------- 375 // RESOURCE FILE BUILDING (resbuild.c) 376 // -------------------------------------------------------- 377 378 void ResSetComment(int32_t filenum, char *comment); // set comment 379 int32_t ResWrite(Id id); // write resource to file 380 void ResKill(Id id); // delete resource & remove from file 381 int32_t ResPack(int32_t filenum); // remove empty entries 382 383 //#define ResAutoPackOn(filenum) (resFile[filenum].pedit->flags |= RFF_AUTOPACK) 384 //#define ResAutoPackOff(filenum) (resFile[filenum].pedit->flags &= 385 //~RFF_AUTOPACK) #define ResNeedsPacking(filenum) (resFile[filenum].pedit->flags 386 //& RFF_NEEDSPACK) 387 // DG: a case-insensitive fopen()-wrapper (see resfile.c) 388 extern FILE *fopen_caseless(const char *path, const char *mode); 389 390 #pragma pack(pop) 391 392 #endif 393