1 /*---------------------------------------------------------------------*
2 Project: tc library
3 File: TCPaletteList.cpp
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: TCPaletteList.cpp,v $
16 Revision 1.1 2006/02/17 09:01:53 mitu
17 1st version
18
19
20 4 4/11/01 3:08p John
21 Updated header copyrights and pathname.
22
23 3 8/10/00 6:02p Mikepc
24
25 2 3/17/00 1:19p Mikepc
26 change tc to use indices numbered from 0.
27
28 1 12/03/99 3:45p Ryan
29
30 10 10/08/99 2:45p Mikepc
31 update for tplConv portability: altered data structures, replaced
32 references to 'read tga code' with ' *fileFn, removed redundant
33 functions. Changed some file conversion paths.
34
35 9 9/17/99 12:19p Mikepc
36 arbitrary palette size has been removed- changed SetPalette() to create
37 only an 8-bit palette
38
39 8 9/16/99 8:47p Mikepc
40 updated code for auto-palette generation
41
42 7 8/26/99 4:59p Mikepc
43 renamed file extensions from .c to .cpp.
44 .cpp extension allows addition of namespace protection to remove
45 potential name collisions with tool code. Exceptions are CreateTplFile
46 and QuickConvert. These are extern "C" linked.
47
48 6 8/26/99 11:38a Mikepc
49
50 5 8/26/99 11:03a Mikepc
51 tplCon rewrite for efficient memory usage, batch file processing
52 ability.
53
54 $NoKeywords: $
55
56 -----------------------------------------------------------------------*/
57
58
59 #include <charPipeline/tc/TCPalTable.h>
60 #include <charPipeline/tc/TCCommon.h>
61
62 #include "TCPaletteList.h"
63 #include "TCMem.h"
64 #include "TCFileInternal.h"
65 #include "TCSrcImageList.h"
66 #include "TCGXDefs.h"
67
68 /********************************/
69 // global internal linked list variables
70 TCPalette* PlHead = 0;
71
72 /********************************/
73 // u8 array indices for color values
74 #define ID_R 0
75 #define ID_G 1
76 #define ID_B 2
77 #define ID_A 3
78
79 /*>*******************************(*)*******************************<*/
80 static void TCSwapPalette ( TCPalette* thisPal, TCPalette* thatPal );
81
82 /*>*******************************(*)*******************************<*/
83 // allocate a PalTable structure; allocate its associated 'rgba' array;
84 // set PalTable->numEntry
85 /*>*******************************(*)*******************************<*/
TCCreatePalTable(u32 numEntry)86 TCPalTable* TCCreatePalTable ( u32 numEntry )
87 {
88 TCPalTable* ptNew;
89
90
91 ptNew = (TCPalTable*)TCCalloc( 1, sizeof(TCPalTable));
92
93 ptNew->numEntry = numEntry;
94 ptNew->rgba = (u8*)TCCalloc( numEntry, 4 ); // 4B per entry (rgba)
95
96 return ptNew;
97 }
98
99 /*>*******************************(*)*******************************<*/
TCSetPalTableValue(TCPalTable * ptPtr,u32 index,u8 r,u8 g,u8 b,u8 a)100 void TCSetPalTableValue ( TCPalTable* ptPtr, u32 index, u8 r, u8 g, u8 b, u8 a )
101 {
102 u8* rgbaPtr;
103
104
105 rgbaPtr = (u8*)( (u8*)(ptPtr->rgba) + (index * 4) );
106
107 rgbaPtr[ID_R] = r;
108 rgbaPtr[ID_G] = g;
109 rgbaPtr[ID_B] = b;
110 rgbaPtr[ID_A] = a;
111 }
112
113 /*>*******************************(*)*******************************<*/
TCGetPalTableValue(TCPalTable * ptPtr,u32 index,u8 * rPtr,u8 * gPtr,u8 * bPtr,u8 * aPtr)114 void TCGetPalTableValue ( TCPalTable* ptPtr, u32 index, u8* rPtr,
115 u8* gPtr, u8* bPtr, u8* aPtr )
116 {
117 u8* rgbaPtr;
118
119
120 rgbaPtr = (u8*)( (u8*)(ptPtr->rgba) + (index * 4) );
121
122 if( rPtr )
123 *rPtr = rgbaPtr[ID_R];
124 if( gPtr )
125 *gPtr = rgbaPtr[ID_G];
126 if( bPtr )
127 *bPtr = rgbaPtr[ID_B];
128 if( aPtr )
129 *aPtr = rgbaPtr[ID_A];
130 }
131
132 /*>*******************************(*)*******************************<*/
133 // note: in this version, palettes must have 256 entries
134 /*>*******************************(*)*******************************<*/
TCSetPalettes(void)135 void TCSetPalettes ( void )
136 {
137 TCPalette* plPtr;
138 TCSrcImage* siPtr;
139 TCFile* dfPtr;
140 u8 r, g, b, a;
141 u32 i;
142
143
144 plPtr = PlHead;
145 while( plPtr )
146 {
147 // find this palette's source image and decode the file
148 siPtr = TCFindSrcImageByIndex( plPtr->srcImage );
149 dfPtr = TCReadFile( siPtr->fileName );
150
151 // make sure a palette is present in the file
152 TCAssertMsg( (dfPtr->palPtr != NULL), "TCSetPalettes: file %s has no palette\n", siPtr->fileName );
153
154 plPtr->palPtr = (TCPalTable*)TCCreatePalTable( dfPtr->palPtr->numEntry );
155
156 // copy out the palette
157 for( i=0; i< dfPtr->palPtr->numEntry; i++ )
158 {
159 TCGetPalTableValue( dfPtr->palPtr, i, &r, &g, &b, &a );
160 TCSetPalTableValue( plPtr->palPtr, i, r, g, b, a );
161 }
162
163 plPtr = plPtr->next;
164
165 } // end while( thisPal )
166
167 }
168
169 /*>*******************************(*)*******************************<*/
TCNewPalette(void)170 TCPalette* TCNewPalette ( void )
171 {
172 TCPalette* newPl, *tail;
173
174
175 newPl = (TCPalette*)TCCalloc( 1, sizeof(TCPalette) );
176
177 if( PlHead == NULL )
178 {
179 PlHead = newPl;
180 }
181 else
182 {
183 tail = PlHead;
184 while( tail->next )
185 {
186 tail = tail->next;
187 }
188
189 tail->next = newPl;
190 newPl->prev = tail;
191 newPl->next = NULL;
192 }
193
194 return newPl;
195 }
196
197 /*>*******************************(*)*******************************<*/
TCSetPaletteIndex(TCPalette * pl,u32 index)198 void TCSetPaletteIndex ( TCPalette* pl, u32 index )
199 {
200 TCAssertMsg( (pl != NULL), "TCSetPaletteIndex: NULL TCPalette ptr\n" );
201
202 pl->index = index;
203 }
204
205 /*>*******************************(*)*******************************<*/
TCSetPaletteSrcImage(TCPalette * pl,u32 srcImage)206 void TCSetPaletteSrcImage ( TCPalette* pl, u32 srcImage )
207 {
208 TCAssertMsg( (pl != NULL), "TCSetPaletteSrcImage: NULL TCPalette ptr\n" );
209
210 pl->srcImage = srcImage;
211 }
212
213 /*>*******************************(*)*******************************<*/
TCSetPaletteEntryFormat(TCPalette * pl,u32 entryFmt)214 void TCSetPaletteEntryFormat( TCPalette* pl, u32 entryFmt )
215 {
216
217 TCAssertMsg( (pl != NULL), "TCSetPaletteEntryFormat: NULL TCPalette ptr\n" );
218
219 switch(entryFmt)
220 {
221 case TPL_PALETTE_ENTRY_FMT_R5G6B5:
222
223 pl->entryFormat = entryFmt;
224 break;
225
226 case TPL_PALETTE_ENTRY_FMT_RGB5A3:
227
228 pl->entryFormat = entryFmt;
229 break;
230
231 default:
232 TCErrorMsg( "TCSetPaletteEntryFormat: palette %d; unknown output format\n", pl->index );
233 break;
234 }
235 }
236
237 /*>*******************************(*)*******************************<*/
238 // sort indices from lowest to highest
239 /*>*******************************(*)*******************************<*/
TCSortPaletteByIndex(void)240 void TCSortPaletteByIndex ( void )
241 {
242 TCPalette* thisPal, *nextPal;
243
244
245 if( (PlHead == NULL) || (PlHead->next == NULL) )
246 {
247 return;
248 }
249
250 thisPal = PlHead;
251 while( thisPal->next )
252 {
253 nextPal = thisPal->next;
254
255 if( nextPal->index < thisPal->index )
256 {
257 // swap just the data, not the pointers
258 TCSwapPalette( thisPal, nextPal );
259
260 thisPal = PlHead;
261 continue;
262 }
263
264 thisPal = thisPal->next;
265 }
266 }
267
268 /*>*******************************(*)*******************************<*/
TCSwapPalette(TCPalette * thisPal,TCPalette * thatPal)269 static void TCSwapPalette ( TCPalette* thisPal, TCPalette* thatPal )
270 {
271 TCPalette tmpPl;
272
273
274 tmpPl.index = thisPal->index;
275 tmpPl.srcImage = thisPal->srcImage;
276 tmpPl.entryFormat = thisPal->entryFormat;
277 tmpPl.palPtr = thisPal->palPtr;
278 tmpPl.tplPaletteBankOffset = thisPal->tplPaletteBankOffset;
279 tmpPl.tplBufferSize = thisPal->tplBufferSize;
280
281 thisPal->index = thatPal->index;
282 thisPal->srcImage = thatPal->srcImage;
283 thisPal->entryFormat = thatPal->entryFormat;
284 thisPal->palPtr = thatPal->palPtr;
285 thisPal->tplPaletteBankOffset = thatPal->tplPaletteBankOffset;
286 thisPal->tplBufferSize = thatPal->tplBufferSize;
287
288 thatPal->index = tmpPl.index;
289 thatPal->srcImage = tmpPl.srcImage;
290 thatPal->entryFormat = tmpPl.entryFormat;
291 thatPal->palPtr = tmpPl.palPtr;
292 thatPal->tplPaletteBankOffset = tmpPl.tplPaletteBankOffset;
293 thatPal->tplBufferSize = tmpPl.tplBufferSize;
294 }
295
296 /*>*******************************(*)*******************************<*/
TCFindPaletteByIndex(u32 index)297 TCPalette* TCFindPaletteByIndex ( u32 index )
298 {
299 TCPalette* plTmp;
300
301
302 if( index == TC_UNUSED )
303 return NULL;
304
305 plTmp = PlHead;
306 while( plTmp )
307 {
308 if( plTmp->index == index )
309 {
310 return plTmp;
311 }
312 plTmp = plTmp->next;
313 }
314
315 TCErrorMsg( "TCFindPaletteByIndex: palette %d is not part of palette list\n", index );
316 return NULL;
317 }
318
319 /*>*******************************(*)*******************************<*/
320 // find the position of an image relative to the list head;
321 // this corresponds to its 'array' index (assume a sorted list)
322 /*>*******************************(*)*******************************<*/
TCFindPalettePos(TCPalette * pl)323 u32 TCFindPalettePos( TCPalette* pl )
324 {
325 TCPalette* plPtr;
326 u32 pos;
327
328
329 TCAssertMsg( (pl != NULL), "TCFindPalettePos: NULL palette ptr\n" );
330 TCAssertMsg( (PlHead != NULL), "TCFindPalettePos: NULL palette list\n" );
331
332 pos = 0;
333 plPtr = PlHead;
334 while( plPtr )
335 {
336 if( pl == plPtr )
337 {
338 return pos;
339 }
340
341 pos++;
342 plPtr = plPtr->next;
343 }
344
345 TCErrorMsg( "TCFindPalettePos: palette %d is not part of palette list\n", pl->index );
346 return 0;
347 }
348
349 /*>*******************************(*)*******************************<*/
350