LIB.CPP 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  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 "wwstd.h"
  46. #include "misc.h"
  47. //PRIVATE unsigned Divide_With_Round(unsigned num, unsigned den);
  48. /***************************************************************************
  49. * Divide_With_Round -- Divides integers and round to nearest integer. *
  50. * *
  51. * INPUT: int numberator. *
  52. * int denominator. *
  53. * *
  54. * OUTPUT: Returns value rounded. *
  55. * *
  56. * WARNINGS: *
  57. * *
  58. * HISTORY: *
  59. * 02/13/1992 SB : Created. *
  60. *=========================================================================*/
  61. static unsigned Divide_With_Round(unsigned num, unsigned den)
  62. {
  63. // return num/den + (0 ro 1). 1 if the remainder is more than half the denominator.
  64. return( (num / den) + (unsigned)((num % den) >= ((den + 1) >> 1)) );
  65. }
  66. #define HSV_BASE 255 // This is used to get a little better persion on HSV conversion.
  67. #define RGB_BASE 63 // Not 64, this is really the max value.
  68. /***************************************************************************
  69. * Convert_RGB_To_HSV -- Converts RGB to RSV coordinates. *
  70. * *
  71. * INPUT: int r,g, and b values. *
  72. * int *h, *s, and *v pointers. *
  73. * *
  74. * OUTPUT: Assigns values to *h, *s, and *v. *
  75. * *
  76. * WARNINGS: The reason we use a different base for HSV then RGB is *
  77. * because we loose alot of persision by not using floating *
  78. * point. Using the same base value (63) made it so that *
  79. * about 50% of the time one RGB value would be one different *
  80. * then the original if you went from RGB to HSV to RGB. *
  81. * Using 255 drop it down to about 9% of the time we get an *
  82. * off value. To get it perfect, we would have to make the *
  83. * HSV base larger - but then you need to do all calculations *
  84. * in long instead of unsigned int. *
  85. * HISTORY: *
  86. * 02/11/1992 SB : Created. *
  87. *=========================================================================*/
  88. void Convert_RGB_To_HSV(unsigned int r, unsigned int g, unsigned int b, unsigned int *h, unsigned int *s, unsigned int *v)
  89. {
  90. unsigned int m, r1, g1, b1, tmp;
  91. // Convert RGB base to HSV base.
  92. r = Divide_With_Round((r * HSV_BASE), RGB_BASE);
  93. g = Divide_With_Round((g * HSV_BASE), RGB_BASE);
  94. b = Divide_With_Round((b * HSV_BASE), RGB_BASE);
  95. // Set hue to default.
  96. *h = 0;
  97. // Set v = Max(r,g,b) to find dominant primary color.
  98. *v = (r > g) ? r : g;
  99. if (b > *v) *v = b;
  100. // Set m = min(r,g,b) to find amount of white.
  101. m = (r < g) ? r : g;
  102. if (b < m) m = b;
  103. // Determine the normalized saturation.
  104. if (*v != 0) {
  105. *s = Divide_With_Round( (*v - m) * HSV_BASE ,*v);
  106. } else {
  107. *s = 0;
  108. }
  109. if (*s != 0) {
  110. tmp = *v - m;
  111. r1 = Divide_With_Round( (*v - r) * HSV_BASE, tmp);
  112. g1 = Divide_With_Round( (*v - g) * HSV_BASE, tmp);
  113. b1 = Divide_With_Round( (*v - b) * HSV_BASE, tmp);
  114. // Find effect of second most predominant color.
  115. // In which section of the hexagon of colors does the color lie?
  116. if ((*v) == r) {
  117. if (m == g) {
  118. *h = 5 * HSV_BASE + b1;
  119. } else {
  120. *h = 1 * HSV_BASE - g1;
  121. }
  122. } else {
  123. if ((*v) == g) {
  124. if (m == b) {
  125. *h = 1 * HSV_BASE + r1;
  126. } else {
  127. *h = 3 * HSV_BASE - b1;
  128. }
  129. } else {
  130. // *v == b
  131. if (m == r) {
  132. *h = 3 * HSV_BASE + g1;
  133. } else {
  134. *h = 5 * HSV_BASE - r1;
  135. }
  136. }
  137. }
  138. // Divide by six and round.
  139. *h = Divide_With_Round(*h, 6);
  140. }
  141. }
  142. /***************************************************************************
  143. * Convert_HSV_To_RGB -- Converts HSV cordinates to RGB values *
  144. * *
  145. * INPUT: int h,s, and v coordinates *
  146. * int *r, *g, and *b pointers. *
  147. * *
  148. * OUTPUT: Assigns values to *r, *g, and *b. *
  149. * *
  150. * WARNINGS: *
  151. * *
  152. * HISTORY: *
  153. * 02/11/1992 SB : Created. *
  154. *=========================================================================*/
  155. void Convert_HSV_To_RGB(unsigned int h, unsigned int s, unsigned int v, unsigned int *r, unsigned int *g, unsigned int *b)
  156. {
  157. unsigned int i; // Integer part.
  158. unsigned int f; // Fractional or remainder part. f/HSV_BASE gives fraction.
  159. unsigned int tmp; // Tempary variable to help with calculations.
  160. unsigned int values[7]; // Possible rgb values. Don't use zero.
  161. h *= 6;
  162. f = h % HSV_BASE;
  163. // Set up possible red, green and blue values.
  164. values[1] =
  165. values[2] = v;
  166. //
  167. // The following lines of code change
  168. // values[3] = (v * (HSV_BASE - ( (s * f) / HSV_BASE) )) / HSV_BASE;
  169. // values[4] = values[5] = (v * (HSV_BASE - s)) / HSV_BASE;
  170. // values[6] = (v * (HSV_BASE - (s * (HSV_BASE - f)) / HSV_BASE)) / HSV_BASE;
  171. // so that the are rounded divides.
  172. //
  173. tmp = Divide_With_Round(s * f, HSV_BASE);
  174. values[3] = Divide_With_Round(v * (HSV_BASE - tmp), HSV_BASE);
  175. values[4] =
  176. values[5] = Divide_With_Round(v * (HSV_BASE - s), HSV_BASE);
  177. tmp = HSV_BASE - Divide_With_Round(s * (HSV_BASE - f), HSV_BASE);
  178. values[6] = Divide_With_Round(v * tmp, HSV_BASE);
  179. // This should not be rounded.
  180. i = h / HSV_BASE;
  181. i += (i > 4) ? -4 : 2;
  182. *r = Divide_With_Round(values[i] * RGB_BASE, HSV_BASE);
  183. i += (i > 4) ? -4 : 2;
  184. *b = Divide_With_Round(values[i] * RGB_BASE, HSV_BASE);
  185. i += (i > 4) ? -4 : 2;
  186. *g = Divide_With_Round(values[i] * RGB_BASE, HSV_BASE);
  187. }