1 /*---------------------------------------------------------------------*
2 Project: tc library
3 File: TCMem.c
4
5 Copyright 1998-2001 Nintendo. All rights reserved.
6
7 These coded instructions, statements and computer programs contain
8 proprietary information of Nintendo of America Inc. and/or Nintendo
9 Company Ltd., and are protected by Federal copyright law. They may
10 not be disclosed to third parties or copied or duplicated in any form,
11 in whole or in part, without the prior written consent of Nintendo.
12
13 Change History:
14
15 $Log: TCMem.cpp,v $
16 Revision 1.1 2006/02/17 09:01:53 mitu
17 1st version
18
19
20 3 4/11/01 3:08p John
21 Updated header copyrights and pathname.
22
23 2 3/17/00 1:19p Mikepc
24 change tc to use indices numbered from 0.
25
26 1 12/03/99 3:45p Ryan
27
28 7 10/13/99 12:35p Mikepc
29 removed unused local var. from mFreeMem.
30
31 6 10/08/99 2:45p Mikepc
32 update for tplConv portability: altered data structures, replaced
33 references to 'read tga code' with ' *fileFn, removed redundant
34 functions. Changed some file conversion paths.
35
36 5 9/02/99 11:12a Mikepc
37 some code re-organization between files.
38 added code (verify.cpp) to invoke s3tc.exe from within tc program.
39 changed some routines to accommodate the new texture creation path.
40
41 4 8/26/99 4:59p Mikepc
42 renamed file extensions from .c to .cpp.
43 .cpp extension allows addition of namespace protection to remove
44 potential name collisions with tool code. Exceptions are CreateTplFile
45 and QuickConvert. These are extern "C" linked.
46
47 3 8/26/99 11:38a Mikepc
48
49 2 8/26/99 11:03a Mikepc
50 tplCon rewrite for efficient memory usage, batch file processing
51 ability.
52
53 $NoKeywords: $
54
55 -----------------------------------------------------------------------*/
56
57 #include <stdio.h>
58 #include <stdlib.h>
59
60 #include <charPipeline/tc/TCCommon.h>
61
62 #include "TCMem.h"
63 #include "TCImageList.h"
64 #include "TCPaletteList.h"
65 #include "TCSrcImageList.h"
66 #include "TCTextureList.h"
67 #include "TCFileInternal.h"
68
69 /********************************/
70 typedef struct TCMemNode
71 {
72 void* mem;
73 u32 size;
74
75 struct TCMemNode* prev;
76 struct TCMemNode* next;
77
78 }TCMemNode, *TCMemNodePtr;
79
80 /********************************/
81 // debugging- compare app. allocated memory to freed memory
82 // including memory allocated to 'MemNodes'
83 u32 TotalAlloc = 0;
84 u32 TotalFreed = 0;
85
86 // allocated memory linked list
87 TCMemNode* MemList = NULL;
88
89 /*>*******************************(*)*******************************<*/
90 static TCMemNode* TCNewMemNode ( void );
91 static void TCFreeMemNode ( TCMemNode** thisNode );
92
93 /*>*******************************(*)*******************************<*/
TCNewMemNode(void)94 static TCMemNode* TCNewMemNode ( void )
95 {
96 TCMemNode* newM, *thisM;
97
98
99 // use stdlib calloc
100 if( (newM = (TCMemNode*)calloc( 1,sizeof(TCMemNode))) == NULL )
101 {
102 TCErrorMsg( "TCNewMemNode: couldn't allocate new TCMemNode\n" );
103 return NULL;
104 }
105
106
107 if( MemList == NULL )
108 {
109 MemList = newM;
110 newM->prev = NULL;
111 newM->next = NULL;
112 return newM;
113 }
114 else if( MemList->next == NULL )
115 {
116 MemList->next = newM;
117 newM->prev = MemList;
118 newM->next = NULL;
119 return newM;
120 }
121 else
122 {
123 thisM = MemList;
124 while( thisM->next )
125 {
126 thisM = thisM->next;
127 }
128
129 thisM->next = newM;
130 newM->prev = thisM;
131 newM->next = NULL;
132 return newM;
133 }
134
135 return newM;
136 }
137
138 /*>*******************************(*)*******************************<*/
139 // free a node from within the list
140 /*>*******************************(*)*******************************<*/
TCFreeMemNode(TCMemNode ** thisNode)141 static void TCFreeMemNode ( TCMemNode** thisNode )
142 {
143 TCMemNode* checkNode = NULL;
144 u32 found = 0;
145
146
147 if( *thisNode == NULL )
148 {
149 TCErrorMsg( "TCFreeMemNode: tried to free a NULL TCMemNode\n" );
150 return;
151 }
152
153
154 // ensure that *thisNode is part of the main memory list
155 // this also guards against an empty list
156 checkNode = MemList;
157 while( checkNode )
158 {
159 if( checkNode == *thisNode )
160 {
161 found = 1;
162 break;
163 }
164
165 checkNode = checkNode->next;
166 }
167
168 // couldn't find *thisNode
169 TCAssertMsg( (found), "TCFreeMemNode: *thisNode is not part of MemList\n" );
170
171
172 // free node data first
173
174 // stdlib free
175 if( (*thisNode)->mem != NULL )
176 {
177 free( (*thisNode)->mem );
178 (*thisNode)->mem = NULL;
179
180 TotalFreed += (*thisNode)->size;
181 }
182 (*thisNode)->size = 0;
183
184
185 //------------------------
186
187 // remove the node from the linked list
188
189 if( *thisNode == MemList ) // head
190 {
191 if( (*thisNode)->next == NULL ) // single node list
192 {
193 (*thisNode)->prev = NULL;
194 (*thisNode)->next = NULL;
195 MemList = NULL;
196 }
197 else // multi-node list
198 {
199 MemList = (*thisNode)->next;
200
201 (*thisNode)->next->prev = NULL;
202 (*thisNode)->prev = NULL;
203 (*thisNode)->next = NULL;
204 }
205 }
206 else
207 {
208 if( (*thisNode)->next == NULL ) // tail
209 {
210 (*thisNode)->prev->next = NULL;
211 (*thisNode)->next = NULL;
212 (*thisNode)->prev = NULL;
213 }
214 else // middle of list
215 {
216 (*thisNode)->prev->next = (*thisNode)->next;
217 (*thisNode)->next->prev = (*thisNode)->prev;
218 (*thisNode)->next = NULL;
219 (*thisNode)->prev = NULL;
220 }
221
222 }
223
224 //-----------------------
225
226 // free thisNode's memory
227 free( *thisNode );
228 TotalFreed += sizeof(TCMemNode);
229 *thisNode = NULL;
230
231 }
232
233 /*>*******************************(*)*******************************<*/
TCMalloc(u32 size)234 void* TCMalloc ( u32 size )
235 {
236 TCMemNode* newM;
237
238
239 newM = TCNewMemNode();
240
241 if( size == 15 )
242 {
243 printf("found mem" );
244 }
245
246 if( (newM->mem = (void*)malloc(size)) == NULL )
247 {
248 TCErrorMsg("TCMalloc: couldn't allocate block of size %d\n", size );
249 return NULL;
250 }
251
252 newM->size = size;
253
254 TotalAlloc += ( size + sizeof(TCMemNode) );
255
256 return newM->mem;
257 }
258
259 /*>*******************************(*)*******************************<*/
TCCalloc(u32 num,u32 size)260 void* TCCalloc ( u32 num, u32 size )
261 {
262 TCMemNode* newM;
263 u32 total;
264
265
266 newM = TCNewMemNode();
267
268 total = num * size;
269
270 if( total == 15 )
271 {
272 printf("found mem" );
273 }
274
275 // use stdlib calloc
276 if( (newM->mem = (void*)calloc(num, size)) == 0 )
277 {
278 TCErrorMsg("TCCalloc: couldn't allocate block of size %d\n", total );
279 return 0;
280 }
281
282 newM->size = total;
283
284 TotalAlloc += ( total + sizeof(TCMemNode) );
285
286 return newM->mem;
287 }
288
289 /*>*******************************(*)*******************************<*/
TCFree(void ** vPtr)290 void TCFree ( void** vPtr )
291 {
292 TCMemNode* thisNode;
293
294
295 if( *vPtr == NULL )
296 {
297 return;
298 }
299
300 thisNode = MemList;
301 while( thisNode != NULL )
302 {
303 if( thisNode->mem != NULL )
304 {
305 if( thisNode->mem == *vPtr )
306 {
307 TCFreeMemNode( &thisNode );
308 *vPtr = NULL;
309 return;
310 }
311 }
312
313 thisNode = thisNode->next;
314 }
315
316 return;
317 }
318
319 /*>*******************************(*)*******************************<*/
TCFreeMem(void)320 void TCFreeMem ( void )
321 {
322 TCMemNode* thisNode, *nextNode;
323
324
325 // free all remaining allocated memory blocks
326 thisNode = MemList;
327 while( thisNode != NULL )
328 {
329 nextNode = thisNode->next;
330
331 TCFreeMemNode( &thisNode );
332
333 thisNode = nextNode;
334 }
335 MemList = NULL;
336
337 // reset all global pointers to NULL
338 SiHead = NULL;
339 ImHead = NULL;
340 PlHead = NULL;
341 TxHead = NULL;
342
343 // file cache
344 DFSize = 0;
345 DF = NULL;
346
347 // file table
348 FileTable = NULL;
349
350 // set the path pointers for txtFile keys to NULL
351 *PathName = '\0';
352 PathPtr = NULL;
353
354
355 // debugging info.
356 printf("\n");
357 printf( "total alloc: %d\n", TotalAlloc );
358 printf( "total freed: %d\n", TotalFreed );
359 }
360
361 /*>*******************************(*)*******************************<*/
362