FS2_Open
Open source remastering of the Freespace 2 engine
palman.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) Volition, Inc. 1999. All rights reserved.
3  *
4  * All source code herein is the property of Volition, Inc. You may not sell
5  * or otherwise commercially exploit the source or things you created based on the
6  * source.
7  *
8 */
9 
10 
11 
12 #include "bmpman/bmpman.h"
13 #include "cfile/cfile.h"
14 #include "debugconsole/console.h"
15 #include "graphics/grinternal.h"
16 #include "palman/palman.h"
17 #include "parse/parselo.h"
18 #include "pcxutils/pcxutils.h"
19 
20 
21 #define SQUARE(x) ((x)*(x))
22 
23 #define NUM_BLEND_TABLES 3
24 float blend_table_factors[NUM_BLEND_TABLES] = { 0.5f, 1.0f, 1.2f };
25 
28 ubyte gr_fade_table[(256*34)*2];
29 static ubyte palette_blend_table[NUM_BLEND_TABLES*256*256];
30 
33 
35 
37 
38 #define LOOKUP_SIZE (64*64*64)
40 
41 static char palette_name[128] = { "none" };
42 
43 static int Palman_restrict_colors = 0;
44 
45 //extern ubyte palette_org[256*3];
46 
49 
52 
53 int palman_is_nondarkening(int r,int g, int b)
54 {
55  int i;
56 
57  for (i=0; i<Palman_num_nondarkening; i++ ) {
58  if ( (r==Palman_non_darkening[i][0]) && (g==Palman_non_darkening[i][1]) && (b==Palman_non_darkening[i][2]) ) {
59  return 1;
60  }
61  }
62  return 0;
63 }
64 
66 {
67  try
68  {
69  // open pixels.tbl
70  read_file_text("pixels.tbl", CF_TYPE_TABLES);
71  reset_parse();
72 
73  // parse pixels
74  while (!optional_string("#END")){
75  // nondarkening pixel
76  if (required_string("+ND")){
78  stuff_ubyte(&Palman_non_darkening_default[Palman_num_nondarkening_default][1]);
79  stuff_ubyte(&Palman_non_darkening_default[Palman_num_nondarkening_default++][2]);
80  }
81  }
82 
83  // set this to be the active table
85  }
86  catch (const parse::ParseException& e)
87  {
88  mprintf(("TABLES: Unable to parse '%s'! Error message = %s.\n", "pixels.tbl", e.what()));
89  return;
90  }
91 }
92 
94 {
95  // if we're supposed to use the passed table
96  memcpy(Palman_non_darkening, colors, MAX_NONDARK_COLORS * 3);
98 }
99 
101 {
102  int i;
103 
104  for (i=0; i<LOOKUP_SIZE; i++ ) {
105  palette_lookup[i] = 255;
106  }
107 }
108 
109 int palette_cache_find( int r, int g, int b )
110 {
111  if ( !palman_is_nondarkening(r,g,b)) {
112  int value = ((r/4)<<12)+((g/4)<<6)+(b/4);
113  if ( palette_lookup[value] != 255 ) {
114  return palette_lookup[value];
115  }
116  }
117  return -1;
118 }
119 
120 void palette_cache_add( int r, int g, int b, int index )
121 {
122  int value = ((r/4)<<12)+((g/4)<<6)+(b/4);
123 
124  if ( !palman_is_nondarkening(r,g,b)) {
125  palette_lookup[value] = (ubyte)index;
126  }
127 }
128 
129 char palette_base_filename[128] = { "default" };
131 
132 void palette_load_table( const char * filename )
133 {
134  int i;
135  int w, h;
136  int pcx_error;
137 
138  strcpy_s( palette_base_filename, filename );
139  char * p = strchr(palette_base_filename,'.');
140  if ( p ) {
141  *p = 0;
142  }
143 
144  pcx_error = pcx_read_header(palette_base_filename, NULL, &w, &h, NULL, palette_org );
145  if ( pcx_error != PCX_ERROR_NONE ) {
146  // Read the old .256 file
147  CFILE *fp;
148  int fsize;
149  fp = cfopen( palette_base_filename, "rb" );
150  if ( fp==NULL)
151  Error( LOCATION, "Can't open palette file <%s>",palette_base_filename);
152 
153  fsize = cfilelength( fp );
154  Assert( fsize == 9472 );
155  cfread( palette_org, 256*3, 1, fp );
156  cfclose(fp);
157 
158  for (i=0; i<768; i++ ) {
159  palette_org[i] = ubyte((palette_org[i]*255)/63);
160  }
161  }
162 
164 
166 }
167 
168 
169 DCF(palette,"Loads a new palette")
170 {
171  char palette_file[MAX_FILENAME_LEN];
172 
173  if (dc_optional_string_either("help", "--help")) {
174  dc_printf( "Usage: palette <filename>\nLoads the palette file.\n" );
175  }
176 
178  palette_load_table(palette_file);
179 }
180 
182 
183 
184 uint palette_find( int r, int g, int b )
185 {
186  int i, j;
187  int best_value, best_index, value;
188 
189  int is_transparent = 0;
190  if ( (r == 0) && (g==255) && (b==0) ) {
191  is_transparent = 1;
192  }
193 
194  int restrict = 0;
195  if ( Palman_restrict_colors && (!Palman_allow_any_color) ) {
196  restrict = 1;
197  }
198 
199 // int rgb = ((r/4)<<12)+((g/4)<<6)+(b/4);
200 
201  i = palette_cache_find(r,g,b);
202  if ( i != -1 ) {
203  if ( restrict ) {
204  if ( i > 127 ) {
205  return i;
206  }
207  } else {
208  return i;
209  }
210  }
211 
212  best_value = 1000000000;
213  best_index = -1;
214 
215  int bottom_color = 0;
216  if ( restrict ) {
217  bottom_color = 128;
218  }
219 
220  j=3*bottom_color;
221 
222  for (i=bottom_color; i<255; i++ ) {
223  int pr, pg, pb;
224 
225  pr = gr_palette[j];
226  pg = gr_palette[j+1];
227  pb = gr_palette[j+2];
228 
229  value = SQUARE(r-pr) + SQUARE(g-pg) + SQUARE(b-pb);
230 
231  if ( (best_index==-1) || (value < best_value) ) {
232  // Don't map anything to 0,255,0 (transparent) ever, except 0,255,0
233  if (value==0) {
234  palette_cache_add( r, g, b, i );
235  return i;
236  }
237  // Not an exact match, so don't let anything map to a nondarkening color.
238  if ( (!is_transparent) && (!palman_is_nondarkening( pr, pg, pb )) ) {
239  best_value = value;
240  best_index = i;
241  }
242  }
243  j += 3;
244  }
245 
246  if ( best_index == -1 ) {
247  best_index = bottom_color;
248  }
249 
250  palette_cache_add( r, g, b, best_index );
251  return best_index;
252 }
253 
254 // version 0 - initial revision
255 // version 2 - changed 16-bpp fade table to include the 1.5 brightening factor
256 // version 3 - changed to put black in color 0 all the time
257 // version 4 - took out all truecolor lookup tables
258 // version 5 - changed palette to use 254 entries for nebula, made color mapping different
259 // version 6 - took out 1.5 brightness
260 // version 7 - added blending tables
261 // version 8 - made glows use additive blending
262 // version 9 - made 255,255,255 not fade
263 // version 10 - made fade table go to white again for anything l above 0.75.
264 // version 11 - made fade table go from 0-1 instead of 0-0.75
265 // version 12 - added variable gamma
266 // version 13 - Reduced blending tables from 5 to 3. Save 128KB RAM.
267 // version 14 - made palette never map anything to green.
268 // version 15 - made green blending with anything be black
269 // version 16 - added compression
270 // version 17 - added more nondarkening colors
271 // version 18 - fixed bug with blue nondarkening colors
272 // version 19 - fixed bug where only colors divisible by 4 got used.
273 // version 20 - added flag to only use lower 128 colors for palette.
274 #define PAL_ID 0x4c415056 // "LAPV" in file = VPAL (Volition Palette)
275 #define PAL_VERSION 20
276 #define PAL_LAST_COMPATIBLE_VERSION 20
277 
279 {
280  CFILE *fp;
281  char new_name[MAX_PATH_LEN];
282 
283  strcpy_s( new_name, name );
284  strcat_s( new_name, ".clr" );
285 
286 // mprintf(( "Writing palette cache file '%s'\n", new_name ));
287 
288  fp = cfopen( new_name, "wb", CFILE_NORMAL, CF_TYPE_CACHE );
289  if ( !fp ) return;
290 
291  cfwrite_uint( PAL_ID, fp );
292  cfwrite_int(PAL_VERSION, fp );
293  cfwrite( &gr_palette_checksum, 4, 1, fp );
294 
295  cfwrite_compressed( &gr_palette, 256*3, 1, fp ); // < 1 KB
296 
297  cfwrite_compressed( &palette_lookup, LOOKUP_SIZE, 1, fp ); // 256KB
298 
300  cfwrite_int(1,fp);
302  cfwrite_compressed( &gr_fade_table, 256*34*2, 1, fp ); // 17KB
303  } else {
304  cfwrite_int(0,fp);
305  }
306 
309  cfwrite_compressed( &palette_blend_table, 256*256, NUM_BLEND_TABLES, fp ); //64KB*
310  } else {
311  cfwrite_int(0,fp);
312  }
313 
314  cfclose(fp);
315 // mprintf(( "Done.\n" ));
316 }
317 
318 // Returns TRUE if successful, else 0
319 
321 {
322  CFILE *fp;
323  char new_name[MAX_PATH_LEN];
324  int version;
325  uint id, new_checksum;
326  ubyte new_palette[768];
327 
328  strcpy_s( new_name, name );
329  strcat_s( new_name, ".clr" );
330 
331 // mprintf(( "Reading palette '%s'\n", name ));
332 
333  fp = cfopen( new_name, "rb", CFILE_NORMAL, CF_TYPE_CACHE );
334 
335  // Couldn't find file
336  if ( !fp ) {
337  mprintf(( "No cached palette file\n" ));
338  return 0;
339  }
340 
341  id = cfread_uint( fp );
342  if ( id != PAL_ID ) {
343  mprintf(( "Cached palette file has incorrect ID\n" ));
344  cfclose(fp);
345  return 0;
346  }
347  version = cfread_int( fp );
348  if ( version < PAL_LAST_COMPATIBLE_VERSION ) {
349  mprintf(( "Cached palette file is an older incompatible version\n" ));
350  cfclose(fp);
351  return 0;
352  }
353 
354  cfread( &new_checksum, 4, 1, fp );
355  if ( gr_palette_checksum != new_checksum ) {
356  mprintf(( "Cached palette file is out of date (Checksum)\n" ));
357  cfclose(fp);
358  return 0;
359  }
360 
361  cfread_compressed( &new_palette, 256*3, 1, fp );
362  if ( memcmp( new_palette, gr_palette, 768 ) ) {
363  mprintf(( "Cached palette file is out of date (Contents)\n" ));
364  cfclose(fp);
365  return 0;
366  }
367 
368  cfread_compressed( &palette_lookup, LOOKUP_SIZE, 1, fp ); // 256KB
369 
370  int fade_table_saved = cfread_int(fp);
371 
372  if ( fade_table_saved ) {
373  int new_gamma;
374  cfread( &new_gamma, 4, 1, fp );
375  cfread_compressed( &gr_fade_table, 256*34*2, 1, fp ); // 17KB
376  if ( new_gamma == Gr_gamma_int ) {
378  } else {
380  }
381  } else {
383  }
384 
385  int num_blend_tables_saved = cfread_int(fp);
386  if ( (num_blend_tables_saved == NUM_BLEND_TABLES) && (num_blend_tables_saved>0)) {
388  cfread_compressed( &palette_blend_table, 256*256, NUM_BLEND_TABLES, fp ); //64KB*
389  } else {
391  }
392 
393  cfclose(fp);
394 
395 // mprintf(( "Done.\n" ));
396 
397  return 1;
398 }
399 
401 {
402  int i;
403 
404  // Make the blending table
405  for (i=0; i<256; i++ ) {
406  int j, r, g, b;
407  float si, fr, fg, fb, br, bg, bb;
408  float Sf, Df;
409 
410  fr = i2fl(gr_palette[i*3+0]);
411  fg = i2fl(gr_palette[i*3+1]);
412  fb = i2fl(gr_palette[i*3+2]);
413 
414  // Make everything blended with Xparent be black
415  if ( i==255 ) {
416  fr = fg = fb = 0.0f;
417  }
418 
419  si = (( fr+fg+fb ) / (256.0f*3.0f)) * factor;
420 
421  if ( factor > 1.0f ) {
422  if ( si > 1.0f ) {
423  Sf = 1.0f;
424  Df = 0.0f;
425  } else {
426  Sf = 1.0f;
427  Df = 1.0f - si;
428  }
429  } else {
430  if ( si > 1.0f ) {
431  Sf = 1.0f;
432  Df = 0.0f;
433  } else {
434  Sf = si;
435  Df = 1.0f;
436  }
437  Sf = factor;
438  Df = 1.0f;
439  }
440 
441 // Sf = Df =1.0f;
442 
443  for (j=0; j<256; j++ ) {
444  br = i2fl(gr_palette[j*3+0]);
445  bg = i2fl(gr_palette[j*3+1]);
446  bb = i2fl(gr_palette[j*3+2]);
447 
448  // Make all things on top of Xparent be black
449  if ( j==255 ) {
450  br = bg = bb = 0.0f;
451  }
452 
453  r = fl2i( fr*Sf + br*Df );
454  g = fl2i( fg*Sf + bg*Df );
455  b = fl2i( fb*Sf + bb*Df );
456 
457  int max = r;
458  if ( g > max ) max = g;
459  if ( b > max ) max = b;
460  if ( max > 255 ) {
461  r = (255*r)/max;
462  g = (255*g)/max;
463  b = (255*b)/max;
464  }
465  if ( r > 255 ) r = 255; else if ( r < 0 ) r = 0;
466  if ( g > 255 ) g = 255; else if ( g < 0 ) g = 0;
467  if ( b > 255 ) b = 255; else if ( b < 0 ) b = 0;
468 
469  if ( i == 255 )
470  table[i*256+j] = (unsigned char)j;
471  else {
472  // If background transparent, and color isn't bright, call it transparent.
473  if ( j == 255 && ((r+g+b) < 110)) {
474  table[i*256+j] = 255;
475  } else {
476  table[i*256+j] = (unsigned char)palette_find(r,g,b);
477  }
478  }
479  }
480  }
481 }
482 
484 {
485  // DB 2/3/99 - I think this was causing some wacky unhandled exceptions at game shutdown. Since we don't use palettes anymore.....
486  /*
487  if ( stricmp( palette_name, "none" ) ) {
488  palette_write_cached1( palette_name );
489  }
490  */
491 }
492 
493 
494 // When gr_set_palette is called, it fills in gr_palette and then calls this
495 // function, which should update all the tables.
496 // Pass NULL to flush current palette.
497 void palette_update(const char *name_with_extension, int restrict_font_to_128)
498 {
499  uint tmp_checksum;
500  char name[MAX_PATH_LEN];
501 
502  Palman_restrict_colors = restrict_font_to_128;
503 
504  strcpy_s( name, name_with_extension );
505  char *p = strchr( name, '.' );
506  if ( p ) *p = 0;
507 
508  strcpy_s( palette_name, name );
509 
510  tmp_checksum = palette_compute_checksum( gr_palette );
511  if ( tmp_checksum == gr_palette_checksum ) return;
512 
513  gr_palette_checksum = tmp_checksum;
514 
515  // Clear the lookup cache, since the palette has changed
519 
520  // For "none" palettes, don't calculate tables
521  if ( !stricmp( name, "none" ) ) {
522  return;
523  }
524 
525  // Read in the cached info if there is any.
526  if ( palette_read_cached( name ) ) {
527  return;
528  }
529 }
530 
531 
533 {
534  int i;
535 
537 // mprintf(( "Creating blending table..." ));
538  for (i=0; i<NUM_BLEND_TABLES; i++ ) {
539  palman_create_blend_table(blend_table_factors[i], &palette_blend_table[i*256*256] );
540  }
541 // mprintf(( "done\n" ));
543  }
544 
545  for (i=0; i<NUM_BLEND_TABLES; i++ ) {
546  if ( alpha <= blend_table_factors[i] )
547  break;
548  }
549  if ( i>NUM_BLEND_TABLES-1 ) i = NUM_BLEND_TABLES-1;
550 
551  return &palette_blend_table[i*256*256];
552 }
553 
554 
555 
556 // compute a simple checksum on the given palette. Used by the bitmap manager
557 // to determine if we need to reload a new palette for a bitmap. Code liberally
558 // stolen from descent networking checksum code
560 {
561  int i;
562  uint sum1, sum2;
563 
564  sum1 = sum2 = 0;
565 
566  for (i = 0; i < 768; i++) {
567  sum1 += (uint)pal[i];
568  if ( sum1 >= 255 ) sum1 -= 255;
569  sum2 += sum1;
570  }
571  sum2 %= 255;
572 
573  return ((sum1<<8)+sum2);
574 }
575 
576 // this function takes a bitmap number and sets the game palette to the palette of this
577 // bitmap.
579 {
580  ubyte tmp[768];
581  char name[MAX_PATH_LEN];
582 
583  bm_get_palette(n, tmp, name); // get the palette for this bitmap
584 
585  gr_set_palette(name, tmp); // load the new palette.
586 }
587 
589 {
590  ubyte tmp[768];
591  memcpy(tmp, palette_org, 3*256);
592 
593  if ( palette_base_loaded ) {
595  }
596 }
#define MAX_FILENAME_LEN
Definition: pstypes.h:324
#define CFILE_NORMAL
Definition: cfile.h:89
int i
Definition: multi_pxo.cpp:466
int cfwrite_compressed(void *param_buf, int param_elsize, int param_nelem, CFILE *cfile)
Definition: cfilelist.cpp:426
GLfloat GLfloat GLfloat GLfloat h
Definition: Glext.h:7280
float blend_table_factors[NUM_BLEND_TABLES]
Definition: palman.cpp:24
int palette_cache_find(int r, int g, int b)
Definition: palman.cpp:109
int Palman_num_nondarkening
Definition: palman.cpp:50
int cfread(void *buf, int elsize, int nelem, CFILE *fp)
GLsizei const GLfloat * value
Definition: Glext.h:5646
GLuint index
Definition: Glext.h:5608
int cfwrite_uint(uint i, CFILE *file)
Definition: cfile.cpp:1316
Assert(pm!=NULL)
#define mprintf(args)
Definition: pstypes.h:238
int Palman_allow_any_color
Definition: palman.cpp:181
void palman_set_nondarkening(ubyte colors[MAX_NONDARK_COLORS][3], int size)
Definition: palman.cpp:93
GLclampf f
Definition: Glext.h:7097
void palette_cache_clear()
Definition: palman.cpp:100
#define PCX_ERROR_NONE
Definition: pcxutils.h:25
int palette_fade_table_calculated
Definition: palman.cpp:32
Definition: cfile.h:28
float factor
Definition: lua.cpp:440
GLsizeiptr size
Definition: Glext.h:5496
GLenum GLsizei GLenum GLenum const GLvoid * table
Definition: Glext.h:5221
DCF(palette,"Loads a new palette")
Definition: palman.cpp:169
cfp version
Definition: cfile.cpp:1063
GLdouble GLdouble GLdouble r
Definition: Glext.h:5337
unsigned int uint
Definition: pstypes.h:64
char palette_base_filename[128]
Definition: palman.cpp:129
GLboolean GLboolean g
Definition: Glext.h:5781
#define cfopen(...)
Definition: cfile.h:134
ubyte gr_fade_table[(256 *34)*2]
Definition: palman.cpp:28
char * filename
#define w(p)
Definition: modelsinc.h:68
#define CF_TYPE_TABLES
Definition: cfile.h:50
GLint fsize
Definition: Glext.h:8879
int palette_read_cached(char *name)
Definition: palman.cpp:320
int required_string(const char *pstr)
Definition: parselo.cpp:468
uint gr_palette_checksum
Definition: palman.cpp:34
int palette_base_loaded
Definition: palman.cpp:130
void palette_write_cached1(char *name)
Definition: palman.cpp:278
int optional_string(const char *pstr)
Definition: parselo.cpp:539
int cfwrite(const void *buf, int elsize, int nelem, CFILE *cfile)
Definition: cfile.cpp:1414
bool dc_optional_string_either(const char *str1, const char *str2)
Searches for an optional string and it's alias.
GLenum GLuint id
Definition: Glext.h:5156
int pcx_read_header(const char *real_filename, CFILE *img_cfp, int *w, int *h, int *bpp, ubyte *pal)
Definition: pcxutils.cpp:40
void read_file_text(const char *filename, int mode, char *processed_text, char *raw_text)
Definition: parselo.cpp:1995
#define MAX_NONDARK_COLORS
Definition: palman.h:43
uint palette_compute_checksum(ubyte *pal)
Definition: palman.cpp:559
cfbp fp
Definition: cfile.cpp:1065
uint palette_find(int r, int g, int b)
Definition: palman.cpp:184
void bm_get_palette(int handle, ubyte *pal, char *name)
Gets the palette for a given bitmap indexed by handle, and optionally the filename.
Definition: bmpman.cpp:850
int cfwrite_int(int i, CFILE *file)
Definition: cfile.cpp:1310
void gr_set_palette(const char *name, ubyte *palette, int restrict_font_to_128)
Definition: 2d.cpp:722
GLclampd n
Definition: Glext.h:7286
unsigned char ubyte
Definition: pstypes.h:62
void palette_flush()
Definition: palman.cpp:483
ubyte palette_org[256 *3]
Definition: palman.cpp:26
void palette_update(const char *name_with_extension, int restrict_font_to_128)
Definition: palman.cpp:497
void _cdecl void void _cdecl Error(const char *filename, int line, SCP_FORMAT_STRING const char *format,...) SCP_FORMAT_STRING_ARGS(3
uint palman_screen_signature
Definition: palman.cpp:36
#define CF_TYPE_CACHE
Definition: cfile.h:72
void reset_parse(char *text)
Definition: parselo.cpp:3305
ubyte gr_palette[256 *3]
Definition: palman.cpp:27
GLuint const GLchar * name
Definition: Glext.h:5608
#define NUM_BLEND_TABLES
Definition: palman.cpp:23
#define MAX_PATH_LEN
Definition: pstypes.h:325
void dc_stuff_string_white(char *out_str, size_t maxlen)
Stuffs a whitespace delimited string to out_str from the command line, stopping at the end of the com...
ubyte palette_lookup[64 *64 *64]
Definition: palman.cpp:39
GLboolean GLboolean GLboolean b
Definition: Glext.h:5781
#define PAL_LAST_COMPATIBLE_VERSION
Definition: palman.cpp:276
#define PAL_ID
Definition: palman.cpp:274
ubyte Palman_non_darkening_default[MAX_NONDARK_COLORS][3]
Definition: palman.cpp:48
void palette_cache_add(int r, int g, int b, int index)
Definition: palman.cpp:120
void palman_load_pixels()
Definition: palman.cpp:65
#define LOOKUP_SIZE
Definition: palman.cpp:38
#define strcat_s(...)
Definition: safe_strings.h:68
void palette_use_bm_palette(int n)
Definition: palman.cpp:578
void palman_create_blend_table(float factor, ubyte *table)
Definition: palman.cpp:400
#define fl2i(fl)
Definition: floating.h:33
int Gr_gamma_int
Definition: 2d.cpp:68
ubyte Palman_non_darkening[MAX_NONDARK_COLORS][3]
Definition: palman.cpp:51
void palette_restore_palette()
Definition: palman.cpp:588
GLfloat GLfloat p
Definition: Glext.h:8373
int palman_is_nondarkening(int r, int g, int b)
Definition: palman.cpp:53
An overhauled/updated debug console to allow monitoring, testing, and general debugging of new featur...
#define LOCATION
Definition: pstypes.h:245
int palette_blend_table_calculated
Definition: palman.cpp:31
int Palman_num_nondarkening_default
Definition: palman.cpp:47
#define i2fl(i)
Definition: floating.h:32
int cfread_int(CFILE *file, int ver, int deflt)
Definition: cfile.cpp:1164
void dc_printf(const char *format,...)
Prints the given char string to the debug console.
Definition: console.cpp:358
void stuff_ubyte(ubyte *i)
Definition: parselo.cpp:2646
int cfread_compressed(void *buf, int elsize, int nelem, CFILE *cfile)
Definition: cfilelist.cpp:385
int cfclose(CFILE *cfile)
Definition: cfile.cpp:895
GLclampf GLclampf GLclampf alpha
Definition: Glext.h:5177
ubyte * palette_get_blend_table(float alpha)
Definition: palman.cpp:532
#define stricmp(s1, s2)
Definition: config.h:271
int cfilelength(CFILE *cfile)
Definition: cfile.cpp:1393
uint cfread_uint(CFILE *file, int ver, uint deflt)
Definition: cfile.cpp:1178
#define SQUARE(x)
Definition: palman.cpp:21
#define strcpy_s(...)
Definition: safe_strings.h:67
void palette_load_table(const char *filename)
Definition: palman.cpp:132
#define PAL_VERSION
Definition: palman.cpp:275