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 <Files.h>
65 #include "lg.h"
66 
67 //#ifndef DATAPATH_H
68 //#include <datapath.h>
69 //#endif
70 
71 #ifndef __TYPES_H
72 #include "lg_types.h"
73 #endif
74 
75 #ifndef __RESTYPES_H
76 #include "restypes.h"
77 #endif
78 
79 //	---------------------------------------------------------
80 //		ID AND REF DEFINITIONS AND MACROS
81 //	---------------------------------------------------------
82 
83 //	Id's refer to resources, Ref's refer to items in compound resources
84 
85 typedef ushort Id;			// ID of a resource
86 typedef ulong Ref;			// high word is ID, low word is index
87 typedef ushort RefIndex;	// index part of ref
88 
89 //	Here's how you get parts of a ref, or make a ref
90 
91 #define REFID(ref) ((ref)>>16)									// get id from ref
92 #define REFINDEX(ref) ((ref)&0xFFFF)						// get index from ref
93 #define MKREF(id,index) ((((long)id)<<16)|(index))	// make ref
94 
95 #define ID_NULL 0			// null resource id
96 #define ID_HEAD 1			// holds head ptr for LRU chain
97 #define ID_TAIL 2			// holds tail ptr for LRU chain
98 #define ID_MIN 3			// id's from 3 and up are valid
99 
100 //	---------------------------------------------------------
101 //		ACCESS TO RESOURCES (ID'S)  (resacc.c)
102 //	---------------------------------------------------------
103 
104 void *ResLock(Id id);								// lock resource & get ptr
105 void *ResLockHi(Id id);							// lock resource hi (Mac only)
106 void ResUnlock(Id id);								// unlock resource
107 void *ResGet(Id id);								// get ptr to resource (dangerous!)
108 void *ResExtract(Id id, void *buffer);		// extract resource into buffer
109 void ResDrop(Id id);								// drop resource from immediate use
110 void ResDelete(Id id);								// delete resource forever
111 
112 //	------------------------------------------------------------
113 //		ACCESS TO ITEMS IN COMPOUND RESOURCES (REF'S)  (refacc.c)
114 //	------------------------------------------------------------
115 
116 //	Each compound resource starts with a Ref Table
117 
118 typedef struct {
119 	RefIndex numRefs;									// # items in compound resource
120 	long offset[1];										// offset to each item (numRefs + 1 of them)
121 } RefTable;
122 
123 void *RefLock(Ref ref);								// lock compound res, get ptr to item
124 #define RefUnlock(ref) ResUnlock(REFID(ref))	// unlock compound res item
125 void *RefGet(Ref ref);									// get ptr to item in comp. res (dangerous!)
126 
127 RefTable *ResReadRefTable(Id id);									// alloc & read ref table
128 #define ResFreeRefTable(prt) (DisposePtr((Ptr)prt))		// free ref table
129 //int ResExtractRefTable(Id id, RefTable *prt, long size); 	// extract reftable
130 void *RefExtract(RefTable *prt, Ref ref, void *buff);			// extract ref
131 
132 #define RefIndexValid(prt,index) ((index) < (prt)->numRefs)
133 #define RefSize(prt,index) (prt->offset[(index)+1]-prt->offset[index])
134 
135 int ResNumRefs(Id id); // returns the number of refs in a resource, extracting if necessary.
136 
137 #define REFTABLESIZE(numrefs) (sizeof(RefIndex) + (((numrefs)+1) * sizeof(long)))
138 #define REFPTR(prt,index) (((uchar *) prt) + prt->offset[index])
139 
140 /*
141 //	-----------------------------------------------------------
142 //		BLOCK-AT-A-TIME ACCESS TO RESOURCES  (resexblk.c)
143 //	-----------------------------------------------------------
144 
145 void ResExtractInBlocks(Id id, void *buff, long blockSize,
146 	long (*f_ProcBlock)(void *buff, long numBytes, long iblock));
147 void RefExtractInBlocks(RefTable *prt, Ref ref, void *buff, long blockSize,
148 	long (*f_ProcBlock)(void *buff, long numBytes, long iblock));
149 
150 #define REBF_FIRST 0x01		// set for 1st block passed to f_ProcBlock
151 #define REBF_LAST  0x02		// set for last block (may also be first!)
152 */
153 
154 //	-----------------------------------------------------------
155 //		IN-MEMORY RESOURCE DESCRIPTORS, AND INFORMATION ROUTINES
156 //	-----------------------------------------------------------
157 //  For Mac version, keep a handle (rather than ptr).  Most ResDesc info not needed
158 //  because the Mac Resource Mgr takes care of it.
159 
160 //	Each resource id gets one of these resource descriptors
161 
162 typedef struct
163 {
164 	Handle	hdl;			// Mac resource handle.  NULL if not in memory (on disk)
165 
166 	short	filenum;		// Mac resource file number
167 	uchar 	lock;			// lock count
168 	uchar	flags;			// misc flags (RDF_XXX, see below)
169 	uchar 	type;			// resource type (RTYPE_XXX, see restypes.h)
170 } ResDesc;
171 
172 #define RESDESC(id) (&gResDesc[id])					// convert id to resource desc ptr
173 #define RESDESC_ID(prd) ((prd)-gResDesc)		// convert resdesc ptr to id
174 
175 #define RDF_LZW				0x01		// if 1, LZW compressed
176 #define RDF_COMPOUND		0x02		// if 1, compound resource
177 #define RDF_RESERVED		0x04		// reserved
178 #define RDF_LOADONOPEN	0x08		// if 1, load block when open file
179 
180 #define RES_MAXLOCK 255				// max locks on a resource
181 
182 extern ResDesc *gResDesc;				// ptr to big array of ResDesc's
183 extern Id resDescMax;						// max id in res desc
184 
185 
186 //	Information about resources
187 
188 #define ResInUse(id) (gResDesc[id].hdl)
189 #define ResPtr(id) (*(gResDesc[id].hdl))
190 long ResSize(Id id);										// It's a function now, in res.c
191 //#define ResSize(id) (MaxSizeRsrc(gResDesc[id].hdl))
192 #define ResLocked(id) (gResDesc[id].lock)
193 //#define ResType(id) (gResDesc[id].type)
194 //#define ResFilenum(id) (gResDesc[id].filenum)
195 #define ResFlags(id) (gResDesc[id].flags)
196 #define ResCompressed(id) (gResDesc[id].flags & RDF_LZW)
197 #define ResIsCompound(id) (gResDesc[id].flags & RDF_COMPOUND)
198 
199 //	------------------------------------------------------------
200 //		RESOURCE MANAGER GENERAL ROUTINES  (res.c)
201 //	------------------------------------------------------------
202 
203 void ResInit();						// init Res, allocate initial ResDesc[]
204 void ResTerm();						// term Res (done auto via atexit)
205 
206 //	------------------------------------------------------------
207 //		RESOURCE FILE ACCESS (resfile.c)
208 //	------------------------------------------------------------
209 
210 typedef enum
211 {
212 	ROM_READ,			// open for reading only
213 	ROM_EDIT,			// open for editing (r/w) only
214 	ROM_EDITCREATE,	// open for editing, create if not found
215 	ROM_CREATE			// open for creation (deletes existing)
216 } ResOpenMode;
217 
218 void ResAddPath(char *path);		// add search path for resfiles
219 short ResOpenResFile(char *fname, ResOpenMode mode, uchar auxinfo)
220 void ResCloseFile(short filenum);	// close res file
221 
222 #define ResOpenFile(specPtr) ResOpenResFile(specPtr, ROM_READ, FALSE)
223 #define ResEditFile(specPtr,creat) ResOpenResFile(specPtr, \
224 	(creat) ? ROM_EDITCREATE : ROM_EDIT, TRUE)
225 #define ResCreateFile(specPtr) ResOpenResFile(specPtr, ROM_CREATE, TRUE)
226 
227 //#define MAX_RESFILENUM 15			// maximum file number
228 
229 //extern Datapath gDatapath;			// res system's datapath (others may use)
230 /*
231 //	---------------------------------------------------------
232 //		RESOURCE MEMORY MANAGMENT ROUTINES  (resmem.c)
233 //	---------------------------------------------------------
234 
235 void *ResMalloc(size_t size);
236 void *ResRealloc(void *p, size_t newsize);
237 void ResFree(void *p);
238 void *ResPage(long size);
239 
240 void ResInstallPager(void *f(long size));
241 
242 //	---------------------------------------------------------
243 //		RESOURCE STATS - ACCESSIBLE AT ANY TIME
244 //	---------------------------------------------------------
245 
246 typedef struct {
247 	ushort numLoaded;					// # resources loaded in ram
248 	ushort numLocked;					// # resources locked
249 	long totMemAlloc;					// total memory alloted to resources
250 } ResStat;
251 
252 extern ResStat resStat;				// stats computed if proper DBG bit set
253 */
254 
255 //	----------------------------------------------------------
256 //		PUBLIC INTERFACE FOR CREATORS OF RESOURCES
257 //	----------------------------------------------------------
258 
259 //	----------------------------------------------------------
260 //		RESOURCE MAKING  (resmake.c)
261 //	----------------------------------------------------------
262 
263 void ResMake(Id id, void *ptr, long size, uchar type, short filenum,
264 	uchar flags);										// make resource from data block
265 void ResMakeCompound(Id id, uchar type, short filenum,
266 	uchar flags);										// make empty compound resource
267 void ResAddRef(Ref ref, void *pitem, long itemSize);	// add item to compound
268 void ResUnmake(Id id);											// unmake a resource
269 
270 //	----------------------------------------------------------
271 //		RESOURCE FILE LAYOUT
272 //	----------------------------------------------------------
273 /*
274 typedef struct					// For Mac version, an array of these are saved in the
275 {									// file's 'hTbl' 128 resource.
276 	Id 			id;					// resource id
277 	uchar 	flags;				// resource flags (RDF_XXX)
278 	uchar	type;				// resource type
279 } ResDirEntry;
280 
281 void ResWriteDir(short filenum);	// Mac version: Write out a resource table for the file.
282 */
283 /*
284 //	Resource-file disk format:  header, data, dir
285 
286 typedef struct {
287 	char signature[16];		// "LG ResFile v2.0\n",
288 	char comment[96];			// user comment, terminated with '\z'
289 	uchar reserved[12];		// reserved for future use, must be 0
290 	long dirOffset;			// file offset of directory
291 } ResFileHeader;				// total 128 bytes (why not?)
292 
293 typedef struct {
294 	ushort numEntries;		// # items referred to by directory
295 	long dataOffset;			// file offset at which data resides
296 									// directory entries follow immediately
297 									// (numEntries of them)
298 } ResDirHeader;
299 
300 typedef struct {
301 	Id id;						// resource id (if 0, entry is deleted)
302 	long size: 24;				// uncompressed size (size in ram)
303 	long flags: 8;				// resource flags (RDF_XXX)
304 	long csize: 24;			// compressed size (size on disk)
305 									// (this size is valid disk size even if not comp.)
306 	long type: 8;				// resource type
307 } ResDirEntry;
308 
309 //	Active resource file table
310 
311 typedef struct {
312 	ushort flags;				// RFF_XXX
313 	ResFileHeader hdr;		// file header
314 	ResDirHeader *pdir;		// ptr to resource directory
315 	ushort numAllocDir;		// # dir entries allocated
316 	long currDataOffset;		// current data offset in file
317 } ResEditInfo;
318 
319 typedef struct {
320 	int fd;						// file descriptor (from open())
321 	ResEditInfo *pedit;		// editing info, or NULL if read-only file
322 } ResFile;
323 
324 #define RFF_NEEDSPACK	0x0001			// resfile has holes, needs packing
325 #define RFF_AUTOPACK		0x0002			// resfile auto-packs (default TRUE)
326 
327 extern ResFile resFile[MAX_RESFILENUM+1];
328 
329 //	Macros to get ptr to resfile's directory, & iterate across entries
330 
331 #define RESFILE_HASDIR(filenum) (resFile[filenum].pedit)
332 #define RESFILE_DIRPTR(filenum) (resFile[filenum].pedit->pdir)
333 #define RESFILE_DIRENTRY(pdir,n) ((ResDirEntry *)((pdir) + 1) + (n))
334 #define RESFILE_FORALLINDIR(pdir,pde) for (pde = RESFILE_DIRENTRY(pdir,0); \
335 	pde < RESFILE_DIRENTRY(pdir,pdir->numEntries); pde++)
336 
337 extern char resFileSignature[16];		// magic header
338 */
339 
340 //	--------------------------------------------------------
341 //		RESOURCE FILE BUILDING  (resbuild.c)
342 //	--------------------------------------------------------
343 
344 void ResSetComment(int filenum, char *comment);	// set comment
345 int ResWrite(Id id);												// write resource to file
346 void ResKill(Id id);													// delete resource & remove from file
347 //long ResPack(int filenum);									// remove empty entries
348 #define ResPack(filenum)
349 
350 //#define ResAutoPackOn(filenum) (resFile[filenum].pedit->flags |= RFF_AUTOPACK)
351 //#define ResAutoPackOff(filenum) (resFile[filenum].pedit->flags &= ~RFF_AUTOPACK)
352 //#define ResNeedsPacking(filenum) (resFile[filenum].pedit->flags & RFF_NEEDSPACK)
353 
354 
355 #endif
356