| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218 |
- /*
- ** Command & Conquer Red Alert(tm)
- ** Copyright 2025 Electronic Arts Inc.
- **
- ** This program is free software: you can redistribute it and/or modify
- ** it under the terms of the GNU General Public License as published by
- ** the Free Software Foundation, either version 3 of the License, or
- ** (at your option) any later version.
- **
- ** This program is distributed in the hope that it will be useful,
- ** but WITHOUT ANY WARRANTY; without even the implied warranty of
- ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- ** GNU General Public License for more details.
- **
- ** You should have received a copy of the GNU General Public License
- ** along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
- /* $Header: g:/library/source/rcs/./lib.c 1.16 1994/05/20 15:34:33 joe_bostic Exp $ */
- /***************************************************************************
- ** 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 **
- ***************************************************************************
- * *
- * Project Name : Library Routines *
- * *
- * File Name : LIB.C *
- * *
- * Programmer : Scott Bowen *
- * *
- * Start Date : January 14, 1993 *
- * *
- * Last Update : May 20, 1993 [PWG] *
- * *
- *-------------------------------------------------------------------------*
- * Functions: *
- * Add_Long_To_Pointer -- Pointer arithmatic when pointer could be XMS. *
- * Find_Argv -- Checks to see if string is in arguement *
- * Mono_Mem_Dump -- Dumps memory to mono monitor with hex and char. *
- * Convert_HSV_To_RGB -- Converts HSV cordinates to RGB values *
- * Convert_RGB_To_HSV -- Converts RGB to RSV coordinates. *
- * Set_Search_Drives -- Sets up the CDRom and HardDrive paths. *
- * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- #include <dos.h>
- #include <stdio.h>
- #include <string.h>
- #include "wwstd.h"
- #include "misc.h"
- //PRIVATE unsigned Divide_With_Round(unsigned num, unsigned den);
- /***************************************************************************
- * Divide_With_Round -- Divides integers and round to nearest integer. *
- * *
- * INPUT: int numberator. *
- * int denominator. *
- * *
- * OUTPUT: Returns value rounded. *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 02/13/1992 SB : Created. *
- *=========================================================================*/
- static unsigned Divide_With_Round(unsigned num, unsigned den)
- {
- // return num/den + (0 ro 1). 1 if the remainder is more than half the denominator.
- return( (num / den) + (unsigned)((num % den) >= ((den + 1) >> 1)) );
- }
- #define HSV_BASE 255 // This is used to get a little better persion on HSV conversion.
- #define RGB_BASE 63 // Not 64, this is really the max value.
- /***************************************************************************
- * Convert_RGB_To_HSV -- Converts RGB to RSV coordinates. *
- * *
- * INPUT: int r,g, and b values. *
- * int *h, *s, and *v pointers. *
- * *
- * OUTPUT: Assigns values to *h, *s, and *v. *
- * *
- * WARNINGS: The reason we use a different base for HSV then RGB is *
- * because we loose alot of persision by not using floating *
- * point. Using the same base value (63) made it so that *
- * about 50% of the time one RGB value would be one different *
- * then the original if you went from RGB to HSV to RGB. *
- * Using 255 drop it down to about 9% of the time we get an *
- * off value. To get it perfect, we would have to make the *
- * HSV base larger - but then you need to do all calculations *
- * in long instead of unsigned int. *
- * HISTORY: *
- * 02/11/1992 SB : Created. *
- *=========================================================================*/
- void Convert_RGB_To_HSV(unsigned int r, unsigned int g, unsigned int b, unsigned int *h, unsigned int *s, unsigned int *v)
- {
- unsigned int m, r1, g1, b1, tmp;
- // Convert RGB base to HSV base.
- r = Divide_With_Round((r * HSV_BASE), RGB_BASE);
- g = Divide_With_Round((g * HSV_BASE), RGB_BASE);
- b = Divide_With_Round((b * HSV_BASE), RGB_BASE);
- // Set hue to default.
- *h = 0;
- // Set v = Max(r,g,b) to find dominant primary color.
- *v = (r > g) ? r : g;
- if (b > *v) *v = b;
- // Set m = min(r,g,b) to find amount of white.
- m = (r < g) ? r : g;
- if (b < m) m = b;
- // Determine the normalized saturation.
- if (*v != 0) {
- *s = Divide_With_Round( (*v - m) * HSV_BASE ,*v);
- } else {
- *s = 0;
- }
- if (*s != 0) {
- tmp = *v - m;
- r1 = Divide_With_Round( (*v - r) * HSV_BASE, tmp);
- g1 = Divide_With_Round( (*v - g) * HSV_BASE, tmp);
- b1 = Divide_With_Round( (*v - b) * HSV_BASE, tmp);
- // Find effect of second most predominant color.
- // In which section of the hexagon of colors does the color lie?
- if ((*v) == r) {
- if (m == g) {
- *h = 5 * HSV_BASE + b1;
- } else {
- *h = 1 * HSV_BASE - g1;
- }
- } else {
- if ((*v) == g) {
- if (m == b) {
- *h = 1 * HSV_BASE + r1;
- } else {
- *h = 3 * HSV_BASE - b1;
- }
- } else {
- // *v == b
- if (m == r) {
- *h = 3 * HSV_BASE + g1;
- } else {
-
- *h = 5 * HSV_BASE - r1;
- }
- }
- }
- // Divide by six and round.
- *h = Divide_With_Round(*h, 6);
- }
- }
- /***************************************************************************
- * Convert_HSV_To_RGB -- Converts HSV cordinates to RGB values *
- * *
- * INPUT: int h,s, and v coordinates *
- * int *r, *g, and *b pointers. *
- * *
- * OUTPUT: Assigns values to *r, *g, and *b. *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 02/11/1992 SB : Created. *
- *=========================================================================*/
- void Convert_HSV_To_RGB(unsigned int h, unsigned int s, unsigned int v, unsigned int *r, unsigned int *g, unsigned int *b)
- {
- unsigned int i; // Integer part.
- unsigned int f; // Fractional or remainder part. f/HSV_BASE gives fraction.
- unsigned int tmp; // Tempary variable to help with calculations.
- unsigned int values[7]; // Possible rgb values. Don't use zero.
- h *= 6;
- f = h % HSV_BASE;
- // Set up possible red, green and blue values.
- values[1] =
- values[2] = v;
- //
- // The following lines of code change
- // values[3] = (v * (HSV_BASE - ( (s * f) / HSV_BASE) )) / HSV_BASE;
- // values[4] = values[5] = (v * (HSV_BASE - s)) / HSV_BASE;
- // values[6] = (v * (HSV_BASE - (s * (HSV_BASE - f)) / HSV_BASE)) / HSV_BASE;
- // so that the are rounded divides.
- //
- tmp = Divide_With_Round(s * f, HSV_BASE);
- values[3] = Divide_With_Round(v * (HSV_BASE - tmp), HSV_BASE);
- values[4] =
- values[5] = Divide_With_Round(v * (HSV_BASE - s), HSV_BASE);
- tmp = HSV_BASE - Divide_With_Round(s * (HSV_BASE - f), HSV_BASE);
- values[6] = Divide_With_Round(v * tmp, HSV_BASE);
- // This should not be rounded.
- i = h / HSV_BASE;
- i += (i > 4) ? -4 : 2;
- *r = Divide_With_Round(values[i] * RGB_BASE, HSV_BASE);
- i += (i > 4) ? -4 : 2;
- *b = Divide_With_Round(values[i] * RGB_BASE, HSV_BASE);
- i += (i > 4) ? -4 : 2;
- *g = Divide_With_Round(values[i] * RGB_BASE, HSV_BASE);
- }
|