// // Copyright 2020 Electronic Arts Inc. // // TiberianDawn.DLL and RedAlert.dll and corresponding source code 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. // TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed // in the hope that it will be useful, but with permitted additional restrictions // under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT // distributed with this program. You should have received a copy of the // GNU General Public License along with permitted additional restrictions // with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection /* $Header: /CounterStrike/JSHELL.H 1 3/03/97 10:24a Joe_bostic $ */ /*********************************************************************************************** *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** *********************************************************************************************** * * * Project Name : Command & Conquer * * * * File Name : JSHELL.H * * * * Programmer : Joe L. Bostic * * * * Start Date : 03/13/95 * * * * Last Update : March 13, 1995 [JLB] * * * *---------------------------------------------------------------------------------------------* * Functions: * * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ #ifndef JSHELL_H #define JSHELL_H #include #ifdef WIN32 //#define getch Get_Key_Num //#define kbhit Check_Key_Num #include "key.h" #else #include #endif /* ** Interface class to the keyboard. This insulates the game from library vagaries. Most ** notable being the return values are declared as "int" in the library whereas C&C ** expects it to be of KeyNumType. */ #ifdef WIN32 //#define KeyNumType int //#define KeyASCIIType int //lint -esym(1725,KeyboardClass::MouseQX,KeyboardClass::MouseQY) struct KeyboardClass : public WWKeyboardClass #else struct KeyboardClass #endif { /* ** This flag is used to indicate whether the WW library has taken over ** the keyboard or not. If not, then the normal console input ** takes precedence. */ unsigned IsLibrary; #ifndef WIN32 int &MouseQX; int &MouseQY; KeyboardClass() : IsLibrary(true), MouseQX(::MouseQX), MouseQY(::MouseQY) {} KeyNumType Get(void) {return (IsLibrary ? (KeyNumType)Get_Key_Num() : (KeyNumType)getch());}; KeyNumType Check(void) {return (IsLibrary ? (KeyNumType)Check_Key_Num() : (KeyNumType)kbhit());}; KeyASCIIType To_ASCII(KeyNumType key) {return((KeyASCIIType)KN_To_KA(key));}; void Clear(void) {if (IsLibrary) Clear_KeyBuffer();}; int Down(KeyNumType key) {return(Key_Down(key));}; #else KeyboardClass() : IsLibrary(true) {} KeyNumType Get(void) {return ((KeyNumType)WWKeyboardClass::Get());}; KeyNumType Check(void) {return ((KeyNumType)WWKeyboardClass::Check());}; KeyASCIIType To_ASCII(KeyNumType key) {return((KeyASCIIType)WWKeyboardClass::To_ASCII(key));}; void Clear(void) {WWKeyboardClass::Clear();}; int Down(KeyNumType key) {return(WWKeyboardClass::Down(key));}; #endif int Mouse_X(void) {return(Get_Mouse_X());}; int Mouse_Y(void) {return(Get_Mouse_Y());}; }; /* ** These templates allow enumeration types to have simple bitwise ** arithmatic performed. The operators must be instatiated for the ** enumerated types desired. */ template inline T operator ++(T & a) { a = (T)((int)a + (int)1); return(a); } template inline T operator ++(T & a, int) { T aa = a; a = (T)((int)a + (int)1); return(aa); } template inline T operator --(T & a) { a = (T)((int)a - (int)1); return(a); } template inline T operator --(T & a, int) { T aa = a; a = (T)((int)a - (int)1); return(aa); } template inline T operator |(T t1, T t2) { return((T)((int)t1 | (int)t2)); } template inline T operator &(T t1, T t2) { return((T)((int)t1 & (int)t2)); } template inline T operator ~(T t1) { return((T)(~(int)t1)); } #ifndef WIN32 template inline T min(T value1, T value2) { if (value1 < value2) { return(value1); } return(value2); } int min(int, int); long min(long, long); template inline T max(T value1, T value2) { if (value1 > value2) { return(value1); } return(value2); } int max(int, int); long max(long, long); #endif template inline void swap(T &value1, T &value2) { T temp = value1; value1 = value2; value2 = temp; } int swap(int, int); long swap(long, long); template inline T Bound(T original, T minval, T maxval) { if (original < minval) return(minval); if (original > maxval) return(maxval); return(original); }; int Bound(signed int, signed int, signed int); unsigned Bound(unsigned, unsigned, unsigned); long Bound(long, long, long); template T _rotl(T X, int n) { return((T)(( ( ( X ) << n ) | ( ( X ) >> ( (sizeof(T)*8) - n ) ) ))); } /* ** This macro serves as a general way to determine the number of elements ** within an array. */ #define ARRAY_LENGTH(x) int(sizeof(x)/sizeof(x[0])) #define ARRAY_SIZE(x) int(sizeof(x)/sizeof(x[0])) /* ** The shape flags are likely to be "or"ed together and other such bitwise ** manipulations. These instatiated operator templates allow this. */ inline ShapeFlags_Type operator |(ShapeFlags_Type, ShapeFlags_Type); inline ShapeFlags_Type operator &(ShapeFlags_Type, ShapeFlags_Type); inline ShapeFlags_Type operator ~(ShapeFlags_Type); void __cdecl Set_Bit(void * array, int bit, int value); int __cdecl Get_Bit(void const * array, int bit); int __cdecl First_True_Bit(void const * array); int __cdecl First_False_Bit(void const * array); int __cdecl Bound(int original, int min, int max); #if (0) void Set_Bit(void * array, int bit, int value); #pragma aux Set_Bit parm [esi] [ecx] [eax] \ modify [esi ebx] = \ "mov ebx,ecx" \ "shr ebx,5" \ "and ecx,01Fh" \ "btr [esi+ebx*4],ecx" \ "or eax,eax" \ "jz ok" \ "bts [esi+ebx*4],ecx" \ "ok:" int Get_Bit(void const * array, int bit); #pragma aux Get_Bit parm [esi] [eax] \ modify [esi ebx] \ value [eax] = \ "mov ebx,eax" \ "shr ebx,5" \ "and eax,01Fh" \ "bt [esi+ebx*4],eax" \ "setc al" int First_True_Bit(void const * array); #pragma aux First_True_Bit parm [esi] \ modify [esi ebx] \ value [eax] = \ "mov eax,-32" \ "again:" \ "add eax,32" \ "mov ebx,[esi]" \ "add esi,4" \ "bsf ebx,ebx" \ "jz again" \ "add eax,ebx" int First_False_Bit(void const * array); #pragma aux First_False_Bit parm [esi] \ modify [esi ebx] \ value [eax] = \ "mov eax,-32" \ "again:" \ "add eax,32" \ "mov ebx,[esi]" \ "not ebx" \ "add esi,4" \ "bsf ebx,ebx" \ "jz again" \ "add eax,ebx" #ifdef OBSOLETE extern int Bound(int original, int min, int max); #pragma aux Bound parm [eax] [ebx] [ecx] \ modify [eax] \ value [eax] = \ "cmp ebx,ecx" \ "jl okorder" \ "xchg ebx,ecx" \ "okorder: cmp eax,ebx" \ "jg okmin" \ "mov eax,ebx" \ "okmin: cmp eax,ecx" \ "jl okmax" \ "mov eax,ecx" \ "okmax:" extern unsigned Bound(unsigned original, unsigned min, unsigned max); #pragma aux Bound parm [eax] [ebx] [ecx] \ modify [eax] \ value [eax] = \ "cmp ebx,ecx" \ "jb okorder" \ "xchg ebx,ecx" \ "okorder: cmp eax,ebx" \ "ja okmin" \ "mov eax,ebx" \ "okmin: cmp eax,ecx" \ "jb okmax" \ "mov eax,ecx" \ "okmax:" #endif unsigned Fixed_To_Cardinal(unsigned base, unsigned fixed); #pragma aux Fixed_To_Cardinal parm [eax] [edx] \ modify [edx] \ value [eax] = \ "mul edx" \ "add eax,080h" \ "test eax,0FF000000h" \ "jz ok" \ "mov eax,000FFFFFFh" \ "ok:" \ "shr eax,8" unsigned Cardinal_To_Fixed(unsigned base, unsigned cardinal); #pragma aux Cardinal_To_Fixed parm [ebx] [eax] \ modify [edx] \ value [eax] = \ "or ebx,ebx" \ "jz fini" \ "shl eax,8" \ "xor edx,edx" \ "div ebx" \ "fini:" #ifndef OUTPORTB #define OUTPORTB extern void outportb(int port, unsigned char data); #pragma aux outportb parm [edx] [al] = \ "out dx,al" extern void outport(int port, unsigned short data); #pragma aux outport parm [edx] [ax] = \ "out dx,al" \ "inc dx" \ "mov al,ah" \ "out dx,al" #endif #endif /* ** Timer objects that fetch the appropriate timer value according to ** the type of timer they are. */ extern long Frame; class FrameTimerClass { public: long operator () (void) const {return(Frame);}; operator long (void) const {return(Frame);}; }; #ifndef WIN32 extern bool TimerSystemOn; extern "C" { long Get_System_Tick_Count(void); long Get_User_Tick_Count(void); } //bool Init_Timer_System(unsigned int freq, int partial=false); bool Remove_Timer_System(void); #else extern WinTimerClass * WindowsTimer; #endif #ifndef SYSTEM_TIMER_CLASS #define SYSTEM_TIMER_CLASS class SystemTimerClass { public: #ifdef WIN32 long operator () (void) const {if (!WindowsTimer) return(0);return(WindowsTimer->Get_System_Tick_Count());}; operator long (void) const {if (!WindowsTimer) return(0);return(WindowsTimer->Get_System_Tick_Count());}; #else long operator () (void) const {return(Get_System_Tick_Count());}; operator long (void) const {return(Get_System_Tick_Count());}; #endif }; #endif class UserTimerClass { public: #ifdef WIN32 long operator () (void) const {if (!WindowsTimer) return(0);return(WindowsTimer->Get_User_Tick_Count());}; operator long (void) const {if (!WindowsTimer) return(0);return(WindowsTimer->Get_User_Tick_Count());}; #else long operator () (void) const {return(Get_User_Tick_Count());}; operator long (void) const {return(Get_User_Tick_Count());}; #endif }; template void Bubble_Sort(T * array, int count) { if (array != NULL && count > 1) { bool swapflag; do { swapflag = false; for (int index = 0; index < count-1; index++) { if (array[index] > array[index+1]) { T temp = array[index]; array[index] = array[index+1]; array[index+1] = temp; swapflag = true; } } } while (swapflag); } } template void PBubble_Sort(T * array, int count) { if (array != NULL && count > 1) { bool swapflag; do { swapflag = false; for (int index = 0; index < count-1; index++) { if (*array[index] > *array[index+1]) { T temp = array[index]; array[index] = array[index+1]; array[index+1] = temp; swapflag = true; } } } while (swapflag); } } template void PNBubble_Sort(T * array, int count) { if (array != NULL && count > 1) { bool swapflag; do { swapflag = false; for (int index = 0; index < count-1; index++) { if (stricmp(array[index]->Name(), array[index+1]->Name()) > 0) { T temp = array[index]; array[index] = array[index+1]; array[index+1] = temp; swapflag = true; } } } while (swapflag); } } template class SmartPtr { public: SmartPtr(NoInitClass const &) {} SmartPtr(T * realptr = 0) : Pointer(realptr) {} SmartPtr(SmartPtr const & rvalue) : Pointer(rvalue.Pointer) {} ~SmartPtr(void) {Pointer = 0;} operator T * (void) const {return(Pointer);} operator long (void) const {return((long)Pointer);} SmartPtr operator ++ (int) {assert(Pointer != 0);SmartPtr temp = *this;++Pointer;return(temp);} SmartPtr & operator ++ (void) {assert(Pointer != 0);++Pointer;return(*this);} SmartPtr operator -- (int) {assert(Pointer != 0);SmartPtr temp = *this;--Pointer;return(temp);} SmartPtr & operator -- (void) {assert(Pointer != 0);--Pointer;return(*this);} SmartPtr & operator = (SmartPtr const & rvalue) {Pointer = rvalue.Pointer;return(*this);} T * operator -> (void) const {assert(Pointer != 0);return(Pointer);} T & operator * (void) const {assert(Pointer != 0);return(*Pointer);} private: T * Pointer; }; #endif