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