AlphaPalette.cpp 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. //===========================================================================//
  2. // Copyright (C) Microsoft Corporation. All rights reserved. //
  3. //===========================================================================//
  4. #include <stdio.h>
  5. #ifndef FILE_H
  6. #include "file.h"
  7. #endif
  8. #include "vfx.h"
  9. #include <string.h>
  10. #include <gameos.hpp>
  11. unsigned char FindClosest( VFX_RGB* Palette, int r, int g, int b );
  12. //
  13. //
  14. // Number of colors listed in the AlphaPal.ini file (>255 are special colors)
  15. //
  16. //
  17. #define NUM_ALPHACOLORS 280 // (One+last color listed)
  18. //
  19. // Table used for alpha effects
  20. // Low byte = Background
  21. // High byte = Sprite
  22. //
  23. char AlphaTable[NUM_ALPHACOLORS*256];
  24. //
  25. // Flag set to 1 when an alpha pixel is used
  26. //
  27. char SpecialColor[NUM_ALPHACOLORS];
  28. enum { R, G, B, SourceAlpha, DestAlpha };
  29. char *g_logistic_fadetable = &AlphaTable[256*256];
  30. char *g_logistic_bluefade = &AlphaTable[267*256];
  31. char *g_logistic_dlgfade = &AlphaTable[268*256];
  32. void InitAlphaLookup( VFX_RGB* Palette)
  33. {
  34. char* pAlphaTable = AlphaTable;
  35. int r,g,b,i;
  36. File *IniFile;
  37. char Line[256];
  38. float AlphaIni[NUM_ALPHACOLORS][5];
  39. int LineNumber;
  40. //
  41. // Clear the AlphaPal.ini array
  42. //
  43. memset(AlphaIni,0,sizeof(AlphaIni));
  44. memset(SpecialColor,0,sizeof(SpecialColor));
  45. //
  46. // Read in and parse the AlphaPal.ini file containing all the color information
  47. //
  48. IniFile = new File;
  49. #ifdef _DEBUG
  50. long AlphapalOpenResult =
  51. #endif
  52. IniFile->open("AlphaPal.ini");
  53. gosASSERT(AlphapalOpenResult == NO_ERR);
  54. LineNumber=0;
  55. while (!IniFile->eof())
  56. {
  57. IniFile->readLine((MemoryPtr)&Line[0], 256);
  58. LineNumber++;
  59. if (Line[0]!='#' && Line[0]!=';' && Line[0]!=0xa && Line[0]!=0)
  60. {
  61. if( EOF == sscanf( Line, "%d", &i ))
  62. break;
  63. gosASSERT(i>=0 && i<NUM_ALPHACOLORS);
  64. SpecialColor[i]=1;
  65. gosASSERT(EOF != sscanf( Line, "%f %f %f %f %f",
  66. &AlphaIni[i][R],
  67. &AlphaIni[i][G],
  68. &AlphaIni[i][B],
  69. &AlphaIni[i][SourceAlpha],
  70. &AlphaIni[i][DestAlpha] ));
  71. gosASSERT(( AlphaIni[i][SourceAlpha]!=0.0 || AlphaIni[i][DestAlpha]!=0.0 ) &&
  72. ( AlphaIni[i][R]!=255 && AlphaIni[i][G]!=255 && AlphaIni[i][B]!=255 ) );
  73. }
  74. }
  75. IniFile->close();
  76. delete IniFile;
  77. IniFile = NULL;
  78. //
  79. // Now generate the 64K alpha value lookup table
  80. //
  81. for( int source=0; source<NUM_ALPHACOLORS; source++ )
  82. {
  83. for( int dest=0; dest<256; dest++ )
  84. {
  85. if( source==255 || source==0 ) // Color 255 and 0 - dest color remains the same (totally transparent)
  86. {
  87. *pAlphaTable++= dest;
  88. }
  89. else if( SpecialColor[source]==0 ) // If not specified, make a solid color
  90. {
  91. *pAlphaTable++= source;
  92. }
  93. else if( dest<10 || dest>245 )
  94. {
  95. *pAlphaTable++= char(-1); // Is dest is ever a bad pixel, make white
  96. }
  97. else
  98. {
  99. if( AlphaIni[source][SourceAlpha]==0.0 && AlphaIni[source][DestAlpha]==0.0 )
  100. {
  101. r = (int) (((float)(Palette[dest].r<<2) * 255 ) / ( 255 - AlphaIni[source][R] ) );
  102. g = (int) (((float)(Palette[dest].g<<2) * 255 ) / ( 255 - AlphaIni[source][G] ) );
  103. b = (int) (((float)(Palette[dest].b<<2) * 255 ) / ( 255 - AlphaIni[source][B] ) );
  104. }
  105. else
  106. {
  107. r = (int)(AlphaIni[source][SourceAlpha] * AlphaIni[source][R] + AlphaIni[source][DestAlpha] * (float)(Palette[dest].r<<2));
  108. g = (int)(AlphaIni[source][SourceAlpha] * AlphaIni[source][G] + AlphaIni[source][DestAlpha] * (float)(Palette[dest].g<<2));
  109. b = (int)(AlphaIni[source][SourceAlpha] * AlphaIni[source][B] + AlphaIni[source][DestAlpha] * (float)(Palette[dest].b<<2));
  110. }
  111. if( r<0 )
  112. r=0;
  113. else if( r>255 )
  114. r=255;
  115. if( g<0 )
  116. g=0;
  117. else if( g>255 )
  118. g=255;
  119. if( b<0 )
  120. b=0;
  121. else if( b>255 )
  122. b=255;
  123. *pAlphaTable++ = FindClosest( Palette,r>>2,g>>2,b>>2 );
  124. }
  125. }
  126. }
  127. }
  128. //
  129. //
  130. // 51% Green
  131. // 39% Red
  132. // 10% Blue
  133. //
  134. // Returns the closest matching color in a palette, dose not check windows colors
  135. //
  136. unsigned char FindClosest( VFX_RGB* Palette, int r, int g, int b )
  137. {
  138. unsigned char Closest = 10;
  139. int Distance = 255*255*255;
  140. int tempR,tempG,tempB,tdist;
  141. for( int t1=10; t1<246; t1++ )
  142. {
  143. tempR = r-Palette[t1].r;
  144. tempG = g-Palette[t1].g;
  145. tempB = b-Palette[t1].b;
  146. tdist = (39*tempR*tempR) + (51*tempG*tempG) + (10*tempB*tempB);
  147. if( Distance > tdist )
  148. {
  149. Distance = tdist;
  150. Closest = t1;
  151. if( tdist==0 )
  152. break;
  153. }
  154. }
  155. return Closest;
  156. }