LIB.CPP 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. /*
  2. ** Command & Conquer Red Alert(tm)
  3. ** Copyright 2025 Electronic Arts Inc.
  4. **
  5. ** This program is free software: you can redistribute it and/or modify
  6. ** it under the terms of the GNU General Public License as published by
  7. ** the Free Software Foundation, either version 3 of the License, or
  8. ** (at your option) any later version.
  9. **
  10. ** This program is distributed in the hope that it will be useful,
  11. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. ** GNU General Public License for more details.
  14. **
  15. ** You should have received a copy of the GNU General Public License
  16. ** along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. /* $Header: g:/library/source/rcs/./lib.c 1.16 1994/05/20 15:34:33 joe_bostic Exp $ */
  19. /***************************************************************************
  20. ** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S **
  21. ***************************************************************************
  22. * *
  23. * Project Name : Library Routines *
  24. * *
  25. * File Name : LIB.C *
  26. * *
  27. * Programmer : Scott Bowen *
  28. * *
  29. * Start Date : January 14, 1993 *
  30. * *
  31. * Last Update : May 20, 1993 [PWG] *
  32. * *
  33. *-------------------------------------------------------------------------*
  34. * Functions: *
  35. * Add_Long_To_Pointer -- Pointer arithmatic when pointer could be XMS. *
  36. * Find_Argv -- Checks to see if string is in arguement *
  37. * Mono_Mem_Dump -- Dumps memory to mono monitor with hex and char. *
  38. * Convert_HSV_To_RGB -- Converts HSV cordinates to RGB values *
  39. * Convert_RGB_To_HSV -- Converts RGB to RSV coordinates. *
  40. * Set_Search_Drives -- Sets up the CDRom and HardDrive paths. *
  41. * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  42. #include <dos.h>
  43. #include <stdio.h>
  44. #include <string.h>
  45. #include "misc.h"
  46. //PRIVATE unsigned Divide_With_Round(unsigned num, unsigned den);
  47. /***************************************************************************
  48. * Divide_With_Round -- Divides integers and round to nearest integer. *
  49. * *
  50. * INPUT: int numberator. *
  51. * int denominator. *
  52. * *
  53. * OUTPUT: Returns value rounded. *
  54. * *
  55. * WARNINGS: *
  56. * *
  57. * HISTORY: *
  58. * 02/13/1992 SB : Created. *
  59. *=========================================================================*/
  60. static unsigned Divide_With_Round(unsigned num, unsigned den)
  61. {
  62. // return num/den + (0 ro 1). 1 if the remainder is more than half the denominator.
  63. return( (num / den) + (unsigned)((num % den) >= ((den + 1) >> 1)) );
  64. }
  65. #define HSV_BASE 255 // This is used to get a little better persion on HSV conversion.
  66. #define RGB_BASE 63 // Not 64, this is really the max value.
  67. /***************************************************************************
  68. * Convert_RGB_To_HSV -- Converts RGB to RSV coordinates. *
  69. * *
  70. * INPUT: int r,g, and b values. *
  71. * int *h, *s, and *v pointers. *
  72. * *
  73. * OUTPUT: Assigns values to *h, *s, and *v. *
  74. * *
  75. * WARNINGS: The reason we use a different base for HSV then RGB is *
  76. * because we loose alot of persision by not using floating *
  77. * point. Using the same base value (63) made it so that *
  78. * about 50% of the time one RGB value would be one different *
  79. * then the original if you went from RGB to HSV to RGB. *
  80. * Using 255 drop it down to about 9% of the time we get an *
  81. * off value. To get it perfect, we would have to make the *
  82. * HSV base larger - but then you need to do all calculations *
  83. * in long instead of unsigned int. *
  84. * HISTORY: *
  85. * 02/11/1992 SB : Created. *
  86. *=========================================================================*/
  87. void Convert_RGB_To_HSV(unsigned int r, unsigned int g, unsigned int b, unsigned int *h, unsigned int *s, unsigned int *v)
  88. {
  89. unsigned int m, r1, g1, b1, tmp;
  90. // Convert RGB base to HSV base.
  91. r = Divide_With_Round((r * HSV_BASE), RGB_BASE);
  92. g = Divide_With_Round((g * HSV_BASE), RGB_BASE);
  93. b = Divide_With_Round((b * HSV_BASE), RGB_BASE);
  94. // Set hue to default.
  95. *h = 0;
  96. // Set v = Max(r,g,b) to find dominant primary color.
  97. *v = (r > g) ? r : g;
  98. if (b > *v) *v = b;
  99. // Set m = min(r,g,b) to find amount of white.
  100. m = (r < g) ? r : g;
  101. if (b < m) m = b;
  102. // Determine the normalized saturation.
  103. if (*v != 0) {
  104. *s = Divide_With_Round( (*v - m) * HSV_BASE ,*v);
  105. } else {
  106. *s = 0;
  107. }
  108. if (*s != 0) {
  109. tmp = *v - m;
  110. r1 = Divide_With_Round( (*v - r) * HSV_BASE, tmp);
  111. g1 = Divide_With_Round( (*v - g) * HSV_BASE, tmp);
  112. b1 = Divide_With_Round( (*v - b) * HSV_BASE, tmp);
  113. // Find effect of second most predominant color.
  114. // In which section of the hexagon of colors does the color lie?
  115. if ((*v) == r) {
  116. if (m == g) {
  117. *h = 5 * HSV_BASE + b1;
  118. } else {
  119. *h = 1 * HSV_BASE - g1;
  120. }
  121. } else {
  122. if ((*v) == g) {
  123. if (m == b) {
  124. *h = 1 * HSV_BASE + r1;
  125. } else {
  126. *h = 3 * HSV_BASE - b1;
  127. }
  128. } else {
  129. // *v == b
  130. if (m == r) {
  131. *h = 3 * HSV_BASE + g1;
  132. } else {
  133. *h = 5 * HSV_BASE - r1;
  134. }
  135. }
  136. }
  137. // Divide by six and round.
  138. *h = Divide_With_Round(*h, 6);
  139. }
  140. }
  141. /***************************************************************************
  142. * Convert_HSV_To_RGB -- Converts HSV cordinates to RGB values *
  143. * *
  144. * INPUT: int h,s, and v coordinates *
  145. * int *r, *g, and *b pointers. *
  146. * *
  147. * OUTPUT: Assigns values to *r, *g, and *b. *
  148. * *
  149. * WARNINGS: *
  150. * *
  151. * HISTORY: *
  152. * 02/11/1992 SB : Created. *
  153. *=========================================================================*/
  154. void Convert_HSV_To_RGB(unsigned int h, unsigned int s, unsigned int v, unsigned int *r, unsigned int *g, unsigned int *b)
  155. {
  156. unsigned int i; // Integer part.
  157. unsigned int f; // Fractional or remainder part. f/HSV_BASE gives fraction.
  158. unsigned int tmp; // Tempary variable to help with calculations.
  159. unsigned int values[7]; // Possible rgb values. Don't use zero.
  160. h *= 6;
  161. f = h % HSV_BASE;
  162. // Set up possible red, green and blue values.
  163. values[1] =
  164. values[2] = v;
  165. //
  166. // The following lines of code change
  167. // values[3] = (v * (HSV_BASE - ( (s * f) / HSV_BASE) )) / HSV_BASE;
  168. // values[4] = values[5] = (v * (HSV_BASE - s)) / HSV_BASE;
  169. // values[6] = (v * (HSV_BASE - (s * (HSV_BASE - f)) / HSV_BASE)) / HSV_BASE;
  170. // so that the are rounded divides.
  171. //
  172. tmp = Divide_With_Round(s * f, HSV_BASE);
  173. values[3] = Divide_With_Round(v * (HSV_BASE - tmp), HSV_BASE);
  174. values[4] =
  175. values[5] = Divide_With_Round(v * (HSV_BASE - s), HSV_BASE);
  176. tmp = HSV_BASE - Divide_With_Round(s * (HSV_BASE - f), HSV_BASE);
  177. values[6] = Divide_With_Round(v * tmp, HSV_BASE);
  178. // This should not be rounded.
  179. i = h / HSV_BASE;
  180. i += (i > 4) ? -4 : 2;
  181. *r = Divide_With_Round(values[i] * RGB_BASE, HSV_BASE);
  182. i += (i > 4) ? -4 : 2;
  183. *b = Divide_With_Round(values[i] * RGB_BASE, HSV_BASE);
  184. i += (i > 4) ? -4 : 2;
  185. *g = Divide_With_Round(values[i] * RGB_BASE, HSV_BASE);
  186. }