CnC_Remastered_Collection/REDALERT/JSHELL.H

479 lines
13 KiB
C++
Raw Normal View History

//
// 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 <assert.h>
#ifdef WIN32
//#define getch Get_Key_Num
//#define kbhit Check_Key_Num
#include "key.h"
#else
#include <conio.h>
#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<class T> inline T operator ++(T & a)
{
a = (T)((int)a + (int)1);
return(a);
}
template<class T> inline T operator ++(T & a, int)
{
T aa = a;
a = (T)((int)a + (int)1);
return(aa);
}
template<class T> inline T operator --(T & a)
{
a = (T)((int)a - (int)1);
return(a);
}
template<class T> inline T operator --(T & a, int)
{
T aa = a;
a = (T)((int)a - (int)1);
return(aa);
}
template<class T> inline T operator |(T t1, T t2)
{
return((T)((int)t1 | (int)t2));
}
template<class T> inline T operator &(T t1, T t2)
{
return((T)((int)t1 & (int)t2));
}
template<class T> inline T operator ~(T t1)
{
return((T)(~(int)t1));
}
#ifndef WIN32
template<class T> inline T min(T value1, T value2)
{
if (value1 < value2) {
return(value1);
}
return(value2);
}
int min(int, int);
long min(long, long);
template<class T> inline T max(T value1, T value2)
{
if (value1 > value2) {
return(value1);
}
return(value2);
}
int max(int, int);
long max(long, long);
#endif
template<class T> inline void swap(T &value1, T &value2)
{
T temp = value1;
value1 = value2;
value2 = temp;
}
int swap(int, int);
long swap(long, long);
template<class T> 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<class T>
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<class T>
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<class T>
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<class T>
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 T>
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<T> operator ++ (int) {assert(Pointer != 0);SmartPtr<T> temp = *this;++Pointer;return(temp);}
SmartPtr<T> & operator ++ (void) {assert(Pointer != 0);++Pointer;return(*this);}
SmartPtr<T> operator -- (int) {assert(Pointer != 0);SmartPtr<T> temp = *this;--Pointer;return(temp);}
SmartPtr<T> & 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