Initial Source Code commit

Initial commit of original Tiberian Dawn and Red Alert source code converted to build as DLLs, and compatible with the release version of Command & Conquer Remastered.
This commit is contained in:
PG-SteveT 2020-05-27 12:16:20 -07:00
parent ea8ecc76fa
commit 03416d24e1
1038 changed files with 629779 additions and 0 deletions

26
CnCRemastered.sln Normal file
View File

@ -0,0 +1,26 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.28307.1022
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TiberianDawn", "TiberianDawn\TiberianDawn.vcxproj", "{1380ED08-82A3-49C2-A171-1915574B3382}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RedAlert", "RedAlert\RedAlert.vcxproj", "{DA948ED9-EF67-4813-94B7-995BE956786E}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{1380ED08-82A3-49C2-A171-1915574B3382}.Release|x86.ActiveCfg = Release|Win32
{1380ED08-82A3-49C2-A171-1915574B3382}.Release|x86.Build.0 = Release|Win32
{DA948ED9-EF67-4813-94B7-995BE956786E}.Release|x86.ActiveCfg = Release|Win32
{DA948ED9-EF67-4813-94B7-995BE956786E}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {712D2733-25EE-407D-AEF8-B2342757E119}
EndGlobalSection
EndGlobal

588
REDALERT/2KEYFRAM.CPP Normal file
View File

@ -0,0 +1,588 @@
//
// 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/2KEYFRAM.CPP 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 : KEYFRAME.CPP *
* *
* Programmer : Joe L. Bostic *
* *
* Start Date : 06/25/95 *
* *
* Last Update : June 25, 1995 [JLB] *
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* Get_Build_Frame_Count -- Fetches the number of frames in data block. *
* Get_Build_Frame_Width -- Fetches the width of the shape image. *
* Get_Build_Frame_Height -- Fetches the height of the shape image. *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "function.h"
#define SUBFRAMEOFFS 7 // 3 1/2 frame offsets loaded (2 offsets/frame)
#define Apply_Delta(buffer, delta) Apply_XOR_Delta((char*)(buffer), (char*)(delta))
typedef struct {
unsigned short frames;
unsigned short x;
unsigned short y;
unsigned short width;
unsigned short height;
unsigned short largest_frame_size;
short flags;
} KeyFrameHeaderType;
#define INITIAL_BIG_SHAPE_BUFFER_SIZE 8000000
#define THEATER_BIG_SHAPE_BUFFER_SIZE 4000000
#define UNCOMPRESS_MAGIC_NUMBER 56789
unsigned BigShapeBufferLength = INITIAL_BIG_SHAPE_BUFFER_SIZE;
unsigned TheaterShapeBufferLength = THEATER_BIG_SHAPE_BUFFER_SIZE;
extern "C"{
char *BigShapeBufferStart = NULL;
char *TheaterShapeBufferStart = NULL;
BOOL UseBigShapeBuffer = FALSE;
bool IsTheaterShape = false;
}
#ifdef FIXIT_SCORE_CRASH
/*
** Global required to fix the score screen crash bug by allowing disabling of uncompressed shapes.
*/
bool OriginalUseBigShapeBuffer = false;
#endif //FIXIT
char *BigShapeBufferPtr = NULL;
int TotalBigShapes=0;
BOOL ReallocShapeBufferFlag = FALSE;
char *TheaterShapeBufferPtr = NULL;
int TotalTheaterShapes = 0;
#define MAX_SLOTS 1500
#define THEATER_SLOT_START 1000
char **KeyFrameSlots [MAX_SLOTS];
int TotalSlotsUsed=0;
int TheaterSlotsUsed = THEATER_SLOT_START;
typedef struct tShapeHeaderType{
unsigned draw_flags;
char *shape_data;
int shape_buffer; //1 if shape is in theater buffer
} ShapeHeaderType;
static int Length;
void *Get_Shape_Header_Data(void *ptr)
{
if (UseBigShapeBuffer) {
ShapeHeaderType *header = (ShapeHeaderType*) ptr;
return ((void*) (header->shape_data + (long)(header->shape_buffer ? TheaterShapeBufferStart : BigShapeBufferStart) ) );
} else {
return (ptr);
}
}
int Get_Last_Frame_Length(void)
{
return(Length);
}
void Reset_Theater_Shapes (void)
{
/*
** Delete any previously allocated slots
*/
for (int i=THEATER_SLOT_START ; i<TheaterSlotsUsed ; i++) {
delete [] KeyFrameSlots [i];
}
TheaterShapeBufferPtr = TheaterShapeBufferStart;
TotalTheaterShapes = 0;
TheaterSlotsUsed = THEATER_SLOT_START;
}
void Reallocate_Big_Shape_Buffer(void)
{
if (ReallocShapeBufferFlag) {
BigShapeBufferLength += 2000000; //Extra 2 Mb of uncompressed shape space
BigShapeBufferPtr -= (unsigned)BigShapeBufferStart;
Memory_Error = NULL;
BigShapeBufferStart = (char*)Resize_Alloc(BigShapeBufferStart, BigShapeBufferLength);
Memory_Error = &Memory_Error_Handler;
/*
** If we have run out of memory then disable the uncompressed shapes
** It may still be possible to continue with compressed shapes
*/
if (!BigShapeBufferStart) {
UseBigShapeBuffer = false;
return;
}
BigShapeBufferPtr += (unsigned)BigShapeBufferStart;
ReallocShapeBufferFlag = FALSE;
}
}
//#ifdef FIXIT_SCORE_CRASH
/***********************************************************************************************
* Disable_Uncompressed_Shapes -- Temporarily turns off shape decompression *
* *
* *
* *
* INPUT: Nothing *
* *
* OUTPUT: Nothing *
* *
* WARNINGS: None *
* *
* HISTORY: *
* 11/19/96 2:37PM ST : Created *
*=============================================================================================*/
void Disable_Uncompressed_Shapes (void)
{
UseBigShapeBuffer = false;
}
/***********************************************************************************************
* Enable_Uncompressed_Shapes -- Restores state of shape decompression before it was disabled *
* *
* *
* *
* INPUT: Nothing *
* *
* OUTPUT: Nothing *
* *
* WARNINGS: None *
* *
* HISTORY: *
* 11/19/96 2:37PM ST : Created *
*=============================================================================================*/
void Enable_Uncompressed_Shapes (void)
{
UseBigShapeBuffer = OriginalUseBigShapeBuffer;
}
//#endif //FIXIT
void Check_Use_Compressed_Shapes (void)
{
#if (1) // Uncompressed shapes enabled for performance reasons. We don't need to worry about memory.
// Uncompressed shapes don't seem to work in RA for rotated/scaled objects so wherever scale/rotate is used,
// we will need to disable it (like in Techno_Draw_Object). ST - 11/6/2019 2:09PM
UseBigShapeBuffer = true;
OriginalUseBigShapeBuffer = true;
#else
MEMORYSTATUS mem_info;
mem_info.dwLength=sizeof(mem_info);
GlobalMemoryStatus(&mem_info);
UseBigShapeBuffer = (mem_info.dwTotalPhys > 16*1024*1024) ? TRUE : FALSE;
#ifdef FIXIT_SCORE_CRASH
/*
** Keep track of our original decision about whether to use cached shapes.
** This is needed for the score screen crash fix.
*/
OriginalUseBigShapeBuffer = UseBigShapeBuffer;
#endif //FIXIT
#endif
}
unsigned long Build_Frame(void const *dataptr, unsigned short framenumber, void *buffptr)
{
#ifdef FIXIT_SCORE_CRASH
char *ptr;
unsigned long offcurr, offdiff;
#else
char *ptr, *lockptr;//, *uncomp_ptr;
unsigned long offcurr, off16, offdiff;
#endif
unsigned long offset[SUBFRAMEOFFS];
KeyFrameHeaderType *keyfr;
unsigned short buffsize, currframe, subframe;
unsigned long length = 0;
char frameflags;
unsigned long return_value;
char *temp_shape_ptr;
//
// valid pointer??
//
Length = 0;
if ( !dataptr || !buffptr ) {
return(0);
}
//
// look at header then check that frame to build is not greater
// than total frames
//
keyfr = (KeyFrameHeaderType *) dataptr;
if ( framenumber >= keyfr->frames ) {
return(0);
}
if (UseBigShapeBuffer) {
/*
** If we havnt yet allocated memory for uncompressed shapes then do so now.
**
*/
if (!BigShapeBufferStart) {
BigShapeBufferStart = (char*)Alloc(BigShapeBufferLength, MEM_NORMAL);
BigShapeBufferPtr = BigShapeBufferStart;
/*
** Allocate memory for theater specific uncompressed shapes
*/
TheaterShapeBufferStart = (char*) Alloc (TheaterShapeBufferLength, MEM_NORMAL);
TheaterShapeBufferPtr = TheaterShapeBufferStart;
}
/*
** If we are running out of memory (<10k left) for uncompressed shapes
** then allocate some more.
*/
if (( (unsigned)BigShapeBufferStart + BigShapeBufferLength) - (unsigned)BigShapeBufferPtr < 128000) {
ReallocShapeBufferFlag = TRUE;
}
/*
** If this animation was not previously uncompressed then
** allocate memory to keep the pointers to the uncompressed data
** for these animation frames
*/
if (keyfr->x != UNCOMPRESS_MAGIC_NUMBER) {
keyfr->x = UNCOMPRESS_MAGIC_NUMBER;
if (IsTheaterShape) {
keyfr->y = TheaterSlotsUsed;
TheaterSlotsUsed++;
} else {
keyfr->y = TotalSlotsUsed;
TotalSlotsUsed++;
}
/*
** Allocate and clear the memory for the shape info
*/
KeyFrameSlots[keyfr->y]= new char *[keyfr->frames];
memset (KeyFrameSlots[keyfr->y] , 0 , keyfr->frames*4);
}
/*
** If this frame was previously uncompressed then just return
** a pointer to the raw data
*/
if (*(KeyFrameSlots[keyfr->y]+framenumber)) {
if (IsTheaterShape) {
return ((unsigned long)TheaterShapeBufferStart + (unsigned long)*(KeyFrameSlots[keyfr->y]+framenumber));
} else {
return ((unsigned long)BigShapeBufferStart + (unsigned long)*(KeyFrameSlots[keyfr->y]+framenumber));
}
}
}
// calc buff size
buffsize = keyfr->width * keyfr->height;
// get offset into data
ptr = (char *)Add_Long_To_Pointer( dataptr, (((unsigned long)framenumber << 3) + sizeof(KeyFrameHeaderType)) );
Mem_Copy( ptr, &offset[0], 12L );
frameflags = (char)(offset[0] >> 24);
if ( (frameflags & KF_KEYFRAME) ) {
ptr = (char *)Add_Long_To_Pointer( dataptr, (offset[0] & 0x00FFFFFFL) );
if (keyfr->flags & 1 ) {
ptr = (char *)Add_Long_To_Pointer( ptr, 768L );
}
length = LCW_Uncompress( ptr, buffptr, buffsize );
} else { // key delta or delta
if ( (frameflags & KF_DELTA) ) {
currframe = (unsigned short)offset[1];
ptr = (char *)Add_Long_To_Pointer( dataptr, (((unsigned long)currframe << 3) + sizeof(KeyFrameHeaderType)) );
Mem_Copy( ptr, &offset[0], (long)(SUBFRAMEOFFS * sizeof(unsigned long)) );
}
// key frame
offcurr = offset[1] & 0x00FFFFFFL;
// key delta
offdiff = (offset[0] & 0x00FFFFFFL) - offcurr;
ptr = (char *)Add_Long_To_Pointer( dataptr, offcurr );
if (keyfr->flags & 1 ) {
ptr = (char *)Add_Long_To_Pointer( ptr, 768L );
}
#ifndef FIXIT_SCORE_CRASH
off16 = (unsigned long)lockptr & 0x00003FFFL;
#endif
length = LCW_Uncompress( ptr, buffptr, buffsize );
if (length > buffsize) {
return(0);
}
#ifndef FIXIT_SCORE_CRASH
if ( ((offset[2] & 0x00FFFFFFL) - offcurr) >= (0x00010000L - off16) ) {
ptr = (char *)Add_Long_To_Pointer( ptr, offdiff );
off16 = (unsigned long)ptr & 0x00003FFFL;
offcurr += offdiff;
offdiff = 0;
}
#endif
length = buffsize;
Apply_Delta(buffptr, Add_Long_To_Pointer(ptr, offdiff));
if ( (frameflags & KF_DELTA) ) {
// adjust to delta after the keydelta
currframe++;
subframe = 2;
while (currframe <= framenumber) {
offdiff = (offset[subframe] & 0x00FFFFFFL) - offcurr;
#ifndef FIXIT_SCORE_CRASH
if ( ((offset[subframe+2] & 0x00FFFFFFL) - offcurr) >= (0x00010000L - off16) ) {
ptr = (char *)Add_Long_To_Pointer( ptr, offdiff );
off16 = (unsigned long)lockptr & 0x00003FFFL;
offcurr += offdiff;
offdiff = 0;
}
#endif
length = buffsize;
Apply_Delta(buffptr, Add_Long_To_Pointer(ptr, offdiff));
currframe++;
subframe += 2;
if ( subframe >= (SUBFRAMEOFFS - 1) &&
currframe <= framenumber ) {
Mem_Copy( Add_Long_To_Pointer( dataptr,
(((unsigned long)currframe << 3) +
sizeof(KeyFrameHeaderType)) ),
&offset[0], (long)(SUBFRAMEOFFS * sizeof(unsigned long)) );
subframe = 0;
}
}
}
}
if (UseBigShapeBuffer) {
/*
** Save the uncompressed shape data so we dont have to uncompress it
** again next time its drawn.
** We keep a space free before the raw shape data so we can add line
** header info before the shape is drawn for the first time
*/
if (IsTheaterShape) {
/*
** Shape is a theater specific shape
*/
return_value = (unsigned long) TheaterShapeBufferPtr;
temp_shape_ptr = TheaterShapeBufferPtr + keyfr->height+sizeof(ShapeHeaderType);
/*
** align the actual shape data
*/
if (3 & (unsigned)temp_shape_ptr) {
temp_shape_ptr = (char *) ((unsigned)(temp_shape_ptr + 3) & 0xfffffffc);
}
memcpy (temp_shape_ptr , buffptr , length);
((ShapeHeaderType *)TheaterShapeBufferPtr)->draw_flags = -1; //Flag that headers need to be generated
((ShapeHeaderType *)TheaterShapeBufferPtr)->shape_data = temp_shape_ptr - (unsigned)TheaterShapeBufferStart; //pointer to old raw shape data
((ShapeHeaderType *)TheaterShapeBufferPtr)->shape_buffer = 1; //Theater buffer
*(KeyFrameSlots[keyfr->y]+framenumber) = TheaterShapeBufferPtr - (unsigned)TheaterShapeBufferStart;
TheaterShapeBufferPtr = (char*)(length + (unsigned)temp_shape_ptr);
/*
** Align the next shape
*/
if (3 & (unsigned)TheaterShapeBufferPtr) {
TheaterShapeBufferPtr = (char *)((unsigned)(TheaterShapeBufferPtr + 3) & 0xfffffffc);
}
Length = length;
return (return_value);
} else {
return_value=(unsigned long)BigShapeBufferPtr;
temp_shape_ptr = BigShapeBufferPtr + keyfr->height+sizeof(ShapeHeaderType);
/*
** align the actual shape data
*/
if (3 & (unsigned)temp_shape_ptr) {
temp_shape_ptr = (char *) ((unsigned)(temp_shape_ptr + 3) & 0xfffffffc);
}
memcpy (temp_shape_ptr , buffptr , length);
((ShapeHeaderType *)BigShapeBufferPtr)->draw_flags = -1; //Flag that headers need to be generated
((ShapeHeaderType *)BigShapeBufferPtr)->shape_data = temp_shape_ptr - (unsigned)BigShapeBufferStart; //pointer to old raw shape data
((ShapeHeaderType *)BigShapeBufferPtr)->shape_buffer = 0; //Normal Big Shape Buffer
*(KeyFrameSlots[keyfr->y]+framenumber) = BigShapeBufferPtr - (unsigned)BigShapeBufferStart;
BigShapeBufferPtr = (char*)(length + (unsigned)temp_shape_ptr);
// Align the next shape
if (3 & (unsigned)BigShapeBufferPtr) {
BigShapeBufferPtr = (char *)((unsigned)(BigShapeBufferPtr + 3) & 0xfffffffc);
}
Length = length;
return (return_value);
}
} else {
return ((unsigned long)buffptr);
}
}
/***********************************************************************************************
* Get_Build_Frame_Count -- Fetches the number of frames in data block. *
* *
* Use this routine to determine the number of shapes within the data block. *
* *
* INPUT: dataptr -- Pointer to the keyframe shape data block. *
* *
* OUTPUT: Returns with the number of shapes in the data block. *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 06/25/1995 JLB : Commented. *
*=============================================================================================*/
unsigned short Get_Build_Frame_Count(void const *dataptr)
{
if (dataptr) {
return(((KeyFrameHeaderType const *)dataptr)->frames);
}
return(0);
}
unsigned short Get_Build_Frame_X(void const *dataptr)
{
if (dataptr) {
return(((KeyFrameHeaderType const *)dataptr)->x);
}
return(0);
}
unsigned short Get_Build_Frame_Y(void const *dataptr)
{
if (dataptr) {
return(((KeyFrameHeaderType const *)dataptr)->y);
}
return(0);
}
/***********************************************************************************************
* Get_Build_Frame_Width -- Fetches the width of the shape image. *
* *
* Use this routine to fetch the width of the shapes within the keyframe shape data block. *
* All shapes within the block have the same width. *
* *
* INPUT: dataptr -- Pointer to the keyframe shape data block. *
* *
* OUTPUT: Returns with the width of the shapes in the block -- expressed in pixels. *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 06/25/1995 JLB : Commented *
*=============================================================================================*/
unsigned short Get_Build_Frame_Width(void const *dataptr)
{
if (dataptr) {
return(((KeyFrameHeaderType const *)dataptr)->width);
}
return(0);
}
/***********************************************************************************************
* Get_Build_Frame_Height -- Fetches the height of the shape image. *
* *
* Use this routine to fetch the height of the shapes within the keyframe shape data block. *
* All shapes within the block have the same height. *
* *
* INPUT: dataptr -- Pointer to the keyframe shape data block. *
* *
* OUTPUT: Returns with the height of the shapes in the block -- expressed in pixels. *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 06/25/1995 JLB : Commented *
*=============================================================================================*/
unsigned short Get_Build_Frame_Height(void const *dataptr)
{
if (dataptr) {
return(((KeyFrameHeaderType const *)dataptr)->height);
}
return(0);
}
bool Get_Build_Frame_Palette(void const * dataptr, void * palette)
{
if (dataptr && (((KeyFrameHeaderType const *)dataptr)->flags & 1)) {
char const * ptr = (char const *)Add_Long_To_Pointer( dataptr,
( (( (long)sizeof(unsigned long) << 1) *
((KeyFrameHeaderType *) dataptr)->frames ) +
16 + sizeof(KeyFrameHeaderType) ) );
memcpy(palette, ptr, 768L);
return(true);
}
return(false);
}

561
REDALERT/2SUPPORT.ASM Normal file
View File

@ -0,0 +1,561 @@
;
; 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: F:\projects\c&c0\vcs\code\2support.asv 5.0 11 Nov 1996 09:40:36 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 : SUPPORT.ASM *
;* *
;* Programmer : Joe L. Bostic *
;* *
;* Start Date : September 23, 1993 *
;* *
;* Last Update : May 10, 1994 [JLB] *
;* *
;*-------------------------------------------------------------------------*
;* Functions: *
;* strtrim -- Remove the trailing white space from a string. *
;* Fat_Put_Pixel -- Draws a fat pixel. *
;* Conquer_Build_Fading_Table -- Builds custom shadow/light fading table.*
;* Remove_From_List -- Removes a pointer from a list of pointers. *
;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
IDEAL
P386
MODEL USE32 FLAT
INCLUDE "gbuffer.inc"
DISPLAY "Command & Conquer assembly support routines."
CODESEG
;***************************************************************************
;* Fat_Put_Pixel -- Draws a fat pixel. *
;* *
;* Use this routine to draw a "pixel" that is bigger than 1 pixel *
;* across. This routine is faster than drawing a similar small shape *
;* and faster than calling Fill_Rect. *
;* *
;* INPUT: x,y -- Screen coordinates to draw the pixel's upper *
;* left corner. *
;* *
;* color -- The color to render the pixel in. *
;* *
;* size -- The number of pixels width of the big "pixel". *
;* *
;* page -- The pointer to a GraphicBuffer class or something *
;* *
;* OUTPUT: none *
;* *
;* WARNINGS: none *
;* *
;* HISTORY: *
;* 03/17/1994 JLB : Created. *
;*=========================================================================*
; VOID cdecl Fat_Put_Pixel(long x, long y, long color, long size, void *page)
GLOBAL C Fat_Put_Pixel:NEAR
PROC Fat_Put_Pixel C near
USES eax, ebx, ecx, edx, edi, esi
ARG x:DWORD ; X coordinate of upper left pixel corner.
ARG y:DWORD ; Y coordinate of upper left pixel corner.
ARG color:DWORD ; Color to use for the "pixel".
ARG siz:DWORD ; Size of "pixel" to plot (square).
ARG gpage:DWORD ; graphic page address to plot onto
cmp [siz],0
je short ??exit
; Set EDI to point to start of logical page memory.
;*===================================================================
; Get the viewport information and put bytes per row in ecx
;*===================================================================
mov ebx,[gpage] ; get a pointer to viewport
mov edi,[(GraphicViewPort ebx).GVPOffset] ; get the correct offset
; Verify the the Y pixel offset is legal.
mov eax,[y]
cmp eax,[(GraphicViewPort ebx).GVPHeight] ;YPIXEL_MAX
jae short ??exit
mov ecx,[(GraphicViewPort ebx).GVPWidth]
add ecx,[(GraphicViewPort ebx).GVPXAdd]
add ecx,[(GraphicViewPort ebx).GVPPitch]
mul ecx
add edi,eax
; Verify the the X pixel offset is legal.
mov edx,[(GraphicViewPort ebx).GVPWidth]
cmp edx,[x]
mov edx,ecx
jbe short ??exit
add edi,[x]
; Write the pixel to the screen.
mov ebx,[siz] ; Copy of pixel size.
sub edx,ebx ; Modulo to reach start of next row.
mov eax,[color]
??again:
mov ecx,ebx
rep stosb
add edi,edx ; EDI points to start of next row.
dec [siz]
jnz short ??again
??exit:
ret
ENDP Fat_Put_Pixel
if 0
;***************************************************************************
;* strtrim -- Remove the trailing white space from a string. *
;* *
;* Use this routine to remove white space characters from the beginning *
;* and end of the string. The string is modified in place by *
;* this routine. *
;* *
;* INPUT: buffer -- Pointer to the string to modify. *
;* *
;* OUTPUT: none *
;* *
;* WARNINGS: none *
;* *
;* HISTORY: *
;* 10/07/1992 JLB : Created. *
;*=========================================================================*
; VOID cdecl strtrim(BYTE *buffer);
GLOBAL C strtrim :NEAR
PROC strtrim C near
USES ax, edi, esi
ARG buffer:DWORD ; Pointer to string to modify.
cmp [buffer],0
je short ??fini
; Prepare for string scanning by loading pointers.
cld
mov esi,[buffer]
mov edi,esi
; Strip white space from the start of the string.
??looper:
lodsb
cmp al,20h ; Space
je short ??looper
cmp al,9 ; TAB
je short ??looper
stosb
; Copy the rest of the string.
??gruntloop:
lodsb
stosb
or al,al
jnz short ??gruntloop
dec edi
; Strip the white space from the end of the string.
??looper2:
mov [edi],al
dec edi
mov ah,[edi]
cmp ah,20h
je short ??looper2
cmp ah,9
je short ??looper2
??fini:
ret
ENDP strtrim
;***************************************************************************
;* Conquer_Build_Fading_Table -- Builds custom shadow/light fading table. *
;* *
;* This routine is used to build a special fading table for C&C. There *
;* are certain colors that get faded to and cannot be faded again. *
;* With this rule, it is possible to draw a shadow multiple times and *
;* not have it get any lighter or darker. *
;* *
;* INPUT: palette -- Pointer to the 768 byte IBM palette to build from. *
;* *
;* dest -- Pointer to the 256 byte remap table. *
;* *
;* color -- Color index of the color to "fade to". *
;* *
;* frac -- The fraction to fade to the specified color *
;* *
;* OUTPUT: Returns with pointer to the remap table. *
;* *
;* WARNINGS: none *
;* *
;* HISTORY: *
;* 10/07/1992 JLB : Created. *
;*=========================================================================*/
;VOID * cdecl Conquer_Build_Fading_Table(VOID *palette, VOID *dest, long color, long frac);
GLOBAL C Conquer_Build_Fading_Table : NEAR
PROC Conquer_Build_Fading_Table C near
USES ebx, ecx, edi, esi
ARG palette:DWORD
ARG dest:DWORD
ARG color:DWORD
ARG frac:DWORD
LOCAL matchvalue:DWORD ; Last recorded match value.
LOCAL targetred:BYTE ; Target gun red.
LOCAL targetgreen:BYTE ; Target gun green.
LOCAL targetblue:BYTE ; Target gun blue.
LOCAL idealred:BYTE
LOCAL idealgreen:BYTE
LOCAL idealblue:BYTE
LOCAL matchcolor:BYTE ; Tentative match color.
ALLOWED_COUNT EQU 16
ALLOWED_START EQU 256-ALLOWED_COUNT
cld
; If the source palette is NULL, then just return with current fading table pointer.
cmp [palette],0
je ??fini1
cmp [dest],0
je ??fini1
; Fractions above 255 become 255.
mov eax,[frac]
cmp eax,0100h
jb short ??ok
mov [frac],0FFh
??ok:
; Record the target gun values.
mov esi,[palette]
mov ebx,[color]
add esi,ebx
add esi,ebx
add esi,ebx
lodsb
mov [targetred],al
lodsb
mov [targetgreen],al
lodsb
mov [targetblue],al
; Main loop.
xor ebx,ebx ; Remap table index.
; Transparent black never gets remapped.
mov edi,[dest]
mov [edi],bl
inc edi
; EBX = source palette logical number (1..255).
; EDI = running pointer into dest remap table.
??mainloop:
inc ebx
mov esi,[palette]
add esi,ebx
add esi,ebx
add esi,ebx
mov edx,[frac]
shr edx,1
; new = orig - ((orig-target) * fraction);
lodsb ; orig
mov dh,al ; preserve it for later.
sub al,[targetred] ; al = (orig-target)
imul dl ; ax = (orig-target)*fraction
shl eax,1
sub dh,ah ; dh = orig - ((orig-target) * fraction)
mov [idealred],dh ; preserve ideal color gun value.
lodsb ; orig
mov dh,al ; preserve it for later.
sub al,[targetgreen] ; al = (orig-target)
imul dl ; ax = (orig-target)*fraction
shl eax,1
sub dh,ah ; dh = orig - ((orig-target) * fraction)
mov [idealgreen],dh ; preserve ideal color gun value.
lodsb ; orig
mov dh,al ; preserve it for later.
sub al,[targetblue] ; al = (orig-target)
imul dl ; ax = (orig-target)*fraction
shl eax,1
sub dh,ah ; dh = orig - ((orig-target) * fraction)
mov [idealblue],dh ; preserve ideal color gun value.
; Sweep through a limited set of existing colors to find the closest
; matching color.
mov eax,[color]
mov [matchcolor],al ; Default color (self).
mov [matchvalue],-1 ; Ridiculous match value init.
mov ecx,ALLOWED_COUNT
mov esi,[palette] ; Pointer to original palette.
add esi,(ALLOWED_START)*3
; BH = color index.
mov bh,ALLOWED_START
??innerloop:
xor edx,edx ; Comparison value starts null.
; Build the comparison value based on the sum of the differences of the color
; guns squared.
lodsb
sub al,[idealred]
mov ah,al
imul ah
add edx,eax
lodsb
sub al,[idealgreen]
mov ah,al
imul ah
add edx,eax
lodsb
sub al,[idealblue]
mov ah,al
imul ah
add edx,eax
jz short ??perfect ; If perfect match found then quit early.
cmp edx,[matchvalue]
jae short ??notclose
mov [matchvalue],edx ; Record new possible color.
mov [matchcolor],bh
??notclose:
inc bh ; Checking color index.
loop ??innerloop
mov bh,[matchcolor]
??perfect:
mov [matchcolor],bh
xor bh,bh ; Make BX valid main index again.
; When the loop exits, we have found the closest match.
mov al,[matchcolor]
stosb
cmp ebx,ALLOWED_START-1
jne ??mainloop
; Fill the remainder of the remap table with values
; that will remap the color to itself.
mov ecx,ALLOWED_COUNT
??fillerloop:
inc bl
mov al,bl
stosb
loop ??fillerloop
??fini1:
mov esi,[dest]
mov eax,esi
ret
ENDP Conquer_Build_Fading_Table
;***************************************************************************
;* Remove_From_List -- Removes a pointer from a list of pointers. *
;* *
;* This low level routine is used to remove a pointer from a list of *
;* pointers. The trailing pointers are moved downward to fill the *
;* hole. *
;* *
;* INPUT: list -- Pointer to list of pointer. *
;* *
;* index -- Pointer to length of pointer list. *
;* *
;* ptr -- The pointer value to search for and remove. *
;* *
;* OUTPUT: none *
;* *
;* WARNINGS: none *
;* *
;* HISTORY: *
;* 04/11/1994 JLB : Created. *
;* 04/22/1994 JLB : Convert to assembly language. *
;* 05/10/1994 JLB : Short pointers now. *
;*=========================================================================*/
;VOID cdecl Remove_From_List(VOID **list, long *index, long ptr);
GLOBAL C Remove_From_List:NEAR
PROC Remove_From_List C near
USES edi, esi, ecx, eax
ARG list:DWORD ; Pointer to list.
ARG index:DWORD ; Pointer to count.
ARG element:DWORD ; Element to remove.
; Fetch the number of elements in the list. If there are no
; elements, then just exit quickly.
mov edi,[index]
mov ecx,[edi]
jcxz short ??fini2
; Fetch pointer to list.
cmp [list],0
je short ??fini2
mov edi,[list]
; Loop through all elements searching for a match.
mov eax,[element]
repne scasd
jne short ??fini2 ; No match found.
; Copy all remaining elements down. If this is the
; last element in the list then nothing needs to be
; copied -- just decrement the list size.
jcxz short ??nocopy ; No copy necessary.
mov esi,edi
sub edi,4
rep movsd
; Reduce the list count by one.
??nocopy:
mov edi,[index]
dec [DWORD PTR edi]
??fini2:
ret
ENDP Remove_From_List
; long cdecl Get_EAX();
GLOBAL C Get_EAX :NEAR
PROC Get_EAX C near
ret
ENDP Get_EAX
endif
DATASEG
TabA DD 6949350
DD 4913933
DD 3474675
DD 2456966
DD 1737338
DD 1228483
DD 868669
DD 614242
DD 434334
DD 307121
DD 217167
DD 153560
DD 108584
DD 76780
DD 54292
DD 38390
DD 27146
DD 19195
DD 13573
DD 9598
DD 6786
DD 4799
DD 3393
DD 2399
DD 1697
DD 1200
DD 848
DD 600
DD 424
DD 300
DD 212
DD 150
DD 106
TabB DD 154
DD 218
DD 309
DD 437
DD 618
DD 874
DD 1236
DD 1748
DD 2472
DD 3496
DD 4944
DD 6992
DD 9888
DD 13983
DD 19775
DD 27967
DD 39551
DD 55933
DD 79101
DD 111866
DD 158203
DD 223732
DD 316405
DD 447465
DD 632811
DD 894929
DD 1265621
DD 1789859
DD 2531243
DD 3579718
DD 5062486
DD 7159436
DD 10124971
CODESEG
;***********************************************************************************************
;* Square_Root -- Finds the square root of the fixed pointer parameter. *
;* *
;* INPUT: val -- The fixed point (16:16) value to find the square root of. *
;* *
;* OUTPUT: Returns with the square root of the fixed pointer parameter. *
;* *
;* WARNINGS: none *
;* *
;* HISTORY: *
;* 10/04/1995 JLB : Adapted. *
;*=============================================================================================*/
;unsigned Square_Root(unsigned val);
GLOBAL C Square_Root :NEAR
PROC Square_Root C near
USES ebx,edx
bsr ebx,eax
jz ??zero
mul [DWORD 4*ebx + OFFSET TabA]
shrd eax,edx,10h
add eax, [4*ebx + OFFSET TabB]
??zero:
ret
ENDP Square_Root
;----------------------------------------------------------------------------
END

504
REDALERT/2TXTPRNT.ASM Normal file
View File

@ -0,0 +1,504 @@
;
; 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]>.
;***************************************************************************
;** 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 : Westwood 32 bit Library *
;* *
;* File Name : TXTPRNT.ASM *
;* *
;* Programmer : Phil W. Gorrow *
;* *
;* Start Date : January 17, 1995 *
;* *
;* Last Update : January 17, 1995 [PWG] *
;* *
;*-------------------------------------------------------------------------*
;* Functions: *
;* MCGA_Print -- Assembly MCGA text print routine *
;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
IDEAL
P386
MODEL USE32 FLAT
;INCLUDE "mcgaprim.inc"
;INCLUDE ".\gbuffer.inc"
GLOBAL C Buffer_Print : NEAR
STRUC GraphicViewPort
GVPOffset DD ? ; offset to virtual viewport
GVPWidth DD ? ; width of virtual viewport
GVPHeight DD ? ; height of virtual viewport
GVPXAdd DD ? ; x mod to get to next line
GVPXPos DD ? ; x pos relative to Graphic Buff
GVPYPos DD ? ; y pos relative to Graphic Buff
GVPPitch dd ? ; modulo of graphic view port
GVPBuffPtr DD ? ; ptr to associated Graphic Buff
ENDS
;*=========================================================================*
;* Extern the font pointer which is defined by the font class *
;*=========================================================================*
GLOBAL C FontPtr:DWORD
GLOBAL C FontXSpacing:DWORD
GLOBAL C FontYSpacing:DWORD
GLOBAL C ColorXlat:BYTE
;*=========================================================================*
;* Define the necessary equates for structures and bounds checking *
;*=========================================================================*
; The header of the font file looks like this:
; UWORD FontLength; 0
; BYTE FontCompress; 2
; BYTE FontDataBlocks; 3
; UWORD InfoBlockOffset; 4
; UWORD OffsetBlockOffset; 6
; UWORD WidthBlockOffset; 8
; UWORD DataBlockOffset; 10
; UWORD HeightOffset; 12
; For this reason the following equates have these values:
FONTINFOBLOCK EQU 4
FONTOFFSETBLOCK EQU 6
FONTWIDTHBLOCK EQU 8
FONTDATABLOCK EQU 10
FONTHEIGHTBLOCK EQU 12
FONTINFOMAXHEIGHT EQU 4
FONTINFOMAXWIDTH EQU 5
LOCALS ??
;*=========================================================================*
;* Define the color xlate table in the data segment *
;*=========================================================================*
DATASEG
ColorXlat DB 000H,001H,002H,003H,004H,005H,006H,007H
DB 008H,009H,00AH,00BH,00CH,00DH,00EH,00FH
DB 001H,000H,000H,000H,000H,000H,000H,000H
DB 000H,000H,000H,000H,000H,000H,000H,000H
DB 002H,000H,000H,000H,000H,000H,000H,000H
DB 000H,000H,000H,000H,000H,000H,000H,000H
DB 003H,000H,000H,000H,000H,000H,000H,000H
DB 000H,000H,000H,000H,000H,000H,000H,000H
DB 004H,000H,000H,000H,000H,000H,000H,000H
DB 000H,000H,000H,000H,000H,000H,000H,000H
DB 005H,000H,000H,000H,000H,000H,000H,000H
DB 000H,000H,000H,000H,000H,000H,000H,000H
DB 006H,000H,000H,000H,000H,000H,000H,000H
DB 000H,000H,000H,000H,000H,000H,000H,000H
DB 007H,000H,000H,000H,000H,000H,000H,000H
DB 000H,000H,000H,000H,000H,000H,000H,000H
DB 008H,000H,000H,000H,000H,000H,000H,000H
DB 000H,000H,000H,000H,000H,000H,000H,000H
DB 009H,000H,000H,000H,000H,000H,000H,000H
DB 000H,000H,000H,000H,000H,000H,000H,000H
DB 00AH,000H,000H,000H,000H,000H,000H,000H
DB 000H,000H,000H,000H,000H,000H,000H,000H
DB 00BH,000H,000H,000H,000H,000H,000H,000H
DB 000H,000H,000H,000H,000H,000H,000H,000H
DB 00CH,000H,000H,000H,000H,000H,000H,000H
DB 000H,000H,000H,000H,000H,000H,000H,000H
DB 00DH,000H,000H,000H,000H,000H,000H,000H
DB 000H,000H,000H,000H,000H,000H,000H,000H
DB 00EH,000H,000H,000H,000H,000H,000H,000H
DB 000H,000H,000H,000H,000H,000H,000H,000H
DB 00FH
CODESEG
;***************************************************************************
;* MCGA_PRINT -- Assembly MCGA text print routine *
;* *
;* *
;* *
;* INPUT: *
;* *
;* OUTPUT: *
;* *
;* PROTO: *
;* *
;* WARNINGS: *
;* *
;* HISTORY: *
;* 01/17/1995 PWG : Created. *
;*=========================================================================*
PROC Buffer_Print C near
USES ebx,ecx,edx,esi,edi
ARG this:DWORD
ARG string:DWORD
ARG x_pixel:DWORD
ARG y_pixel:DWORD
ARG fcolor:DWORD
ARG bcolor:DWORD
LOCAL infoblock:DWORD ; pointer to info block
LOCAL offsetblock:DWORD ; pointer to offset block (UWORD *)
LOCAL widthblock:DWORD ; pointer to width block (BYTE *)
LOCAL heightblock:DWORD ; pointer to height block (UWORD *)
LOCAL curline:DWORD ; pointer to first column of current row.
LOCAL bufferwidth:DWORD ; width of buffer (vpwidth + Xadd)
LOCAL nextdraw:DWORD ; bufferwidth - width of cur character.
LOCAL startdraw:DWORD ; where next character will start being drawn.
LOCAL char:DWORD ; current character value.
LOCAL maxheight:BYTE ; max height of characters in font.
LOCAL bottomblank:BYTE ; amount of empty space below current character.
LOCAL charheight:BYTE ; true height of current character.
LOCAL vpwidth:DWORD
LOCAL vpheight:DWORD
LOCAL original_x:DWORD ; Starting X position.
;-------------------------------- Where to draw -----------------------------------------------
; Set up memory location to start drawing.
mov ebx,[this] ; get a pointer to dest
mov eax,[(GraphicViewPort ebx).GVPHeight] ; get height of viewport
mov [vpheight],eax ; save off height of viewport
mov eax,[(GraphicViewPort ebx).GVPWidth] ; get width of viewport
mov [vpwidth],eax ; save it off for later
add eax,[(GraphicViewPort ebx).GVPXAdd] ; add in xadd for bytes_per_line
add eax,[(GraphicViewPort ebx).GVPPitch] ; add in pitch of direct draw surface
mov [bufferwidth],eax ; save it off for later use.
mul [y_pixel] ; multiply rowsize * y_pixel start.
mov edi,[(GraphicViewPort ebx).GVPOffset] ; get start of the viewport
add edi,eax ; add y position to start of vp
mov [curline],edi ; save 0,y address for line feed stuff.
add edi,[x_pixel] ; add to get starting column in starting row.
mov [startdraw],edi ; save it off.
mov eax,[x_pixel]
mov [original_x],eax
;-------------------------------- Create block pointers ----------------------------------------
; Get the pointer to the font.
; We could check for NULL but why waste the time.
; It is up to programmer to make sure it is set.
mov esi,[FontPtr] ; Get the font pointer
or esi,esi
jz ??overflow
; Set up some pointers to the different memory blocks.
; esi (FontPtr) is added to each to get the true address of each block.
; Many registers are used for P5 optimizations.
; ebx is used for InfoBlock which is then used in the next section.
movzx eax,[WORD PTR esi+FONTOFFSETBLOCK] ; get offset to offset block
movzx ebx,[WORD PTR esi+FONTINFOBLOCK] ; get offset to info block (must be ebx for height test)
movzx ecx,[WORD PTR esi+FONTWIDTHBLOCK] ; get offset to width block
movzx edx,[WORD PTR esi+FONTHEIGHTBLOCK] ; get offset to height block
add eax,esi ; add offset of FontPtr to offset block
add ebx,esi ; add offset of FontPtr to info block
add ecx,esi ; add offset of FontPtr to width block
add edx,esi ; add offset of FontPtr to height block
mov [offsetblock],eax ; save offset to offset block
mov [infoblock],ebx ; save offset to info block
mov [widthblock],ecx ; save offset to width block
mov [heightblock],edx ; save offset to height block
;------------------------------------------ Test for fit ----------------------------------------------
; Test to make sure the height of the max character will fit on this line
; and and not fall out of the viewport.
; remember we set ebx to FONTINFOBLOCK above.
movzx eax,[BYTE PTR ebx + FONTINFOMAXHEIGHT]; get the max height in font.
mov [maxheight],al ; save it for later use.
add eax,[y_pixel] ; add current y_value.
cmp eax,[vpheight] ; are we over the edge?
jg ??overflow ; if so, we're outa here.
mov [y_pixel],eax ; save for next line feed. y value for next line.
cld ; Make sure we are always forward copying.
;------------------------ Set palette foreground and background ----------------------------------
mov eax,[fcolor] ; foreground color
mov [ColorXlat+1],al
mov [ColorXlat+16],al
mov eax,[bcolor] ; background color
mov [ColorXlat],al
;-------------------------------------------------------------------------------------------------
;----------------------------------------- Main loop ----------------------------------------------
; Now we go into the main loop of reading each character in the string and doing
; something with it.
??next_char:
; while (*string++)
xor eax,eax ; zero out since we will just load al.
mov esi,[string] ; get address on next character.
lodsb ; load the character into al.
test eax,0FFH ; test to see if character is a NULL
jz ??done ; character is NULL, get outa here.
mov edi,[startdraw] ; Load the starting address.
mov [string],esi ; save index into string. (incremented by lodsb)
cmp al,10 ; is the character a line feed?
je ??line_feed ; if so, go to special case.
cmp al,13 ; is the character a line feed?
je ??line_feed ; if so, go to special case.
mov [char],eax ; save the character off for later reference.
mov ebx,eax ; save it in ebx for later use also.
add eax,[widthblock] ; figure address of width of character.
mov ecx,[x_pixel] ; get current x_pixel.
movzx edx,[BYTE PTR eax] ; get the width of the character in dl.
add ecx,edx ; add width of char to current x_pixel.
mov eax,[FontXSpacing]
add ecx,eax
add [startdraw],edx ; save start draw for next character.
add [startdraw],eax ; adjust for the font spacing value
cmp ecx,[vpwidth] ; is the pixel greater then the vp width?
jg ??force_line_feed ; if so, force a line feed.
mov [x_pixel],ecx ; save value of start of next character.
mov ecx,[bufferwidth] ; get amount to next y same x (one row down)
sub ecx,edx ; take the current width off.
mov [nextdraw],ecx ; save it to add to edi when done with a row.
; At this point we got the character. It is now time to find out specifics
; about drawing the darn thing.
; ebx = char so they can be used as an indexes.
; edx = width of character for loop later.
; get offset of data for character into esi.
shl ebx,1 ; mult by 2 to later use as a WORD index.
mov esi,[offsetblock] ; get pointer to begining of offset block.
add esi,ebx ; index into offset block.
movzx esi,[WORD PTR esi] ; get true offset into data block from FontPtr.
add esi,[FontPtr] ; Now add FontPtr address to get true address.
; Get top and bottom blank sizes and the true height of the character.
add ebx,[heightblock] ; point ebx to element in height array.
mov al,[ebx+1] ; load the data height into dl.
mov cl,[ebx] ; load the first data row into cl.
mov bl,[maxheight] ; get the max height of characters.
mov [charheight],al ; get number of rows with data.
add al,cl ; add the two heights.
sub bl,al ; subract topblank + char height from maxheight.
mov [bottomblank],bl ; save off the number of blank rows on the bottom.
; leaving this section:
; dl is still the width of the character.
; cl is the height of the top blank area.
mov ebx,OFFSET ColorXlat ; setup ebx for xlat commands.
mov dh,dl ; save the width of the character to restore each loop.
cmp cl,0 ; is there any blank rows on top?
jz ??draw_char ; if not go and draw the real character.
xor eax,eax ; get color 0 for background.
xlat [ebx] ; get translated color into al
test al,al ; is it transparent black
jnz ??loop_top ; if not go and write the color
;----------------------------------------- skip Top blank area ----------------------------------------
; this case, the top is transparrent, but we need to increase our dest pointer to correct row.
movzx eax,cl ; get number of rows into eax;
mov ecx,edx ; save width since edx will be destroyed by mul.
mul [bufferwidth] ; multiply that by the width of the buffer.
mov edx,ecx ; restore the width
add edi,eax ; update the pointer.
jmp short ??draw_char ; now go draw the character.
;----------------------------------------- fill Top blank area ----------------------------------------
; edi was set a long time ago.
; al is the translated color
??loop_top:
stosb ; store the value
dec dh ; decrement our width.
jnz ??loop_top ; if more width, continue on.
add edi,[nextdraw] ; add amount for entire row.
dec cl ; decrement or row count
mov dh,dl ; restore width in dh for loop.
jz ??draw_char ; we are done here, go draw the character.
jmp short ??loop_top ; go back to top of loop.
;----------------------------------------- Draw character ----------------------------------------------
??draw_char:
movzx ecx,[charheight] ; get the height of character to count down rows.
test ecx,ecx ; is there any data? (blank would not have any)
jz ??next_char ; if no data, go on to next character.
??while_data:
lodsb ; get byte value from font data
mov ah,al ; save hinibble
and eax,0F00FH ; mask of low nibble in al hi nibble in ah.
xlat [ebx] ; get new color
test al,al ; is it a transparent?
jz short ??skiplo ; skip over write
mov [es:edi],al ; write it out
??skiplo:
inc edi
dec dh ; decrement our width.
jz short ??nextrow ; check if done with width of char
mov al,ah ; restore to get
; test the time difference between looking up in a large table when shr al,4 is not done as
; compared to using only a 16 byte table when using the shr al,4
;shr al,4 ; shift the hi nibble down to low nibble
xlat [ebx] ; get new color
test al,al ; is it a transparent?
jz short ??skiphi ; skip over write
mov [es:edi],al ; write it out
??skiphi:
inc edi
dec dh ; decrement our width.
jnz short ??while_data ; check if done with width of char
??nextrow:
add edi,[nextdraw] ; go to next line.
dec ecx ; decrement the number of rows to go
mov dh,dl ; restore our column count for row.
jnz ??while_data ; more data for character.
; Now it is time to setup for clearing out the bottom of the character.
movzx ecx,[bottomblank] ; get amount on bottom that is blank
cmp ecx,0 ; if there is no blank bottom...
jz ??next_char ; then skip to go to next character
xor eax,eax ; get color 0 for background.
xlat [ebx] ; get translated color into al
test al,al ; is it transparent black
jz ??next_char ; skip the top black section to let the background through
mov dh,dl ; restore width in dh for loop.
;----------------------------------------- Blank below character -----------------------------------
??loop_bottom:
stosb ; store the value
dec dh ; decrement our width.
jnz ??loop_bottom ; if more width, continue on.
add edi,[nextdraw] ; add amount for entire row.
mov dh,dl ; restore width in dh for loop.
dec cl ; decrement or row count
jz ??next_char ; we are done here, go to the next character.
jmp short ??loop_bottom ; go back to top of loop.
;----------------------------------- end of next_char (main) loop ------------------------------------
;-------------------------------------------------------------------------------------------------
;----------------------------------- special case line feeds ----------------------------------------
??force_line_feed:
; decrement pointer *string so that it will be back at same character
; when it goes through the loop.
mov eax,[string] ; get string pointer.
dec eax ; decrement it to point to previos char
mov [string],eax ; save it back off.
xor eax,eax
; Now go into the line feed code.....
??line_feed:
mov bl,al
mov edx,[y_pixel] ; get the current y pixel value.
movzx ecx,[maxheight] ; get max height for later use.
add ecx,[FontYSpacing]
add edx,ecx ; add max height to y_pixel
cmp edx,[vpheight] ; are we over the edge?
jg ??overflow ; if so, we are outa here.
mov eax,[bufferwidth] ; get bytes to next line.
mov edi,[curline] ; get start of current line.
mul ecx ; mult max height * next line.
add edi,eax ; add adjustment to current line.
add [y_pixel],ecx ; increment to our next y position.
;;; DRD
mov [curline],edi ; save it off for next line_feed.
; Move the cursor to either the left edge of the screen
; or the left margin of the print position depending
; on whether <CR> or <LF> was specified. <CR> = left margin
; <LF> = left edge of screen
xor eax,eax
cmp bl,10
je ??lfeed
mov eax,[original_x]
??lfeed:
mov [x_pixel],eax ; zero out x_pixel
add edi,eax
;;; DRD mov [curline],edi ; save it off for next line_feed.
mov [startdraw],edi ; save it off so we know where to draw next char.w
jmp ??next_char
??overflow:
mov [startdraw],0 ; Indicate that there is no valid next pos.
??done:
mov eax,[startdraw] ; return this so calling routine
ret ; can figure out where to draw next.
ENDP Buffer_Print
;***************************************************************************
;* GET_FONT_PALETTE_PTR -- Returns a pointer to the 256 byte font palette *
;* *
;* INPUT: none *
;* *
;* OUTPUT: none *
;* *
;* PROTO: void *Get_Font_Palette_Ptr(void); *
;* *
;* HISTORY: *
;* 08/18/1995 PWG : Created. *
;*=========================================================================*
GLOBAL C Get_Font_Palette_Ptr:NEAR
PROC Get_Font_Palette_Ptr C near
mov eax, OFFSET ColorXlat
ret
ENDP Get_Font_Palette_Ptr
END

655
REDALERT/AADATA.CPP Normal file
View File

@ -0,0 +1,655 @@
//
// 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/AADATA.CPP 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 : AADATA.CPP *
* *
* Programmer : Joe L. Bostic *
* *
* Start Date : July 22, 1994 *
* *
* Last Update : July 9, 1996 [JLB] *
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* AircraftTypeClass::AircraftTypeClass -- Constructor for aircraft objects. *
* AircraftTypeClass::As_Reference -- Given an aircraft type, find the matching type object. *
* AircraftTypeClass::Create_And_Place -- Creates and places aircraft using normal game syste*
* AircraftTypeClass::Create_One_Of -- Creates an aircraft object of the appropriate type. *
* AircraftTypeClass::Dimensions -- Fetches the graphic dimensions of the aircraft type. *
* AircraftTypeClass::Display -- Displays a generic version of the aircraft type. *
* AircraftTypeClass::From_Name -- Converts an ASCII name into an aircraft type number. *
* AircraftTypeClass::Init_Heap -- Initialize the aircraft type class heap. *
* AircraftTypeClass::Max_Pips -- Fetches the maximum number of pips allowed. *
* AircraftTypeClass::Occupy_List -- Returns with occupation list for landed aircraft. *
* AircraftTypeClass::One_Time -- Performs one time initialization of the aircraft type class*
* AircraftTypeClass::Overlap_List -- Determines the overlap list for a landed aircraft. *
* AircraftTypeClass::Prep_For_Add -- Prepares the scenario editor for adding an aircraft obj*
* AircraftTypeClass::operator delete -- Returns aircraft type to special memory pool. *
* AircraftTypeClass::operator new -- Allocates an aircraft type object from special pool. *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "function.h"
void const * AircraftTypeClass::LRotorData = NULL;
void const * AircraftTypeClass::RRotorData = NULL;
// Badger bomber
static AircraftTypeClass const BadgerPlane(
AIRCRAFT_BADGER, // What kind of aircraft is this.
TXT_BADGER, // Translated text number for aircraft.
"BADR", // INI name of aircraft.
0x0000, // Vertical offset.
0x0000, // Primary weapon offset along turret centerline.
0x0000, // Primary weapon lateral offset along turret centerline.
true, // Fixed wing aircraft?
false, // Equipped with a rotor?
false, // Custom rotor sets for each facing?
false, // Can this aircraft land on clear terrain?
true, // Is it invisible on radar?
false, // Can the player select it so as to give it orders?
true, // Can it be assigned as a target for attack.
false, // Is it insignificant (won't be announced)?
false, // Is it immune to normal combat damage?
STRUCT_NONE, // Preferred landing building.
0xFF, // Landing speed
16, // Number of rotation stages.
MISSION_HUNT // Default mission for aircraft.
);
// Photo recon plane.
static AircraftTypeClass const U2Plane(
AIRCRAFT_U2, // What kind of aircraft is this.
TXT_U2, // Translated text number for aircraft.
"U2", // INI name of aircraft.
0x0000, // Vertical offset.
0x0000, // Primary weapon offset along turret centerline.
0x0000, // Primary weapon lateral offset along turret centerline.
true, // Fixed wing aircraft?
false, // Equipped with a rotor?
false, // Custom rotor sets for each facing?
false, // Can this aircraft land on clear terrain?
true, // Is it invisible on radar?
false, // Can the player select it so as to give it orders?
true, // Can it be assigned as a target for attack.
false, // Is it insignificant (won't be announced)?
false, // Is it immune to normal combat damage?
STRUCT_NONE, // Preferred landing building.
0xFF, // Landing speed
16, // Number of rotation stages.
MISSION_HUNT // Default mission for aircraft.
);
// Mig attack aircraft.
static AircraftTypeClass const MigPlane(
AIRCRAFT_MIG, // What kind of aircraft is this.
TXT_MIG, // Translated text number for aircraft.
"MIG", // INI name of aircraft.
0x0000, // Vertical offset.
0x0020, // Primary weapon offset along turret centerline.
0x0020, // Primary weapon lateral offset along turret centerline.
true, // Fixed wing aircraft?
false, // Equipped with a rotor?
false, // Custom rotor sets for each facing?
false, // Can this aircraft land on clear terrain?
true, // Is it invisible on radar?
true, // Can the player select it so as to give it orders?
true, // Can it be assigned as a target for attack.
false, // Is it insignificant (won't be announced)?
false, // Is it immune to normal combat damage?
STRUCT_AIRSTRIP, // Preferred landing building.
0xC0, // Landing speed
16, // Number of rotation stages.
MISSION_HUNT // Default mission for aircraft.
);
// Yak attack aircraft.
static AircraftTypeClass const YakPlane(
AIRCRAFT_YAK, // What kind of aircraft is this.
TXT_YAK, // Translated text number for aircraft.
"YAK", // INI name of aircraft.
0x0000, // Vertical offset.
0x0020, // Primary weapon offset along turret centerline.
0x0020, // Primary weapon lateral offset along turret centerline.
true, // Fixed wing aircraft?
false, // Equipped with a rotor?
false, // Custom rotor sets for each facing?
false, // Can this aircraft land on clear terrain?
true, // Is it invisible on radar?
true, // Can the player select it so as to give it orders?
true, // Can it be assigned as a target for attack.
false, // Is it insignificant (won't be announced)?
false, // Is it immune to normal combat damage?
STRUCT_AIRSTRIP, // Preferred landing building.
0xFF, // Landing speed
16, // Number of rotation stages.
MISSION_HUNT // Default mission for aircraft.
);
// Transport helicopter.
static AircraftTypeClass const TransportHeli(
AIRCRAFT_TRANSPORT, // What kind of aircraft is this.
TXT_TRANS, // Translated text number for aircraft.
"TRAN", // INI name of aircraft.
0x0000, // Vertical offset.
0x0000, // Primary weapon offset along turret centerline.
0x0000, // Primary weapon lateral offset along turret centerline.
false, // Fixed wing aircraft?
true, // Equipped with a rotor?
true, // Custom rotor sets for each facing?
true, // Can this aircraft land on clear terrain?
true, // Is it invisible on radar?
true, // Can the player select it so as to give it orders?
true, // Can it be assigned as a target for attack.
false, // Is it insignificant (won't be announced)?
false, // Is it immune to normal combat damage?
STRUCT_NONE, // Preferred landing building.
0xFF, // Landing speed
32, // Number of rotation stages.
MISSION_HUNT // Default mission for aircraft.
);
// Longbow attack helicopter
static AircraftTypeClass const AttackHeli(
AIRCRAFT_LONGBOW, // What kind of aircraft is this.
TXT_HELI, // Translated text number for aircraft.
"HELI", // INI name of aircraft.
0x0000, // Vertical offset.
0x0040, // Primary weapon offset along turret centerline.
0x0000, // Primary weapon lateral offset along turret centerline.
false, // Fixed wing aircraft?
true, // Equipped with a rotor?
false, // Custom rotor sets for each facing?
false, // Can this aircraft land on clear terrain?
true, // Is it invisible on radar?
true, // Can the player select it so as to give it orders?
true, // Can it be assigned as a target for attack.
false, // Is it insignificant (won't be announced)?
false, // Is it immune to normal combat damage?
STRUCT_HELIPAD, // Preferred landing building.
0xFF, // Landing speed
32, // Number of rotation stages.
MISSION_HUNT // Default mission for aircraft.
);
// Hind
static AircraftTypeClass const OrcaHeli(
AIRCRAFT_HIND, // What kind of aircraft is this.
TXT_ORCA, // Translated text number for aircraft.
"HIND", // INI name of aircraft.
0x0000, // Vertical offset.
0x0040, // Primary weapon offset along turret centerline.
0x0000, // Primary weapon lateral offset along turret centerline.
false, // Fixed wing aircraft?
true, // Equipped with a rotor?
false, // Custom rotor sets for each facing?
false, // Can this aircraft land on clear terrain?
true, // Is it invisible on radar?
true, // Can the player select it so as to give it orders?
true, // Can it be assigned as a target for attack.
false, // Is it insignificant (won't be announced)?
false, // Is it immune to normal combat damage?
STRUCT_HELIPAD, // Preferred landing building.
0xFF, // Landing speed
32, // Number of rotation stages.
MISSION_HUNT // Default mission for aircraft.
);
/***********************************************************************************************
* AircraftTypeClass::AircraftTypeClass -- Constructor for aircraft objects. *
* *
* This is the constructor for the aircraft object. *
* *
* INPUT: see below... *
* *
* OUTPUT: none *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 07/26/1994 JLB : Created. *
*=============================================================================================*/
AircraftTypeClass::AircraftTypeClass(
AircraftType airtype,
int name,
char const * ininame,
int verticaloffset,
int primaryoffset,
int primarylateral,
bool is_fixedwing,
bool is_rotorequipped,
bool is_rotorcustom,
bool is_landable,
bool is_stealthy,
bool is_selectable,
bool is_legal_target,
bool is_insignificant,
bool is_immune,
StructType building,
int landingspeed,
int rotation,
MissionType deforder
) :
TechnoTypeClass(RTTI_AIRCRAFTTYPE,
int(airtype),
name,
ininame,
REMAP_NORMAL,
verticaloffset,
primaryoffset,
primarylateral,
primaryoffset,
primarylateral,
false,
is_stealthy,
is_selectable,
is_legal_target,
is_insignificant,
is_immune,
false,
false,
true,
true,
rotation,
SPEED_WINGED),
IsFixedWing(is_fixedwing),
IsLandable(is_landable),
IsRotorEquipped(is_rotorequipped),
IsRotorCustom(is_rotorcustom),
Type(airtype),
Mission(deforder),
Building(building),
LandingSpeed(landingspeed)
{
/*
** Forced aircraft overrides from the default.
*/
Speed = SPEED_WINGED;
}
/***********************************************************************************************
* AircraftTypeClass::operator new -- Allocates an aircraft type object from special pool. *
* *
* This will allocate an aircraft type class object from the memory pool of that purpose. *
* *
* INPUT: none *
* *
* OUTPUT: Returns with a pointer to the newly allocated aircraft type class object. If there *
* was insufficient memory to fulfill the request, then NULL is returned. *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 07/09/1996 JLB : Created. *
*=============================================================================================*/
void * AircraftTypeClass::operator new(size_t)
{
return(AircraftTypes.Alloc());
}
/***********************************************************************************************
* AircraftTypeClass::operator delete -- Returns aircraft type to special memory pool. *
* *
* This will return the aircraft type class object back to the special memory pool that *
* it was allocated from. *
* *
* INPUT: pointer -- Pointer to the aircraft type class object to delete. *
* *
* OUTPUT: none *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 07/09/1996 JLB : Created. *
*=============================================================================================*/
void AircraftTypeClass::operator delete(void * pointer)
{
AircraftTypes.Free((AircraftTypeClass *)pointer);
}
/***********************************************************************************************
* AircraftTypeClass::Init_Heap -- Initialize the aircraft type class heap. *
* *
* This will initialize the aircraft type class heap by pre-allocating all known aircraft *
* types. It should be called once and before the rules.ini file is processed. *
* *
* INPUT: none *
* *
* OUTPUT: none *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 07/09/1996 JLB : Created. *
*=============================================================================================*/
void AircraftTypeClass::Init_Heap(void)
{
/*
** These aircraft type class objects must be allocated in the exact order that they
** are specified in the AircraftSmen enumeration. This is necessary because the heap
** allocation block index serves double duty as the type number index.
*/
new AircraftTypeClass(TransportHeli);
new AircraftTypeClass(BadgerPlane);
new AircraftTypeClass(U2Plane);
new AircraftTypeClass(MigPlane);
new AircraftTypeClass(YakPlane);
new AircraftTypeClass(AttackHeli);
new AircraftTypeClass(OrcaHeli);
}
/***********************************************************************************************
* AircraftTypeClass::From_Name -- Converts an ASCII name into an aircraft type number. *
* *
* This routine is used to convert an ASCII representation of an aircraft into the *
* matching aircraft type number. This is used by the scenario INI reader code. *
* *
* INPUT: name -- Pointer to ASCII name to translate. *
* *
* OUTPUT: Returns the aircraft type number that matches the ASCII name provided. If no *
* match could be found, then AIRCRAFT_NONE is returned. *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 07/26/1994 JLB : Created. *
*=============================================================================================*/
AircraftType AircraftTypeClass::From_Name(char const * name)
{
if (name != NULL) {
for (int classid = AIRCRAFT_FIRST; classid < AIRCRAFT_COUNT; classid++) {
if (stricmp(As_Reference((AircraftType)classid).IniName, name) == 0) {
return(AircraftType)classid;
}
}
}
return(AIRCRAFT_NONE);
}
/***********************************************************************************************
* AircraftTypeClass::One_Time -- Performs one time initialization of the aircraft type class. *
* *
* This routine is used to perform the onetime initialization of the aircraft type. This *
* includes primarily the shape and other graphic data loading. *
* *
* INPUT: none *
* *
* OUTPUT: none *
* *
* WARNINGS: This goes to disk and also must only be called ONCE. *
* *
* HISTORY: *
* 07/26/1994 JLB : Created. *
*=============================================================================================*/
void AircraftTypeClass::One_Time(void)
{
for (int index = AIRCRAFT_FIRST; index < AIRCRAFT_COUNT; index++) {
char fullname[_MAX_FNAME+_MAX_EXT];
AircraftTypeClass const & uclass = As_Reference((AircraftType)index);
/*
** Fetch the supporting data files for the unit.
*/
char buffer[_MAX_FNAME];
sprintf(buffer, "%sICON", uclass.Graphic_Name());
_makepath(fullname, NULL, NULL, buffer, ".SHP");
((void const *&)uclass.CameoData) = MFCD::Retrieve(fullname);
/*
** Generic shape for all houses load method.
*/
_makepath(fullname, NULL, NULL, uclass.Graphic_Name(), ".SHP");
((void const *&)uclass.ImageData) = MFCD::Retrieve(fullname);
}
LRotorData = MFCD::Retrieve("LROTOR.SHP");
RRotorData = MFCD::Retrieve("RROTOR.SHP");
}
/***********************************************************************************************
* AircraftTypeClass::Create_One_Of -- Creates an aircraft object of the appropriate type. *
* *
* This routine is used to create an aircraft object that matches the aircraft type. It *
* serves as a shortcut to creating an object using the "new" operator and "if" checks. *
* *
* INPUT: house -- The house owner of the aircraft that is to be created. *
* *
* OUTPUT: Returns with a pointer to the aircraft created. If the aircraft could not be *
* created, then a NULL is returned. *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 07/26/1994 JLB : Created. *
*=============================================================================================*/
ObjectClass * AircraftTypeClass::Create_One_Of(HouseClass * house) const
{
return(new AircraftClass(Type, house->Class->House));
}
#ifdef SCENARIO_EDITOR
/***********************************************************************************************
* AircraftTypeClass::Prep_For_Add -- Prepares the scenario editor for adding an aircraft objec*
* *
* This routine is used by the scenario editor to prepare for the adding operation. It *
* builds a list of pointers to object types that can be added. *
* *
* INPUT: none *
* *
* OUTPUT: none *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 07/26/1994 JLB : Created. *
*=============================================================================================*/
void AircraftTypeClass::Prep_For_Add(void)
{
for (AircraftType index = AIRCRAFT_FIRST; index < AIRCRAFT_COUNT; index++) {
if (As_Reference(index).Get_Image_Data()) {
Map.Add_To_List(&As_Reference(index));
}
}
}
/***********************************************************************************************
* AircraftTypeClass::Display -- Displays a generic version of the aircraft type. *
* *
* This routine is used by the scenario editor to display a generic version of the object *
* type. This is displayed in the object selection dialog box. *
* *
* INPUT: x,y -- The coordinates to draw the aircraft at (centered). *
* *
* window -- The window to base the coordinates upon. *
* *
* house -- The owner of this generic aircraft. *
* *
* OUTPUT: none *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 07/26/1994 JLB : Created. *
*=============================================================================================*/
void AircraftTypeClass::Display(int x, int y, WindowNumberType window, HousesType ) const
{
int shape = 0;
void const * ptr = Get_Cameo_Data();
if (ptr == NULL) {
ptr = Get_Image_Data();
shape = 5;
}
CC_Draw_Shape(ptr, shape, x, y, window, SHAPE_CENTER|SHAPE_WIN_REL);
}
#endif
/***********************************************************************************************
* AircraftTypeClass::Occupy_List -- Returns with occupation list for landed aircraft. *
* *
* This determines the occupation list for the aircraft (if it was landed). *
* *
* INPUT: placement -- Is this for placement legality checking only? The normal condition *
* is for marking occupation flags. *
* *
* OUTPUT: Returns with a pointer to a cell offset occupation list for the aircraft. *
* *
* WARNINGS: This occupation list is only valid if the aircraft is landed. *
* *
* HISTORY: *
* 07/26/1994 JLB : Created. *
*=============================================================================================*/
short const * AircraftTypeClass::Occupy_List(bool) const
{
static short const _list[] = {0, REFRESH_EOL};
return(_list);
}
/***********************************************************************************************
* AircraftTypeClass::Overlap_List -- Determines the overlap list for a landed aircraft. *
* *
* This routine figures out the overlap list for the aircraft as if it were landed. *
* *
* INPUT: none *
* *
* OUTPUT: Returns with the cell offset overlap list for the aircraft. *
* *
* WARNINGS: This overlap list is only valid when the aircraft is landed. *
* *
* HISTORY: *
* 07/26/1994 JLB : Created. *
*=============================================================================================*/
short const * AircraftTypeClass::Overlap_List(void) const
{
static short const _list[] = {-(MAP_CELL_W-1), -MAP_CELL_W, -(MAP_CELL_W+1), -1, 1, (MAP_CELL_W-1), MAP_CELL_W, (MAP_CELL_W+1), REFRESH_EOL};
return(_list);
}
/***********************************************************************************************
* AircraftTypeClass::Max_Pips -- Fetches the maximum number of pips allowed. *
* *
* Use this routine to retrieve the maximum pip count allowed for this aircraft. This is *
* the maximum number of passengers. *
* *
* INPUT: none *
* *
* OUTPUT: Returns with the maximum number of pips for this aircraft. *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 06/26/1995 JLB : Created. *
*=============================================================================================*/
int AircraftTypeClass::Max_Pips(void) const
{
if (PrimaryWeapon != NULL) {
// Camera weapon (ex. on the Spy plane) doesn't display any pips
if (!PrimaryWeapon->IsCamera) {
return(5);
}
}
return(Max_Passengers());
}
/***********************************************************************************************
* AircraftTypeClass::Create_And_Place -- Creates and places aircraft using normal game system *
* *
* This routine is used to create and place an aircraft through the normal game system. *
* Since creation of aircraft in this fashion is prohibited, this routine does nothing. *
* *
* INPUT: na *
* *
* OUTPUT: Always returns a failure code (false). *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 08/07/1995 JLB : Created. *
*=============================================================================================*/
bool AircraftTypeClass::Create_And_Place(CELL, HousesType) const
{
return(false);
}
/***********************************************************************************************
* AircraftTypeClass::Dimensions -- Fetches the graphic dimensions of the aircraft type. *
* *
* This routine will fetch the pixel dimensions of this aircraft type. These dimensions *
* are used to control map refresh and select box rendering. *
* *
* INPUT: width -- Reference to variable that will be filled in with aircraft width. *
* *
* height -- Reference to variable that will be filled in with aircraft height. *
* *
* OUTPUT: none *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 08/07/1995 JLB : Created. *
*=============================================================================================*/
void AircraftTypeClass::Dimensions(int &width, int &height) const
{
if (Type == AIRCRAFT_BADGER) {
width = 56;
height = 56;
} else {
width = 21;
height = 20;
}
}
/***********************************************************************************************
* AircraftTypeClass::As_Reference -- Given an aircraft type, find the matching type object. *
* *
* This routine is used to fetch a reference to the aircraft type class object that matches *
* the aircraft type specified. *
* *
* INPUT: aircraft -- The aircraft type to fetch a reference to the type class object of. *
* *
* OUTPUT: Returns with a reference to the type class object of this aircraft type. *
* *
* WARNINGS: Be sure that the aircraft type specified is legal. Illegal values will result *
* in undefined behavior. *
* *
* HISTORY: *
* 07/09/1996 JLB : Created. *
*=============================================================================================*/
AircraftTypeClass & AircraftTypeClass::As_Reference(AircraftType aircraft)
{
return(*AircraftTypes.Ptr(aircraft));
}

213
REDALERT/ABSTRACT.CPP Normal file
View File

@ -0,0 +1,213 @@
//
// 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/ABSTRACT.CPP 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 : ABSTRACT.CPP *
* *
* Programmer : Joe L. Bostic *
* *
* Start Date : 01/26/95 *
* *
* Last Update : July 10, 1996 [JLB] *
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* AbstractClass::Debug_Dump -- Display debug information to mono screen. *
* AbstractClass::Distance -- Determines distance to target. *
* AbstractTypeClass::AbstractTypeClass -- Constructor for abstract type objects. *
* AbstractTypeClass::Coord_Fixup -- Performs custom adjustments to location coordinate. *
* AbstractTypeClass::Full_Name -- Returns the full name (number) of this object type. *
* AbstractTypeClass::Get_Ownable -- Fetch the ownable bits for this object. *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "function.h"
/***********************************************************************************************
* AbstractClass::Debug_Dump -- Display debug information to mono screen. *
* *
* This debug only routine will display various information about this abstract class *
* object to the monochrome screen specified. *
* *
* INPUT: mono -- Pointer to the monochrome screen to display the debug information to. *
* *
* OUTPUT: none *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 07/10/1996 JLB : Created. *
*=============================================================================================*/
#ifdef CHEAT_KEYS
void AbstractClass::Debug_Dump(MonoClass * mono) const
{
assert(IsActive);
mono->Set_Cursor(11, 5);mono->Printf("%08X", As_Target());
mono->Set_Cursor(20, 1);mono->Printf("%08X", Coord);
mono->Set_Cursor(29, 1);mono->Printf("%3d", Height);
if (Owner() != HOUSE_NONE) {
mono->Set_Cursor(1, 3);
mono->Printf("%-18s", Text_String(HouseTypeClass::As_Reference(Owner()).FullName));
}
}
#endif
/***********************************************************************************************
* AbstractClass::Distance -- Determines distance to target. *
* *
* This will determine the distance (direct line) to the target. The distance is in *
* 'leptons'. This routine is typically used for weapon range checks. *
* *
* INPUT: target -- The target to determine range to. *
* *
* OUTPUT: Returns with the range to the specified target (in leptons). *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 08/17/1994 JLB : Created. *
*=============================================================================================*/
int AbstractClass::Distance(TARGET target) const
{
/*
** Should subtract a fudge-factor distance for building targets.
*/
BuildingClass * obj = As_Building(target);
int dist = Distance(As_Coord(target));
/*
** If the object is a building the adjust it by the average radius
** of the object.
*/
if (obj && obj->IsActive) {
dist -= ((obj->Class->Width() + obj->Class->Height()) * (0x100 / 4));
if (dist < 0) dist = 0;
}
/*
** Return the distance to the target
*/
return(dist);
}
/***********************************************************************************************
* AbstractTypeClass::AbstractTypeClass -- Constructor for abstract type objects. *
* *
* This is the constructor for AbstractTypeClass objects. It initializes the INI name and *
* the text name for this object type. *
* *
* INPUT: name -- Text number for the full name of the object. *
* *
* ini -- The ini name for this object type. *
* *
* OUTPUT: none *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 05/22/1995 JLB : Created. *
*=============================================================================================*/
AbstractTypeClass::AbstractTypeClass(RTTIType rtti, int id, int name, char const * ini) :
RTTI(rtti),
ID(id),
FullName(name)
{
strncpy((char *)IniName, ini, sizeof(IniName));
((char &)IniName[sizeof(IniName)-1]) = '\0';
}
/***********************************************************************************************
* AbstractTypeClass::Coord_Fixup -- Performs custom adjustments to location coordinate. *
* *
* This routine is called when the placement coordinate should be fixed up according *
* to any special rules specific to this object type. At this level, no transformation *
* occurs. Derived classes will transform the coordinate as necessary. *
* *
* INPUT: coord -- The proposed coordinate that this object type will be placed down at. *
* *
* OUTPUT: Returns with the adjusted coordinate that the object should be placed down at. *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 09/21/1995 JLB : Created. *
*=============================================================================================*/
COORDINATE AbstractTypeClass::Coord_Fixup(COORDINATE coord) const
{
return(coord);
}
/***********************************************************************************************
* AbstractTypeClass::Full_Name -- Returns the full name (number) of this object type. *
* *
* This routine is used to fetch the full name of this object type. The name value *
* returned is actually the index number into the text array. *
* *
* INPUT: none *
* *
* OUTPUT: Returns with the full name index number for this object type. *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 09/21/1995 JLB : Created. *
*=============================================================================================*/
int AbstractTypeClass::Full_Name(void) const
{
#ifdef FIXIT_NAME_OVERRIDE
for (int index = 0; index < ARRAY_SIZE(NameOverride); index++) {
if (NameIDOverride[index] == ((RTTI+1) * 100) + ID) {
return(-(index+1));
}
}
#endif
return(FullName);
}
/***********************************************************************************************
* AbstractTypeClass::Get_Ownable -- Fetch the ownable bits for this object. *
* *
* This returns a bit flag that indicates which houses are allowed to own this object *
* type. At this level, all houses have ownership rights. This routine will be overridden *
* by object types that restrict ownership. *
* *
* INPUT: none *
* *
* OUTPUT: Returns with a bit flag indicating which houses have ownership rights. *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 09/21/1995 JLB : Created. *
*=============================================================================================*/
int AbstractTypeClass::Get_Ownable(void) const
{
return(HOUSEF_ALLIES | HOUSEF_SOVIET | HOUSEF_OTHERS);
}

144
REDALERT/ABSTRACT.H Normal file
View File

@ -0,0 +1,144 @@
//
// 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/ABSTRACT.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 : ABSTRACT.H *
* *
* Programmer : Joe L. Bostic *
* *
* Start Date : 01/26/95 *
* *
* Last Update : January 26, 1995 [JLB] *
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef ABSTRACT_H
#define ABSTRACT_H
DirType Direction(CELL cell1, CELL cell2);
DirType Direction(COORDINATE coord1, COORDINATE coord2);
int Distance(COORDINATE coord1, COORDINATE coord2);
COORDINATE As_Coord(TARGET target);
class AbstractTypeClass;
/*
** This class is the base class for all game objects that have an existence on the
** battlefield.
*/
class AbstractClass
{
public:
/*
** This specifies the type of object and the unique ID number
** associated with it. The ID number happens to match the index into
** the object heap appropriate for this object type.
*/
RTTIType RTTI;
int ID;
/*
** The coordinate location of the unit. For vehicles, this is the center
** point. For buildings, it is the upper left corner.
*/
COORDINATE Coord;
/*
** This is the height of the object above ground (expressed in leptons).
*/
int Height;
/*
** The actual object ram-space is located in arrays in the data segment. This flag
** is used to indicate which objects are free to be reused and which are currently
** in use by the game.
*/
unsigned IsActive:1;
/*
** A flag to indicate that this object was recently created. Since an object's allocation is just a matter of whether
** the IsActive flag is set, during a logic frame an object with a given ID could be 'deleted' then reallocated
** as a different type of object in a different location. This flag lets us know that this happened. ST - 8/19/2019 5:33PM
*/
unsigned IsRecentlyCreated:1;
/*-----------------------------------------------------------------------------------
** Constructor & destructors.
*/
AbstractClass(RTTIType rtti, int id) : RTTI(rtti), ID(id), Coord(0xFFFFFFFFL), Height(0) {};
AbstractClass(NoInitClass const & x) {x();};
virtual ~AbstractClass(void) {};
/*
** Query functions.
*/
virtual char const * Name(void) const {return("");}
virtual HousesType Owner(void) const {return HOUSE_NONE;};
TARGET As_Target(void) const {return(Build_Target(RTTI, ID));};
RTTIType What_Am_I(void) const {return(RTTI);};
/*
** Scenario and debug support.
*/
#ifdef CHEAT_KEYS
virtual void Debug_Dump(MonoClass * mono) const;
#endif
/*
** Coordinate query support functions.
*/
virtual COORDINATE Center_Coord(void) const {return Coord;};
virtual COORDINATE Target_Coord(void) const {return Coord;};
/*
** Coordinate inquiry functions. These are used for both display and
** combat purposes.
*/
DirType Direction(AbstractClass const * object) const {return ::Direction(Center_Coord(), object->Target_Coord());};
DirType Direction(COORDINATE coord) const {return ::Direction(Center_Coord(), coord);};
DirType Direction(TARGET target) const {return ::Direction(Center_Coord(), As_Coord(target));};
DirType Direction(CELL cell) const {return ::Direction(Coord_Cell(Center_Coord()), cell);};
int Distance(TARGET target) const;
int Distance(COORDINATE coord) const {return ::Distance(Center_Coord(), coord);};
int Distance(AbstractClass const * object) const {return ::Distance(Center_Coord(), object->Target_Coord());};
/*
** Object entry and exit from the game system.
*/
virtual MoveType Can_Enter_Cell(CELL , FacingType = FACING_NONE) const {return MOVE_OK;};
/*
** AI.
*/
virtual void AI(void) {};
/*
** Set the new recently created flag every time the active flag is set. ST - 8/19/2019 5:41PM
*/
void Set_Active(void) {IsActive = true; IsRecentlyCreated = true;}
};
#endif

2553
REDALERT/ADATA.CPP Normal file

File diff suppressed because it is too large Load Diff

80
REDALERT/ADPCM.CPP Normal file
View File

@ -0,0 +1,80 @@
//
// 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
#include "function.h"
extern "C" {
#include "soscomp.h"
#include "itable.cpp"
#include "dtable.cpp"
void sosCODECInitStream(_SOS_COMPRESS_INFO* info)
{
info->dwSampleIndex = 0;
info->dwPredicted = 0;
}
unsigned long sosCODECDecompressData(_SOS_COMPRESS_INFO* info, unsigned long numbytes)
{
unsigned long token;
long sample;
unsigned int fastindex;
unsigned char *inbuff;
unsigned short *outbuff;
inbuff = (unsigned char *)info->lpSource;
outbuff = (unsigned short *)info->lpDest;
// Preload variables before the big loop
fastindex = (unsigned int)info->dwSampleIndex;
sample = info->dwPredicted;
if (!numbytes)
goto SkipLoop;
do {
// First nibble
token = *inbuff++;
fastindex += token & 0x0f;
sample += DiffTable[fastindex];
fastindex = IndexTable[fastindex];
if (sample > 32767L)
sample = 32767L;
if (sample < -32768L)
sample = -32768L;
*outbuff++ = (unsigned short)sample;
// Second nibble
fastindex += token >> 4;
sample += DiffTable[fastindex];
fastindex = IndexTable[fastindex];
if (sample > 32767L)
sample = 32767L;
if (sample < -32768L)
sample = -32768L;
*outbuff++ = (unsigned short)sample;
} while(--numbytes);
SkipLoop:
// Put local vars back
info->dwSampleIndex = (unsigned long)fastindex;
info->dwPredicted = sample;
return(numbytes << 2);
}
}

4437
REDALERT/AIRCRAFT.CPP Normal file

File diff suppressed because it is too large Load Diff

252
REDALERT/AIRCRAFT.H Normal file
View File

@ -0,0 +1,252 @@
//
// 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/AIRCRAFT.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 : AIRCRAFT.H *
* *
* Programmer : Joe L. Bostic *
* *
* Start Date : July 22, 1994 *
* *
* Last Update : November 28, 1994 [JLB] *
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef AIRCRAFT_H
#define AIRCRAFT_H
#include "radio.h"
#include "fly.h"
#include "target.h"
/*
** This aircraft class is used for all flying sentient objects. This includes fixed wing
** aircraft as well as helicopters. It excludes bullets even though some bullets might
** be considered to be "flying" in a loose interpretatin of the word.
*/
class AircraftClass : public FootClass, public FlyClass
{
public:
/*
** This is a pointer to the class control structure for the aircraft.
*/
CCPtr<AircraftTypeClass> Class;
//-----------------------------------------------------------------------------
static void * operator new(size_t);
static void * operator new(size_t, void * ptr) {return(ptr);};
static void operator delete(void *);
operator AircraftType(void) const {return Class->Type;};
AircraftClass(AircraftType classid, HousesType house);
AircraftClass(NoInitClass const & x) : FootClass(x), FlyClass(x), Class(x), SecondaryFacing(x), SightTimer(x) {};
virtual ~AircraftClass(void);
static void Init(void);
virtual int Mission_Attack(void);
virtual int Mission_Unload(void);
virtual int Mission_Hunt(void);
virtual int Mission_Retreat(void);
virtual int Mission_Move(void);
virtual int Mission_Enter(void);
virtual int Mission_Guard(void);
virtual int Mission_Guard_Area(void);
virtual void Assign_Destination(TARGET target);
/*
** State machine support routines.
*/
bool Process_Take_Off(void);
bool Process_Landing(void);
int Process_Fly_To(bool slowdown, TARGET dest);
/*
** Query functions.
*/
virtual LayerType In_Which_Layer(void) const;
virtual DirType Turret_Facing(void) const {return(SecondaryFacing.Current());}
int Shape_Number(void) const;
virtual MoveType Can_Enter_Cell(CELL cell, FacingType facing=FACING_NONE) const;
virtual ObjectTypeClass const & Class_Of(void) const {return *Class;};
virtual ActionType What_Action(ObjectClass const * target) const;
virtual ActionType What_Action(CELL cell) const;
virtual DirType Desired_Load_Dir(ObjectClass * passenger, CELL & moveto) const;
virtual int Pip_Count(void) const;
TARGET Good_Fire_Location(TARGET target) const;
bool Cell_Seems_Ok(CELL cell, bool landing=false) const;
DirType Pose_Dir(void) const;
TARGET Good_LZ(void) const;
virtual DirType Fire_Direction(void) const;
virtual FireErrorType Can_Fire(TARGET target, int which) const;
/*
** Landing zone support functionality.
*/
virtual void Per_Cell_Process(PCPType why);
bool Is_LZ_Clear(TARGET target) const;
TARGET New_LZ(TARGET oldlz) const;
/*
** Coordinate inquiry functions. These are used for both display and
** combat purposes.
*/
virtual COORDINATE Sort_Y(void) const;
/*
** Object entry and exit from the game system.
*/
virtual bool Unlimbo(COORDINATE , DirType facing = DIR_N);
/*
** Display and rendering support functionality. Supports imagery and how
** object interacts with the map and thus indirectly controls rendering.
*/
virtual void Look(bool incremental=false);
void Draw_Rotors(int x, int y, WindowNumberType window) const;
virtual int Exit_Object(TechnoClass *);
virtual short const * Overlap_List(bool redraw=false) const;
virtual void Draw_It(int x, int y, WindowNumberType window) const;
virtual void Set_Speed(int speed);
/*
** User I/O.
*/
virtual void Active_Click_With(ActionType action, ObjectClass * object);
virtual void Active_Click_With(ActionType action, CELL cell);
virtual void Player_Assign_Mission(MissionType mission, TARGET target=TARGET_NONE, TARGET destination=TARGET_NONE);
virtual void Response_Select(void);
virtual void Response_Move(void);
virtual void Response_Attack(void);
/*
** Combat related.
*/
virtual ResultType Take_Damage(int & damage, int distance, WarheadType warhead, TechnoClass * source, bool forced=false);
virtual BulletClass * Fire_At(TARGET target, int which);
/*
** AI.
*/
bool Landing_Takeoff_AI(void);
bool Edge_Of_World_AI(void);
void Movement_AI(void);
void Rotation_AI(void);
int Paradrop_Cargo(void);
virtual void AI(void);
virtual void Enter_Idle_Mode(bool initial = false);
virtual RadioMessageType Receive_Message(RadioClass * from, RadioMessageType message, long & param);
virtual void Scatter(COORDINATE threat, bool forced=false, bool nokidding=false);
/*
** Scenario and debug support.
*/
#ifdef CHEAT_KEYS
virtual void Debug_Dump(MonoClass *mono) const;
#endif
/*
** File I/O.
*/
static void Read_INI(CCINIClass & ini);
static char * INI_Name(void) {return "AIRCRAFT";};
bool Load(Straw & file);
bool Save(Pipe & file) const;
virtual unsigned Spied_By() const;
public:
/*
** This is the facing used for the body of the aircraft. Typically, this is the same
** as the PrimaryFacing, but in the case of helicopters, it can be different.
*/
FacingClass SecondaryFacing;
/*
** If this is a passenger carrying aircraft then this flag will be set. This is
** necessary because once the passengers are unloaded, the fact that it was a
** passenger carrier must still be known.
*/
bool Passenger;
private:
/*
** Aircraft can be in either state of landing, taking off, or in steady altitude.
** These flags are used to control transition between flying and landing. It is
** necessary to handle the transition in this manner so that it occurs smoothly
** during the graphic processing section.
*/
unsigned IsLanding:1;
unsigned IsTakingOff:1;
/*
** It is very common for aircraft to be homing in on a target. When this flag is
** true, the aircraft will constantly adjust its facing toward the TarCom. When the
** target is very close (one cell away or less), then this flag is automatically cleared.
** This is because the homing algorithm is designed to get the aircraft to the destination
** but no more. Checking when this flag is cleared is a way of flagging transition into
** a new mode. Example: Transport helicopters go into a hovering into correct position
** mode when the target is reached.
*/
unsigned IsHoming:1;
/*
** Helicopters that are about to land must hover into a position exactly above the landing
** zone. When this flag is true, the aircraft will be adjusted so that it is exactly over
** the TarCom. The facing of the aircraft is not altered by this movement. The affect
** like the helicopter is hovering and shifting sideways to position over the landing
** zone. When the position is over the landing zone, then this flag is set to false.
*/
unsigned IsHovering:1;
/*
** This is the jitter tracker to be used when the aircraft is a helicopter and
** is flying. It is most noticeable when the helicopter is hovering.
*/
unsigned char Jitter;
private:
/*
** This timer controls when the aircraft will reveal the terrain around itself.
** When this timer expires and this aircraft has a sight range, then the
** look around process will occur.
*/
CDTimerClass<FrameTimerClass> SightTimer;
/*
** Most attack aircraft can make several attack runs. This value contains the
** number of attack runs the aircraft has left. When this value reaches
** zero then the aircraft is technically out of ammo.
*/
char AttacksRemaining;
/*
** Some additional padding in case we need to add data to the class and maintain backwards compatibility for save/load
*/
unsigned char SaveLoadPadding[32];
};
#endif

1221
REDALERT/ANIM.CPP Normal file

File diff suppressed because it is too large Load Diff

189
REDALERT/ANIM.H Normal file
View File

@ -0,0 +1,189 @@
//
// 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/ANIM.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 : ANIM.H *
* *
* Programmer : Joe L. Bostic *
* *
* Start Date : May 30, 1994 *
* *
* Last Update : May 30, 1994 [JLB] *
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef ANIM_H
#define ANIM_H
#include "type.h"
/**********************************************************************************************
** This is the class that controls the shape animation objects. Shape animation objects are
** displayed over the top of the game map. Typically, they are used for explosion and fire
** effects.
*/
class AnimClass : public ObjectClass, public StageClass {
/*
** This points to the type of animation object this is.
*/
CCPtr<AnimTypeClass> Class;
public:
AnimClass(AnimType animnum, COORDINATE coord, unsigned char timedelay=0, unsigned char loop=1);
AnimClass(NoInitClass const & x) : ObjectClass(x), Class(x), StageClass(x) {};
virtual ~AnimClass(void);
operator AnimType(void) const {return Class->Type;};
static void * operator new(size_t size);
static void * operator new(size_t , void * ptr) {return(ptr);};
static void operator delete(void *ptr);
/*---------------------------------------------------------------------
** Member function prototypes.
*/
static void Init(void);
void Attach_To(ObjectClass *obj);
void Sort_Above(TARGET target);
void Make_Invisible(void) {IsInvisible = true;};
void Make_Visible(void) {IsInvisible = false;};
static void Do_Atom_Damage(HousesType ownerhouse, CELL cell);
/*
** 2019/09/19 JAS
** Added functions for accessing which players can see this anim
*/
void Set_Visible_Flags(unsigned flags) { VisibleFlags = flags; }
unsigned Get_Visible_Flags() const { return (Delay == 0) ? VisibleFlags : 0; }
virtual bool Can_Place_Here(COORDINATE ) const {return true;}
virtual bool Mark(MarkType mark=MARK_CHANGE);
virtual bool Render(bool forced) const;
virtual COORDINATE Center_Coord(void) const;
virtual COORDINATE Sort_Y(void) const;
virtual LayerType In_Which_Layer(void) const;
virtual ObjectTypeClass const & Class_Of(void) const {return *Class;};
virtual short const * Occupy_List(bool = false) const;
virtual short const * Overlap_List(void) const;
virtual void Draw_It(int x, int y, WindowNumberType window) const;
virtual void AI(void);
virtual void Detach(TARGET target, bool all);
/*
** File I/O.
*/
bool Load(Straw & file);
bool Save(FileClass & file);
/*
** If this animation is attached to an object, then this points to that object. An
** animation that is attached will follow that object as it moves. This is important
** for animations such as flames and smoke.
*/
TARGET xObject;
/*
** If specified, this animation uses the sort target for Y sorting
*/
TARGET SortTarget;
/*
** If this animation has an owner, then it will be recorded here. An owner
** is used when damage is caused by this animation during the middle of its
** animation.
*/
HousesType OwnerHouse;
/*
** This counter tells how many more times the animation should loop before it
** terminates.
*/
unsigned char Loops;
protected:
void Middle(void);
void Start(void);
void Chain(void);
private:
/*
** Delete this animation at the next opportunity. This is flagged when the
** animation is to be prematurely ended as a result of some outside event.
*/
unsigned IsToDelete:1;
/*
** If the animation has just been created, then don't do any animation
** processing until it has been through the render loop at least once.
*/
unsigned IsBrandNew:1;
/*
** If this animation is invisible, then this flag will be true. An invisible
** animation is one that is created for the sole purpose of keeping all
** machines synchronized. It will not be displayed.
*/
unsigned IsInvisible:1;
/*
** 2019/09/19 JAS
** Flags storing which players can see this anim.
*/
unsigned VisibleFlags;
/*
** Is this animation in a temporary suspended state? If so, then it won't
** be rendered until this value is zero. The flag will be set to false
** after the first countdown timer reaches 0.
*/
int Delay;
/*
** If this is an animation that damages whatever it is attached to, then this
** value holds the accumulation of fractional damage points. When the accumulated
** fractions reach 256, then one damage point is applied to the attached object.
*/
fixed Accum;
/*
** The map layer this animation is in when attached to an object.
*/
LayerType AttachLayer;
/*
** This references the virtual animation.
*/
TARGET VirtualAnimTarget;
/*
** Some additional padding in case we need to add data to the class and maintain backwards compatibility for save/load
*/
unsigned char SaveLoadPadding[32];
};
#endif

858
REDALERT/AUDIO.CPP Normal file
View File

@ -0,0 +1,858 @@
//
// 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/AUDIO.CPP 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 : AUDIO.CPP *
* *
* Programmer : Joe L. Bostic *
* *
* Start Date : September 10, 1993 *
* *
* Last Update : November 1, 1996 [JLB] *
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* Is_Speaking -- Checks to see if the eva voice is still playing. *
* Sound_Effect -- General purpose sound player. *
* Sound_Effect -- Plays a sound effect in the tactical map. *
* Speak -- Computer speaks to the player. *
* Speak_AI -- Handles starting the EVA voices. *
* Speech_Name -- Fetches the name for the voice specified. *
* Stop_Speaking -- Forces the EVA voice to stop talking. *
* Voc_From_Name -- Fetch VocType from ASCII name specified. *
* Voc_Name -- Fetches the name for the sound effect. *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "function.h"
/*
**
**
** Win32lib stubs
**
**
**
*/
SFX_Type SoundType;
Sample_Type SampleType;
int File_Stream_Sample(char const *filename, BOOL real_time_start) { return 1; };
int File_Stream_Sample_Vol(char const *filename, int volume, BOOL real_time_start) { return 1; };
void __cdecl Sound_Callback(void) {};
void __cdecl far maintenance_callback(void) {};
void *Load_Sample(char const *filename) { return NULL; };
long Load_Sample_Into_Buffer(char const *filename, void *buffer, long size) { return 0; }
long Sample_Read(int fh, void *buffer, long size) { return 0; };
void Free_Sample(void const *sample) {};
BOOL Audio_Init(HWND window, int bits_per_sample, BOOL stereo, int rate, int reverse_channels) { return 0; };
void Sound_End(void) {};
void Stop_Sample(int handle) {};
BOOL Sample_Status(int handle) { return 0; };
BOOL Is_Sample_Playing(void const * sample) { return 0; };
void Stop_Sample_Playing(void const * sample) {};
int Play_Sample(void const *sample, int priority, int volume, signed short panloc) { return 1; };
int Play_Sample_Handle(void const *sample, int priority, int volume, signed short panloc, int id) { return 1; };
int Set_Sound_Vol(int volume) { return 0; };
int Set_Score_Vol(int volume) { return 0; };
void Fade_Sample(int handle, int ticks) {};
int Get_Free_Sample_Handle(int priority) { return 1; };
int Get_Digi_Handle(void) { return 1; }
long Sample_Length(void const *sample) { return 0; };
void Restore_Sound_Buffers(void) {};
BOOL Set_Primary_Buffer_Format(void) { return 0; };
BOOL Start_Primary_Sound_Buffer(BOOL forced) { return 0; };
void Stop_Primary_Sound_Buffer(void) {};
/***************************************************************************
** Controls what special effects may occur on the sound effect.
*/
typedef enum {
IN_NOVAR, // No variation or alterations allowed.
IN_VAR // Infantry variance response modification.
} ContextType;
// static struct { // MBL 02.21.2019
// Had to name the struct for VS 2017 distributed build. ST - 4/10/2019 3:59PM
struct SoundEffectNameStruct {
char const * Name; // Digitized voice file name.
int Priority; // Playback priority of this sample.
ContextType Where; // In what game context does this sample exist.
} SoundEffectName[VOC_COUNT] = {
/*
** Civilian voices (technicians too).
*/
{"GIRLOKAY", 20, IN_NOVAR}, // VOC_GIRL_OKAY
{"GIRLYEAH", 20, IN_NOVAR}, // VOC_GIRL_YEAH
{"GUYOKAY1", 20, IN_NOVAR}, // VOC_GUY_OKAY
{"GUYYEAH1", 20, IN_NOVAR}, // VOC_GUY_YEAH
{"MINELAY1", 5, IN_VAR}, // VOC_MINELAY1
/*
** Infantry and vehicle responses.
*/
{"ACKNO", 20, IN_VAR}, // VOC_ACKNOWL "acknowledged"
{"AFFIRM1", 20, IN_VAR}, // VOC_AFFIRM "affirmative"
{"AWAIT1", 20, IN_VAR}, // VOC_AWAIT1 "awaiting orders"
{"EAFFIRM1", 20, IN_NOVAR}, // VOC_ENG_AFFIRM Engineer: "affirmative"
{"EENGIN1", 20, IN_NOVAR}, // VOC_ENG_ENG Engineer: "engineering"
{"NOPROB", 20, IN_VAR}, // VOC_NO_PROB "not a problem"
{"READY", 20, IN_VAR}, // VOC_READY "ready and waiting"
{"REPORT1", 20, IN_VAR}, // VOC_REPORT "reporting"
{"RITAWAY", 20, IN_VAR}, // VOC_RIGHT_AWAY "right away sir"
{"ROGER", 20, IN_VAR}, // VOC_ROGER "roger"
{"UGOTIT", 20, IN_VAR}, // VOC_UGOTIT "you got it"
{"VEHIC1", 20, IN_VAR}, // VOC_VEHIC1 "vehicle reporting"
{"YESSIR1", 20, IN_VAR}, // VOC_YESSIR "yes sir"
{"DEDMAN1", 10, IN_NOVAR}, // VOC_SCREAM1 short infantry scream
{"DEDMAN2", 10, IN_NOVAR}, // VOC_SCREAM3 short infantry scream
{"DEDMAN3", 10, IN_NOVAR}, // VOC_SCREAM4 short infantry scream
{"DEDMAN4", 10, IN_NOVAR}, // VOC_SCREAM5 short infantry scream
{"DEDMAN5", 10, IN_NOVAR}, // VOC_SCREAM6 short infantry scream
{"DEDMAN6", 10, IN_NOVAR}, // VOC_SCREAM7 short infantry scream
{"DEDMAN7", 10, IN_NOVAR}, // VOC_SCREAM10 short infantry scream
{"DEDMAN8", 10, IN_NOVAR}, // VOC_SCREAM11 short infantry scream
{"DEDMAN10", 10, IN_NOVAR}, // VOC_YELL1 long infantry scream
{"CHRONO2", 5, IN_NOVAR}, // VOC_CHRONO Chronosphere sound
{"CANNON1", 1, IN_NOVAR}, // VOC_CANNON1 Cannon sound (medium).
{"CANNON2", 1, IN_NOVAR}, // VOC_CANNON2 Cannon sound (short).
{"IRONCUR9", 10, IN_NOVAR}, // VOC_IRON1
{"EMOVOUT1", 20, IN_NOVAR}, // VOC_ENG_MOVEOUT Engineer: "movin' out"
{"SONPULSE", 10, IN_NOVAR}, // VOC_SONAR
{"SANDBAG2", 5, IN_NOVAR}, // VOC_SANDBAG sand bag crunch
{"MINEBLO1", 5, IN_NOVAR}, // VOC_MINEBLOW weird mine explosion
{"CHUTE1", 1, IN_NOVAR}, // VOC_CHUTE1 Wind swoosh sound.
{"DOGY1", 5, IN_NOVAR}, // VOC_DOG_BARK Dog bark.
{"DOGW5", 10, IN_NOVAR}, // VOC_DOG_WHINE Dog whine.
{"DOGG5P", 10, IN_NOVAR}, // VOC_DOG_GROWL2 Strong dog growl.
{"FIREBL3", 1, IN_NOVAR}, // VOC_FIRE_LAUNCH Fireball launch sound.
{"FIRETRT1", 1, IN_NOVAR}, // VOC_FIRE_EXPLODE Fireball explode sound.
{"GRENADE1", 1, IN_NOVAR}, // VOC_GRENADE_TOSS Grenade toss.
{"GUN11", 1, IN_NOVAR}, // VOC_GUN_5 5 round gun burst (slow).
{"GUN13", 1, IN_NOVAR}, // VOC_GUN_7 7 round gun burst (fast).
{"EYESSIR1", 20, IN_NOVAR}, // VOC_ENG_YES, Engineer: "yes sir"
{"GUN27", 1, IN_NOVAR}, // VOC_GUN_RIFLE Rifle shot.
{"HEAL2", 1, IN_NOVAR}, // VOC_HEAL Healing effect.
{"HYDROD1", 1, IN_NOVAR}, // VOC_DOOR Hyrdrolic door.
{"INVUL2", 1, IN_NOVAR}, // VOC_INVULNERABLE Invulnerability effect.
{"KABOOM1", 1, IN_NOVAR}, // VOC_KABOOM1 Long explosion (muffled).
{"KABOOM12", 1, IN_NOVAR}, // VOC_KABOOM12 Very long explosion (muffled).
{"KABOOM15", 1, IN_NOVAR}, // VOC_KABOOM15 Very long explosion (muffled).
{"SPLASH9", 5, IN_NOVAR}, // VOC_SPLASH water splash
{"KABOOM22", 1, IN_NOVAR}, // VOC_KABOOM22 Long explosion (sharp).
{"AACANON3", 1, IN_NOVAR},
{"TANDETH1", 10, IN_NOVAR},
{"MGUNINF1", 1, IN_NOVAR}, // VOC_GUN_5F 5 round gun burst (fast).
{"MISSILE1", 1, IN_NOVAR}, // VOC_MISSILE_1 Missile with high tech effect.
{"MISSILE6", 1, IN_NOVAR}, // VOC_MISSILE_2 Long missile launch.
{"MISSILE7", 1, IN_NOVAR}, // VOC_MISSILE_3 Short missile launch.
{"x", 1, IN_NOVAR},
{"PILLBOX1", 1, IN_NOVAR}, // VOC_GUN_5R 5 round gun burst (rattles).
{"RABEEP1", 1, IN_NOVAR}, // VOC_BEEP Generic beep sound.
{"RAMENU1", 1, IN_NOVAR}, // VOC_CLICK Generic click sound.
{"SILENCER", 1, IN_NOVAR}, // VOC_SILENCER Silencer.
{"TANK5", 1, IN_NOVAR}, // VOC_CANNON6 Long muffled cannon shot.
{"TANK6", 1, IN_NOVAR}, // VOC_CANNON7 Sharp mechanical cannon fire.
{"TORPEDO1", 1, IN_NOVAR}, // VOC_TORPEDO Torpedo launch.
{"TURRET1", 1, IN_NOVAR}, // VOC_CANNON8 Sharp cannon fire.
{"TSLACHG2", 10, IN_NOVAR}, // VOC_TESLA_POWER_UP Hum charge up.
{"TESLA1", 10, IN_NOVAR}, // VOC_TESLA_ZAP Tesla zap effect.
{"SQUISHY2", 10, IN_NOVAR}, // VOC_SQUISH Squish effect.
{"SCOLDY1", 10, IN_NOVAR}, // VOC_SCOLD Scold bleep.
{"RADARON2", 20, IN_NOVAR}, // VOC_RADAR_ON Powering up electronics.
{"RADARDN1", 10, IN_NOVAR}, // VOC_RADAR_OFF B movie power down effect.
{"PLACBLDG", 10, IN_NOVAR}, // VOC_PLACE_BUILDING_DOWN Building slam down sound.
{"KABOOM30", 1, IN_NOVAR}, // VOC_KABOOM30 Short explosion (HE).
{"KABOOM25", 10, IN_NOVAR}, // VOC_KABOOM25 Short growling explosion.
{"x", 10, IN_NOVAR},
{"DOGW7", 10, IN_NOVAR}, // VOC_DOG_HURT Dog whine (loud).
{"DOGW3PX", 10, IN_NOVAR}, // VOC_DOG_YES Dog 'yes sir'.
{"CRMBLE2", 10, IN_NOVAR}, // VOC_CRUMBLE Building crumble.
{"CASHUP1", 10, IN_NOVAR}, // VOC_MONEY_UP Rising money tick.
{"CASHDN1", 10, IN_NOVAR}, // VOC_MONEY_DOWN Falling money tick.
{"BUILD5", 10, IN_NOVAR}, // VOC_CONSTRUCTION Building construction sound.
{"BLEEP9", 10, IN_NOVAR}, // VOC_GAME_CLOSED Long bleep.
{"BLEEP6", 10, IN_NOVAR}, // VOC_INCOMING_MESSAGE Soft happy warble.
{"BLEEP5", 10, IN_NOVAR}, // VOC_SYS_ERROR Sharp soft warble.
{"BLEEP17", 10, IN_NOVAR}, // VOC_OPTIONS_CHANGED Mid range soft warble.
{"BLEEP13", 10, IN_NOVAR}, // VOC_GAME_FORMING Long warble.
{"BLEEP12", 10, IN_NOVAR}, // VOC_PLAYER_LEFT Chirp sequence.
{"BLEEP11", 10, IN_NOVAR}, // VOC_PLAYER_JOINED Reverse chirp sequence.
{"H2OBOMB2", 10, IN_NOVAR}, // VOC_DEPTH_CHARGE Distant explosion sound.
{"CASHTURN", 10, IN_NOVAR}, // VOC_CASHTURN Airbrake.
{"TUFFGUY1", 20, IN_NOVAR}, // VOC_TANYA_CHEW Tanya: "Chew on this"
{"ROKROLL1", 20, IN_NOVAR}, // VOC_TANYA_ROCK Tanya: "Let's rock"
{"LAUGH1", 20, IN_NOVAR}, // VOC_TANYA_LAUGH Tanya: "ha ha ha"
{"CMON1", 20, IN_NOVAR}, // VOC_TANYA_SHAKE Tanya: "Shake it baby"
{"BOMBIT1", 20, IN_NOVAR}, // VOC_TANYA_CHING Tanya: "Cha Ching"
{"GOTIT1", 20, IN_NOVAR}, // VOC_TANYA_GOT Tanya: "That's all you got"
{"KEEPEM1", 20, IN_NOVAR}, // VOC_TANYA_KISS Tanya: "Kiss it bye bye"
{"ONIT1", 20, IN_NOVAR}, // VOC_TANYA_THERE Tanya: "I'm there"
{"LEFTY1", 20, IN_NOVAR}, // VOC_TANYA_GIVE Tanya: "Give it to me"
{"YEAH1", 20, IN_NOVAR}, // VOC_TANYA_YEA Tanya: "Yea?"
{"YES1", 20, IN_NOVAR}, // VOC_TANYA_YES Tanya: "Yes sir?"
{"YO1", 20, IN_NOVAR}, // VOC_TANYA_WHATS Tanya: "What's up."
{"WALLKIL2", 5, IN_NOVAR}, // VOC_WALLKILL2 Crushing wall sound.
{"x", 10, IN_NOVAR},
{"GUN5", 5, IN_NOVAR}, // VOC_TRIPLE_SHOT Three quick shots in succession.
{"SUBSHOW1", 5, IN_NOVAR}, // VOC_SUBSHOW Submarine surface sound.
{"EINAH1", 20, IN_NOVAR}, // VOC_E_AH, Einstien "ah"
{"EINOK1", 20, IN_NOVAR}, // VOC_E_OK, Einstien "ok"
{"EINYES1", 20, IN_NOVAR}, // VOC_E_YES, Einstien "yes"
{"MINE1", 10, IN_NOVAR}, // VOC_TRIP_MINE mine explosion sound
{"SCOMND1", 20, IN_NOVAR}, // VOC_SPY_COMMANDER Spy: "commander?"
{"SYESSIR1", 20, IN_NOVAR}, // VOC_SPY_YESSIR Spy: "yes sir"
{"SINDEED1", 20, IN_NOVAR}, // VOC_SPY_INDEED Spy: "indeed"
{"SONWAY1", 20, IN_NOVAR}, // VOC_SPY_ONWAY Spy: "on my way"
{"SKING1", 20, IN_NOVAR}, // VOC_SPY_KING Spy: "for king and country"
{"MRESPON1", 20, IN_NOVAR}, // VOC_MED_REPORTING Medic: "reporting"
{"MYESSIR1", 20, IN_NOVAR}, // VOC_MED_YESSIR Medic: "yes sir"
{"MAFFIRM1", 20, IN_NOVAR}, // VOC_MED_AFFIRM Medic: "affirmative"
{"MMOVOUT1", 20, IN_NOVAR}, // VOC_MED_MOVEOUT Medic: "movin' out"
{"BEEPSLCT", 10, IN_NOVAR}, // VOC_BEEP_SELECT map selection beep
{"SYEAH1", 20, IN_NOVAR}, // VOC_THIEF_YEA Thief: "yea?"
{"ANTDIE", 20, IN_NOVAR}, // VOC_ANTDIE
{"ANTBITE", 20, IN_NOVAR}, // VOC_ANTBITE
{"SMOUT1", 20, IN_NOVAR}, // VOC_THIEF_MOVEOUT Thief: "movin' out"
{"SOKAY1", 20, IN_NOVAR}, // VOC_THIEF_OKAY Thief: "ok"
{"x", 20, IN_NOVAR},
{"SWHAT1", 20, IN_NOVAR}, // VOC_THIEF_WHAT Thief: "what"
{"SAFFIRM1", 20, IN_NOVAR}, // VOC_THIEF_AFFIRM Thief: "affirmative"
//ADDED VG 2/24/97
{"STAVCMDR", 20, IN_NOVAR},
{"STAVCRSE", 20, IN_NOVAR},
{"STAVYES", 20, IN_NOVAR},
{"STAVMOV", 20, IN_NOVAR},
{"BUZZY1", 20, IN_NOVAR},
{"RAMBO1", 20, IN_NOVAR},
{"RAMBO2", 20, IN_NOVAR},
{"RAMBO3", 20, IN_NOVAR},
#ifdef FIXIT_CSII // checked - ajw 9/28/98
{"MYES1", 20, IN_NOVAR}, // VOC_MECHYES1 Mechanic: "Yes sir!"
{"MHOWDY1", 20, IN_NOVAR}, // VOC_MECHHOWDY1 Mechanic: "Howdy!"
{"MRISE1", 20, IN_NOVAR}, // VOC_MECHRISE1 Mechanic: "Rise 'n shine!"
{"MHUH1", 20, IN_NOVAR}, // VOC_MECHHUH1 Mechanic: "Huh?"
{"MHEAR1", 20, IN_NOVAR}, // VOC_MECHHEAR1 Mechanic: "I Hear Ya!"
{"MLAFF1", 20, IN_NOVAR}, // VOC_MECHLAFF1 Mechanic: guffaw
{"MBOSS1", 20, IN_NOVAR}, // VOC_MECHBOSS1 Mechanic: "Sure Thing, Boss!"
{"MYEEHAW1", 20, IN_NOVAR}, // VOC_MECHYEEHAW1 Mechanic: "Yee Haw!"
{"MHOTDIG1", 20, IN_NOVAR}, // VOC_MECHHOTDIG1 Mechanic: "Hot Diggity Dog!"
{"MWRENCH1", 20, IN_NOVAR}, // VOC_MECHWRENCH1 Mechanic: "I'll get my wrench."
{"JBURN1", 20, IN_NOVAR}, // VOC_STBURN1 Shock Trooper: "Burn baby burn!"
{"JCHRGE1", 20, IN_NOVAR}, // VOC_STCHRGE1 Shock Trooper: "Fully charged!"
{"JCRISP1", 20, IN_NOVAR}, // VOC_STCRISP1 Shock Trooper: "Extra Crispy!"
{"JDANCE1", 20, IN_NOVAR}, // VOC_STDANCE1 Shock Trooper: "Let's Dance!"
{"JJUICE1", 20, IN_NOVAR}, // VOC_STJUICE1 Shock Trooper: "Got juice?"
{"JJUMP1", 20, IN_NOVAR}, // VOC_STJUMP1 Shock Trooper: "Need a jump?"
{"JLIGHT1", 20, IN_NOVAR}, // VOC_STLIGHT1 Shock Trooper: "Lights out!"
{"JPOWER1", 20, IN_NOVAR}, // VOC_STPOWER1 Shock Trooper: "Power on!"
{"JSHOCK1", 20, IN_NOVAR}, // VOC_STSHOCK1 Shock Trooper: "Shocking!"
{"JYES1", 20, IN_NOVAR}, // VOC_STYES1 Shock Trooper: "Yesssss!"
{"CHROTNK1", 20, IN_NOVAR}, // VOC_CHRONOTANK1 Chrono tank teleport
{"FIXIT1", 20, IN_NOVAR}, // VOC_MECH_FIXIT1 Mechanic fixes something
{"MADCHRG2", 20, IN_NOVAR}, // VOC_MAD_CHARGE MAD tank charges up
{"MADEXPLO", 20, IN_NOVAR}, // VOC_MAD_EXPLODE MAD tank explodes
{"SHKTROP1", 20, IN_NOVAR}, // VOC_SHOCK_TROOP1 Shock Trooper fires
#endif
};
//
// External handlers. MBL 06.17.2019
//
extern void On_Sound_Effect(int sound_index, int variation, COORDINATE coord, int house);
// extern void On_Speech(int speech_index); MBL 02.06.2020
extern void On_Speech(int speech_index, HouseClass *house);
extern void On_Ping(const HouseClass* player_ptr, COORDINATE coord);
/***********************************************************************************************
* Voc_From_Name -- Fetch VocType from ASCII name specified. *
* *
* This will find the corresponding VocType from the ASCII string specified. It does this *
* by finding a root filename that matches the string. *
* *
* INPUT: name -- Pointer to the ASCII string that will be converted into a VocType. *
* *
* OUTPUT: Returns with the VocType that matches the string specified. If no match could be *
* found, then VOC_NONE is returned. *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 07/06/1996 JLB : Created. *
*=============================================================================================*/
VocType Voc_From_Name(char const * name)
{
if (name == NULL) return(VOC_NONE);
for (VocType voc = VOC_FIRST; voc < VOC_COUNT; voc++) {
if (stricmp(name, SoundEffectName[voc].Name) == 0) {
return(voc);
}
}
return(VOC_NONE);
}
/***********************************************************************************************
* Voc_Name -- Fetches the name for the sound effect. *
* *
* This routine returns the descriptive name of the sound effect. Currently, this is just *
* the root of the file name. *
* *
* INPUT: voc -- The VocType that the corresponding name is requested. *
* *
* OUTPUT: Returns with a pointer to the text string the represents the sound effect. *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 05/06/1996 JLB : Created. *
*=============================================================================================*/
char const * Voc_Name(VocType voc)
{
if (voc == VOC_NONE) return("none");
return(SoundEffectName[voc].Name);
}
/***********************************************************************************************
* Sound_Effect -- Plays a sound effect in the tactical map. *
* *
* This routine is used when a sound effect occurs in the game world. It handles fading *
* the sound according to distance. *
* *
* INPUT: voc -- The sound effect number to play. *
* *
* coord -- The world location that the sound originates from. *
* *
* variation -- This is the optional variation number to use when playing special *
* sound effects that have variations. For normal sound effects, this *
* parameter is ignored. *
* *
* house -- This specifies the optional house override value to use when playing *
* sound effects that have a variation. If not specified, then the current *
* player is examined for the house variation to use. *
* *
* OUTPUT: none *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 11/12/1994 JLB : Created. *
* 01/05/1995 JLB : Reduces sound more dramatically when off screen. *
* 09/15/1996 JLB : Revamped volume logic. *
* 11/01/1996 JLB : House override control. *
*=============================================================================================*/
void Sound_Effect(VocType voc, COORDINATE coord, int variation, HousesType house)
{
//
// Intercept sound effect calls. MBL 06.17.2019
//
On_Sound_Effect((int)voc, variation, coord, (int)house);
#if 0
CELL cell_pos = 0;
int pan_value;
if (Debug_Quiet || Options.Volume == 0 || voc == VOC_NONE || !SoundOn || SampleType == SAMPLE_NONE) {
return;
}
if (coord) {
cell_pos = Coord_Cell(coord);
}
fixed volume = 1;
pan_value = 0;
if (coord && !Map.In_View(cell_pos)) {
int distance = Distance(coord, Map.TacticalCoord) / CELL_LEPTON_W;
fixed dfixed = fixed(distance, 128+64);
dfixed.Sub_Saturate(1);
volume = fixed(1) - dfixed;
pan_value = Cell_X(cell_pos);
pan_value -= Coord_XCell(Map.TacticalCoord) + (Lepton_To_Cell(Map.TacLeptonWidth) / 2);
if (ABS(pan_value) > Lepton_To_Cell(Map.TacLeptonWidth / 2)) {
pan_value *= 0x8000;
pan_value /= (MAP_CELL_W >> 2);
pan_value = Bound(pan_value, -0x7FFF, 0x7FFF);
} else {
pan_value = 0;
}
}
Sound_Effect(voc, volume, variation, pan_value, house);
#endif
}
/***********************************************************************************************
* Sound_Effect -- General purpose sound player. *
* *
* This is used for general purpose sound effects. These are sounds that occur outside *
* of the game world. They do not have a corresponding game world location as their source. *
* *
* INPUT: voc -- The sound effect number to play. *
* *
* volume -- The volume to assign to this sound effect. *
* *
* variation -- This is the optional variation number to use when playing special *
* sound effects that have variations. For normal sound effects, this *
* parameter is ignored. *
* *
* house -- This specifies the optional house override value to use when playing *
* sound effects that have a variation. If not specified, then the current *
* player is examined for the house variation to use. *
* *
* OUTPUT: Returns with the sound handle (-1 if no sound was played). *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 11/12/1994 JLB : Created. *
* 11/12/1994 JLB : Handles cache logic. *
* 05/04/1995 JLB : Variation adjustments. *
* 11/01/1996 JLB : House override control. *
*=============================================================================================*/
int Sound_Effect(VocType voc, fixed volume, int variation, signed short pan_value, HousesType house)
{
//
// Intercept sound effect calls. MBL 06.17.2019
//
pan_value;
COORDINATE coord = 0;
On_Sound_Effect((int)voc, variation, coord, (int)house);
#if 0
char name[_MAX_FNAME+_MAX_EXT]; // Working filename of sound effect.
if (Debug_Quiet || Options.Volume == 0 || voc == VOC_NONE || !SoundOn || SampleType == SAMPLE_NONE) {
return(-1);
}
/*
** Alter the volume according to the game volume setting.
*/
volume = volume * Options.Volume;
/*
** Fetch a pointer to the sound effect data. Modify the sound as appropriate and desired.
*/
char const * ext = ".AUD";
if (SoundEffectName[voc].Where == IN_VAR) {
/*
** If there is no forced house, then use the current player
** act like house.
*/
if (house == HOUSE_NONE) {
house = PlayerPtr->ActLike;
}
/*
** Change the extension based on the variation and house accent requested.
*/
if (((1 << house) & HOUSEF_ALLIES) != 0) {
/*
** For infantry, use a variation on the response. For vehicles, always
** use the vehicle response table.
*/
if (variation < 0) {
if (ABS(variation) % 2) {
ext = ".V00";
} else {
ext = ".V02";
}
} else {
if (variation % 2) {
ext = ".V01";
} else {
ext = ".V03";
}
}
} else {
if (variation < 0) {
if (ABS(variation) % 2) {
ext = ".R00";
} else {
ext = ".R02";
}
} else {
if (variation % 2) {
ext = ".R01";
} else {
ext = ".R03";
}
}
}
}
_makepath(name, NULL, NULL, SoundEffectName[voc].Name, ext);
void const * ptr = MFCD::Retrieve(name);
/*
** If the sound data pointer is not null, then presume that it is valid.
*/
if (ptr != NULL) {
volume.Sub_Saturate(1);
return(Play_Sample(ptr, SoundEffectName[voc].Priority * volume, volume*256, pan_value));
}
#endif
return(-1);
}
/*
** This elaborates all the EVA speech voices.
*/
/*static PG*/ char const * Speech[VOX_COUNT] = {
"MISNWON1", // VOX_ACCOMPLISHED mission accomplished
"MISNLST1", // VOX_FAIL your mission has failed
"PROGRES1", // VOX_NO_FACTORY unable to comply, building in progress
"CONSCMP1", // VOX_CONSTRUCTION construction complete
"UNITRDY1", // VOX_UNIT_READY unit ready
"NEWOPT1", // VOX_NEW_CONSTRUCT new construction options
"NODEPLY1", // VOX_DEPLOY cannot deploy here
"STRCKIL1", // VOX_STRUCTURE_DESTROYED, structure destroyed
"NOPOWR1", // VOX_INSUFFICIENT_POWER, insufficient power
"NOFUNDS1", // VOX_NO_CASH insufficient funds
"BCT1", // VOX_CONTROL_EXIT battle control terminated
"REINFOR1", // VOX_REINFORCEMENTS reinforcements have arrived
"CANCLD1", // VOX_CANCELED canceled
"ABLDGIN1", // VOX_BUILDING building
"LOPOWER1", // VOX_LOW_POWER low power
"NOFUNDS1", // VOX_NEED_MO_MONEY insufficent funds
"BASEATK1", // VOX_BASE_UNDER_ATTACK our base is under attack
"NOBUILD1", // VOX_UNABLE_TO_BUILD unable to build more
"PRIBLDG1", // VOX_PRIMARY_SELECTED primary building selected
#ifdef FIXIT_CSII // checked - ajw 9/28/98
#ifdef ENGLISH
"TANK01", // VOX_MADTANK_DEPLOYED M.A.D. Tank Deployed
#else
"none",
#endif
#else
"none",
#endif
"none", // VOX_SOVIET_CAPTURED Allied building captured
"UNITLST1", // VOX_UNIT_LOST unit lost
"SLCTTGT1", // VOX_SELECT_TARGET select target
"ENMYAPP1", // VOX_PREPARE enemy approaching
"SILOND1", // VOX_NEED_MO_CAPACITY silos needed
"ONHOLD1", // VOX_SUSPENDED on hold
"REPAIR1", // VOX_REPAIRING repairing
"none",
"none",
"AUNITL1", // VOX_AIRCRAFT_LOST airborne unit lost
"none",
"AAPPRO1", // VOX_ALLIED_FORCES_APPROACHING allied forces approaching
"AARRIVE1", // VOX_ALLIED_APPROACHING allied reinforcements have arrived
"none",
"none",
"BLDGINF1", // VOX_BUILDING_INFILTRATED building infiltrated
"CHROCHR1", // VOX_CHRONO_CHARGING chronosphere charging
"CHRORDY1", // VOX_CHRONO_READY chronosphere ready
"CHROYES1", // VOX_CHRONO_TEST chronosphere test successful
"CMDCNTR1", // VOX_HQ_UNDER_ATTACK command center under attack
"CNTLDED1", // VOX_CENTER_DEACTIVATED control center deactivated
"CONVYAP1", // VOX_CONVOY_APPROACHING convoy approaching
"CONVLST1", // VOX_CONVOY_UNIT_LOST convoy unit lost
"XPLOPLC1", // VOX_EXPLOSIVE_PLACED explosive charge placed
"CREDIT1", // VOX_MONEY_STOLEN credits stolen
"NAVYLST1", // VOX_SHIP_LOST naval unit lost
"SATLNCH1", // VOX_SATALITE_LAUNCHED satalite launched
"PULSE1", // VOX_SONAR_AVAILABLE sonar pulse available
"none",
"SOVFAPP1", // VOX_SOVIET_FORCES_APPROACHING soviet forces approaching
"SOVREIN1", // VOX_SOVIET_REINFROCEMENTS soviet reinforcements have arrived
"TRAIN1", // VOX_TRAINING training
"AREADY1", // VOX_ABOMB_READY
"ALAUNCH1", // VOX_ABOMB_LAUNCH
"AARRIVN1", // VOX_ALLIES_N
"AARRIVS1", // VOX_ALLIES_S
"AARIVE1", // VOX_ALLIES_E
"AARRIVW1", // VOX_ALLIES_W
"1OBJMET1", // VOX_OBJECTIVE1
"2OBJMET1", // VOX_OBJECTIVE2
"3OBJMET1", // VOX_OBJECTIVE3
"IRONCHG1", // VOX_IRON_CHARGING
"IRONRDY1", // VOX_IRON_READY
"KOSYRES1", // VOX_RESCUED
"OBJNMET1", // VOX_OBJECTIVE_NOT
"FLAREN1", // VOX_SIGNAL_N
"FLARES1", // VOX_SIGNAL_S
"FLAREE1", // VOX_SIGNAL_E
"FLAREW1", // VOX_SIGNAL_W
"SPYPLN1", // VOX_SPY_PLANE
"TANYAF1", // VOX_FREED
"ARMORUP1", // VOX_UPGRADE_ARMOR
"FIREPO1", // VOX_UPGRADE_FIREPOWER
"UNITSPD1", // VOX_UPGRADE_SPEED
"MTIMEIN1", // VOX_MISSION_TIMER
"UNITFUL1", // VOX_UNIT_FULL
"UNITREP1", // VOX_UNIT_REPAIRED
"40MINR", // VOX_TIME_40
"30MINR", // VOX_TIME_30
"20MINR", // VOX_TIME_20
"10MINR", // VOX_TIME_10
"5MINR", // VOX_TIME_5
"4MINR", // VOX_TIME_4
"3MINR", // VOX_TIME_3
"2MINR", // VOX_TIME_2
"1MINR", // VOX_TIME_1
"TIMERNO1", // VOX_TIME_STOP
"UNITSLD1", // VOX_UNIT_SOLD
"TIMERGO1", // VOX_TIMER_STARTED
"TARGRES1", // VOX_TARGET_RESCUED
"TARGFRE1", // VOX_TARGET_FREED
"TANYAR1", // VOX_TANYA_RESCUED
"STRUSLD1", // VOX_STRUCTURE_SOLD
"SOVFORC1", // VOX_SOVIET_FORCES_FALLEN
"SOVEMP1", // VOX_SOVIET_SELECTED
"SOVEFAL1", // VOX_SOVIET_EMPIRE_FALLEN
"OPTERM1", // VOX_OPERATION_TERMINATED
"OBJRCH1", // VOX_OBJECTIVE_REACHED
"OBJNRCH1", // VOX_OBJECTIVE_NOT_REACHED
"OBJMET1", // VOX_OBJECTIVE_MET
"MERCR1", // VOX_MERCENARY_RESCUED
"MERCF1", // VOX_MERCENARY_FREED
"KOSYFRE1", // VOX_KOSOYGEN_FREED
"FLARE1", // VOX_FLARE_DETECTED
"COMNDOR1", // VOX_COMMANDO_RESCUED
"COMNDOF1", // VOX_COMMANDO_FREED
"BLDGPRG1", // VOX_BUILDING_IN_PROGRESS
"ATPREP1", // VOX_ATOM_PREPPING
"ASELECT1", // VOX_ALLIED_SELECTED
"APREP1", // VOX_ABOMB_PREPPING
"ATLNCH1", // VOX_ATOM_LAUNCHED
"AFALLEN1", // VOX_ALLIED_FORCES_FALLEN
"AAVAIL1", // VOX_ABOMB_AVAILABLE
"AARRIVE1", // VOX_ALLIED_REINFORCEMENTS
"SAVE1", // VOX_MISSION_SAVED
"LOAD1" // VOX_MISSION_LOADED
};
static VoxType CurrentVoice = VOX_NONE;
/***********************************************************************************************
* Speech_Name -- Fetches the name for the voice specified. *
* *
* Use this routine to fetch the ASCII name of the speech id specified. Typical use of this *
* would be to build a displayable list of the speech types. The trigger system uses this *
* so that a speech type can be selected. *
* *
* INPUT: speech -- The speech type id to convert to ASCII string. *
* *
* OUTPUT: Returns with a pointer to the speech ASCII representation of the speech id type. *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 06/01/1996 JLB : Created. *
*=============================================================================================*/
char const * Speech_Name(VoxType speech)
{
if (speech == VOX_NONE) return("none");
return(Speech[speech]);
}
/***********************************************************************************************
* Speak -- Computer speaks to the player. *
* *
* This routine is used to have the game computer (EVA) speak to the player. *
* *
* INPUT: voice -- The voice number to speak (see defines.h). *
* *
* OUTPUT: Returns with the handle of the playing speech (-1 if no voice started). *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 11/12/1994 JLB : Created. *
*=============================================================================================*/
// void Speak(VoxType voice) // MBL 02.06.2020
void Speak(VoxType voice, HouseClass *house, COORDINATE coord)
{
// MBL 06.17.2019
if (voice == VOX_NONE)
{
return;
}
//
// Intercept speech calls. MBL 06.17.2019
//
// On_Speech((int)voice); // MBL 02.06.2020
On_Speech((int)voice, house);
if (coord) {
On_Ping(house, coord);
}
#if 0
if (!Debug_Quiet && Options.Volume != 0 && SampleType != 0 && voice != VOX_NONE && voice != SpeakQueue && voice != CurrentVoice && SpeakQueue == VOX_NONE) {
SpeakQueue = voice;
Speak_AI();
}
#endif
}
/***********************************************************************************************
* Speak_AI -- Handles starting the EVA voices. *
* *
* This starts the EVA voice talking as well. If there is any speech request in the queue, *
* it will be started when the current voice is finished. Call this routine as often as *
* possible (once per game tick is sufficient). *
* *
* INPUT: none *
* *
* OUTPUT: none *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 12/27/1994 JLB : Created. *
* 10/11/1996 JLB : Handles multiple speech buffers. *
*=============================================================================================*/
void Speak_AI(void)
{
// MBL 06.17.2019 KO
#if 0
static int _index = 0;
if (Debug_Quiet || SampleType == 0) return;
if (!Is_Sample_Playing(SpeechBuffer[_index])) {
CurrentVoice = VOX_NONE;
if (SpeakQueue != VOX_NONE) {
/*
** Try to find a previously loaded copy of the EVA speech in one of the
** speech buffers.
*/
void const * speech = NULL;
for (int index = 0; index < ARRAY_SIZE(SpeechRecord); index++) {
if (SpeechRecord[index] == SpeakQueue) break;
}
/*
** If a previous copy could not be located, then load the requested
** voice into the oldest buffer available.
*/
if (speech == NULL) {
_index = (_index + 1) % ARRAY_SIZE(SpeechRecord);
char name[_MAX_FNAME+_MAX_EXT];
_makepath(name, NULL, NULL, Speech[SpeakQueue], ".AUD");
CCFileClass file(name);
if (file.Is_Available() && file.Read(SpeechBuffer[_index], SPEECH_BUFFER_SIZE)) {
speech = SpeechBuffer[_index];
SpeechRecord[_index] = SpeakQueue;
}
}
/*
** Since the speech file was loaded, play it.
*/
if (speech != NULL) {
Play_Sample(speech, 254, Options.Volume * 256);
CurrentVoice = SpeakQueue;
}
SpeakQueue = VOX_NONE;
}
}
#endif
// MBL 06.18.2019
if (SpeakQueue != VOX_NONE)
{
// On_Speech((int)SpeakQueue); // MBL 02.06.2020
On_Speech((int)SpeakQueue, NULL);
SpeakQueue = VOX_NONE;
}
}
/***********************************************************************************************
* Stop_Speaking -- Forces the EVA voice to stop talking. *
* *
* Use this routine to immediately stop the EVA voice from speaking. It also clears out *
* the pending voice queue. *
* *
* INPUT: none *
* *
* OUTPUT: none *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 12/27/1994 JLB : Created. *
*=============================================================================================*/
void Stop_Speaking(void)
{
SpeakQueue = VOX_NONE;
Stop_Sample_Playing(SpeechBuffer);
}
/***********************************************************************************************
* Is_Speaking -- Checks to see if the eva voice is still playing. *
* *
* Call this routine when the EVA voice being played needs to be checked. A typical use *
* of this would be when some action needs to be delayed until the voice has finished -- *
* say the end of the game. *
* *
* INPUT: none *
* *
* OUTPUT: bool; Is the EVA voice still playing? *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 03/12/1995 JLB : Created. *
*=============================================================================================*/
bool Is_Speaking(void)
{
Speak_AI();
if (!Debug_Quiet && SampleType != 0 && (SpeakQueue != VOX_NONE || Is_Sample_Playing(SpeechBuffer))) {
return(true);
}
return(false);
}

96
REDALERT/AUDIO.H Normal file
View File

@ -0,0 +1,96 @@
//
// 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: F:\projects\c&c0\vcs\code\audio.h_v 4.43 05 Jul 1996 17:58:10 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 : AUDIO.H *
* *
* Programmer : Joe L. Bostic *
* *
* Start Date : June 21, 1994 *
* *
* Last Update : June 21, 1994 [JLB] *
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef AUDIO_H
#define AUDIO_H
#include "memory.h"
class AudioClass {
char const * Name; // Name of audio asset.
void const * Data; // Loaded audio data.
int Handle; // Handle of asset (as it is playing).
MemoryClass *Mem; // Pointer to memory handler class.
unsigned IsMIDI:1; // Is this a midi file?
public:
AudioClass(void);
AudioClass(char const *name, MemoryClass &mem);
virtual ~AudioClass(void);
bool Load(char const *name = 0);
bool Free(void);
bool Play(int volume = 0xFF);
bool Stop(void);
bool Pause(void);
bool Resume(void);
bool Set_Name(char const *name);
bool Is_Playing(void) const;
bool Is_Loaded(void) const;
bool Is_MIDI(void) const;
};
inline AudioClass::AudioClass(void)
{
Name = 0;
Data = 0;
Mem = 0;
Handle = -1;
};
inline AudioClass::AudioClass(char const *name, MemoryClass &mem)
{
if (mem) {
Mem = &mem;
} else {
Mem = &::Mem; // Uses global default memory handler.
}
Name = strdup(name);
Data = 0;
Handle = -1;
};
inline AudioClass::~AudioClass(void)
{
if (GameActive) {
if (Name) free(Name);
if (Data) Mem->Free(Data);
Name = 0;
Data = 0;
Handle = -1;
}
};
#endif

162
REDALERT/B64PIPE.CPP Normal file
View File

@ -0,0 +1,162 @@
//
// 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/B64PIPE.CPP 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 : B64PIPE.CPP *
* *
* Programmer : Joe L. Bostic *
* *
* Start Date : 06/30/96 *
* *
* Last Update : July 3, 1996 [JLB] *
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* Base64Pipe::Put -- Processes a block of data through the pipe. *
* Base64Pipe::Flush -- Flushes the final pending data through the pipe. *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "b64pipe.h"
#include "base64.h"
#include <string.h>
/***********************************************************************************************
* Base64Pipe::Put -- Processes a block of data through the pipe. *
* *
* This will take the data submitted and either Base64 encode or decode it (as specified *
* in the pipe's constructor). The nature of Base64 encoding means that the data will *
* grow 30% in size when encoding and decrease by a like amount when decoding. *
* *
* INPUT: source -- Pointer to the data to be translated. *
* *
* length -- The number of bytes to translate. *
* *
* OUTPUT: Returns with the actual number of bytes output at the far distant final end of *
* the pipe chain. *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 07/03/1996 JLB : Created. *
*=============================================================================================*/
int Base64Pipe::Put(void const * source, int slen)
{
if (source == NULL || slen < 1) {
return(Pipe::Put(source, slen));
}
int total = 0;
char * from;
int fromsize;
char * to;
int tosize;
if (Control == ENCODE) {
from = PBuffer;
fromsize = sizeof(PBuffer);
to = CBuffer;
tosize = sizeof(CBuffer);
} else {
from = CBuffer;
fromsize = sizeof(CBuffer);
to = PBuffer;
tosize = sizeof(PBuffer);
}
if (Counter > 0) {
int len = (slen < (fromsize-Counter)) ? slen : (fromsize-Counter);
memmove(&from[Counter], source, len);
Counter += len;
slen -= len;
source = ((char *)source) + len;
if (Counter == fromsize) {
int outcount;
if (Control == ENCODE) {
outcount = Base64_Encode(from, fromsize, to, tosize);
} else {
outcount = Base64_Decode(from, fromsize, to, tosize);
}
total += Pipe::Put(to, outcount);
Counter = 0;
}
}
while (slen >= fromsize) {
int outcount;
if (Control == ENCODE) {
outcount = Base64_Encode(source, fromsize, to, tosize);
} else {
outcount = Base64_Decode(source, fromsize, to, tosize);
}
source = ((char *)source) + fromsize;
total += Pipe::Put(to, outcount);
slen -= fromsize;
}
if (slen > 0) {
memmove(from, source, slen);
Counter = slen;
}
return(total);
}
/***********************************************************************************************
* Base64Pipe::Flush -- Flushes the final pending data through the pipe. *
* *
* If there is any non-processed data accumulated in the holding buffer (quite likely when *
* encoding), then it will be processed and flushed out the end of the pipe. *
* *
* INPUT: none *
* *
* OUTPUT: Returns with the number of bytes output at the far distant final end of the pipe *
* chain. *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 07/03/1996 JLB : Created. *
*=============================================================================================*/
int Base64Pipe::Flush(void)
{
int len = 0;
if (Counter) {
if (Control == ENCODE) {
int chars = Base64_Encode(PBuffer, Counter, CBuffer, sizeof(CBuffer));
len += Pipe::Put(CBuffer, chars);
} else {
int chars = Base64_Decode(CBuffer, Counter, PBuffer, sizeof(PBuffer));
len += Pipe::Put(PBuffer, chars);
}
Counter = 0;
}
len += Pipe::Flush();
return(len);
}

89
REDALERT/B64PIPE.H Normal file
View File

@ -0,0 +1,89 @@
//
// 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/B64PIPE.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 : B64PIPE.H *
* *
* Programmer : Joe L. Bostic *
* *
* Start Date : 06/30/96 *
* *
* Last Update : June 30, 1996 [JLB] *
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef B64PIPE_H
#define B64PIPE_H
#include "pipe.h"
/*
** This class performs Base64 encoding/decoding to the data that is piped through. Note that
** encoded data will grow in size by about 30%. The reverse occurs when decoding.
*/
class Base64Pipe : public Pipe
{
public:
typedef enum CodeControl {
ENCODE,
DECODE
} CodeControl;
Base64Pipe(CodeControl control) : Control(control), Counter(0) {}
virtual int Flush(void);
virtual int Put(void const * source, int slen);
private:
/*
** Indicates if this is for encoding or decoding of Base64 data.
*/
CodeControl Control;
/*
** The counter of the number of accumulated bytes pending for processing.
*/
int Counter;
/*
** Buffer that holds the Base64 coded bytes. This will be the staging buffer if
** this is for a decoding process. Otherwise, it will be used as a scratch buffer.
*/
char CBuffer[4];
/*
** Buffer that holds the plain bytes. This will be the staging buffer if this
** is for an encoding process. Otherwise, it will be used as a scratch buffer.
*/
char PBuffer[3];
/*
** Explicitly disable the copy constructor and the assignment operator.
*/
Base64Pipe(Base64Pipe & rvalue);
Base64Pipe & operator = (Base64Pipe const & pipe);
};
#endif

114
REDALERT/B64STRAW.CPP Normal file
View File

@ -0,0 +1,114 @@
//
// 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/B64STRAW.CPP 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 : B64STRAW.CPP *
* *
* Programmer : Joe L. Bostic *
* *
* Start Date : 07/02/96 *
* *
* Last Update : July 3, 1996 [JLB] *
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* Base64Straw::Get -- Fetch data and convert it to/from base 64 encoding. *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "b64straw.h"
#include "base64.h"
#include <string.h>
/***********************************************************************************************
* Base64Straw::Get -- Fetch data and convert it to/from base 64 encoding. *
* *
* This routine will fetch the number of bytes requested and perform any conversion as *
* necessary upon the data. The nature of Base 64 encoding means that the data will *
* increase in size by 30% when encoding and decrease in like manner when decoding. *
* *
* INPUT: source -- The buffer to hold the processed data. *
* *
* length -- The number of bytes requested. *
* *
* OUTPUT: Returns with the number of bytes stored into the buffer. If the number is less *
* than requested, then this indicates that the data stream has been exhausted. *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 07/03/1996 JLB : Created. *
*=============================================================================================*/
int Base64Straw::Get(void * source, int slen)
{
int total = 0;
char * from;
int fromsize;
char * to;
int tosize;
if (Control == ENCODE) {
from = PBuffer;
fromsize = sizeof(PBuffer);
to = CBuffer;
tosize = sizeof(CBuffer);
} else {
from = CBuffer;
fromsize = sizeof(CBuffer);
to = PBuffer;
tosize = sizeof(PBuffer);
}
/*
** Process the byte request in code blocks until there are either
** no more source bytes available or the request has been fulfilled.
*/
while (slen > 0) {
/*
** Transfer any processed bytes available to the request buffer.
*/
if (Counter > 0) {
int len = (slen < Counter) ? slen : Counter;
memmove(source, &to[tosize-Counter], len);
Counter -= len;
slen -= len;
source = ((char *)source) + len;
total += len;
}
if (slen == 0) break;
/*
** More bytes are needed, so fetch and process another base 64 block.
*/
int incount = Straw::Get(from, fromsize);
if (Control == ENCODE) {
Counter = Base64_Encode(from, incount, to, tosize);
} else {
Counter = Base64_Decode(from, incount, to, tosize);
}
if (Counter == 0) break;
}
return(total);
}

88
REDALERT/B64STRAW.H Normal file
View File

@ -0,0 +1,88 @@
//
// 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/B64STRAW.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 : B64STRAW.H *
* *
* Programmer : Joe L. Bostic *
* *
* Start Date : 07/02/96 *
* *
* Last Update : July 2, 1996 [JLB] *
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef B64STRAW_H
#define B64STRAW_H
#include "straw.h"
/*
** Performs Base 64 encoding/decoding on the data that is drawn through the straw. Note that
** encoding increases the data size by about 30%. The reverse occurs when decoding.
*/
class Base64Straw : public Straw
{
public:
typedef enum CodeControl {
ENCODE,
DECODE
} CodeControl;
Base64Straw(CodeControl control) : Control(control), Counter(0) {}
virtual int Get(void * source, int slen);
private:
/*
** Indicates if this is for encoding or decoding of Base64 data.
*/
CodeControl Control;
/*
** The counter of the number of accumulated bytes pending for processing.
*/
int Counter;
/*
** Buffer that holds the Base64 coded bytes. This will be the staging buffer if
** this is for a decoding process. Otherwise, it will be used as a scratch buffer.
*/
char CBuffer[4];
/*
** Buffer that holds the plain bytes. This will be the staging buffer if this
** is for an encoding process. Otherwise, it will be used as a scratch buffer.
*/
char PBuffer[3];
/*
** Explicitly disable the copy constructor and the assignment operator.
*/
Base64Straw(Base64Straw & rvalue);
Base64Straw & operator = (Base64Straw const & pipe);
};
#endif

236
REDALERT/BAR.CPP Normal file
View File

@ -0,0 +1,236 @@
//
// 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/BAR.CPP 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 : BAR.CPP *
* *
* Programmer : Joe L. Bostic *
* *
* Start Date : 08/16/96 *
* *
* Last Update : August 16, 1996 [JLB] *
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* ProgressBarClass::Is_Horizontal -- Determines if the bargraph is horizontal or not. *
* ProgressBarClass::Outline -- Draw an outline around the bargraph if supposed to. *
* ProgressBarClass::ProgressBarClass -- Constructor for the bargraph object. *
* ProgressBarClass::Redraw -- Redraw the bargraph. *
* ProgressBarClass::Set_Limit -- Set the logic tracking value. *
* ProgressBarClass::Update -- Update the value and redraw as necessary. *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "function.h"
#include "bar.h"
#include "fixed.h"
/***********************************************************************************************
* ProgressBarClass::ProgressBarClass -- Constructor for the bargraph object. *
* *
* This is the constructor for the bargraph object. It establishes the dimensions and *
* coordinate of the bargraph as well as the colors it will use when drawn. *
* *
* INPUT: w,y -- Pixel coordinate of the upper left corner of the bargraph. *
* *
* width,height -- Dimensions of the bargraph. *
* *
* forecolor -- The color to use for the filled portion of the bargraph. *
* *
* backcolor -- The color to use for the non-filled portion of the bargraph. *
* *
* bordercolor -- Optional border color. If not zero, then the bargraph will be *
* outlined with this color. *
* *
* OUTPUT: none *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 08/16/1996 JLB : Created. *
*=============================================================================================*/
ProgressBarClass::ProgressBarClass(int x, int y, int width, int height, int forecolor, int backcolor, int bordercolor) :
X(x),
Y(y),
Width(width),
Height(height),
BarColor(forecolor),
BackColor(backcolor),
BorderColor(bordercolor),
CurrentValue(0),
LastDisplayCurrent(0),
IsDrawn(false)
{
}
/***********************************************************************************************
* ProgressBarClass::Is_Horizontal -- Determines if the bargraph is horizontal or not. *
* *
* If the bargraph is oriented horizontally, then this function will return TRUE. *
* *
* INPUT: none *
* *
* OUTPUT: bool; Is this bargraph horizontal? *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 08/16/1996 JLB : Created. *
*=============================================================================================*/
bool ProgressBarClass::Is_Horizontal(void) const
{
if (Width > Height) return(true);
return(false);
}
/***********************************************************************************************
* ProgressBarClass::Update -- Update the value and redraw as necessary. *
* *
* This will update the value of the bargraph to the fill ratio specified and then *
* redraw it if required. Very small changes to the bargraph value might not result in a *
* visual change. *
* *
* INPUT: value -- The new value to assign to this bargraph. *
* *
* OUTPUT: none *
* *
* WARNINGS: bool; Did this update result in a redraw? *
* *
* HISTORY: *
* 08/16/1996 JLB : Created. *
*=============================================================================================*/
bool ProgressBarClass::Update(fixed value)
{
CurrentValue = value;
if (!IsDrawn || value - LastDisplayCurrent >= fixed(1, 10)) {
Redraw();
return(true);
}
return(false);
}
/***********************************************************************************************
* ProgressBarClass::Outline -- Draw an outline around the bargraph if supposed to. *
* *
* This routine will draw a border around the bargraph if this bargraph has a color *
* specified for the border. *
* *
* INPUT: none *
* *
* OUTPUT: none *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 08/16/1996 JLB : Created. *
*=============================================================================================*/
void ProgressBarClass::Outline(void) const
{
if (Is_Outlined()) {
LogicPage->Draw_Line(X, Y, X+Width, Y, BorderColor);
LogicPage->Draw_Line(X, Y, X, Y+Height, BorderColor);
LogicPage->Draw_Line(X, Y+Height, X, Y+Height, BorderColor);
LogicPage->Draw_Line(X+Width, Y, X+Width, Y+Height, BorderColor);
}
}
/***********************************************************************************************
* ProgressBarClass::Redraw -- Redraw the bargraph. *
* *
* This will redraw the entire bargraph. *
* *
* INPUT: none *
* *
* OUTPUT: none *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 08/16/1996 JLB : Created. *
*=============================================================================================*/
void ProgressBarClass::Redraw(void) const
{
Hide_Mouse();
Outline();
/*
** Determine the inner dimensions of the bargraph. This will be
** somewhat smaller than indicated if it has a border.
*/
int x = X;
int y = Y;
int w = Width;
int h = Height;
if (Is_Outlined()) {
x += 1;
y += 1;
w -= 2;
h -= 2;
}
/*
** The working "length" of the bargraph is dependant on whether the
** bargraph is horizontal or vertical.
*/
int size = Is_Horizontal() ? w : h;
/*
** Determine the number of pixels to fill in the bargraph depending on the
** size of the internal value. The larger the internal value the more
** filled the bargraph becomes.
*/
int fill = CurrentValue * size;
/*
** Draw the filled portion of the bargraph if there is any pixels to draw.
*/
if (fill > 0) {
if (Is_Horizontal()) {
LogicPage->Fill_Rect(x, y, x+fill, y+h, BarColor);
} else {
LogicPage->Fill_Rect(x, y+fill, x+w, y+h, BarColor);
}
}
/*
** Draw the unfilled portion of the bargraph if there are any pixels to
** draw of it.
*/
if (w-fill > 0) {
if (Is_Horizontal()) {
LogicPage->Fill_Rect(x+fill, y, x+w, y+h, BackColor);
} else {
LogicPage->Fill_Rect(x, y, x+w, y+fill-1, BackColor);
}
}
Show_Mouse();
ProgressBarClass * me = (ProgressBarClass *)this;
me->LastDisplayCurrent = CurrentValue;
me->IsDrawn = true;
}

108
REDALERT/BAR.H Normal file
View File

@ -0,0 +1,108 @@
//
// 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/BAR.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 : BAR.H *
* *
* Programmer : Joe L. Bostic *
* *
* Start Date : 08/16/96 *
* *
* Last Update : August 16, 1996 [JLB] *
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef BAR_H
#define BAR_H
/*
** The "bool" integral type was defined by the C++ committee in
** November of '94. Until the compiler supports this, use the following
** definition.
*/
#ifndef __BORLANDC__
#ifndef TRUE_FALSE_DEFINED
#define TRUE_FALSE_DEFINED
enum {false=0,true=1};
typedef int bool;
#endif
#endif
#include "fixed.h"
/*
** This is a manager for a progress (or other) bargraph. Such a graph consists of a fill
** and a background region. The fill percentage of the bargraph is controlled by an
** update value. The bargraph can be optionally outlined.
*/
class ProgressBarClass
{
public:
ProgressBarClass(int x, int y, int width, int height, int forecolor, int backcolor, int bordercolor=0);
bool Update(fixed value);
void Redraw(void) const;
private:
void Outline(void) const;
bool Is_Horizontal(void) const;
bool Is_Outlined(void) const {return(BorderColor != 0);}
/*
** This is the upper left coordinates of the bargraph.
*/
int X,Y;
/*
** This is the dimensions of the bargraph.
*/
int Width, Height;
/*
** These are the colors to use when drawing the progress bar.
*/
int BarColor;
int BackColor;
int BorderColor;
/*
** This is the current value of the bargraph.
*/
fixed CurrentValue;
/*
** This is the current value as of the last time the bargraph was rendered.
*/
fixed LastDisplayCurrent;
/*
** If the bargraph has been drawn at least once, then this flag will
** be true.
*/
unsigned IsDrawn:1;
};
#endif

545
REDALERT/BASE.CPP Normal file
View File

@ -0,0 +1,545 @@
//
// 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/BASE.CPP 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 : BASE.CPP *
* *
* Programmer : Bill Randolph *
* *
* Start Date : 03/27/95 *
* *
* Last Update : July 30, 1996 [JLB] *
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* BaseClass::Get_Building -- Returns ptr to the built building for the given node *
* BaseClass::Get_Node -- Finds the node that matches the cell specified. *
* BaseClass::Get_Node -- Returns ptr to the node corresponding to given object *
* BaseClass::Is_Built -- Tells if given item in the list has been built yet *
* BaseClass::Is_Node -- Tells if the given building is part of our base list *
* BaseClass::Load -- loads from a saved game file *
* BaseClass::Next_Buildable -- returns ptr to the next node that needs to be built *
* BaseClass::Read_INI -- INI reading routine *
* BaseClass::Save -- saves to a saved game file *
* BaseClass::Write_INI -- Writes all the base information to the INI database. *
* BaseNodeClass::operator != -- inequality operator *
* BaseNodeClass::operator == -- equality operator *
* BaseNodeClass::operator > -- greater-than operator *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "function.h"
/***********************************************************************************************
* BaseNodeClass::operator == -- equality operator *
* *
* INPUT: *
* node node to test against *
* *
* OUTPUT: *
* true = equal, false = not equal *
* *
* WARNINGS: *
* none. *
* *
* HISTORY: *
* 03/24/1995 BRR : Created. *
*=============================================================================================*/
int BaseNodeClass::operator == (BaseNodeClass const & node)
{
return(Type == node.Type && Cell == node.Cell);
}
/***********************************************************************************************
* BaseNodeClass::operator != -- inequality operator *
* *
* INPUT: *
* node node to test against *
* *
* OUTPUT: *
* comparison result *
* *
* WARNINGS: *
* none. *
* *
* HISTORY: *
* 03/24/1995 BRR : Created. *
*=============================================================================================*/
int BaseNodeClass::operator !=(BaseNodeClass const & node)
{
return(!(*this == node));
}
/***********************************************************************************************
* BaseNodeClass::operator > -- greater-than operator *
* *
* INPUT: *
* node node to test against *
* *
* OUTPUT: *
* comparison result *
* *
* WARNINGS: *
* none. *
* *
* HISTORY: *
* 03/24/1995 BRR : Created. *
*=============================================================================================*/
int BaseNodeClass::operator > (BaseNodeClass const & )
{
return(true);
}
/***********************************************************************************************
* BaseClass::Load -- loads from a saved game file *
* *
* INPUT: *
* file open file *
* *
* OUTPUT: *
* true = success, false = failure *
* *
* WARNINGS: *
* none. *
* *
* HISTORY: *
* 03/24/1995 BRR : Created. *
* 07/04/1996 JLB : Converted to demand driven data source. *
*=============================================================================================*/
bool BaseClass::Load(Straw & file)
{
int num_struct;
int i;
BaseNodeClass node;
/*
** Read in & check the size of this class
*/
if (file.Get(&i, sizeof(i)) != sizeof(i)) {
return(false);
}
if (i != sizeof(*this)) {
return(false);
}
/*
** Read in the House & the number of structures in the base
*/
if (file.Get(&House, sizeof(House)) != sizeof(House)) {
return(false);
}
if (file.Get(&num_struct, sizeof(num_struct)) != sizeof(num_struct)) {
return(false);
}
/*
** Read each node entry & add it to the list
*/
for (i = 0; i < num_struct; i++) {
if (file.Get(&node, sizeof(node)) != sizeof(node)) {
return(false);
}
Nodes.Add(node);
}
return(true);
}
/***********************************************************************************************
* BaseClass::Save -- saves to a saved game file *
* *
* INPUT: *
* file open file *
* *
* OUTPUT: *
* true = success, false = failure *
* *
* WARNINGS: *
* none. *
* *
* HISTORY: *
* 03/24/1995 BRR : Created. *
* 07/04/1996 JLB : Converted to supply driven data output. *
*=============================================================================================*/
bool BaseClass::Save(Pipe & file) const
{
int num_struct;
int i;
BaseNodeClass node;
/*
** Write the size of this class
*/
i = sizeof(*this);
file.Put(&i, sizeof(i));
/*
** Write the House & the number of structures in the base
*/
file.Put(&House, sizeof(House));
num_struct = Nodes.Count();
file.Put(&num_struct, sizeof(num_struct));
/*
** Write each node entry
*/
for (i = 0; i < num_struct; i++) {
node = Nodes[i];
file.Put(&node, sizeof(node));
}
return(true);
}
/***********************************************************************************************
* BaseClass::Is_Built -- Tells if given item in the list has been built yet *
* *
* INPUT: *
* index index into base list *
* *
* OUTPUT: *
* true = yes, false = no *
* *
* WARNINGS: *
* none. *
* *
* HISTORY: *
* 03/24/1995 BRR : Created. *
*=============================================================================================*/
bool BaseClass::Is_Built(int index) const
{
if (Get_Building(index) != NULL) {
return(true);
} else {
return(false);
}
}
/***********************************************************************************************
* BaseClass::Get_Building -- Returns ptr to the built building for the given node *
* *
* INPUT: *
* obj pointer to building to test *
* *
* OUTPUT: *
* ptr to already-built building, NULL if none *
* *
* WARNINGS: *
* none. *
* *
* HISTORY: *
* 03/24/1995 BRR : Created. *
* 07/30/1996 JLB : Handle arbitrary overlapper list length. *
*=============================================================================================*/
BuildingClass * BaseClass::Get_Building(int index) const
{
ObjectClass * obj[1 + ARRAY_SIZE(Map[(CELL)0].Overlapper)];
/*
** Check the location on the map where this building should be; if it's
** there, return a pointer to it.
*/
CELL cell = Nodes[index].Cell;
obj[0] = Map[cell].Cell_Building();
int count = 1;
for (int xindex = 0; xindex < ARRAY_SIZE(Map[cell].Overlapper); xindex++) {
if (Map[cell].Overlapper[xindex] != NULL) {
obj[count++] = Map[cell].Overlapper[xindex];
}
}
BuildingClass * bldg = NULL;
for (int i = 0; i < count; i++) {
if (obj[i] &&
Coord_Cell(obj[i]->Coord) == Nodes[index].Cell &&
obj[i]->What_Am_I() == RTTI_BUILDING &&
((BuildingClass *)obj[i])->Class->Type == Nodes[index].Type) {
bldg = (BuildingClass *)obj[i];
break;
}
}
return(bldg);
}
/***********************************************************************************************
* BaseClass::Is_Node -- Tells if the given building is part of our base list *
* *
* INPUT: *
* obj pointer to building to test *
* *
* OUTPUT: *
* true = building is a node in the list, false = isn't *
* *
* WARNINGS: *
* none. *
* *
* HISTORY: *
* 03/24/1995 BRR : Created. *
*=============================================================================================*/
bool BaseClass::Is_Node(BuildingClass const * obj)
{
if (Get_Node(obj) != NULL) {
return(true);
} else {
return(false);
}
}
/***********************************************************************************************
* BaseClass::Get_Node -- Returns ptr to the node corresponding to given object *
* *
* INPUT: *
* obj pointer to building to test *
* *
* OUTPUT: *
* ptr to node *
* *
* WARNINGS: *
* none. *
* *
* HISTORY: *
* 03/24/1995 BRR : Created. *
*=============================================================================================*/
BaseNodeClass * BaseClass::Get_Node(BuildingClass const * obj)
{
for (int i = 0; i < Nodes.Count(); i++) {
if (obj->Class->Type == Nodes[i].Type && Coord_Cell(obj->Coord) == Nodes[i].Cell) {
return(&Nodes[i]);
}
}
return(NULL);
}
/***********************************************************************************************
* BaseClass::Get_Node -- Finds the node that matches the cell specified. *
* *
* This routine is used to find a matching node the corresponds to the cell specified. *
* *
* INPUT: cell -- The cell to use in finding a match. *
* *
* OUTPUT: Returns a pointer to the matching node if found. If not found, then NULL is *
* returned. *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 03/12/1996 JLB : Created. *
*=============================================================================================*/
BaseNodeClass * BaseClass::Get_Node(CELL cell)
{
for (int index = 0; index < Nodes.Count(); index++) {
if (cell == Nodes[index].Cell) {
return(&Nodes[index]);
}
}
return(NULL);
}
/***********************************************************************************************
* BaseClass::Next_Buildable -- returns ptr to the next node that needs to be built *
* *
* If 'type' is not NONE, returns ptr to the next "hole" in the list of the given type. *
* Otherwise, returns ptr to the next hole in the list of any type. *
* *
* INPUT: *
* type type of building to check for *
* *
* OUTPUT: *
* ptr to a BaseNodeClass, NULL if none *
* *
* WARNINGS: *
* none. *
* *
* HISTORY: *
* 03/24/1995 BRR : Created. *
*=============================================================================================*/
BaseNodeClass * BaseClass::Next_Buildable(StructType type)
{
/*
** Loop through all node entries, returning a pointer to the first
** un-built one that matches the requested type.
*/
for (int i = 0; i < Nodes.Count(); i++) {
/*
** For STRUCT_NONE, return the first hole found
*/
if (type == STRUCT_NONE) {
if (!Is_Built(i)) {
return(&Nodes[i]);
}
} else {
/*
** For a "real" building type, return the first hold for that type
*/
if (Nodes[i].Type==type && !Is_Built(i)) {
return(&Nodes[i]);
}
}
}
// If no entry could be found, then create a fake one that will allow
// placement of the building. Make it static and reuse the next time this
// routine is called.
return(NULL);
}
/***********************************************************************************************
* BaseClass::Read_INI -- INI reading routine *
* *
* INI entry format: *
* BLDG=COORDINATE *
* BLDG=COORDINATE *
* ... *
* *
* INPUT: *
* buffer pointer to loaded INI file *
* *
* OUTPUT: *
* none. *
* *
* WARNINGS: *
* This routines assumes there is only one base defined for the scenario. *
* *
* HISTORY: *
* 03/24/1995 BRR : Created. *
* 02/20/1996 JLB : Fixed to know what house to build base from. *
*=============================================================================================*/
void BaseClass::Read_INI(CCINIClass & ini)
{
char buf[128];
char uname[10];
BaseNodeClass node; // node to add to list
Mono_Clear_Screen();
/*
** First, determine the house of the human player, and set the Base's house
** accordingly.
*/
House = ini.Get_HousesType(INI_Name(), "Player", PlayerPtr->Class->House);
/*
** Read the number of buildings that will go into the base node list
*/
int count = ini.Get_Int(INI_Name(), "Count", 0);
/*
** Read each entry in turn, in the same order they were written out.
*/
for (int i = 0; i < count; i++) {
/*
** Get an INI entry
*/
sprintf(uname,"%03d",i);
ini.Get_String(INI_Name(), uname, NULL, buf, sizeof(buf));
/*
** Set the node's building type
*/
node.Type = BuildingTypeClass::From_Name(strtok(buf,","));
/*
** Read & set the node's coordinate
*/
node.Cell = atoi(strtok(NULL,","));
/*
** Add this node to the Base's list
*/
Nodes.Add(node);
}
}
/***********************************************************************************************
* BaseClass::Write_INI -- Writes all the base information to the INI database. *
* *
* Use this routine to write all prebuild base information to the INI database specified. *
* *
* INPUT: ini -- Reference to the INI database to store the data to. *
* *
* OUTPUT: none *
* *
* WARNINGS: If there was any preexisting prebuild base data in the database, it will be *
* be erased by this routine. *
* *
* HISTORY: *
* 07/30/1996 JLB : Created. *
*=============================================================================================*/
void BaseClass::Write_INI(CCINIClass & ini)
{
/*
** Clear out all existing base data from the ini file.
*/
ini.Clear(INI_Name());
if (House != HOUSE_NONE) {
/*
** Write out the owner of this buildable list.
*/
ini.Put_HousesType(INI_Name(), "Player", House);
/*
** Save the # of buildings in the Nodes list. This is essential because
** they must be read in the same order they were created, so "000" must be
** read first, etc.
*/
ini.Put_Int(INI_Name(), "Count", Nodes.Count());
/*
** Write each entry into the INI
*/
for (int i = 0; i < Nodes.Count(); i++) {
char buf[128];
char uname[10];
sprintf(uname,"%03d",i);
sprintf(buf,"%s,%d",
BuildingTypeClass::As_Reference(Nodes[i].Type).IniName,
Nodes[i].Cell);
ini.Put_String(INI_Name(), uname, buf);
}
}
}

127
REDALERT/BASE.H Normal file
View File

@ -0,0 +1,127 @@
//
// 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/BASE.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 : BASE.H *
* *
* Programmer : Bill Randolph *
* *
* Start Date : 03/27/95 *
* *
* Last Update : March 27, 1995 *
* *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef BASE_H
#define BASE_H
/****************************************************************************
** This class defines one "node" in the pre-built base list. Each node
** contains a type of building to build, and the COORDINATE to build it at.
*/
class BaseNodeClass
{
public:
BaseNodeClass(void) {};
BaseNodeClass(StructType building, CELL cell) : Type(building), Cell(cell) {};
int operator == (BaseNodeClass const & node);
int operator != (BaseNodeClass const & node);
int operator > (BaseNodeClass const & node);
StructType Type;
CELL Cell;
};
/****************************************************************************
** This is the class that defines a pre-built base for the computer AI.
** (Despite its name, this is NOT the "base" class for C&C's class hierarchy!)
*/
class BaseClass
{
public:
/*
** Constructor/Destructor
*/
BaseClass(void) {};
virtual ~BaseClass() {Nodes.Clear();}
/*
** Initialization
*/
void Init(void) {House = HOUSE_NONE; Nodes.Clear();}
/*
** The standard suite of load/save support routines
*/
void Read_INI(CCINIClass & ini);
void Write_INI(CCINIClass & ini);
static char *INI_Name(void) {return "Base";}
bool Load(Straw & file);
bool Save(Pipe & file) const;
virtual void Code_Pointers(void) {};
virtual void Decode_Pointers(void) {};
/*
** Tells if the given node has been built or not
*/
bool Is_Built(int index) const;
/*
** Returns a pointer to the object for the given node
*/
BuildingClass * Get_Building(int index) const;
/*
** Tells if the given building ptr is a node in this base's list.
*/
bool Is_Node(BuildingClass const * obj);
/*
** Returns a pointer to the requested node.
*/
BaseNodeClass * Get_Node(BuildingClass const * obj);
BaseNodeClass * Get_Node(int index) { return (&Nodes[index]); }
BaseNodeClass * Get_Node(CELL cell);
/*
** Returns a pointer to the next "hole" in the Nodes list.
*/
BaseNodeClass * Next_Buildable(StructType type = STRUCT_NONE);
/*
** This is the list of "nodes" that define the base. Portions of this
** list can be pre-built by simply saving those buildings in the INI
** along with non-base buildings, so Is_Built will return true for them.
*/
DynamicVectorClass<BaseNodeClass> Nodes;
/*
** This is the house this base belongs to.
*/
HousesType House;
};
#endif

434
REDALERT/BASE64.CPP Normal file
View File

@ -0,0 +1,434 @@
//
// 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/BASE64.CPP 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 : BASE64.CPP *
* *
* Programmer : Joe L. Bostic *
* *
* Start Date : 06/29/96 *
* *
* Last Update : July 6, 1996 [JLB] *
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* Base64_Decode -- Decodes Base 64 data into its original data form. *
* Base64_Encode -- Encode data into Base 64 format. *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "base64.h"
#include <stddef.h>
/*
** This is the magic padding character used to fill out the encoded data to a multiple of
** 4 characters even though the source data is less than necessary to accomplish this.
** The pad character lets the decoder know of this condition and it will compensate
** accordingly.
*/
static char const * const _pad = "=";
/*
** This encoder translation table will convert a 6 bit number into an ASCII character.
*/
static char const * const _encoder = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
/*
** The decoder translation table takes an ASCII character and converts it into a
** 6 bit number.
*/
#define BAD 0xFE // Ignore this character in source data.
#define END 0xFF // Signifies premature end of input data.
static unsigned char const _decoder[256] = {
BAD,BAD,BAD,BAD,BAD,BAD,BAD,BAD,BAD,BAD,BAD,BAD,BAD,BAD,BAD,BAD,
BAD,BAD,BAD,BAD,BAD,BAD,BAD,BAD,BAD,BAD,BAD,BAD,BAD,BAD,BAD,BAD,
BAD,BAD,BAD,BAD,BAD,BAD,BAD,BAD,BAD,BAD,BAD,62,BAD,BAD,BAD,63,
52,53,54,55,56,57,58,59,60,61,BAD,BAD,BAD,END,BAD,BAD,
BAD,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,
15,16,17,18,19,20,21,22,23,24,25,BAD,BAD,BAD,BAD,BAD,
BAD,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,
41,42,43,44,45,46,47,48,49,50,51,BAD,BAD,BAD,BAD,BAD,
BAD,BAD,BAD,BAD,BAD,BAD,BAD,BAD,BAD,BAD,BAD,BAD,BAD,BAD,BAD,BAD,
BAD,BAD,BAD,BAD,BAD,BAD,BAD,BAD,BAD,BAD,BAD,BAD,BAD,BAD,BAD,BAD,
BAD,BAD,BAD,BAD,BAD,BAD,BAD,BAD,BAD,BAD,BAD,BAD,BAD,BAD,BAD,BAD,
BAD,BAD,BAD,BAD,BAD,BAD,BAD,BAD,BAD,BAD,BAD,BAD,BAD,BAD,BAD,BAD,
BAD,BAD,BAD,BAD,BAD,BAD,BAD,BAD,BAD,BAD,BAD,BAD,BAD,BAD,BAD,BAD,
BAD,BAD,BAD,BAD,BAD,BAD,BAD,BAD,BAD,BAD,BAD,BAD,BAD,BAD,BAD,BAD,
BAD,BAD,BAD,BAD,BAD,BAD,BAD,BAD,BAD,BAD,BAD,BAD,BAD,BAD,BAD,BAD,
BAD,BAD,BAD,BAD,BAD,BAD,BAD,BAD,BAD,BAD,BAD,BAD,BAD,BAD,BAD,BAD
};
int const PacketChars = 4;
/*
** The packet type is used to construct and disect the Base64 data blocks. The data
** consists of three source data bytes mapped onto four 6 bit Base64 code elements.
*/
typedef union {
struct {
#ifdef BIG_ENDIAN
unsigned char C1;
unsigned char C2;
unsigned char C3;
#else
unsigned char C3;
unsigned char C2;
unsigned char C1;
#endif
unsigned char pad;
} Char;
struct {
#ifdef BIG_ENDIAN
unsigned O1:6;
unsigned O2:6;
unsigned O3:6;
unsigned O4:6;
#else
unsigned O4:6;
unsigned O3:6;
unsigned O2:6;
unsigned O1:6;
#endif
unsigned pad:8;
} SubCode;
unsigned int Raw;
} PacketType;
/***********************************************************************************************
* Base64_Encode -- Encode data into Base 64 format. *
* *
* This will take an arbitrary length of source data and transform it into base 64 format *
* data. Base 64 format has the property of being very portable across text editors and *
* country character encoding schemes. As such it is ideal for e-mail. Note that the output *
* data will be about 33% larger than the source. *
* *
* INPUT: source -- Pointer to the source data to convert. *
* *
* slen -- The number of bytes to encode. *
* *
* dest -- Pointer to the destination buffer that will hold the encoded data. *
* *
* dlen -- The size of the destination buffer. *
* *
* OUTPUT: Returns with the number of bytes stored into the destination buffer. *
* *
* WARNINGS: Be sure that the destination buffer is big enough to hold the encoded output. *
* *
* HISTORY: *
* 07/06/1996 JLB : Created. *
*=============================================================================================*/
int Base64_Encode(void const * source, int slen, void * dest, int dlen)
{
/*
** Check the parameters for legality.
*/
if (source == NULL || slen == 0 || dest == NULL || dlen == 0) {
return(0);
}
/*
** Process the source data in blocks of three bytes. Fewer than three bytes
** results in special padding output characters (automatically discarded
** during the decode process).
*/
int total = 0;
unsigned char const * sptr = (unsigned char const *)source;
unsigned char * dptr = (unsigned char *)dest;
while (slen > 0 && dlen >= PacketChars) {
/*
** Fetch 24 bits of source data.
*/
PacketType packet;
int pad = 0;
packet.Raw = 0;
packet.Char.C1 = *sptr++;
slen--;
if (slen) {
packet.Char.C2 = *sptr++;
slen--;
} else {
pad++;
}
if (slen) {
packet.Char.C3 = *sptr++;
slen--;
} else {
pad++;
}
/*
** Translate and write 4 characters of Base64 data. Pad with pad
** characters if there is insufficient source data for a full packet.
*/
*dptr++ = _encoder[packet.SubCode.O1];
*dptr++ = _encoder[packet.SubCode.O2];
if (pad < 2) {
*dptr++ = _encoder[packet.SubCode.O3];
} else {
*dptr++ = _pad[0];
}
if (pad < 1) {
*dptr++ = _encoder[packet.SubCode.O4];
} else {
*dptr++ = _pad[0];
}
dlen -= PacketChars;
total += PacketChars;
}
/*
** Add a trailing null as a courtesy measure.
*/
if (dlen > 0) {
*dptr = '\0';
}
/*
** Return with the total number of characters in the output buffer.
*/
return(total);
}
/***********************************************************************************************
* Base64_Decode -- Decodes Base 64 data into its original data form. *
* *
* Use this routine to decode base 64 data back into the original data. A property of this *
* decode process is that unrecognized input characters are ignored. This allows mangled *
* source (filled with line breaks or spaces) to be correctly decoded. The decode process *
* terminates when the end of the source data has been reached or the special end of data *
* marker is encountered. *
* *
* INPUT: source -- Pointer to the source data to decode. *
* *
* slen -- The number of bytes in the source data buffer. *
* *
* dest -- Pointer to the destination buffer to be filled with the decoded data. *
* *
* dlen -- The maximum size of the destination buffer. *
* *
* OUTPUT: Returns with the number of bytes stored into the destination buffer. This will *
* always be less than the number of source bytes (usually by about 33%). *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 07/06/1996 JLB : Created. *
*=============================================================================================*/
int Base64_Decode(void const * source, int slen, void * dest, int dlen)
{
/*
** Check the parameters for legality.
*/
if (source == NULL || slen == 0 || dest == NULL || dlen == 0) {
return(0);
}
int total = 0;
unsigned char const * sptr = (unsigned char const *)source;
unsigned char * dptr = (unsigned char *)dest;
while (slen > 0 && dlen > 0) {
PacketType packet;
packet.Raw = 0;
/*
** Process input until a full packet has been accumulated or the
** source is exhausted.
*/
int pcount = 0;
while (pcount < PacketChars && slen > 0) {
unsigned char c = *sptr++;
slen--;
unsigned char code = _decoder[c];
/*
** An unrecognized character is skipped.
*/
if (code == BAD) continue;
/*
** The "=" character signifies the end of data regardless of what
** the source buffer length value may be.
*/
if (code == END) {
slen = 0;
break;
}
/*
** A valid Base64 character was found so add it to the packet
** data.
*/
switch (pcount) {
case 0:
packet.SubCode.O1 = code;
break;
case 1:
packet.SubCode.O2 = code;
break;
case 2:
packet.SubCode.O3 = code;
break;
case 3:
packet.SubCode.O4 = code;
break;
}
pcount++;
}
/*
** A packet block is ready for output into the destination buffer.
*/
*dptr++ = packet.Char.C1;
dlen--;
total++;
if (dlen > 0 && pcount > 2) {
*dptr++ = packet.Char.C2;
dlen--;
total++;
}
if (dlen > 0 && pcount > 3) {
*dptr++ = packet.Char.C3;
dlen--;
total++;
}
}
/*
** Return with the total number of characters decoded into the
** output buffer.
*/
return(total);
}
/*
Base64 Content-Transfer-Encoding
The Base64 Content-Transfer-Encoding is designed to represent arbitrary
sequences of octets in a form that need not be humanly readable. The encoding
and decoding algorithms are simple, but the encoded data are consistently
only about 33 percent larger than the unencoded data. This encoding is
virtually identical to the one used in Privacy Enhanced Mail (PEM)
applications, as defined in RFC 1421. The base64 encoding is adapted from
RFC 1421, with one change: base64 eliminates the "*" mechanism for embedded
clear text.
A 65-character subset of US-ASCII is used, enabling 6 bits to be represented
per printable character. (The extra 65th character, "=", is used to signify a
special processing function.)
NOTE:
This subset has the important property that it is represented identically
in all versions of ISO 646, including US ASCII, and all characters in the
subset are also represented identically in all versions of EBCDIC. Other
popular encodings, such as the encoding used by the uuencode utility and
the base85 encoding specified as part of Level 2 PostScript, do not share
these properties, and thus do not fulfill the portability requirements a
binary transport encoding for mail must meet.
The encoding process represents 24-bit groups of input bits as output strings
of 4 encoded characters. Proceeding from left to right, a 24-bit input group is
formed by concatenating 3 8-bit input groups. These 24 bits are then treated as
4 concatenated 6-bit groups, each of which is translated into a single digit in
the base64 alphabet. When encoding a bit stream via the base64 encoding, the
bit stream must be presumed to be ordered with the most-significant-bit first.
That is, the first bit in the stream will be the high-order bit in the first
byte, and the eighth bit will be the low-order bit in the first byte, and so on.
Each 6-bit group is used as an index into an array of 64 printable characters.
The character referenced by the index is placed in the output string. These
characters, identified in Table 1, below, are selected so as to be universally
representable, and the set excludes characters with particular significance to
SMTP (e.g., ".", CR, LF) and to the encapsulation boundaries defined in this
document (e.g., "-").
Table 1: The Base64 Alphabet
Value Encoding Value Encoding Value Encoding Value Encoding
0 A 17 R 34 i 51 z
1 B 18 S 35 j 52 0
2 C 19 T 36 k 53 1
3 D 20 U 37 l 54 2
4 E 21 V 38 m 55 3
5 F 22 W 39 n 56 4
6 G 23 X 40 o 57 5
7 H 24 Y 41 p 58 6
8 I 25 Z 42 q 59 7
9 J 26 a 43 r 60 8
10 K 27 b 44 s 61 9
11 L 28 c 45 t 62 +
12 M 29 d 46 u 63 /
13 N 30 e 47 v
14 O 31 f 48 w (pad) =
15 P 32 g 49 x
16 Q 33 h 50 y
The output stream (encoded bytes) must be represented in lines of no more than
76 characters each. All line breaks or other characters not found in Table 1
must be ignored by decoding software. In base64 data, characters other than
those in Table 1, line breaks, and other white space probably indicate a
transmission error, about which a warning message or even a message rejection
might be appropriate under some circumstances.
Special processing is performed if fewer than 24 bits are available at the end
of the data being encoded. A full encoding quantum is always completed at the
end of a body. When fewer than 24 input bits are available in an input group,
zero bits are added (on the right) to form an integral number of 6-bit groups.
Padding at the end of the data is performed using the '=' character. Since all
base64 input is an integral number of octets, only the following cases can
arise: (1) the final quantum of encoding input is an integral multiple of 24
bits; here, the final unit of encoded output will be an integral multiple of 4
characters with no "=" padding, (2) the final quantum of encoding input is
exactly 8 bits; here, the final unit of encoded output will be two characters
followed by two "=" padding characters, or (3) the final quantum of encoding
input is exactly 16 bits; here, the final unit of encoded output will be three
characters followed by one "=" padding character.
Because it is used only for padding at the end of the data, the occurrence of
any '=' characters may be taken as evidence that the end of the data has been
reached (without truncation in transit). No such assurance is possible,
however, when the number of octets transmitted was a multiple of three.
Any characters outside of the base64 alphabet are to be ignored in
base64-encoded data. The same applies to any illegal sequence of characters in
the base64 encoding, such as "====="
Care must be taken to use the proper octets for line breaks if base64 encoding
is applied directly to text material that has not been converted to canonical
form. In particular, text line breaks must be converted into CRLF sequences
prior to base64 encoding. The important thing to note is that this may be done
directly by the encoder rather than in a prior canonicalization step in some
implementations.
NOTE:
There is no need to worry about quoting apparent encapsulation boundaries
within base64-encoded parts of multipart entities because no hyphen
characters are used in the base64 encoding.
*/

37
REDALERT/BASE64.H Normal file
View File

@ -0,0 +1,37 @@
//
// 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/BASE64.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 : BASE64.H *
* *
* Programmer : Joe L. Bostic *
* *
* Start Date : 06/29/96 *
* *
* Last Update : June 29, 1996 [JLB] *
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
int Base64_Encode(void const * source, int slen, void * dest, int dlen);
int Base64_Decode(void const * source, int slen, void * dest, int dlen);

297
REDALERT/BBDATA.CPP Normal file
View File

@ -0,0 +1,297 @@
//
// 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/BBDATA.CPP 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 : BBDATA.CPP *
* *
* Programmer : Joe L. Bostic *
* *
* Start Date : May 23, 1994 *
* *
* Last Update : July 19, 1996 [JLB] *
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* BulletTypeClass::As_Reference -- Returns with a reference to the bullet type object specif*
* BulletTypeClass::BulletTypeClass -- Constructor for bullet type objects. *
* BulletTypeClass::Init_Heap -- Initialize the heap objects for the bullet type. *
* BulletTypeClass::Load_Shapes -- Load shape data for bullet types. *
* BulletTypeClass::One_Time -- Performs the one time processing for bullets. *
* BulletTypeClass::Read_INI -- Fetch the bullet type data from the INI database. *
* BulletTypeClass::operator delete -- Deletes a bullet type object from the special heap. *
* BulletTypeClass::operator new -- Allocates a bullet type object from the special heap. *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "function.h"
/***********************************************************************************************
* BulletTypeClass::BulletTypeClass -- Constructor for bullet type objects. *
* *
* This is basically a constructor for static type objects used by bullets. All bullets *
* are of a type constructed by this routine at game initialization time. *
* *
* INPUT: see below... *
* *
* OUTPUT: none *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 10/17/1994 JLB : Created. *
* 07/17/1996 JLB : Uses correct default values. *
*=============================================================================================*/
BulletTypeClass::BulletTypeClass(char const * name) :
ObjectTypeClass( RTTI_BULLETTYPE,
BulletTypes.ID(this),
true,
true,
false,
false,
true,
true,
false,
TXT_NONE,
name
),
IsHigh(false),
IsShadow(true),
IsArcing(false),
IsDropping(false),
IsInvisible(false),
IsProximityArmed(false),
IsFlameEquipped(false),
IsFueled(false),
IsFaceless(true),
IsInaccurate(false),
IsTranslucent(false),
IsAntiAircraft(false),
IsAntiGround(true),
IsAntiSub(false),
IsDegenerate(false),
IsSubSurface(false),
IsParachuted(false),
IsGigundo(false),
Type(BulletType(ID)),
ROT(0),
Arming(0),
Tumble(0)
{
}
/***********************************************************************************************
* BulletTypeClass::operator new -- Allocates a bullet type object from the special heap. *
* *
* This allocates a bullet type object from a special heap that is used just for *
* objects of this type. *
* *
* INPUT: none *
* *
* OUTPUT: Returns with a pointer to an allocated block or NULL if the allocation could not *
* occur. *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 07/06/1996 JLB : Created. *
*=============================================================================================*/
void * BulletTypeClass::operator new(size_t)
{
return(BulletTypes.Alloc());
}
/***********************************************************************************************
* BulletTypeClass::operator delete -- Deletes a bullet type object from the special heap. *
* *
* This is the counterpart to the operator new function for bullet type objects. It will *
* return the bullet type object back to the special heap used for bullet type object *
* allocation. *
* *
* INPUT: ptr -- Pointer to the bullet type object to free. *
* *
* OUTPUT: none *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 07/06/1996 JLB : Created. *
*=============================================================================================*/
void BulletTypeClass::operator delete(void * ptr)
{
BulletTypes.Free((BulletTypeClass *)ptr);
}
/***********************************************************************************************
* BulletTypeClass::Init_Heap -- Initialize the heap objects for the bullet type. *
* *
* This performs any necessary initialization for the bullet types. *
* *
* INPUT: none *
* *
* OUTPUT: none *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 07/06/1996 JLB : Created. *
*=============================================================================================*/
void BulletTypeClass::Init_Heap(void)
{
/*
** These bullet type class objects must be allocated in the exact order that they
** are specified in the BulletType enumeration. This is necessary because the heap
** allocation block index serves double duty as the type number index.
*/
new BulletTypeClass("Invisible"); // BULLET_INVISIBLE
new BulletTypeClass("Cannon"); // BULLET_CANNON
new BulletTypeClass("Ack"); // BULLET_ACK
new BulletTypeClass("Torpedo"); // BULLET_TORPEDO
new BulletTypeClass("FROG"); // BULLET_FROG
new BulletTypeClass("HeatSeeker"); // BULLET_HEAT_SEEKER
new BulletTypeClass("LaserGuided"); // BULLET_LASER_GUIDED
new BulletTypeClass("Lobbed"); // BULLET_LOBBED
new BulletTypeClass("Bomblet"); // BULLET_BOMBLET
new BulletTypeClass("Ballistic"); // BULLET_BALLISTIC
new BulletTypeClass("Parachute"); // BULLET_PARACHUTE
new BulletTypeClass("Fireball"); // BULLET_FIREBALL
new BulletTypeClass("LeapDog"); // BULLET_DOG
new BulletTypeClass("Catapult"); // BULLET_CATAPULT
new BulletTypeClass("AAMissile"); // BULLET_AAMISSILE
new BulletTypeClass("GPSSatellite");// BULLET_GPS_SATELLITE
new BulletTypeClass("NukeUp"); // BULLET_NUKE_UP
new BulletTypeClass("NukeDown"); // BULLET_NUKE_DOWN
}
/***********************************************************************************************
* BulletTypeClass::One_Time -- Performs the one time processing for bullets. *
* *
* This routine is used to perform any one time processing for the bullet type class. It *
* handles loading of the shape files. *
* *
* INPUT: none *
* *
* OUTPUT: none *
* *
* WARNINGS: This routine must be called before any rendering of bullets occurs and should *
* only be called once. *
* *
* HISTORY: *
* 05/28/1994 JLB : Created. *
*=============================================================================================*/
void BulletTypeClass::One_Time(void)
{
/*
** Load the bullet shapes.
*/
for (int index = BULLET_FIRST; index < BULLET_COUNT; index++) {
BulletTypeClass const & bullet = As_Reference((BulletType)index);
char fullname[_MAX_FNAME+_MAX_EXT];
if (!bullet.IsInvisible) {
_makepath(fullname, NULL, NULL, bullet.GraphicName, ".SHP");
#ifdef NDEBUG
((void const *&)bullet.ImageData) = MFCD::Retrieve(fullname);
#else
RawFileClass file(fullname);
if (file.Is_Available()) {
((void const *&)bullet.ImageData) = Load_Alloc_Data(file);
} else {
((void const *&)bullet.ImageData) = MFCD::Retrieve(fullname);
}
#endif
}
}
}
/***********************************************************************************************
* BulletTypeClass::As_Reference -- Returns with a reference to the bullet type object specifi *
* *
* Given a bullet type identifier, this routine will return a reference to the bullet type *
* object it refers to. *
* *
* INPUT: type -- The bullet type identifier to convert to a reference. *
* *
* OUTPUT: Returns with a reference to the bullet type object. *
* *
* WARNINGS: Make sure that the type parameter specified is a valid bullet type. If not, *
* then the results are undefined. *
* *
* HISTORY: *
* 07/06/1996 JLB : Created. *
*=============================================================================================*/
BulletTypeClass & BulletTypeClass::As_Reference(BulletType type)
{
return(*BulletTypes.Ptr(type));
}
/***********************************************************************************************
* BulletTypeClass::Read_INI -- Fetch the bullet type data from the INI database. *
* *
* Use this routine to fetch override information about this bullet type class object *
* from the INI database specified. *
* *
* INPUT: ini -- Reference to the INI database to examine. *
* *
* OUTPUT: bool; Was the section for this bullet found and the data extracted? *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 07/19/1996 JLB : Created. *
*=============================================================================================*/
bool BulletTypeClass::Read_INI(CCINIClass & ini)
{
if (ini.Is_Present(Name())) {
Arming = ini.Get_Int(Name(), "Arm", Arming);
ROT = ini.Get_Int(Name(), "ROT", ROT);
Tumble = ini.Get_Int(Name(), "Frames", Tumble);
IsHigh = ini.Get_Bool(Name(), "High", IsHigh);
IsShadow = ini.Get_Bool(Name(), "Shadow", IsShadow);
IsArcing = ini.Get_Bool(Name(), "Arcing", IsArcing);
IsDropping = ini.Get_Bool(Name(), "Dropping", IsDropping);
IsInvisible = ini.Get_Bool(Name(), "Inviso", IsInvisible);
IsProximityArmed = ini.Get_Bool(Name(), "Proximity", IsProximityArmed);
IsFlameEquipped = ini.Get_Bool(Name(), "Animates", IsFlameEquipped);
IsFueled = ini.Get_Bool(Name(), "Ranged", IsFueled);
IsInaccurate = ini.Get_Bool(Name(), "Inaccuate", IsInaccurate);
IsAntiAircraft = ini.Get_Bool(Name(), "AA", IsAntiAircraft);
IsAntiGround = ini.Get_Bool(Name(), "AG", IsAntiGround);
IsAntiSub = ini.Get_Bool(Name(), "ASW", IsAntiSub);
IsDegenerate = ini.Get_Bool(Name(), "Degenerates", IsDegenerate);
IsSubSurface = ini.Get_Bool(Name(), "UnderWater", IsSubSurface);
IsParachuted = ini.Get_Bool(Name(), "Parachuted", IsParachuted);
IsFaceless = !ini.Get_Bool(Name(), "Rotates", !IsFaceless);
IsTranslucent = ini.Get_Bool(Name(), "Translucent", IsTranslucent);
IsGigundo = ini.Get_Bool(Name(), "Gigundo", IsGigundo);
ini.Get_String(Name(), "Image", GraphicName, GraphicName, sizeof(GraphicName));
return(true);
}
return(false);
}

3832
REDALERT/BDATA.CPP Normal file

File diff suppressed because it is too large Load Diff

165
REDALERT/BENCH.CPP Normal file
View File

@ -0,0 +1,165 @@
//
// 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/BENCH.CPP 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 : BENCH.CPP *
* *
* Programmer : Joe L. Bostic *
* *
* Start Date : 07/17/96 *
* *
* Last Update : July 18, 1996 [JLB] *
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* Benchmark::Begin -- Start the benchmark operation. *
* Benchmark::Benchmark -- Constructor for the benchmark object. *
* Benchmark::End -- Mark the end of a benchmarked operation *
* Benchmark::Reset -- Clear out the benchmark statistics. *
* Benchmark::Value -- Fetch the current average benchmark time. *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#if (0)
#include "bench.h"
#include "mpu.h"
/***********************************************************************************************
* Benchmark::Benchmark -- Constructor for the benchmark object. *
* *
* This will construct the benchmark object. *
* *
* INPUT: none *
* *
* OUTPUT: none *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 07/18/1996 JLB : Created. *
*=============================================================================================*/
Benchmark::Benchmark(void) :
Average(0),
Counter(0),
TotalCount(0)
{
}
/***********************************************************************************************
* Benchmark::Reset -- Clear out the benchmark statistics. *
* *
* Use this routine to clear out all the accumulated statistics within this benchmark *
* object. The object is set just as if it was freshly constructed. *
* *
* INPUT: none *
* *
* OUTPUT: none *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 07/18/1996 JLB : Created. *
*=============================================================================================*/
void Benchmark::Reset(void)
{
Average = 0;
Counter = 0;
TotalCount = 0;
}
/***********************************************************************************************
* Benchmark::Begin -- Start the benchmark operation. *
* *
* Call this routine before the operation to be benchmarked is begun. The corresponding *
* End() function must be called after the operation has completed. *
* *
* INPUT: reset -- Should the entire benchmark object be reset at this time as well? *
* *
* OUTPUT: none *
* *
* WARNINGS: The Begin() and End() functions are NOT nestable. *
* *
* HISTORY: *
* 07/18/1996 JLB : Created. *
*=============================================================================================*/
void Benchmark::Begin(bool reset)
{
if (reset) Reset();
Clock = 0;
}
/***********************************************************************************************
* Benchmark::End -- Mark the end of a benchmarked operation *
* *
* This routine is called at the end of the operation that is being benchmarked. It is *
* important to call this routine as soon as possible after the event being benchmarked *
* has completed. *
* *
* INPUT: none *
* *
* OUTPUT: none *
* *
* WARNINGS: The Being() and End() functions are NOT nestable. *
* *
* HISTORY: *
* 07/18/1996 JLB : Created. *
*=============================================================================================*/
void Benchmark::End(void)
{
unsigned long value = Clock;
if (Counter == MAXIMUM_EVENT_COUNT) {
Average -= Average / MAXIMUM_EVENT_COUNT;
Average += value;
} else {
Average += value;
Counter++;
}
TotalCount++;
}
/***********************************************************************************************
* Benchmark::Value -- Fetch the current average benchmark time. *
* *
* This routine will take the statistics already accumulated and determine the average *
* time recorded. This value will be returned. *
* *
* INPUT: none *
* *
* OUTPUT: Returns with the average time that all events tracked by this object. *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 07/18/1996 JLB : Created. *
*=============================================================================================*/
unsigned long Benchmark::Value(void) const
{
if (Counter) {
return(Average / Counter);
}
return(0);
}
#endif

121
REDALERT/BENCH.H Normal file
View File

@ -0,0 +1,121 @@
//
// 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/BENCH.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 : BENCH.H *
* *
* Programmer : Joe L. Bostic *
* *
* Start Date : 07/17/96 *
* *
* Last Update : July 17, 1996 [JLB] *
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef BENCH_H
#define BENCH_H
#if (0)
#include "mpu.h"
#include "ftimer.h"
/*
** The "bool" integral type was defined by the C++ committee in
** November of '94. Until the compiler supports this, use the following
** definition.
*/
#ifndef __BORLANDC__
#ifndef TRUE_FALSE_DEFINED
#define TRUE_FALSE_DEFINED
enum {false=0,true=1};
typedef int bool;
#endif
#endif
/*
** This is a timer access object that will fetch the internal Pentium
** clock value.
*/
class PentiumTimerClass
{
public:
unsigned long operator () (void) const {unsigned long h;unsigned long l = Get_CPU_Clock(h);return((l >> 4) | (h << 28));}
operator unsigned long (void) const {unsigned long h;unsigned long l = Get_CPU_Clock(h);return((l >> 4) | (h << 28));}
};
/*
** A performance tracking tool object. It is used to track elapsed time. Unlike a simple clock, this
** class will keep a running average of the duration. Typical use of this would be to benchmark some
** process that occurs multiple times. By benchmarking an average time, inconsistencies in a particular
** run can be overcome.
*/
class Benchmark
{
public:
Benchmark(void);
void Begin(bool reset=false);
void End(void);
void Reset(void);
unsigned long Value(void) const;
unsigned long Count(void) const {return(TotalCount);}
private:
/*
** The maximum number of events to keep running average of. If
** events exceed this number, then older events drop off the
** accumulated time. This number needs to be as small as
** is reasonable. The larger this number gets, the less magnitude
** that the benchmark timer can handle. Example; At a value of
** 256, the magnitude of the timer can only be 24 bits.
*/
enum {MAXIMUM_EVENT_COUNT=256};
/*
** This is the timer the is used to clock the events.
*/
BasicTimerClass<PentiumTimerClass> Clock;
/*
** The total time off all events tracked so far.
*/
unsigned long Average;
/*
** The total number of events tracked so far.
*/
unsigned long Counter;
/*
** Absolute total number of events (possibly greater than the
** number of events tracked in the average).
*/
unsigned long TotalCount;
};
#endif
#endif

984
REDALERT/BFIOFILE.CPP Normal file
View File

@ -0,0 +1,984 @@
//
// 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/BFIOFILE.CPP 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 : Westwood Library *
* *
* File Name : RAMFILE.CPP *
* *
* Programmer : David R. Dettmer *
* *
* Start Date : November 10, 1995 *
* *
* Last Update : November 10, 1995 [DRD] *
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* BufferIOFileClass::BufferIOFileClass -- Filename based constructor for a file object. *
* BufferIOFileClass::BufferIOFileClass -- default constructor for a file object. *
* BufferIOFileClass::Cache -- Load part or all of a file data into RAM. *
* BufferIOFileClass::Close -- Perform a closure of the file. *
* BufferIOFileClass::Commit -- Writes the cache to the file if it has changed. *
* BufferIOFileClass::Free -- Frees the allocated buffer. *
* BufferIOFileClass::Is_Available -- Checks for existence of file cached or on disk. *
* BufferIOFileClass::Is_Open -- Determines if the file is open. *
* BufferIOFileClass::Open -- Assigns name and opens file in one operation. *
* BufferIOFileClass::Open -- Opens the file object with the rights specified. *
* BufferIOFileClass::Read -- Reads data from the file cache. *
* BufferIOFileClass::Seek -- Moves the current file pointer in the file. *
* BufferIOFileClass::Set_Name -- Checks for name changed for a cached file. *
* BufferIOFileClass::Size -- Determines size of file (in bytes). *
* BufferIOFileClass::Write -- Writes data to the file cache. *
* BufferIOFileClass::~BufferIOFileClass -- Destructor for the file object. *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "bfiofile.h"
#include <string.h>
/***********************************************************************************************
* BufferIOFileClass::BufferIOFileClass -- Filename based constructor for a file object. *
* *
* This constructor is called when a file object is created with a supplied filename, but *
* not opened at the same time. In this case, an assumption is made that the supplied *
* filename is a constant string. A duplicate of the filename string is not created since *
* it would be wasteful in that case. *
* *
* INPUT: filename -- The filename to assign to this file object. *
* *
* OUTPUT: none *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 11/10/1995 DRD : Created. *
*=============================================================================================*/
BufferIOFileClass::BufferIOFileClass(char const * filename) :
IsAllocated(false),
IsOpen(false),
IsDiskOpen(false),
IsCached(false),
IsChanged(false),
UseBuffer(false),
BufferRights(0),
Buffer(0),
BufferSize(0),
BufferPos(0),
BufferFilePos(0),
BufferChangeBeg(-1),
BufferChangeEnd(-1),
FileSize(0),
FilePos(0),
TrueFileStart(0)
{
BufferIOFileClass::Set_Name(filename);
}
/***********************************************************************************************
* BufferIOFileClass::BufferIOFileClass -- default constructor for a file object. *
* *
* This is the default constructor for a file object. *
* *
* INPUT: none *
* *
* OUTPUT: none *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 11/10/1995 DRD : Created. *
*=============================================================================================*/
BufferIOFileClass::BufferIOFileClass(void) :
IsAllocated(false),
IsOpen(false),
IsDiskOpen(false),
IsCached(false),
IsChanged(false),
UseBuffer(false),
BufferRights(0),
Buffer(0),
BufferSize(0),
BufferPos(0),
BufferFilePos(0),
BufferChangeBeg(-1),
BufferChangeEnd(-1),
FileSize(0),
FilePos(0),
TrueFileStart(0)
{
}
/***********************************************************************************************
* BufferIOFileClass::~BufferIOFileClass -- Destructor for the file object. *
* *
* This destructor will free all memory allocated thru using Cache routines. *
* *
* INPUT: none *
* *
* OUTPUT: none *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 11/10/1995 DRD : Created. *
*=============================================================================================*/
BufferIOFileClass::~BufferIOFileClass(void)
{
Free();
}
/***********************************************************************************************
* BufferIOFileClass::Cache -- Load part or all of a file data into RAM. *
* *
* INPUT: none *
* *
* OUTPUT: bool; Was the file load successful? It could fail if there wasn't enough room *
* to allocate the raw data block. *
* *
* WARNINGS: This routine goes to disk for a potentially very long time. *
* *
* HISTORY: *
* 11/10/1995 DRD : Created. *
*=============================================================================================*/
bool BufferIOFileClass::Cache( long size, void * ptr )
{
if (Buffer) {
//
// if trying to cache again with size or ptr fail
//
if (size || ptr) {
return( false );
} else {
return( true );
}
}
if ( Is_Available() ) {
FileSize = Size();
} else {
FileSize = 0;
}
if (size) {
//
// minimum buffer size for performance
//
if (size < MINIMUM_BUFFER_SIZE) {
size = MINIMUM_BUFFER_SIZE;
/*
** Specifying a size smaller than the minimum is an error
** IF a buffer pointer was also specified. In such a case the
** system cannot use the buffer.
*/
if (ptr) {
Error(EINVAL);
}
}
BufferSize = size;
} else {
BufferSize = FileSize;
}
//
// if size == 0 and a ptr to a buffer is specified then that is invalid.
// if the BufferSize is 0 then this must be a new file and no size was
// specified so exit.
//
if ( (size == 0 && ptr) || !BufferSize) {
return( false );
}
if (ptr) {
Buffer = ptr;
} else {
Buffer = new char [BufferSize];
}
if (Buffer) {
IsAllocated = true;
IsDiskOpen = false;
BufferPos = 0;
BufferFilePos = 0;
BufferChangeBeg = -1;
BufferChangeEnd = -1;
FilePos = 0;
TrueFileStart = 0;
//
// the file was checked for availability then set the FileSize
//
if (FileSize) {
long readsize;
int opened = false;
long prevpos = 0;
if (FileSize <= BufferSize) {
readsize = FileSize;
} else {
readsize = BufferSize;
}
if ( Is_Open() ) {
//
// get previous file position
//
prevpos = Seek(0);
//
// get true file position
//
if ( RawFileClass::Is_Open() ) {
TrueFileStart = RawFileClass::Seek(0);
} else {
TrueFileStart = prevpos;
}
if (FileSize <= BufferSize) {
//
// if previous position is non-zero seek to the beginning
//
if (prevpos) {
Seek(0, SEEK_SET);
}
//
// set the buffer position for future reads/writes
//
BufferPos = prevpos;
} else {
BufferFilePos = prevpos;
}
FilePos = prevpos;
} else {
if ( Open() ) {
TrueFileStart = RawFileClass::Seek(0);
opened = true;
}
}
long actual = Read(Buffer, readsize);
if (actual != readsize) {
Error(EIO);
}
if (opened) {
Close();
} else {
//
// seek to the previous position in the file
//
Seek(prevpos, SEEK_SET);
}
IsCached = true;
}
UseBuffer = true;
return(true);
}
Error(ENOMEM);
return(false);
}
/***********************************************************************************************
* BufferIOFileClass::Free -- Frees the allocated buffer. *
* *
* This routine will free the buffer. By using this in conjunction with the *
* Cache() function, one can maintain tight control of memory usage. *
* *
* INPUT: none *
* *
* OUTPUT: none *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 11/10/1995 DRD : Created. *
*=============================================================================================*/
void BufferIOFileClass::Free(void)
{
if (Buffer) {
if (IsAllocated) {
delete [] Buffer;
IsAllocated = false;
}
Buffer = 0;
}
BufferSize = 0;
IsOpen = false;
IsCached = false;
IsChanged = false;
UseBuffer = false;
}
/***********************************************************************************************
* BufferIOFileClass::Commit -- Writes the cache to the file if it has changed. *
* *
* *
* INPUT: none *
* *
* OUTPUT: false, did not need to write the buffer. *
* true, wrote the buffer. *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 11/15/1995 DRD : Created. *
*=============================================================================================*/
bool BufferIOFileClass::Commit( void )
{
long size;
if (UseBuffer) {
if (IsChanged) {
size = BufferChangeEnd - BufferChangeBeg;
if (IsDiskOpen) {
RawFileClass::Seek( TrueFileStart + BufferFilePos +
BufferChangeBeg, SEEK_SET );
RawFileClass::Write( Buffer, size );
RawFileClass::Seek( TrueFileStart + FilePos, SEEK_SET );
} else {
RawFileClass::Open();
RawFileClass::Seek( TrueFileStart + BufferFilePos +
BufferChangeBeg, SEEK_SET );
RawFileClass::Write( Buffer, size );
RawFileClass::Close();
}
IsChanged = false;
return( true );
} else {
return( false );
}
} else {
return( false );
}
}
/***********************************************************************************************
* BufferIOFileClass::Set_Name -- Checks for name changed for a cached file. *
* *
* Checks for a previous filename and that it is cached. If so, then check the *
* new filename against the old. If they are the same then return that filename. *
* Otherwise, the file object's name is set with just the raw filename as passed *
* to this routine. *
* *
* INPUT: filename -- Pointer to the filename to set as the name of this file object. *
* *
* OUTPUT: Returns a pointer to the final and complete filename of this file object. This *
* may have a path attached to the file. *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 11/15/1995 DRD : Created. *
*=============================================================================================*/
char const * BufferIOFileClass::Set_Name(char const * filename)
{
if ( File_Name() && UseBuffer) {
if ( strcmp(filename, File_Name() ) == 0) {
return( File_Name() );
} else {
Commit();
IsCached = false;
}
}
RawFileClass::Set_Name(filename);
return( File_Name() );
}
/***********************************************************************************************
* BufferIOFileClass::Is_Available -- Checks for existence of file cached or on disk. *
* *
* *
* INPUT: none *
* *
* OUTPUT: bool; Is the file available for opening? *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 11/16/1995 DRD : Created. *
*=============================================================================================*/
int BufferIOFileClass::Is_Available(int )
{
if (UseBuffer) {
return(true);
}
return( RawFileClass::Is_Available() );
}
/***********************************************************************************************
* BufferIOFileClass::Is_Open -- Determines if the file is open. *
* *
* If part or all of the file is cached, then return that it is opened. A closed file *
* doesn't have a valid pointer. *
* *
* INPUT: none *
* *
* OUTPUT: bool; Is the file open? *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 11/14/1995 DRD : Created. *
*=============================================================================================*/
int BufferIOFileClass::Is_Open(void) const
{
if (IsOpen && UseBuffer) {
return( true );
}
return( RawFileClass::Is_Open() );
}
/***********************************************************************************************
* BufferIOFileClass::Open -- Assigns name and opens file in one operation. *
* *
* This routine will assign the specified filename to the file object and open it at the *
* same time. If the file object was already open, then it will be closed first. If the *
* file object was previously assigned a filename, then it will be replaced with the new *
* name. Typically, this routine is used when an anonymous file object has been crated and *
* now it needs to be assigned a name and opened. *
* *
* INPUT: filename -- The filename to assign to this file object. *
* *
* rights -- The open file access rights to use. *
* *
* OUTPUT: bool; Was the file opened? The return value of this is moot, since the open file *
* is designed to never return unless it succeeded. *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 11/14/1995 DRD : Created. *
*=============================================================================================*/
int BufferIOFileClass::Open(char const * filename, int rights)
{
Set_Name(filename);
return( BufferIOFileClass::Open( rights ) );
}
/***********************************************************************************************
* BufferIOFileClass::Open -- Opens the file object with the rights specified. *
* *
* This routine is used to open the specified file object with the access rights indicated. *
* This only works if the file has already been assigned a filename. It is guaranteed, by *
* the error handler, that this routine will always return with success. *
* *
* INPUT: rights -- The file access rights to use when opening this file. This is a *
* combination of READ and/or WRITE bit flags. *
* *
* OUTPUT: bool; Was the file opened successfully? This will always return true by reason of *
* the error handler. *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 11/14/1995 DRD : Created. *
*=============================================================================================*/
int BufferIOFileClass::Open(int rights)
{
BufferIOFileClass::Close();
if (UseBuffer) {
BufferRights = rights; // save rights requested for checks later
if (rights != READ ||
(rights == READ && FileSize > BufferSize) ) {
if (rights == WRITE) {
RawFileClass::Open( rights );
RawFileClass::Close();
rights = READ | WRITE;
TrueFileStart = 0; // now writing to single file
}
if (TrueFileStart) {
UseBuffer = false;
Open( rights );
UseBuffer = true;
} else {
RawFileClass::Open( rights );
}
IsDiskOpen = true;
if (BufferRights == WRITE) {
FileSize = 0;
}
} else {
IsDiskOpen = false;
}
BufferPos = 0;
BufferFilePos = 0;
BufferChangeBeg = -1;
BufferChangeEnd = -1;
FilePos = 0;
IsOpen = true;
} else {
RawFileClass::Open( rights );
}
return( true );
}
/***********************************************************************************************
* BufferIOFileClass::Write -- Writes data to the file cache. *
* *
* *
* INPUT: buffer -- Pointer to the buffer that holds the data to be written. *
* *
* size -- The number of bytes to write. *
* *
* OUTPUT: Returns the number of bytes actually written. *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 11/15/1995 DRD : Created. *
*=============================================================================================*/
long BufferIOFileClass::Write(void const * buffer, long size)
{
int opened = false;
if ( !Is_Open() ) {
if (!Open(WRITE)) {
return(0);
}
TrueFileStart = RawFileClass::Seek(0);
opened = true;
}
if (UseBuffer) {
long sizewritten = 0;
if (BufferRights != READ) {
while (size) {
long sizetowrite;
if (size >= (BufferSize - BufferPos) ) {
sizetowrite = (BufferSize - BufferPos);
} else {
sizetowrite = size;
}
if (sizetowrite != BufferSize) {
if ( !IsCached ) {
long readsize;
if (FileSize < BufferSize) {
readsize = FileSize;
BufferFilePos = 0;
} else {
readsize = BufferSize;
BufferFilePos = FilePos;
}
if (TrueFileStart) {
UseBuffer = false;
Seek( FilePos, SEEK_SET );
Read( Buffer, BufferSize );
Seek( FilePos, SEEK_SET );
UseBuffer = true;
} else {
RawFileClass::Seek( BufferFilePos, SEEK_SET );
RawFileClass::Read( Buffer, readsize );
}
BufferPos = 0;
BufferChangeBeg = -1;
BufferChangeEnd = -1;
IsCached = true;
}
}
memmove((char *)Buffer + BufferPos, (char *)buffer + sizewritten, sizetowrite);
IsChanged = true;
sizewritten += sizetowrite;
size -= sizetowrite;
if (BufferChangeBeg == -1) {
BufferChangeBeg = BufferPos;
BufferChangeEnd = BufferPos;
} else {
if (BufferChangeBeg > BufferPos) {
BufferChangeBeg = BufferPos;
}
}
BufferPos += sizetowrite;
if (BufferChangeEnd < BufferPos) {
BufferChangeEnd = BufferPos;
}
FilePos = BufferFilePos + BufferPos;
if (FileSize < FilePos) {
FileSize = FilePos;
}
//
// end of buffer reached?
//
if (BufferPos == BufferSize) {
Commit();
BufferPos = 0;
BufferFilePos = FilePos;
BufferChangeBeg = -1;
BufferChangeEnd = -1;
if (size && FileSize > FilePos) {
if (TrueFileStart) {
UseBuffer = false;
Seek( FilePos, SEEK_SET );
Read( Buffer, BufferSize );
Seek( FilePos, SEEK_SET );
UseBuffer = true;
} else {
RawFileClass::Seek( FilePos, SEEK_SET );
RawFileClass::Read( Buffer, BufferSize );
}
} else {
IsCached = false;
}
}
}
} else {
Error(EACCES);
}
size = sizewritten;
} else {
size = RawFileClass::Write(buffer, size);
}
if (opened) {
Close();
}
return( size );
}
/***********************************************************************************************
* BufferIOFileClass::Read -- Reads data from the file cache. *
* *
* *
* INPUT: buffer -- Pointer to the buffer to place the read data. *
* *
* size -- The number of bytes to read. *
* *
* OUTPUT: Returns the actual number of bytes read (this could be less than requested). *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 11/15/1995 DRD : Created. *
*=============================================================================================*/
long BufferIOFileClass::Read(void * buffer, long size)
{
int opened = false;
if ( !Is_Open() ) {
if ( Open() ) {
TrueFileStart = RawFileClass::Seek(0);
opened = true;
}
}
if (UseBuffer) {
long sizeread = 0;
if (BufferRights != WRITE) {
while (size) {
long sizetoread;
if (size >= (BufferSize - BufferPos) ) {
sizetoread = (BufferSize - BufferPos);
} else {
sizetoread = size;
}
if ( !IsCached ) {
long readsize;
if (FileSize < BufferSize) {
readsize = FileSize;
BufferFilePos = 0;
} else {
readsize = BufferSize;
BufferFilePos = FilePos;
}
if (TrueFileStart) {
UseBuffer = false;
Seek( FilePos, SEEK_SET );
Read( Buffer, BufferSize );
Seek( FilePos, SEEK_SET );
UseBuffer = true;
} else {
RawFileClass::Seek( BufferFilePos, SEEK_SET );
RawFileClass::Read( Buffer, readsize );
}
BufferPos = 0;
BufferChangeBeg = -1;
BufferChangeEnd = -1;
IsCached = true;
}
memmove((char *)buffer + sizeread, (char *)Buffer + BufferPos, sizetoread);
sizeread += sizetoread;
size -= sizetoread;
BufferPos += sizetoread;
FilePos = BufferFilePos + BufferPos;
//
// end of buffer reached?
//
if (BufferPos == BufferSize) {
Commit();
BufferPos = 0;
BufferFilePos = FilePos;
BufferChangeBeg = -1;
BufferChangeEnd = -1;
if (size && FileSize > FilePos) {
if (TrueFileStart) {
UseBuffer = false;
Seek( FilePos, SEEK_SET );
Read( Buffer, BufferSize );
Seek( FilePos, SEEK_SET );
UseBuffer = true;
} else {
RawFileClass::Seek( FilePos, SEEK_SET );
RawFileClass::Read( Buffer, BufferSize );
}
} else {
IsCached = false;
}
}
}
} else {
Error(EACCES);
}
size = sizeread;
} else {
size = RawFileClass::Read(buffer, size);
}
if (opened) {
Close();
}
return( size );
}
/***********************************************************************************************
* BufferIOFileClass::Seek -- Moves the current file pointer in the file. *
* *
* This routine will change the current file pointer to the position specified. It follows *
* the same rules the a normal Seek() does, but if the file is part of the mixfile system, *
* then only the position value needs to be updated. *
* *
* INPUT: pos -- The position to move the file to relative to the position indicated *
* by the "dir" parameter. *
* *
* dir -- The direction to affect the position change against. This can be *
* either SEEK_CUR, SEEK_END, or SEEK_SET. *
* *
* OUTPUT: Returns with the position of the new location. *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 11/15/1995 DRD : Created. *
*=============================================================================================*/
long BufferIOFileClass::Seek(long pos, int dir)
{
if (UseBuffer) {
bool adjusted = false;
switch (dir) {
case SEEK_END:
FilePos = FileSize;
break;
case SEEK_SET:
FilePos = 0;
break;
case SEEK_CUR:
default:
break;
}
if (TrueFileStart) {
if (pos >= TrueFileStart) {
pos -= TrueFileStart;
adjusted = true;
}
}
FilePos += pos;
if (FilePos < 0) {
FilePos = 0;
}
if (FilePos > FileSize ) {
FilePos = FileSize;
}
if (FileSize <= BufferSize) {
BufferPos = FilePos;
} else {
if (FilePos >= BufferFilePos &&
FilePos < (BufferFilePos + BufferSize) ) {
BufferPos = FilePos - BufferFilePos;
} else {
Commit();
// check!!
if (TrueFileStart) {
UseBuffer = false;
Seek(FilePos, SEEK_SET);
UseBuffer = true;
} else {
RawFileClass::Seek(FilePos, SEEK_SET);
}
IsCached = false;
}
}
if (TrueFileStart && adjusted) {
return( FilePos + TrueFileStart );
}
return( FilePos );
}
return( RawFileClass::Seek(pos, dir) );
}
/***********************************************************************************************
* BufferIOFileClass::Size -- Determines size of file (in bytes). *
* *
* If part or all of the file is cached, then the size of the file is already *
* determined and available. Otherwise, go to the low level system to find the file *
* size. *
* *
* INPUT: none *
* *
* OUTPUT: Returns with the number of bytes in the file. *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 11/14/1995 DRD : Created. *
*=============================================================================================*/
long BufferIOFileClass::Size(void)
{
if (IsOpen && UseBuffer) {
return( FileSize );
}
return( RawFileClass::Size() );
}
/***********************************************************************************************
* BufferIOFileClass::Close -- Perform a closure of the file. *
* *
* Call Commit() to write the buffer if the file is cached and the buffer has changed, *
* then call lower level Close(). *
* *
* INPUT: none *
* *
* OUTPUT: none *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 11/14/1995 DRD : Created. *
*=============================================================================================*/
void BufferIOFileClass::Close(void)
{
if (UseBuffer) {
Commit();
if (IsDiskOpen) {
if (TrueFileStart) {
UseBuffer = false;
Close();
UseBuffer = true;
} else {
RawFileClass::Close();
}
IsDiskOpen = false;
}
IsOpen = false;
} else {
RawFileClass::Close();
}
}

92
REDALERT/BFIOFILE.H Normal file
View File

@ -0,0 +1,92 @@
//
// 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/BFIOFILE.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 : Westwood Library *
* *
* File Name : BFIOFILE.H *
* *
* Programmer : David R. Dettmer *
* *
* Start Date : November 10, 1995 *
* *
* Last Update : November 10, 1995 [DRD] *
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef BFIOFILE_H
#define BFIOFILE_H
#include "rawfile.h"
/*
** This derivation of the raw file class handles buffering the input/output in order to
** achieve greater speed. The buffering is not active by default. It must be activated
** by setting the appropriate buffer through the Cache() function.
*/
class BufferIOFileClass : public RawFileClass
{
public:
BufferIOFileClass(char const *filename);
BufferIOFileClass(void);
virtual ~BufferIOFileClass(void);
bool Cache( long size=0, void *ptr=NULL );
void Free( void );
bool Commit( void );
virtual char const * Set_Name(char const *filename);
virtual int Is_Available(int forced=false);
virtual int Is_Open(void) const;
virtual int Open(char const *filename, int rights=READ);
virtual int Open(int rights=READ);
virtual long Read(void *buffer, long size);
virtual long Seek(long pos, int dir=SEEK_CUR);
virtual long Size(void);
virtual long Write(void const *buffer, long size);
virtual void Close(void);
enum {MINIMUM_BUFFER_SIZE=1024};
private:
unsigned IsAllocated:1;
unsigned IsOpen:1;
unsigned IsDiskOpen:1;
unsigned IsCached:1;
unsigned IsChanged:1;
unsigned UseBuffer:1;
int BufferRights;
void *Buffer;
long BufferSize;
long BufferPos;
long BufferFilePos;
long BufferChangeBeg;
long BufferChangeEnd;
long FileSize;
long FilePos;
long TrueFileStart;
};
#endif

81
REDALERT/BIGCHECK.CPP Normal file
View File

@ -0,0 +1,81 @@
//
// 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
// BigCheck.cpp
// ajw 9/14/98
#ifdef WOLAPI_INTEGRATION
#include "function.h"
#include "bigcheck.h"
//***********************************************************************************************
int BigCheckBoxClass::Draw_Me( int forced )
{
if (ToggleClass::Draw_Me(forced))
{
Hide_Mouse();
if( !IsOn )
{
if( !IsDisabled )
CC_Draw_Shape( MFCD::Retrieve( "bigcheck.shp" ), 0, X, Y, WINDOW_MAIN, SHAPE_NORMAL );
else
CC_Draw_Shape( MFCD::Retrieve( "bigcheck.shp" ), 2, X, Y, WINDOW_MAIN, SHAPE_NORMAL );
}
else
{
if( !IsDisabled )
CC_Draw_Shape( MFCD::Retrieve( "bigcheck.shp" ), 1, X, Y, WINDOW_MAIN, SHAPE_NORMAL );
else
CC_Draw_Shape( MFCD::Retrieve( "bigcheck.shp" ), 3, X, Y, WINDOW_MAIN, SHAPE_NORMAL );
}
TextPrintType flags = TextFlags;
RemapControlType* pScheme;
// if( !IsDisabled )
pScheme = GadgetClass::Get_Color_Scheme();
// else
// {
// pScheme = &GreyScheme;
// flags = flags | TPF_MEDIUM_COLOR;
// }
Conquer_Clip_Text_Print( szCaption, X + BIGCHECK_OFFSETX, Y + BIGCHECK_OFFSETY, pScheme, TBLACK, flags, Width, 0 );
Show_Mouse();
return true;
}
return false;
}
//***********************************************************************************************
int BigCheckBoxClass::Action(unsigned flags, KeyNumType & key)
{
/* if( flags & LEFTPRESS )
{
if (IsOn) {
Turn_Off();
} else {
Turn_On();
}
}
*/
return(ToggleClass::Action(flags, key));
}
#endif

71
REDALERT/BIGCHECK.H Normal file
View File

@ -0,0 +1,71 @@
//
// 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
// Bigcheck.h
// ajw 9/14/98
#ifdef WOLAPI_INTEGRATION
#ifndef BIGCHECKBOX_H
#define BIGCHECKBOX_H
#include "toggle.h"
#define BIGCHECK_OFFSETX 20
#define BIGCHECK_OFFSETY 0
//***********************************************************************************************
class BigCheckBoxClass : public ToggleClass
{
public:
BigCheckBoxClass( unsigned id, int x, int y, int w, int h, const char* szCaptionIn, TextPrintType TextFlags,
bool bInitiallyChecked = false ) :
ToggleClass( id, x, y, w, h ),
TextFlags( TextFlags )
{
szCaption = new char[ strlen( szCaptionIn ) + 1 ];
strcpy( szCaption, szCaptionIn );
if( bInitiallyChecked )
Turn_On();
IsToggleType = 1;
}
virtual ~BigCheckBoxClass()
{
delete [] szCaption;
}
virtual int Draw_Me(int forced=false);
virtual int Action(unsigned flags, KeyNumType & key);
bool Toggle()
{
if( IsOn )
{
Turn_Off();
return false;
}
Turn_On();
return true;
}
protected:
TextPrintType TextFlags;
char* szCaption;
};
#endif
#endif

595
REDALERT/BLOWFISH.CPP Normal file
View File

@ -0,0 +1,595 @@
//
// 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/BLOWFISH.CPP 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 : BLOWFISH.CPP *
* *
* Programmer : Joe L. Bostic *
* *
* Start Date : 04/14/96 *
* *
* Last Update : July 8, 1996 [JLB] *
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* BlowfishEngine::Decrypt -- Decrypts data using blowfish algorithm. *
* BlowfishEngine::Encrypt -- Encrypt an arbitrary block of data. *
* BlowfishEngine::Process_Block -- Process a block of data using Blowfish algorithm. *
* BlowfishEngine::Sub_Key_Encrypt -- Encrypts a block for use in S-Box processing. *
* BlowfishEngine::Submit_Key -- Submit a key that will allow data processing. *
* BlowfishEngine::~BlowfishEngine -- Destructor for the Blowfish engine. *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "blowfish.h"
#include <string.h>
#include <assert.h>
/*
** Byte order controlled long integer. This integer is constructed
** so that character 0 (C0) is the most significant byte of the
** integer. This is biased toward big endian architecture, but that
** just happens to be how the Blowfish algorithm was designed.
*/
typedef union {
unsigned long Long;
struct {
unsigned char C3;
unsigned char C2;
unsigned char C1;
unsigned char C0;
} Char;
} Int;
/***********************************************************************************************
* BlowfishEngine::~BlowfishEngine -- Destructor for the Blowfish engine. *
* *
* This destructor will clear out the s-box tables so that even if the memory for the *
* class remains, it will contain no compromising data. *
* *
* INPUT: none *
* *
* OUTPUT: none *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 07/08/1996 JLB : Created. *
*=============================================================================================*/
BlowfishEngine::~BlowfishEngine(void)
{
if (IsKeyed) {
Submit_Key(NULL, 0);
}
}
/***********************************************************************************************
* BlowfishEngine::Submit_Key -- Submit a key that will allow data processing. *
* *
* This routine must be called before any data can be encrypted or decrypted. This routine *
* need only be called when the key is to be changed or set for the first time. Once the *
* key has been set, the engine may be used to encrypt, decrypt, or both operations *
* indefinitely. The key must be 56 bytes or less in length. This is necessary because *
* any keys longer than that will not correctly affect the encryption process. *
* *
* If the key pointer is NULL, then the S-Box tables are reset to identity. This will *
* mask the previous key setting. Use this method to clear the engine after processing in *
* order to gain a measure of security. *
* *
* INPUT: key -- Pointer to the key data block. *
* *
* length -- The length of the submitted key. *
* *
* OUTPUT: none *
* *
* WARNINGS: This is a time consuming process. *
* *
* HISTORY: *
* 04/14/1996 JLB : Created. *
*=============================================================================================*/
void BlowfishEngine::Submit_Key(void const * key, int length)
{
assert(length <= MAX_KEY_LENGTH);
/*
** Initialize the permutation and S-Box tables to a known
** constant value.
*/
memcpy(P_Encrypt, P_Init, sizeof(P_Init));
memcpy(P_Decrypt, P_Init, sizeof(P_Init));
memcpy(bf_S, S_Init, sizeof(S_Init));
/*
** Validate parameters.
*/
if (key == 0 || length == 0) {
IsKeyed = false;
return;
}
/*
** Combine the key with the permutation table. Wrap the key
** as many times as necessary to ensure that the entire
** permutation table has been modified. The key is lifted
** into a long by using endian independent means.
*/
int j = 0;
unsigned char const * key_ptr = (unsigned char const *)key;
unsigned long * p_ptr = &P_Encrypt[0];
for (int index = 0; index < ROUNDS+2; index++) {
unsigned long data = 0;
data = (data << CHAR_BIT) | key_ptr[j++ % length];
data = (data << CHAR_BIT) | key_ptr[j++ % length];
data = (data << CHAR_BIT) | key_ptr[j++ % length];
data = (data << CHAR_BIT) | key_ptr[j++ % length];
*p_ptr++ ^= data;
}
/*
** The permutation table must be scrambled by means of the key. This
** is how the key is factored into the encryption -- by merely altering
** the permutation (and S-Box) tables. Because this transformation alters
** the table data WHILE it is using the table data, the tables are
** thoroughly obfuscated by this process.
*/
unsigned long left = 0x00000000L;
unsigned long right = 0x00000000L;
unsigned long * p_en = &P_Encrypt[0]; // Encryption table.
unsigned long * p_de = &P_Decrypt[ROUNDS+1]; // Decryption table.
for (int p_index = 0; p_index < ROUNDS+2; p_index += 2) {
Sub_Key_Encrypt(left, right);
*p_en++ = left;
*p_en++ = right;
*p_de-- = left;
*p_de-- = right;
}
/*
** Perform a similar transmutation to the S-Box tables. Also notice that the
** working 64 bit number is carried into this process from the previous
** operation.
*/
for (int sbox_index = 0; sbox_index < 4; sbox_index++) {
for (int ss_index = 0; ss_index < UCHAR_MAX+1; ss_index += 2) {
Sub_Key_Encrypt(left, right);
bf_S[sbox_index][ss_index] = left;
bf_S[sbox_index][ss_index + 1] = right;
}
}
IsKeyed = true;
}
/***********************************************************************************************
* BlowfishEngine::Encrypt -- Encrypt an arbitrary block of data. *
* *
* Use this routine to encrypt an arbitrary block of data. The block must be an even *
* multiple of 8 bytes. Any bytes left over will not be encrypted. The 8 byte requirement *
* is necessary because the underlying algorithm processes blocks in 8 byte chunks. *
* Partial blocks are unrecoverable and useless. *
* *
* INPUT: plaintext-- Pointer to the data block to be encrypted. *
* *
* length -- The length of the data block. *
* *
* cyphertext- Pointer to the output buffer that will hold the encrypted data. *
* *
* OUTPUT: Returns with the actual number of bytes encrypted. *
* *
* WARNINGS: You must submit the key before calling this routine. This will only encrypt *
* the plaintext in 8 byte increments. Modulo bytes left over are not processed. *
* *
* HISTORY: *
* 04/14/1996 JLB : Created. *
*=============================================================================================*/
int BlowfishEngine::Encrypt(void const * plaintext, int length, void * cyphertext)
{
if (plaintext == 0 || length == 0) {
return(0);
}
if (cyphertext == 0) cyphertext = (void *)plaintext;
if (IsKeyed) {
/*
** Validate parameters.
*/
int blocks = length / BYTES_PER_BLOCK;
/*
** Process the buffer in 64 bit chunks.
*/
for (int index = 0; index < blocks; index++) {
Process_Block(plaintext, cyphertext, P_Encrypt);
plaintext = ((char *)plaintext) + BYTES_PER_BLOCK;
cyphertext = ((char *)cyphertext) + BYTES_PER_BLOCK;
}
int encrypted = blocks * BYTES_PER_BLOCK;
/*
** Copy over any trailing left over appendix bytes.
*/
if (encrypted < length) {
memmove(cyphertext, plaintext, length - encrypted);
}
return(encrypted);
}
/*
** Non-keyed processing merely copies the data.
*/
if (plaintext != cyphertext) {
memmove(cyphertext, plaintext, length);
}
return(length);
}
/***********************************************************************************************
* BlowfishEngine::Decrypt -- Decrypt an arbitrary block of data. *
* *
* Use this routine to decrypt an arbitrary block of data. The block must be an even *
* multiple of 8 bytes. Any bytes left over will not be decrypted. The 8 byte requirement *
* is necessary because the underlying algorithm processes blocks in 8 byte chunks. *
* Partial blocks are unrecoverable and useless. *
* *
* INPUT: cyphertext- Pointer to the data block to be decrypted. *
* *
* length -- The length of the data block. *
* *
* plaintext-- Pointer to the output buffer that will hold the decrypted data. *
* *
* OUTPUT: Returns with the actual number of bytes decrypted. *
* *
* WARNINGS: You must submit the key before calling this routine. This will only decrypt *
* the cyphertext in 8 byte increments. Modulo bytes left over are not processed. *
* *
* HISTORY: *
* 04/14/1996 JLB : Created. *
*=============================================================================================*/
int BlowfishEngine::Decrypt(void const * cyphertext, int length, void * plaintext)
{
if (cyphertext == 0 || length == 0) {
return(0);
}
if (plaintext == 0) plaintext = (void *)cyphertext;
if (IsKeyed) {
/*
** Validate parameters.
*/
int blocks = length / BYTES_PER_BLOCK;
/*
** Process the buffer in 64 bit chunks.
*/
for (int index = 0; index < blocks; index++) {
Process_Block(cyphertext, plaintext, P_Decrypt);
cyphertext = ((char *)cyphertext) + BYTES_PER_BLOCK;
plaintext = ((char *)plaintext) + BYTES_PER_BLOCK;
}
int encrypted = blocks * BYTES_PER_BLOCK;
/*
** Copy over any trailing left over appendix bytes.
*/
if (encrypted < length) {
memmove(plaintext, cyphertext, length - encrypted);
}
return(encrypted);
}
/*
** Non-keyed processing merely copies the data.
*/
if (plaintext != cyphertext) {
memmove(plaintext, cyphertext, length);
}
return(length);
}
/***********************************************************************************************
* BlowfishEngine::Process_Block -- Process a block of data using Blowfish algorithm. *
* *
* This is the main processing routine for encryption and decryption. The algorithm *
* consists of a 16 round Feistal network and uses mathematics from different algebraic *
* groups (strengthens against differential cryptanalysis). The large S-Boxes and the *
* rounds strengthen it against linear cryptanalysis. *
* *
* INPUT: plaintext -- Pointer to the source text (it actually might be a pointer to *
* the cyphertext if this is called as a decryption process). *
* *
* cyphertext -- Pointer to the output buffer that will hold the processed block. *
* *
* ptable -- Pointer to the permutation table. This algorithm will encrypt *
* and decrypt using the same S-Box tables. The encryption control *
* is handled by the permutation table. *
* *
* OUTPUT: none *
* *
* WARNINGS: The source and destination buffers must be 8 bytes long. *
* *
* HISTORY: *
* 04/19/1996 JLB : Created. *
*=============================================================================================*/
void BlowfishEngine::Process_Block(void const * plaintext, void * cyphertext, unsigned long const * ptable)
{
/*
** Input the left and right halves of the source block such that
** the byte order is constant regardless of the endian
** persuasion of the current processor. The blowfish algorithm is
** biased toward "big endian" architecture and some optimizations
** could be done for big endian processors in that case.
*/
unsigned char const * source = (unsigned char const *)plaintext;
Int left;
left.Char.C0 = *source++;
left.Char.C1 = *source++;
left.Char.C2 = *source++;
left.Char.C3 = *source++;
Int right;
right.Char.C0 = *source++;
right.Char.C1 = *source++;
right.Char.C2 = *source++;
right.Char.C3 = *source;
/*
** Perform all Feistal rounds on the block. This is the encryption/decryption
** process. Since there is an exchange that occurs after each round, two
** rounds are combined in this loop to avoid unnecessary exchanging.
*/
for (int index = 0; index < ROUNDS/2; index++) {
left.Long ^= *ptable++;
right.Long ^= ((( bf_S[0][left.Char.C0] + bf_S[1][left.Char.C1]) ^ bf_S[2][left.Char.C2]) + bf_S[3][left.Char.C3]);
right.Long ^= *ptable++;
left.Long ^= ((( bf_S[0][right.Char.C0] + bf_S[1][right.Char.C1]) ^ bf_S[2][right.Char.C2]) + bf_S[3][right.Char.C3]);
}
/*
** The final two longs in the permutation table are processed into the block.
** The left and right halves are still reversed as a side effect of the last
** round.
*/
left.Long ^= *ptable++;
right.Long ^= *ptable;
/*
** The final block data is output in endian architecture
** independent format. Notice that the blocks are output as
** right first and left second. This is to counteract the final
** superfluous exchange that occurs as a side effect of the
** encryption rounds.
*/
unsigned char * out = (unsigned char *)cyphertext;
*out++ = right.Char.C0;
*out++ = right.Char.C1;
*out++ = right.Char.C2;
*out++ = right.Char.C3;
*out++ = left.Char.C0;
*out++ = left.Char.C1;
*out++ = left.Char.C2;
*out = left.Char.C3;
}
/***********************************************************************************************
* BlowfishEngine::Sub_Key_Encrypt -- Encrypts a block for use in S-Box processing. *
* *
* This is the same as the normal process block function but it doesn't have the endian *
* fixup logic. Since this routine is only called for S-Box table generation and it is *
* known that the S-Box initial data is already in local machine endian format, the *
* byte order fixups are not needed. This also has a tendency to speed up S-Box generation *
* as well. *
* *
* INPUT: left -- The left half of the data block. *
* *
* right -- The right half of the data block. *
* *
* OUTPUT: none, but the processed block is stored back into the left and right half *
* integers. *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 04/19/1996 JLB : Created. *
*=============================================================================================*/
void BlowfishEngine::Sub_Key_Encrypt(unsigned long & left, unsigned long & right)
{
Int l;
l.Long = left;
Int r;
r.Long = right;
for (int index = 0; index < ROUNDS; index += 2) {
l.Long ^= P_Encrypt[index];
r.Long ^= ((( bf_S[0][l.Char.C0] + bf_S[1][l.Char.C1]) ^ bf_S[2][l.Char.C2]) + bf_S[3][l.Char.C3]);
r.Long ^= P_Encrypt[index+1];
l.Long ^= ((( bf_S[0][r.Char.C0] + bf_S[1][r.Char.C1]) ^ bf_S[2][r.Char.C2]) + bf_S[3][r.Char.C3]);
}
left = r.Long ^ P_Encrypt[ROUNDS+1];
right = l.Long ^ P_Encrypt[ROUNDS];
}
/*
** These tables have the bytes stored in machine endian format. Because of this,
** a special block cypher routine is needed when the sub-keys are generated.
** This is kludgier than it otherwise should be. However, storing these
** integers in machine independent format would be even more painful.
*/
unsigned long const BlowfishEngine::P_Init[BlowfishEngine::ROUNDS+2] = {
0x243F6A88U,0x85A308D3U,0x13198A2EU,0x03707344U,0xA4093822U,0x299F31D0U,0x082EFA98U,0xEC4E6C89U,
0x452821E6U,0x38D01377U,0xBE5466CFU,0x34E90C6CU,0xC0AC29B7U,0xC97C50DDU,0x3F84D5B5U,0xB5470917U,
0x9216D5D9U,0x8979FB1BU
} ;
unsigned long const BlowfishEngine::S_Init[4][UCHAR_MAX+1] = {
{
0xD1310BA6U,0x98DFB5ACU,0x2FFD72DBU,0xD01ADFB7U,0xB8E1AFEDU,0x6A267E96U,0xBA7C9045U,0xF12C7F99U,
0x24A19947U,0xB3916CF7U,0x0801F2E2U,0x858EFC16U,0x636920D8U,0x71574E69U,0xA458FEA3U,0xF4933D7EU,
0x0D95748FU,0x728EB658U,0x718BCD58U,0x82154AEEU,0x7B54A41DU,0xC25A59B5U,0x9C30D539U,0x2AF26013U,
0xC5D1B023U,0x286085F0U,0xCA417918U,0xB8DB38EFU,0x8E79DCB0U,0x603A180EU,0x6C9E0E8BU,0xB01E8A3EU,
0xD71577C1U,0xBD314B27U,0x78AF2FDAU,0x55605C60U,0xE65525F3U,0xAA55AB94U,0x57489862U,0x63E81440U,
0x55CA396AU,0x2AAB10B6U,0xB4CC5C34U,0x1141E8CEU,0xA15486AFU,0x7C72E993U,0xB3EE1411U,0x636FBC2AU,
0x2BA9C55DU,0x741831F6U,0xCE5C3E16U,0x9B87931EU,0xAFD6BA33U,0x6C24CF5CU,0x7A325381U,0x28958677U,
0x3B8F4898U,0x6B4BB9AFU,0xC4BFE81BU,0x66282193U,0x61D809CCU,0xFB21A991U,0x487CAC60U,0x5DEC8032U,
0xEF845D5DU,0xE98575B1U,0xDC262302U,0xEB651B88U,0x23893E81U,0xD396ACC5U,0x0F6D6FF3U,0x83F44239U,
0x2E0B4482U,0xA4842004U,0x69C8F04AU,0x9E1F9B5EU,0x21C66842U,0xF6E96C9AU,0x670C9C61U,0xABD388F0U,
0x6A51A0D2U,0xD8542F68U,0x960FA728U,0xAB5133A3U,0x6EEF0B6CU,0x137A3BE4U,0xBA3BF050U,0x7EFB2A98U,
0xA1F1651DU,0x39AF0176U,0x66CA593EU,0x82430E88U,0x8CEE8619U,0x456F9FB4U,0x7D84A5C3U,0x3B8B5EBEU,
0xE06F75D8U,0x85C12073U,0x401A449FU,0x56C16AA6U,0x4ED3AA62U,0x363F7706U,0x1BFEDF72U,0x429B023DU,
0x37D0D724U,0xD00A1248U,0xDB0FEAD3U,0x49F1C09BU,0x075372C9U,0x80991B7BU,0x25D479D8U,0xF6E8DEF7U,
0xE3FE501AU,0xB6794C3BU,0x976CE0BDU,0x04C006BAU,0xC1A94FB6U,0x409F60C4U,0x5E5C9EC2U,0x196A2463U,
0x68FB6FAFU,0x3E6C53B5U,0x1339B2EBU,0x3B52EC6FU,0x6DFC511FU,0x9B30952CU,0xCC814544U,0xAF5EBD09U,
0xBEE3D004U,0xDE334AFDU,0x660F2807U,0x192E4BB3U,0xC0CBA857U,0x45C8740FU,0xD20B5F39U,0xB9D3FBDBU,
0x5579C0BDU,0x1A60320AU,0xD6A100C6U,0x402C7279U,0x679F25FEU,0xFB1FA3CCU,0x8EA5E9F8U,0xDB3222F8U,
0x3C7516DFU,0xFD616B15U,0x2F501EC8U,0xAD0552ABU,0x323DB5FAU,0xFD238760U,0x53317B48U,0x3E00DF82U,
0x9E5C57BBU,0xCA6F8CA0U,0x1A87562EU,0xDF1769DBU,0xD542A8F6U,0x287EFFC3U,0xAC6732C6U,0x8C4F5573U,
0x695B27B0U,0xBBCA58C8U,0xE1FFA35DU,0xB8F011A0U,0x10FA3D98U,0xFD2183B8U,0x4AFCB56CU,0x2DD1D35BU,
0x9A53E479U,0xB6F84565U,0xD28E49BCU,0x4BFB9790U,0xE1DDF2DAU,0xA4CB7E33U,0x62FB1341U,0xCEE4C6E8U,
0xEF20CADAU,0x36774C01U,0xD07E9EFEU,0x2BF11FB4U,0x95DBDA4DU,0xAE909198U,0xEAAD8E71U,0x6B93D5A0U,
0xD08ED1D0U,0xAFC725E0U,0x8E3C5B2FU,0x8E7594B7U,0x8FF6E2FBU,0xF2122B64U,0x8888B812U,0x900DF01CU,
0x4FAD5EA0U,0x688FC31CU,0xD1CFF191U,0xB3A8C1ADU,0x2F2F2218U,0xBE0E1777U,0xEA752DFEU,0x8B021FA1U,
0xE5A0CC0FU,0xB56F74E8U,0x18ACF3D6U,0xCE89E299U,0xB4A84FE0U,0xFD13E0B7U,0x7CC43B81U,0xD2ADA8D9U,
0x165FA266U,0x80957705U,0x93CC7314U,0x211A1477U,0xE6AD2065U,0x77B5FA86U,0xC75442F5U,0xFB9D35CFU,
0xEBCDAF0CU,0x7B3E89A0U,0xD6411BD3U,0xAE1E7E49U,0x00250E2DU,0x2071B35EU,0x226800BBU,0x57B8E0AFU,
0x2464369BU,0xF009B91EU,0x5563911DU,0x59DFA6AAU,0x78C14389U,0xD95A537FU,0x207D5BA2U,0x02E5B9C5U,
0x83260376U,0x6295CFA9U,0x11C81968U,0x4E734A41U,0xB3472DCAU,0x7B14A94AU,0x1B510052U,0x9A532915U,
0xD60F573FU,0xBC9BC6E4U,0x2B60A476U,0x81E67400U,0x08BA6FB5U,0x571BE91FU,0xF296EC6BU,0x2A0DD915U,
0xB6636521U,0xE7B9F9B6U,0xFF34052EU,0xC5855664U,0x53B02D5DU,0xA99F8FA1U,0x08BA4799U,0x6E85076AU,
},{
0x4B7A70E9U,0xB5B32944U,0xDB75092EU,0xC4192623U,0xAD6EA6B0U,0x49A7DF7DU,0x9CEE60B8U,0x8FEDB266U,
0xECAA8C71U,0x699A17FFU,0x5664526CU,0xC2B19EE1U,0x193602A5U,0x75094C29U,0xA0591340U,0xE4183A3EU,
0x3F54989AU,0x5B429D65U,0x6B8FE4D6U,0x99F73FD6U,0xA1D29C07U,0xEFE830F5U,0x4D2D38E6U,0xF0255DC1U,
0x4CDD2086U,0x8470EB26U,0x6382E9C6U,0x021ECC5EU,0x09686B3FU,0x3EBAEFC9U,0x3C971814U,0x6B6A70A1U,
0x687F3584U,0x52A0E286U,0xB79C5305U,0xAA500737U,0x3E07841CU,0x7FDEAE5CU,0x8E7D44ECU,0x5716F2B8U,
0xB03ADA37U,0xF0500C0DU,0xF01C1F04U,0x0200B3FFU,0xAE0CF51AU,0x3CB574B2U,0x25837A58U,0xDC0921BDU,
0xD19113F9U,0x7CA92FF6U,0x94324773U,0x22F54701U,0x3AE5E581U,0x37C2DADCU,0xC8B57634U,0x9AF3DDA7U,
0xA9446146U,0x0FD0030EU,0xECC8C73EU,0xA4751E41U,0xE238CD99U,0x3BEA0E2FU,0x3280BBA1U,0x183EB331U,
0x4E548B38U,0x4F6DB908U,0x6F420D03U,0xF60A04BFU,0x2CB81290U,0x24977C79U,0x5679B072U,0xBCAF89AFU,
0xDE9A771FU,0xD9930810U,0xB38BAE12U,0xDCCF3F2EU,0x5512721FU,0x2E6B7124U,0x501ADDE6U,0x9F84CD87U,
0x7A584718U,0x7408DA17U,0xBC9F9ABCU,0xE94B7D8CU,0xEC7AEC3AU,0xDB851DFAU,0x63094366U,0xC464C3D2U,
0xEF1C1847U,0x3215D908U,0xDD433B37U,0x24C2BA16U,0x12A14D43U,0x2A65C451U,0x50940002U,0x133AE4DDU,
0x71DFF89EU,0x10314E55U,0x81AC77D6U,0x5F11199BU,0x043556F1U,0xD7A3C76BU,0x3C11183BU,0x5924A509U,
0xF28FE6EDU,0x97F1FBFAU,0x9EBABF2CU,0x1E153C6EU,0x86E34570U,0xEAE96FB1U,0x860E5E0AU,0x5A3E2AB3U,
0x771FE71CU,0x4E3D06FAU,0x2965DCB9U,0x99E71D0FU,0x803E89D6U,0x5266C825U,0x2E4CC978U,0x9C10B36AU,
0xC6150EBAU,0x94E2EA78U,0xA5FC3C53U,0x1E0A2DF4U,0xF2F74EA7U,0x361D2B3DU,0x1939260FU,0x19C27960U,
0x5223A708U,0xF71312B6U,0xEBADFE6EU,0xEAC31F66U,0xE3BC4595U,0xA67BC883U,0xB17F37D1U,0x018CFF28U,
0xC332DDEFU,0xBE6C5AA5U,0x65582185U,0x68AB9802U,0xEECEA50FU,0xDB2F953BU,0x2AEF7DADU,0x5B6E2F84U,
0x1521B628U,0x29076170U,0xECDD4775U,0x619F1510U,0x13CCA830U,0xEB61BD96U,0x0334FE1EU,0xAA0363CFU,
0xB5735C90U,0x4C70A239U,0xD59E9E0BU,0xCBAADE14U,0xEECC86BCU,0x60622CA7U,0x9CAB5CABU,0xB2F3846EU,
0x648B1EAFU,0x19BDF0CAU,0xA02369B9U,0x655ABB50U,0x40685A32U,0x3C2AB4B3U,0x319EE9D5U,0xC021B8F7U,
0x9B540B19U,0x875FA099U,0x95F7997EU,0x623D7DA8U,0xF837889AU,0x97E32D77U,0x11ED935FU,0x16681281U,
0x0E358829U,0xC7E61FD6U,0x96DEDFA1U,0x7858BA99U,0x57F584A5U,0x1B227263U,0x9B83C3FFU,0x1AC24696U,
0xCDB30AEBU,0x532E3054U,0x8FD948E4U,0x6DBC3128U,0x58EBF2EFU,0x34C6FFEAU,0xFE28ED61U,0xEE7C3C73U,
0x5D4A14D9U,0xE864B7E3U,0x42105D14U,0x203E13E0U,0x45EEE2B6U,0xA3AAABEAU,0xDB6C4F15U,0xFACB4FD0U,
0xC742F442U,0xEF6ABBB5U,0x654F3B1DU,0x41CD2105U,0xD81E799EU,0x86854DC7U,0xE44B476AU,0x3D816250U,
0xCF62A1F2U,0x5B8D2646U,0xFC8883A0U,0xC1C7B6A3U,0x7F1524C3U,0x69CB7492U,0x47848A0BU,0x5692B285U,
0x095BBF00U,0xAD19489DU,0x1462B174U,0x23820E00U,0x58428D2AU,0x0C55F5EAU,0x1DADF43EU,0x233F7061U,
0x3372F092U,0x8D937E41U,0xD65FECF1U,0x6C223BDBU,0x7CDE3759U,0xCBEE7460U,0x4085F2A7U,0xCE77326EU,
0xA6078084U,0x19F8509EU,0xE8EFD855U,0x61D99735U,0xA969A7AAU,0xC50C06C2U,0x5A04ABFCU,0x800BCADCU,
0x9E447A2EU,0xC3453484U,0xFDD56705U,0x0E1E9EC9U,0xDB73DBD3U,0x105588CDU,0x675FDA79U,0xE3674340U,
0xC5C43465U,0x713E38D8U,0x3D28F89EU,0xF16DFF20U,0x153E21E7U,0x8FB03D4AU,0xE6E39F2BU,0xDB83ADF7U,
},{
0xE93D5A68U,0x948140F7U,0xF64C261CU,0x94692934U,0x411520F7U,0x7602D4F7U,0xBCF46B2EU,0xD4A20068U,
0xD4082471U,0x3320F46AU,0x43B7D4B7U,0x500061AFU,0x1E39F62EU,0x97244546U,0x14214F74U,0xBF8B8840U,
0x4D95FC1DU,0x96B591AFU,0x70F4DDD3U,0x66A02F45U,0xBFBC09ECU,0x03BD9785U,0x7FAC6DD0U,0x31CB8504U,
0x96EB27B3U,0x55FD3941U,0xDA2547E6U,0xABCA0A9AU,0x28507825U,0x530429F4U,0x0A2C86DAU,0xE9B66DFBU,
0x68DC1462U,0xD7486900U,0x680EC0A4U,0x27A18DEEU,0x4F3FFEA2U,0xE887AD8CU,0xB58CE006U,0x7AF4D6B6U,
0xAACE1E7CU,0xD3375FECU,0xCE78A399U,0x406B2A42U,0x20FE9E35U,0xD9F385B9U,0xEE39D7ABU,0x3B124E8BU,
0x1DC9FAF7U,0x4B6D1856U,0x26A36631U,0xEAE397B2U,0x3A6EFA74U,0xDD5B4332U,0x6841E7F7U,0xCA7820FBU,
0xFB0AF54EU,0xD8FEB397U,0x454056ACU,0xBA489527U,0x55533A3AU,0x20838D87U,0xFE6BA9B7U,0xD096954BU,
0x55A867BCU,0xA1159A58U,0xCCA92963U,0x99E1DB33U,0xA62A4A56U,0x3F3125F9U,0x5EF47E1CU,0x9029317CU,
0xFDF8E802U,0x04272F70U,0x80BB155CU,0x05282CE3U,0x95C11548U,0xE4C66D22U,0x48C1133FU,0xC70F86DCU,
0x07F9C9EEU,0x41041F0FU,0x404779A4U,0x5D886E17U,0x325F51EBU,0xD59BC0D1U,0xF2BCC18FU,0x41113564U,
0x257B7834U,0x602A9C60U,0xDFF8E8A3U,0x1F636C1BU,0x0E12B4C2U,0x02E1329EU,0xAF664FD1U,0xCAD18115U,
0x6B2395E0U,0x333E92E1U,0x3B240B62U,0xEEBEB922U,0x85B2A20EU,0xE6BA0D99U,0xDE720C8CU,0x2DA2F728U,
0xD0127845U,0x95B794FDU,0x647D0862U,0xE7CCF5F0U,0x5449A36FU,0x877D48FAU,0xC39DFD27U,0xF33E8D1EU,
0x0A476341U,0x992EFF74U,0x3A6F6EABU,0xF4F8FD37U,0xA812DC60U,0xA1EBDDF8U,0x991BE14CU,0xDB6E6B0DU,
0xC67B5510U,0x6D672C37U,0x2765D43BU,0xDCD0E804U,0xF1290DC7U,0xCC00FFA3U,0xB5390F92U,0x690FED0BU,
0x667B9FFBU,0xCEDB7D9CU,0xA091CF0BU,0xD9155EA3U,0xBB132F88U,0x515BAD24U,0x7B9479BFU,0x763BD6EBU,
0x37392EB3U,0xCC115979U,0x8026E297U,0xF42E312DU,0x6842ADA7U,0xC66A2B3BU,0x12754CCCU,0x782EF11CU,
0x6A124237U,0xB79251E7U,0x06A1BBE6U,0x4BFB6350U,0x1A6B1018U,0x11CAEDFAU,0x3D25BDD8U,0xE2E1C3C9U,
0x44421659U,0x0A121386U,0xD90CEC6EU,0xD5ABEA2AU,0x64AF674EU,0xDA86A85FU,0xBEBFE988U,0x64E4C3FEU,
0x9DBC8057U,0xF0F7C086U,0x60787BF8U,0x6003604DU,0xD1FD8346U,0xF6381FB0U,0x7745AE04U,0xD736FCCCU,
0x83426B33U,0xF01EAB71U,0xB0804187U,0x3C005E5FU,0x77A057BEU,0xBDE8AE24U,0x55464299U,0xBF582E61U,
0x4E58F48FU,0xF2DDFDA2U,0xF474EF38U,0x8789BDC2U,0x5366F9C3U,0xC8B38E74U,0xB475F255U,0x46FCD9B9U,
0x7AEB2661U,0x8B1DDF84U,0x846A0E79U,0x915F95E2U,0x466E598EU,0x20B45770U,0x8CD55591U,0xC902DE4CU,
0xB90BACE1U,0xBB8205D0U,0x11A86248U,0x7574A99EU,0xB77F19B6U,0xE0A9DC09U,0x662D09A1U,0xC4324633U,
0xE85A1F02U,0x09F0BE8CU,0x4A99A025U,0x1D6EFE10U,0x1AB93D1DU,0x0BA5A4DFU,0xA186F20FU,0x2868F169U,
0xDCB7DA83U,0x573906FEU,0xA1E2CE9BU,0x4FCD7F52U,0x50115E01U,0xA70683FAU,0xA002B5C4U,0x0DE6D027U,
0x9AF88C27U,0x773F8641U,0xC3604C06U,0x61A806B5U,0xF0177A28U,0xC0F586E0U,0x006058AAU,0x30DC7D62U,
0x11E69ED7U,0x2338EA63U,0x53C2DD94U,0xC2C21634U,0xBBCBEE56U,0x90BCB6DEU,0xEBFC7DA1U,0xCE591D76U,
0x6F05E409U,0x4B7C0188U,0x39720A3DU,0x7C927C24U,0x86E3725FU,0x724D9DB9U,0x1AC15BB4U,0xD39EB8FCU,
0xED545578U,0x08FCA5B5U,0xD83D7CD3U,0x4DAD0FC4U,0x1E50EF5EU,0xB161E6F8U,0xA28514D9U,0x6C51133CU,
0x6FD5C7E7U,0x56E14EC4U,0x362ABFCEU,0xDDC6C837U,0xD79A3234U,0x92638212U,0x670EFA8EU,0x406000E0U,
},{
0x3A39CE37U,0xD3FAF5CFU,0xABC27737U,0x5AC52D1BU,0x5CB0679EU,0x4FA33742U,0xD3822740U,0x99BC9BBEU,
0xD5118E9DU,0xBF0F7315U,0xD62D1C7EU,0xC700C47BU,0xB78C1B6BU,0x21A19045U,0xB26EB1BEU,0x6A366EB4U,
0x5748AB2FU,0xBC946E79U,0xC6A376D2U,0x6549C2C8U,0x530FF8EEU,0x468DDE7DU,0xD5730A1DU,0x4CD04DC6U,
0x2939BBDBU,0xA9BA4650U,0xAC9526E8U,0xBE5EE304U,0xA1FAD5F0U,0x6A2D519AU,0x63EF8CE2U,0x9A86EE22U,
0xC089C2B8U,0x43242EF6U,0xA51E03AAU,0x9CF2D0A4U,0x83C061BAU,0x9BE96A4DU,0x8FE51550U,0xBA645BD6U,
0x2826A2F9U,0xA73A3AE1U,0x4BA99586U,0xEF5562E9U,0xC72FEFD3U,0xF752F7DAU,0x3F046F69U,0x77FA0A59U,
0x80E4A915U,0x87B08601U,0x9B09E6ADU,0x3B3EE593U,0xE990FD5AU,0x9E34D797U,0x2CF0B7D9U,0x022B8B51U,
0x96D5AC3AU,0x017DA67DU,0xD1CF3ED6U,0x7C7D2D28U,0x1F9F25CFU,0xADF2B89BU,0x5AD6B472U,0x5A88F54CU,
0xE029AC71U,0xE019A5E6U,0x47B0ACFDU,0xED93FA9BU,0xE8D3C48DU,0x283B57CCU,0xF8D56629U,0x79132E28U,
0x785F0191U,0xED756055U,0xF7960E44U,0xE3D35E8CU,0x15056DD4U,0x88F46DBAU,0x03A16125U,0x0564F0BDU,
0xC3EB9E15U,0x3C9057A2U,0x97271AECU,0xA93A072AU,0x1B3F6D9BU,0x1E6321F5U,0xF59C66FBU,0x26DCF319U,
0x7533D928U,0xB155FDF5U,0x03563482U,0x8ABA3CBBU,0x28517711U,0xC20AD9F8U,0xABCC5167U,0xCCAD925FU,
0x4DE81751U,0x3830DC8EU,0x379D5862U,0x9320F991U,0xEA7A90C2U,0xFB3E7BCEU,0x5121CE64U,0x774FBE32U,
0xA8B6E37EU,0xC3293D46U,0x48DE5369U,0x6413E680U,0xA2AE0810U,0xDD6DB224U,0x69852DFDU,0x09072166U,
0xB39A460AU,0x6445C0DDU,0x586CDECFU,0x1C20C8AEU,0x5BBEF7DDU,0x1B588D40U,0xCCD2017FU,0x6BB4E3BBU,
0xDDA26A7EU,0x3A59FF45U,0x3E350A44U,0xBCB4CDD5U,0x72EACEA8U,0xFA6484BBU,0x8D6612AEU,0xBF3C6F47U,
0xD29BE463U,0x542F5D9EU,0xAEC2771BU,0xF64E6370U,0x740E0D8DU,0xE75B1357U,0xF8721671U,0xAF537D5DU,
0x4040CB08U,0x4EB4E2CCU,0x34D2466AU,0x0115AF84U,0xE1B00428U,0x95983A1DU,0x06B89FB4U,0xCE6EA048U,
0x6F3F3B82U,0x3520AB82U,0x011A1D4BU,0x277227F8U,0x611560B1U,0xE7933FDCU,0xBB3A792BU,0x344525BDU,
0xA08839E1U,0x51CE794BU,0x2F32C9B7U,0xA01FBAC9U,0xE01CC87EU,0xBCC7D1F6U,0xCF0111C3U,0xA1E8AAC7U,
0x1A908749U,0xD44FBD9AU,0xD0DADECBU,0xD50ADA38U,0x0339C32AU,0xC6913667U,0x8DF9317CU,0xE0B12B4FU,
0xF79E59B7U,0x43F5BB3AU,0xF2D519FFU,0x27D9459CU,0xBF97222CU,0x15E6FC2AU,0x0F91FC71U,0x9B941525U,
0xFAE59361U,0xCEB69CEBU,0xC2A86459U,0x12BAA8D1U,0xB6C1075EU,0xE3056A0CU,0x10D25065U,0xCB03A442U,
0xE0EC6E0EU,0x1698DB3BU,0x4C98A0BEU,0x3278E964U,0x9F1F9532U,0xE0D392DFU,0xD3A0342BU,0x8971F21EU,
0x1B0A7441U,0x4BA3348CU,0xC5BE7120U,0xC37632D8U,0xDF359F8DU,0x9B992F2EU,0xE60B6F47U,0x0FE3F11DU,
0xE54CDA54U,0x1EDAD891U,0xCE6279CFU,0xCD3E7E6FU,0x1618B166U,0xFD2C1D05U,0x848FD2C5U,0xF6FB2299U,
0xF523F357U,0xA6327623U,0x93A83531U,0x56CCCD02U,0xACF08162U,0x5A75EBB5U,0x6E163697U,0x88D273CCU,
0xDE966292U,0x81B949D0U,0x4C50901BU,0x71C65614U,0xE6C6C7BDU,0x327A140AU,0x45E1D006U,0xC3F27B9AU,
0xC9AA53FDU,0x62A80F00U,0xBB25BFE2U,0x35BDD2F6U,0x71126905U,0xB2040222U,0xB6CBCF7CU,0xCD769C2BU,
0x53113EC0U,0x1640E3D3U,0x38ABBD60U,0x2547ADF0U,0xBA38209CU,0xF746CE76U,0x77AFA1C5U,0x20756060U,
0x85CBFE4EU,0x8AE88DD8U,0x7AAAF9B0U,0x4CF9AA7EU,0x1948C25CU,0x02FB8A8CU,0x01C36AE4U,0xD6EBE1F9U,
0x90D4F869U,0xA65CDEA0U,0x3F09252DU,0xC208E69FU,0xB74E6132U,0xCE77E25BU,0x578FDFE3U,0x3AC372E6U
}
};

114
REDALERT/BLOWFISH.H Normal file
View File

@ -0,0 +1,114 @@
//
// 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/BLOWFISH.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 : BLOWFISH.H *
* *
* Programmer : Joe L. Bostic *
* *
* Start Date : 04/14/96 *
* *
* Last Update : April 14, 1996 [JLB] *
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef BLOWFISH_H
#define BLOWFISH_H
#include <limits.h>
/*
** The "bool" integral type was defined by the C++ committee in
** November of '94. Until the compiler supports this, use the following
** definition.
*/
#ifndef __BORLANDC__
#ifndef TRUE_FALSE_DEFINED
#define TRUE_FALSE_DEFINED
enum {false=0,true=1};
typedef int bool;
#endif
#endif
/*
** This engine will process data blocks by encryption and decryption.
** The "Blowfish" algorithm is in the public domain. It uses
** a Feistal network (similar to IDEA). It has no known
** weaknesses, but is still relatively new. Blowfish is particularly strong
** against brute force attacks. It is also quite strong against linear and
** differential cryptanalysis. Its weakness is that it takes a relatively
** long time to set up with a new key (1/100th of a second on a P6-200).
** The time to set up a key is equivalent to encrypting 4240 bytes.
*/
class BlowfishEngine {
public:
BlowfishEngine(void) : IsKeyed(false) {}
~BlowfishEngine(void);
void Submit_Key(void const * key, int length);
int Encrypt(void const * plaintext, int length, void * cyphertext);
int Decrypt(void const * cyphertext, int length, void * plaintext);
/*
** This is the maximum key length supported.
*/
enum {MAX_KEY_LENGTH=56};
private:
bool IsKeyed;
void Sub_Key_Encrypt(unsigned long & left, unsigned long & right);
void Process_Block(void const * plaintext, void * cyphertext, unsigned long const * ptable);
void Initialize_Tables(void);
enum {
ROUNDS = 16, // Feistal round count (16 is standard).
BYTES_PER_BLOCK=8 // The number of bytes in each cypher block (don't change).
};
/*
** Initialization data for sub keys. The initial values are constant and
** filled with a number generated from pi. Thus they are not random but
** they don't hold a weak pattern either.
*/
static unsigned long const P_Init[(int)ROUNDS+2];
static unsigned long const S_Init[4][UCHAR_MAX+1];
/*
** Permutation tables for encryption and decryption.
*/
unsigned long P_Encrypt[(int)ROUNDS+2];
unsigned long P_Decrypt[(int)ROUNDS+2];
/*
** S-Box tables (four).
*/
unsigned long bf_S[4][UCHAR_MAX+1];
};
#endif

199
REDALERT/BLOWPIPE.CPP Normal file
View File

@ -0,0 +1,199 @@
//
// 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/BLOWPIPE.CPP 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 : BLOWPIPE.CPP *
* *
* Programmer : Joe L. Bostic *
* *
* Start Date : 06/30/96 *
* *
* Last Update : July 3, 1996 [JLB] *
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* BlowPipe::Flush -- Flushes any pending data out the pipe. *
* BlowPipe::Key -- Submit a key to the blowfish pipe handler. *
* BlowPipe::Put -- Submit a block of data for encrypt/decrypt. *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "blowpipe.h"
#include <string.h>
#include <assert.h>
/***********************************************************************************************
* BlowPipe::Flush -- Flushes any pending data out the pipe. *
* *
* If there is any pending data in the holding buffer, then this routine will force it to *
* be flushed out the end of the pipe. *
* *
* INPUT: none *
* *
* OUTPUT: Returns with the actual number of bytes output at the end final distant pipe *
* segment in the chain. *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 07/03/1996 JLB : Created. *
*=============================================================================================*/
int BlowPipe::Flush(void)
{
int total = 0;
if (Counter > 0 && BF != NULL) {
total += Pipe::Put(Buffer, Counter);
}
Counter = 0;
total += Pipe::Flush();
return(total);
}
/***********************************************************************************************
* BlowPipe::Put -- Submit a block of data for encrypt/decrypt. *
* *
* This will take the data block specified and process it before passing it on to the next *
* link in the pipe chain. A key must be submitted before this routine will actually perform*
* any processing. Prior to key submission, the data is passed through unchanged. *
* *
* INPUT: source -- Pointer to the buffer that contains the data to pass through. *
* *
* length -- The length of the data in the buffer. *
* *
* OUTPUT: Returns with then actual number of bytes output at the final distant end link in *
* the pipe chain. *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 07/03/1996 JLB : Created. *
*=============================================================================================*/
int BlowPipe::Put(void const * source, int slen)
{
if (source == NULL || slen < 1) {
return(Pipe::Put(source, slen));
}
/*
** If there is no blowfish engine present, then merely pass the data through
** unchanged in any way.
*/
if (BF == NULL) {
return(Pipe::Put(source, slen));
}
int total = 0;
/*
** If there is a partial block accumulated, then tag on the new data to
** this block and process it if the block is full. Proceed with the bulk
** processing if there are any left over bytes from this step. This step
** can be skipped if there are no pending bytes in the buffer.
*/
if (Counter) {
int sublen = ((int)sizeof(Buffer)-Counter < slen) ? (sizeof(Buffer)-Counter) : slen;
memmove(&Buffer[Counter], source, sublen);
Counter += sublen;
source = ((char *)source) + sublen;
slen -= sublen;
if (Counter == sizeof(Buffer)) {
if (Control == DECRYPT) {
BF->Decrypt(Buffer, sizeof(Buffer), Buffer);
} else {
BF->Encrypt(Buffer, sizeof(Buffer), Buffer);
}
total += Pipe::Put(Buffer, sizeof(Buffer));
Counter = 0;
}
}
/*
** Process the input data in blocks until there is not enough
** source data to fill a full block of data.
*/
while (slen >= sizeof(Buffer)) {
if (Control == DECRYPT) {
BF->Decrypt(source, sizeof(Buffer), Buffer);
} else {
BF->Encrypt(source, sizeof(Buffer), Buffer);
}
total += Pipe::Put(Buffer, sizeof(Buffer));
source = ((char *)source) + sizeof(Buffer);
slen -= sizeof(Buffer);
}
/*
** If there are any left over bytes, then they must be less than the size of
** the staging buffer. Store the bytes in the staging buffer for later
** processing.
*/
if (slen > 0) {
memmove(Buffer, source, slen);
Counter = slen;
}
/*
** Return with the total number of bytes flushed out to the final end of the
** pipe chain.
*/
return(total);
}
/***********************************************************************************************
* BlowPipe::Key -- Submit a key to the blowfish pipe handler. *
* *
* This routine will take the key provided and use it to process the data that passes *
* through this pipe. Prior to a key being submitted, the data passes through the pipe *
* unchanged. *
* *
* INPUT: key -- Pointer to the key data to use. *
* *
* length-- The length of the key. The key length must not be greater than 56 bytes. *
* *
* OUTPUT: none *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 07/03/1996 JLB : Created. *
*=============================================================================================*/
void BlowPipe::Key(void const * key, int length)
{
/*
** Create the blowfish engine if one isn't already present.
*/
if (BF == NULL) {
BF = new BlowfishEngine;
}
assert(BF != NULL);
if (BF != NULL) {
BF->Submit_Key(key, length);
}
}

82
REDALERT/BLOWPIPE.H Normal file
View File

@ -0,0 +1,82 @@
//
// 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/BLOWPIPE.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 : BLOWPIPE.H *
* *
* Programmer : Joe L. Bostic *
* *
* Start Date : 06/30/96 *
* *
* Last Update : June 30, 1996 [JLB] *
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef BLOWPIPE_H
#define BLOWPIPE_H
#include "pipe.h"
#include "blowfish.h"
/*
** Performs Blowfish encryption/decryption on the data stream that is piped
** through this class.
*/
class BlowPipe : public Pipe
{
public:
typedef enum CryptControl {
ENCRYPT,
DECRYPT
} CryptControl;
BlowPipe(CryptControl control) : BF(NULL), Counter(0), Control(control) {}
virtual ~BlowPipe(void) {delete BF;BF = NULL;}
virtual int Flush(void);
virtual int Put(void const * source, int slen);
// Submit key for blowfish engine.
void Key(void const * key, int length);
protected:
/*
** The Blowfish engine used for encryption/decryption. If this pointer is
** NULL, then this indicates that the blowfish engine is not active and no
** key has been submitted. All data would pass through this pipe unchanged
** in that case.
*/
BlowfishEngine * BF;
private:
char Buffer[8];
int Counter;
CryptControl Control;
BlowPipe(BlowPipe & rvalue);
BlowPipe & operator = (BlowPipe const & pipe);
};
#endif

158
REDALERT/BLWSTRAW.CPP Normal file
View File

@ -0,0 +1,158 @@
//
// 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/BLWSTRAW.CPP 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 : BLWSTRAW.CPP *
* *
* Programmer : Joe L. Bostic *
* *
* Start Date : 07/02/96 *
* *
* Last Update : July 3, 1996 [JLB] *
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* BlowStraw::Get -- Fetch a block of data from the straw. *
* BlowStraw::Key -- Submit a key to the Blowfish straw. *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "blwstraw.h"
#include <string.h>
#include <assert.h>
/***********************************************************************************************
* BlowStraw::Get -- Fetch a block of data from the straw. *
* *
* This routine will take a block of data from the straw and process it according to the *
* encrypt/decrypt flag and the key supplied. Prior to a key be supplied, the data passes *
* through this straw unchanged. *
* *
* INPUT: source -- Pointer to the buffer to hold the data being requested. *
* *
* length -- The length of the data being requested. *
* *
* OUTPUT: Returns with the actual number of bytes stored into the buffer. If the number *
* returned is less than the number requested, then this indicates that the data *
* source has been exhausted. *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 07/03/1996 JLB : Created. *
*=============================================================================================*/
int BlowStraw::Get(void * source, int slen)
{
/*
** Verify the parameter for legality.
*/
if (source == NULL || slen <= 0) {
return(0);
}
/*
** If there is no blowfish engine present, then merely pass the data through
** unchanged.
*/
if (BF == NULL) {
return(Straw::Get(source, slen));
}
int total = 0;
while (slen > 0) {
/*
** If there are any left over bytes in the buffer, pass them
** through first.
*/
if (Counter > 0) {
int sublen = (slen < Counter) ? slen : Counter;
memmove(source, &Buffer[sizeof(Buffer)-Counter], sublen);
Counter -= sublen;
source = ((char *)source) + sublen;
slen -= sublen;
total += sublen;
}
if (slen == 0) break;
/*
** Fetch and encrypt/decrypt the next block.
*/
int incount = Straw::Get(Buffer, sizeof(Buffer));
if (incount == 0) break;
/*
** Only full blocks are processed. Partial blocks are
** merely passed through unchanged.
*/
if (incount == sizeof(Buffer)) {
if (Control == DECRYPT) {
BF->Decrypt(Buffer, incount, Buffer);
} else {
BF->Encrypt(Buffer, incount, Buffer);
}
} else {
memmove(&Buffer[sizeof(Buffer)-incount], Buffer, incount);
}
Counter = incount;
}
/*
** Return with the total number of bytes placed into the buffer.
*/
return(total);
}
/***********************************************************************************************
* BlowStraw::Key -- Submit a key to the Blowfish straw. *
* *
* This will take the key specified and use it to process the data that flows through this *
* straw segment. Prior to a key being submitted, the data will flow through unchanged. *
* *
* INPUT: key -- Pointer to the key to submit. *
* *
* length-- The length of the key. The length must not exceed 56 bytes. *
* *
* OUTPUT: none *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 07/03/1996 JLB : Created. *
*=============================================================================================*/
void BlowStraw::Key(void const * key, int length)
{
/*
** Create the blowfish engine if one isn't already present.
*/
if (BF == NULL) {
BF = new BlowfishEngine;
}
assert(BF != NULL);
if (BF != NULL) {
BF->Submit_Key(key, length);
}
}

84
REDALERT/BLWSTRAW.H Normal file
View File

@ -0,0 +1,84 @@
//
// 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/BLWSTRAW.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 : BLWSTRAW.H *
* *
* Programmer : Joe L. Bostic *
* *
* Start Date : 07/02/96 *
* *
* Last Update : July 2, 1996 [JLB] *
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef BLWSTRAW_H
#define BLWSTRAW_H
#include "straw.h"
#include "blowfish.h"
/*
** Performs Blowfish encryption/decryption to the data that is drawn through this straw. The
** process is controlled by the key which must be submitted to the class before any data
** manipulation will occur. The Blowfish algorithm is symmetric, thus the same key is used
** for encryption as is for decryption.
*/
class BlowStraw : public Straw
{
public:
typedef enum CryptControl {
ENCRYPT,
DECRYPT
} CryptControl;
BlowStraw(CryptControl control) : BF(NULL), Counter(0), Control(control) {}
virtual ~BlowStraw(void) {delete BF;BF = NULL;}
virtual int Get(void * source, int slen);
// Submit key for blowfish engine.
void Key(void const * key, int length);
protected:
/*
** The Blowfish engine used for encryption/decryption. If this pointer is
** NULL, then this indicates that the blowfish engine is not active and no
** key has been submitted. All data would pass through this straw unchanged
** in that case.
*/
BlowfishEngine * BF;
private:
char Buffer[8];
int Counter;
CryptControl Control;
BlowStraw(BlowStraw & rvalue);
BlowStraw & operator = (BlowStraw const & straw);
};
#endif

186
REDALERT/BMP8.CPP Normal file
View File

@ -0,0 +1,186 @@
//
// 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
#include "bmp8.h"
//***********************************************************************************************
BMP8::~BMP8()
{
// free resources
if( hBitmap )
::DeleteObject( hBitmap );
if( hPal )
::DeleteObject( hPal );
}
//***********************************************************************************************
bool BMP8::Init( const char* szFile, HWND hWnd )
{
int i;
char string[128];
DWORD dwRead;
BITMAPFILEHEADER bitmapHeader;
BITMAPINFOHEADER bitmapInfoHeader;
LPLOGPALETTE lpLogPalette;
char *palData;
HGLOBAL hmem2;
LPVOID lpvBits;
PAINTSTRUCT ps;
HDC hdc;
HPALETTE select;
UINT realize;
RECT rect;
// Remember window handle for use later.
this->hWnd = hWnd;
// Retrieve a handle identifying the file.
HANDLE hFile = ::CreateFile(
szFile,
GENERIC_READ,
FILE_SHARE_READ,
(LPSECURITY_ATTRIBUTES)NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_READONLY,
(HANDLE)NULL );
if( !hFile )
return false;
// Retrieve the BITMAPFILEHEADER structure.
::ReadFile( hFile, &bitmapHeader, sizeof(BITMAPFILEHEADER), &dwRead, (LPOVERLAPPED)NULL );
// Retrieve the BITMAPFILEHEADER structure.
::ReadFile( hFile, &bitmapInfoHeader, sizeof(BITMAPINFOHEADER), &dwRead, (LPOVERLAPPED)NULL );
// Allocate memory for the BITMAPINFO structure.
HGLOBAL infoHeaderMem = ::GlobalAlloc( GHND, sizeof(BITMAPINFOHEADER) + ((1<<bitmapInfoHeader.biBitCount) * sizeof(RGBQUAD)) );
LPBITMAPINFO lpHeaderMem = (LPBITMAPINFO)::GlobalLock( infoHeaderMem );
// Load BITMAPINFOHEADER into the BITMAPINFO structure.
lpHeaderMem->bmiHeader.biSize = bitmapInfoHeader.biSize;
lpHeaderMem->bmiHeader.biWidth = bitmapInfoHeader.biWidth;
lpHeaderMem->bmiHeader.biHeight = bitmapInfoHeader.biHeight;
lpHeaderMem->bmiHeader.biPlanes = bitmapInfoHeader.biPlanes;
lpHeaderMem->bmiHeader.biBitCount = bitmapInfoHeader.biBitCount;
lpHeaderMem->bmiHeader.biCompression = bitmapInfoHeader.biCompression;
lpHeaderMem->bmiHeader.biSizeImage = bitmapInfoHeader.biSizeImage;
lpHeaderMem->bmiHeader.biXPelsPerMeter = bitmapInfoHeader.biXPelsPerMeter;
lpHeaderMem->bmiHeader.biYPelsPerMeter = bitmapInfoHeader.biYPelsPerMeter;
lpHeaderMem->bmiHeader.biClrUsed = bitmapInfoHeader.biClrUsed;
lpHeaderMem->bmiHeader.biClrImportant = bitmapInfoHeader.biClrImportant;
// Retrieve the color table.
// 1 << bitmapInfoHeader.biBitCount == 2 ^ bitmapInfoHeader.biBitCount
::ReadFile( hFile, lpHeaderMem->bmiColors, ((1<<bitmapInfoHeader.biBitCount) * sizeof(RGBQUAD)),
&dwRead, (LPOVERLAPPED)NULL );
lpLogPalette = (LPLOGPALETTE)new char[ (sizeof(LOGPALETTE) + sizeof(PALETTEENTRY)*256) ];
lpLogPalette->palVersion=0x300;
lpLogPalette->palNumEntries=256;
palData = (char*)lpHeaderMem->bmiColors;
for( i = 0; i < 256; i++ )
{
lpLogPalette->palPalEntry[i].peRed = *palData++;
lpLogPalette->palPalEntry[i].peGreen = *palData++;
lpLogPalette->palPalEntry[i].peBlue = *palData++;
lpLogPalette->palPalEntry[i].peFlags = *palData++;
}
hPal = ::CreatePalette( lpLogPalette );
delete [] lpLogPalette;
// Allocate memory for the required number of bytes.
hmem2 = ::GlobalAlloc( GHND, (bitmapHeader.bfSize - bitmapHeader.bfOffBits) );
lpvBits = ::GlobalLock( hmem2 );
// Retrieve the bitmap data.
::ReadFile( hFile, lpvBits, (bitmapHeader.bfSize - bitmapHeader.bfOffBits), &dwRead, (LPOVERLAPPED)NULL );
// Create a bitmap from the data stored in the .BMP file.
hdc = ::GetDC( hWnd );
select = ::SelectPalette( hdc, hPal, 0 );
if( !select )
return false;
realize = ::RealizePalette( hdc );
if( realize == GDI_ERROR )
return false;
hBMP = ::CreateDIBitmap( hdc, &bitmapInfoHeader, CBM_INIT, lpvBits, lpHeaderMem, DIB_RGB_COLORS );
::ReleaseDC( hWnd, hdc );
// Unlock the global memory objects and close the .BMP file.
::GlobalUnlock( infoHeaderMem );
::GlobalUnlock( hmem2 );
::CloseHandle( hFile );
if( !hBMP )
return false;
return true;
}
bit8 BMP8::drawBmp(void)
{
// Paint the window (and draw the bitmap).
PAINTSTRUCT ps;
HDC hdc;
char string[128];
InvalidateRect(WindowHandle_,NULL,FALSE); // keep windows from screwing up the
// redrawing (as much).
hdc=BeginPaint(WindowHandle_,&ps);
//Do palette stuff
HPALETTE select=SelectPalette(ps.hdc,PalHandle_,0);
if (select==NULL)
{
sprintf(string,"Select Pal Fail: %d",GetLastError());
MessageBox(NULL,string,"OK",MB_OK);
}
UINT realize=RealizePalette(ps.hdc);
if (realize==GDI_ERROR)
{
sprintf(string,"Realize Pal Fail: %d",GetLastError());
MessageBox(NULL,string,"OK",MB_OK);
}
HDC hdcMem = CreateCompatibleDC(ps.hdc);
SelectObject(hdcMem, BitmapHandle_);
BITMAP bm;
GetObject(BitmapHandle_, sizeof(BITMAP), (LPSTR) &bm);
/// for non-stretching version
///////BitBlt(ps.hdc, 0, 0, bm.bmWidth, bm.bmHeight, hdcMem, 0, 0, SRCCOPY);
RECT clientRect;
GetClientRect(WindowHandle_,&clientRect);
SetStretchBltMode(ps.hdc,COLORONCOLOR);
StretchBlt(ps.hdc,0,0,clientRect.right,clientRect.bottom,hdcMem,0,0,bm.bmWidth,
bm.bmHeight,SRCCOPY);
DeleteDC(hdcMem);
EndPaint(WindowHandle_,&ps);
return(TRUE);
}

40
REDALERT/BMP8.H Normal file
View File

@ -0,0 +1,40 @@
//
// 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
#ifndef BMP8_H
#define BMP8_H
//#include<stdlib.h>
//#include<stdio.h>
//#include "wstypes.h"
//#include "winblows.h"
class BMP8
{
public:
BMP8() : hBMP( NULL ), hPal( NULL ), hWnd( NULL ) {}
~BMP8();
bool Init( const char* szFile, HWND hWnd );
bool Draw(void); // call this from your WM_PAINT message
private:
HBITMAP hBMP;
HPALETTE hPal;
HWND hWnd;
};
#endif

217
REDALERT/BUFF.CPP Normal file
View File

@ -0,0 +1,217 @@
//
// 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/BUFF.CPP 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 : BUFF.CPP *
* *
* Programmer : Joe L. Bostic *
* *
* Start Date : 07/29/96 *
* *
* Last Update : September 7, 1996 [JLB] *
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* Buffer::Buffer -- Constructor for buffer object. *
* Buffer::Buffer -- Copy constructor for buffer object. *
* Buffer::Buffer -- Self-allocating constructor for buffer object. *
* Buffer::Reset -- Clears the buffer object to null state. *
* Buffer::operator = -- Assignment operator for the buffer object. *
* Buffer::~Buffer -- Destructor for buffer object. *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "buff.h"
#include <stddef.h>
/***********************************************************************************************
* Buffer::Buffer -- Constructor for buffer object. *
* *
* This is the normal constructor for a buffer object. The buffer pointer and size are *
* specified as parameters. *
* *
* INPUT: buffer -- Pointer to the buffer. *
* *
* size -- The size of the buffer. *
* *
* OUTPUT: none *
* *
* WARNINGS: It is possible to construct a Buffer object that has a pointer but a size *
* value of zero. The Buffer object can still be used for its pointer, but it *
* any function that requires a size will fail. *
* *
* HISTORY: *
* 07/29/1996 JLB : Created. *
*=============================================================================================*/
Buffer::Buffer(void * buffer, long size) :
BufferPtr(buffer),
Size(size),
IsAllocated(false)
{
}
// Alternate constructor for char * pointer.
Buffer::Buffer(char * buffer, long size) :
BufferPtr(buffer),
Size(size),
IsAllocated(false)
{
}
// Alternate constructor for void const * pointer.
Buffer::Buffer(void const * buffer, long size) :
BufferPtr((void*)buffer),
Size(size),
IsAllocated(false)
{
}
/***********************************************************************************************
* Buffer::Buffer -- Self-allocating constructor for buffer object. *
* *
* This construtor for a buffer object will automatically allocate the bytes necessary *
* to fulfill the size requested. This object is also responsible for deleting the buffer *
* it allocated. *
* *
* INPUT: size -- The size of the buffer to allocated. *
* *
* OUTPUT: none *
* *
* WARNINGS: There is no way to tell if the allocation failed. To verify, call Get_Buffer *
* and compare with NULL. *
* *
* HISTORY: *
* 07/29/1996 JLB : Created. *
*=============================================================================================*/
Buffer::Buffer(long size) :
BufferPtr(NULL),
Size(size),
IsAllocated(false)
{
if (size > 0) {
BufferPtr = new char[size];
IsAllocated = true;
}
}
/***********************************************************************************************
* Buffer::Buffer -- Copy constructor for buffer object. *
* *
* This will make a duplicate of the specified buffer object. The ownership of the pointer *
* remains with the original object. This prevents multiple deletion of the same pointer. *
* *
* INPUT: buffer -- Reference to the buffer object to be dupilcated. *
* *
* OUTPUT: none *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 08/02/1996 JLB : Created. *
*=============================================================================================*/
Buffer::Buffer(Buffer const & buffer) :
IsAllocated(false)
{
BufferPtr = buffer.BufferPtr;
Size = buffer.Size;
}
/***********************************************************************************************
* Buffer::operator = -- Assignment operator for the buffer object. *
* *
* This will make a duplicate of the buffer object specified. Any buffer pointed to by the *
* left hand buffer will be lost (possibley freed as a result). *
* *
* INPUT: buffer -- Reference to the right hand buffer object. *
* *
* OUTPUT: Returns with a reference to the copied buffer object. *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 08/02/1996 JLB : Created. *
*=============================================================================================*/
Buffer & Buffer::operator = (Buffer const & buffer)
{
if (buffer != this) {
if (IsAllocated) {
delete [] BufferPtr;
}
IsAllocated = false;
BufferPtr = buffer.BufferPtr;
Size = buffer.Size;
}
return(*this);
}
/***********************************************************************************************
* Buffer::~Buffer -- Destructor for buffer object. *
* *
* This destructor will free any buffer it is responsible for. *
* *
* INPUT: none *
* *
* OUTPUT: none *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 07/29/1996 JLB : Created. *
*=============================================================================================*/
Buffer::~Buffer(void)
{
Reset();
}
/***********************************************************************************************
* Buffer::Reset -- Clears the buffer object to null state. *
* *
* This routine will bring the buffer object into a null (newly constructed) state. If *
* there was any buffer allocated or referred to by this object, it will be freed or *
* dereferenced as necessary. *
* *
* INPUT: none *
* *
* OUTPUT: none *
* *
* WARNINGS: This routine will free the buffer if it is responsible for doing so when *
* it is no longer referenced. *
* *
* HISTORY: *
* 09/07/1996 JLB : Created. *
*=============================================================================================*/
void Buffer::Reset(void)
{
if (IsAllocated) {
delete [] BufferPtr;
}
BufferPtr = NULL;
Size = 0;
IsAllocated = false;
}

96
REDALERT/BUFF.H Normal file
View File

@ -0,0 +1,96 @@
//
// 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/BUFF.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 : BUFF.H *
* *
* Programmer : Joe L. Bostic *
* *
* Start Date : 07/29/96 *
* *
* Last Update : July 29, 1996 [JLB] *
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef CCBUFF_H
#define CCBUFF_H
/*
** The "bool" integral type was defined by the C++ committee in
** November of '94. Until the compiler supports this, use the following
** definition.
*/
#ifndef __BORLANDC__
#ifndef TRUE_FALSE_DEFINED
#define TRUE_FALSE_DEFINED
enum {false=0,true=1};
typedef int bool;
#endif
#endif
/*
** A general purpose buffer pointer handler object. It holds not only the pointer to the
** buffer, but its size as well. By using this class instead of separate pointer and size
** values, function interfaces and algorithms become simpler to manage and understand.
*/
class Buffer {
public:
Buffer(char * ptr, long size=0);
Buffer(void * ptr=0, long size=0);
Buffer(void const * ptr, long size=0);
Buffer(long size);
Buffer(Buffer const & buffer);
~Buffer(void);
Buffer & operator = (Buffer const & buffer);
operator void * (void) const {return(BufferPtr);}
operator char * (void) const {return((char *)BufferPtr);}
void Reset(void);
void * Get_Buffer(void) const {return(BufferPtr);}
long Get_Size(void) const {return(Size);}
bool Is_Valid(void) const {return(BufferPtr != 0);}
protected:
/*
** Pointer to the buffer memory.
*/
void * BufferPtr;
/*
** The size of the buffer memory.
*/
long Size;
/*
** Was the buffer allocated by this class? If so, then this class
** will be responsible for freeing the buffer.
*/
bool IsAllocated;
};
#endif

98
REDALERT/BUFFERX.H Normal file
View File

@ -0,0 +1,98 @@
//
// 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/BUFFERX.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 : BUFFER.H *
* *
* Programmer : Joe L. Bostic *
* *
* Start Date : 05/04/96 *
* *
* Last Update : May 4, 1996 [JLB] *
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef BUFFERx_H
#define BUFFERx_H
#include "wwfile.h"
/*
** This is a transmuter interface designed to aid implementation of compression, encryption, or
** data analysis classes. The Transmuter should be derived into a class that performs the necessary
** processing.
*/
class Transmuter {
public:
Transmuter(void) : Output(0) {}
virtual ~Transmuter(void) {}
/*
** These are the interface function that are used to pass data to the transmuter. The
** default implementation of these functions do nothing other than pass the data onto
** the subsequent transmuter. For practical use, these functions should be overloaded to
** do something more useful.
*/
virtual void Attach(Transmuter * transmuter) {Output = transmuter;}
virtual void Flush(void) {if (Output) Output->Flush();}
virtual void Put(const void * input, unsigned length) {if (Output) Output->Put(input, length);}
protected:
/*
** Pointer to the output transmuter.
*/
Transmuter * Output;
};
class FileTransmuter {
public:
FileTransmuter(FileClass * file = NULL) : OutputFile(file) {}
virtual void Attach(FileClass * file) {OutputFile = file;}
virtual void Flush(void) {}
virtual void Put(const void * input, unsigned length) {if (OutputFile) OutputFile->Write(input, length);}
protected:
FileClass * OutputFile;
};
class BufferTransmuter {
public:
BufferTransmuter(void * buffer = NULL) : BufferPtr(buffer) {}
virtual void Attach(void * buffer) {BufferPtr = buffer;}
virtual void Flush(void) {}
virtual void Put(const void * input, unsigned length) {if (BufferPtr) {memcpy(BufferPtr, input, length);((char *&)BufferPtr) += length;}}
protected:
void * BufferPtr;
};
#endif

6054
REDALERT/BUILDING.CPP Normal file

File diff suppressed because it is too large Load Diff

361
REDALERT/BUILDING.H Normal file
View File

@ -0,0 +1,361 @@
//
// 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/BUILDING.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 : BUILDING.H *
* *
* Programmer : Joe L. Bostic *
* *
* Start Date : April 14, 1994 *
* *
* Last Update : April 14, 1994 [JLB] *
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef BUILDING_H
#define BUILDING_H
#include "radio.h"
#include "cargo.h"
#include "mission.h"
#include "bullet.h"
#include "target.h"
#include "factory.h"
#include "techno.h"
#define MAX_DOOR_STAGE 18 // # of frames of door opening on weapons factory
#define DOOR_OPEN_STAGE 9 // frame on which the door is entirely open
#define MAX_REPAIR_ANIM_STAGE 5 // # of stages of anim for repair center cycling
/****************************************************************************
** For each instance of a building in the game, there is one of
** these structures. This structure holds information that is specific
** and dynamic for a particular building.
*/
class BuildingClass : public TechnoClass
{
public:
/*
** This points to the control data that gives this building its characteristics.
*/
CCPtr<BuildingTypeClass> Class;
/*
** If this building is in the process of producing something, then this
** will point to the factory manager.
*/
CCPtr<FactoryClass> Factory;
/*
** This is the house that originally owned this factory. Objects buildable
** by this house type will be produced from this factory regardless of who
** the current owner is.
*/
HousesType ActLike;
/*
** This building should be rebuilt if it is destroyed. This is in spite
** of the condition of the prebuilt base list.
*/
unsigned IsToRebuild:1;
/*
** Is the building allowed to repair itself?
*/
unsigned IsToRepair:1;
/*
** If the computer owns this building, then it is allowed to sell it if
** the situation warrants it. In the other case, it cannot sell the
** building regardless of conditions.
*/
unsigned IsAllowedToSell:1;
/*
** If the building is at a good point to change orders, then this
** flag will be set to true.
*/
unsigned IsReadyToCommence:1;
/*
** If this building is currently spending money to repair itself, then
** this flag is true. It will automatically be set to false when the building
** has reached full strength, when money is exhausted, or if the player
** specifically stops the repair process.
*/
unsigned IsRepairing:1;
/*
** If repair is currently in progress and this flag is true, then a wrench graphic
** will be overlaid on the building to give visual feedback for the repair process.
*/
unsigned IsWrenchVisible:1;
/*
** This flag is set when a commando has raided the building and planted
** plastic explosives. When the CommandoCountDown timer expires, the
** building takes massive damage.
*/
unsigned IsGoingToBlow:1;
/*
** If this building was destroyed by some method that would prevent
** survivors, then this flag will be true.
*/
unsigned IsSurvivorless:1;
/*
** These state control variables are used by the obelisk for the charging
** animation.
*/
unsigned IsCharging:1;
unsigned IsCharged:1;
/*
** A building that has been captured will not contain the full compliment
** of crew. This is true even if it subsequently gets captured back.
*/
unsigned IsCaptured:1;
/*
** Used by the gap generator to decide if it should jam or unjam
*/
unsigned IsJamming:1;
/*
** Used by radar facilities to know if they're being jammed by a mobile
** radar jammer
*/
unsigned IsJammed:1;
/*
** Used only by advanced tech center, this keeps track of whether the
** GPS satellite has been fired or not.
*/
unsigned HasFired:1;
/*
** If Grand_Opening was already called for this building, then this
** flag will be true. By utilizing this flag, multiple inadvertant
** calls to Grand_Opening won't cause problems.
*/
unsigned HasOpened:1;
/*
** Special countdown to destruction value. If the building is destroyed,
** it won't actually be removed from the map until this value reaches
** zero. This delay is for cosmetic reasons.
*/
CDTimerClass<FrameTimerClass> CountDown;
/*
** This is the current animation processing state that the building is
** in.
*/
BStateType BState;
BStateType QueueBState;
/*
** For multiplayer games, this keeps track of the last house to damage
** this building, so if it burns to death or otherwise gradually dies,
** proper credit can be given for the kill.
*/
HousesType WhoLastHurtMe;
/*
** This is the saboteur responsible for this building's destruction.
*/
TARGET WhomToRepay;
/*
** This is a record of the last strength of the building. Every so often,
** it will compare this strength to the current strength. If there is a
** discrepancy, then the owner power is adjusted accordingly.
*/
int LastStrength;
/*
** This is a target id of an animation we're keeping track of. Examples
** of this usage are the advanced tech center, which needs to know
** when the sputdoor animation has reached a certain stage.
*/
TARGET AnimToTrack;
/*
** This is the countdown timer that regulates placement retry logic
** for factory type buildings.
*/
CDTimerClass<FrameTimerClass> PlacementDelay;
/*---------------------------------------------------------------------
** Constructors, Destructors, and overloaded operators.
*/
static void * operator new(size_t size);
static void * operator new(size_t , void * ptr) {return(ptr);};
static void operator delete(void *ptr);
BuildingClass(StructType type, HousesType house);
#ifdef FIXIT_MULTI_SAVE
BuildingClass(NoInitClass const & x) : TechnoClass(x), Class(x), Factory(x), CountDown(x), PlacementDelay(x) {};
#else
BuildingClass(NoInitClass const & x) : TechnoClass(x), Class(x), CountDown(x), PlacementDelay(x) {};
#endif
virtual ~BuildingClass(void);
operator StructType(void) const {return Class->Type;};
/*---------------------------------------------------------------------
** Member function prototypes.
*/
static void Init(void);
TARGET Target_Scan(void);
BuildingTypeClass::AnimControlType const * Fetch_Anim_Control(void) {return (&Class->Anims[BState]);};
/*
** Query functions.
*/
virtual int Value(void) const;
virtual void const * Get_Image_Data(void) const;
virtual int How_Many_Survivors(void) const;
virtual DirType Turret_Facing(void) const;
virtual CELL Find_Exit_Cell(TechnoClass const * techno) const;
virtual InfantryType Crew_Type(void) const;
virtual int Pip_Count(void) const;
virtual bool Can_Player_Move(void) const;
virtual ActionType What_Action(ObjectClass const * target) const;
virtual ActionType What_Action(CELL cell) const;
virtual bool Can_Demolish(void) const;
virtual bool Can_Demolish_Unit(void) const;
virtual ObjectTypeClass const & Class_Of(void) const {return *Class;};
virtual DirType Fire_Direction(void) const;
virtual short const * Overlap_List(bool redraw=false) const;
int Shape_Number(void) const;
int Power_Output(void) const;
CELL Check_Point(CheckPointType cp) const;
/*
** Coordinate inquiry functions. These are used for both display and
** combat purposes.
*/
virtual COORDINATE Target_Coord(void) const;
virtual COORDINATE Docking_Coord(void) const;
virtual COORDINATE Center_Coord(void) const;
virtual COORDINATE Sort_Y(void) const;
virtual COORDINATE Exit_Coord(void) const;
/*
** Object entry and exit from the game system.
*/
virtual void Detach(TARGET target, bool all);
virtual void Detach_All(bool all=true);
virtual void Grand_Opening(bool captured = false);
virtual void Update_Buildables(void);
virtual MoveType Can_Enter_Cell(CELL cell, FacingType = FACING_NONE) const;
virtual bool Unlimbo(COORDINATE , DirType dir = DIR_N);
virtual bool Limbo(void);
/*
** Display and rendering support functionality. Supports imagery and how
** object interacts with the map and thus indirectly controls rendering.
*/
virtual void const * Remap_Table(void);
virtual int Exit_Object(TechnoClass * base);
virtual void Draw_It(int x, int y, WindowNumberType window) const;
virtual bool Mark(MarkType mark=MARK_CHANGE);
virtual void Fire_Out(void);
void Begin_Mode(BStateType bstate);
/*
** User I/O.
*/
virtual void Active_Click_With(ActionType action, ObjectClass * object);
virtual void Active_Click_With(ActionType action, CELL cell);
/*
** Combat related.
*/
virtual void Death_Announcement(TechnoClass const * source=0) const;
virtual FireErrorType Can_Fire(TARGET, int which) const;
virtual TARGET Greatest_Threat(ThreatType threat) const;
virtual ResultType Take_Damage(int & damage, int distance, WarheadType warhead, TechnoClass * source=0, bool forced=false);
virtual bool Captured(HouseClass * newowner);
void Update_Radar_Spied(void);
/*
** AI.
*/
void Charging_AI(void);
void Rotation_AI(void);
void Factory_AI(void);
void Repair_AI(void);
void Animation_AI(void);
virtual bool Revealed(HouseClass * house);
virtual void Repair(int control);
virtual void Sell_Back(int control);
virtual RadioMessageType Receive_Message(RadioClass * from, RadioMessageType message, long & param);
virtual void AI(void);
virtual void Assign_Target(TARGET target);
virtual bool Toggle_Primary(void);
bool Flush_For_Placement(TechnoClass * techno, CELL cell);
virtual int Mission_Unload(void);
virtual int Mission_Repair(void);
virtual int Mission_Attack(void);
virtual int Mission_Harvest(void);
virtual int Mission_Guard(void);
virtual int Mission_Construction(void);
virtual int Mission_Deconstruction(void);
virtual int Mission_Missile(void);
virtual void Enter_Idle_Mode(bool initial=false);
void Remove_Gap_Effect(void);
/*
** Scenario and debug support.
*/
#ifdef CHEAT_KEYS
virtual void Debug_Dump(MonoClass *mono) const;
#endif
/*
** File I/O.
*/
static void Read_INI(CCINIClass & ini);
static void Write_INI(CCINIClass & ini);
static char *INI_Name(void) {return "STRUCTURES";};
bool Load(Straw & file);
bool Save(Pipe & file) const;
virtual unsigned Spied_By() const;
private:
void Drop_Debris(TARGET source = TARGET_NONE);
/*
** Some additional padding in case we need to add data to the class and maintain backwards compatibility for save/load
*/
unsigned char SaveLoadPadding[32];
static COORDINATE const CenterOffset[BSIZE_COUNT];
};
#endif

1110
REDALERT/BULLET.CPP Normal file

File diff suppressed because it is too large Load Diff

150
REDALERT/BULLET.H Normal file
View File

@ -0,0 +1,150 @@
//
// 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/BULLET.H 2 3/06/97 1:46p 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 : BULLET.H *
* *
* Programmer : Joe L. Bostic *
* *
* Start Date : April 23, 1994 *
* *
* Last Update : April 23, 1994 [JLB] *
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef BULLET_H
#define BULLET_H
#include "object.h"
#include "fly.h"
#include "fuse.h"
class BulletClass : public ObjectClass,
public FlyClass,
public FuseClass
{
public:
/*
** This specifies exactly what kind of bullet this is. All of the static attributes
** for this bullet is located in the BulletTypeClass pointed to by this variable.
*/
CCPtr<BulletTypeClass> Class;
private:
/*
** Records who sent this "present" so that an appropriate "thank you" can
** be returned.
*/
TechnoClass * Payback;
/*
** This is the facing that the projectile is travelling.
*/
FacingClass PrimaryFacing;
public:
/*---------------------------------------------------------------------
** Constructors, Destructors, and overloaded operators.
*/
static void * operator new(size_t size);
static void * operator new(size_t , void * ptr) {return(ptr);};
static void operator delete(void *ptr);
BulletClass(BulletType id, TARGET target, TechnoClass * Payback, int strength, WarheadType warhead, int speed);
#ifdef FIXIT_MULTI_SAVE
BulletClass(NoInitClass const & x) : ObjectClass(x), Class(x), FlyClass(x), FuseClass(x), PrimaryFacing(x) {};
#else
BulletClass(NoInitClass const & x) : ObjectClass(x), Class(x), FlyClass(x), FuseClass(x) {};
#endif
virtual ~BulletClass(void);
operator BulletType(void) const {return Class->Type;};
/*---------------------------------------------------------------------
** Member function prototypes.
*/
static void Init(void);
bool Is_Forced_To_Explode(COORDINATE & coord) const;
void Bullet_Explodes(bool forced);
int Shape_Number(void) const;
virtual LayerType In_Which_Layer(void) const;
virtual COORDINATE Sort_Y(void) const;
virtual void Assign_Target(TARGET target) {TarCom = target;};
virtual bool Unlimbo(COORDINATE , DirType facing = DIR_N);
virtual ObjectTypeClass const & Class_Of(void) const {return *Class;};
virtual void Detach(TARGET target, bool all);
virtual void Draw_It(int x, int y, WindowNumberType window) const;
virtual bool Mark(MarkType mark=MARK_CHANGE);
virtual void AI(void);
virtual short const * Occupy_List(bool = false) const;
virtual short const * Overlap_List(void) const {return Occupy_List(false);};
virtual COORDINATE Target_Coord(void) const;
/*
** File I/O.
*/
bool Load(Straw & file);
bool Save(Pipe & file) const;
virtual void Code_Pointers(void);
virtual void Decode_Pointers(void);
/*
** If this bullet is forced to be inaccurate because of some outside means. A tank
** firing while moving is a good example.
*/
unsigned IsInaccurate:1;
private:
// Crude animation flag.
unsigned IsToAnimate:1;
/*
** Is this missile allowed to come in from out of bounds?
*/
unsigned IsLocked:1;
/*
** This is the target of the projectile. It is especially significant for those projectiles
** that home in on a target.
*/
TARGET TarCom;
/*
** The speed of this projectile.
*/
int MaxSpeed;
/*
** The warhead of this projectile.
*/
WarheadType Warhead;
/*
** Some additional padding in case we need to add data to the class and maintain backwards compatibility for save/load
*/
unsigned char SaveLoadPadding[32];
};
#endif

180
REDALERT/CARGO.CPP Normal file
View File

@ -0,0 +1,180 @@
//
// 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/CARGO.CPP 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 : CARGO.CPP *
* *
* Programmer : Joe L. Bostic *
* *
* Start Date : April 23, 1994 *
* *
* Last Update : 10/31/94 [JLB] *
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* CargoClass::Attach -- Add unit to cargo hold. *
* CargoClass::Attached_Object -- Determine attached unit pointer. *
* CargoClass::Debug_Dump -- Displays the cargo value to the monochrome screen. *
* CargoClass::Detach_Object -- Removes a unit from the cargo hold. *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "function.h"
#ifdef CHEAT_KEYS
/***********************************************************************************************
* CargoClass::Debug_Dump -- Displays the cargo value to the monochrome screen. *
* *
* This routine is used to dump the current cargo value to the monochrome monitor. *
* *
* INPUT: none *
* *
* OUTPUT: none *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 06/02/1994 JLB : Created. *
*=============================================================================================*/
void CargoClass::Debug_Dump(MonoClass * mono) const
{
if (How_Many()) {
mono->Set_Cursor(63, 3);
mono->Printf("(%d)%04X", How_Many(), Attached_Object());
}
}
#endif
/***********************************************************************************************
* CargoClass::Attach -- Add unit to cargo hold. *
* *
* This routine will add the specified unit to the cargo hold. The *
* unit will chain to any existing units in the hold. The chaining is *
* in a LIFO order. *
* *
* INPUT: object-- Pointer to the object to attach to the cargo hold. *
* *
* OUTPUT: none *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 04/23/1994 JLB : Created. *
* 10/31/94 JLB : Handles chained objects. *
*=============================================================================================*/
void CargoClass::Attach(FootClass * object)
{
/*
** If there is no object, then no action is necessary.
*/
if (object == NULL) return;
object->Limbo();
/*
** Attach any existing cargo hold object to the end of the list as indicated by the
** object pointer passed into this routine. This is necessary because several objects may
** be attached at one time or several objects may be attached as a result of several calls
** to this routine. Either case must be handled properly.
*/
ObjectClass * o = object->Next;
while (o != NULL) {
if (o->Next == (void*)NULL) break;
o = o->Next;
}
if (o != NULL) {
o->Next = CargoHold;
} else {
object->Next = CargoHold;
}
/*
** Finally, assign the object pointer as the first object attached to this cargo hold.
*/
CargoHold = object;
Quantity = 0;
object = CargoHold;
while (object != NULL) {
Quantity++;
object = (FootClass *)(ObjectClass *)object->Next;
}
}
/***********************************************************************************************
* CargoClass::Detach_Object -- Removes a unit from the cargo hold. *
* *
* This routine will take a unit from the cargo hold and extract it. *
* The unit extracted is the last unit added to the hold. If there *
* is no unit in the hold or the occupant is not a unit, then NULL is *
* returned. *
* *
* INPUT: none *
* *
* OUTPUT: Returns with a pointer to the unit that has been extracted. *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 04/23/1994 JLB : Created. *
* 06/07/1994 JLB : Handles generic object types. *
*=============================================================================================*/
FootClass * CargoClass::Detach_Object(void)
{
TechnoClass * unit = Attached_Object();
if (unit != NULL) {
CargoHold = (FootClass *)(ObjectClass *)unit->Next;
unit->Next = 0;
Quantity--;
}
return((FootClass *)unit);
}
/***********************************************************************************************
* CargoClass::Attached_Object -- Determine attached unit pointer. *
* *
* This routine will return with a pointer to the attached unit if one *
* is present. One would need to know this if this is a transport *
* unit and it needs to unload. *
* *
* INPUT: none *
* *
* OUTPUT: Returns a pointer to the attached unit. If there is no *
* attached unit, then return NULL. *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 09/07/1992 JLB : Created. *
* 06/07/1994 JLB : Handles generic object types. *
*=============================================================================================*/
FootClass * CargoClass::Attached_Object(void) const
{
if (Is_Something_Attached()) {
return(CargoHold);
}
return(NULL);
}

90
REDALERT/CARGO.H Normal file
View File

@ -0,0 +1,90 @@
//
// 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/CARGO.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 : CARGO.H *
* *
* Programmer : Joe L. Bostic *
* *
* Start Date : April 23, 1994 *
* *
* Last Update : April 23, 1994 [JLB] *
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef CARGO_H
#define CARGO_H
class FootClass;
/****************************************************************************
** This class handles the basic cargo logic.
*/
class CargoClass {
public:
/*---------------------------------------------------------------------
** Constructors, Destructors, and overloaded operators.
*/
CargoClass(void) : Quantity(0), CargoHold(0) {};
CargoClass(NoInitClass const & ) {};
~CargoClass(void) {CargoHold=0;};
/*---------------------------------------------------------------------
** Member function prototypes.
*/
#ifdef CHEAT_KEYS
void Debug_Dump(MonoClass *mono) const;
#endif
void AI(void) {};
int How_Many(void) const {return Quantity;};
bool Is_Something_Attached(void) const {return (CargoHold != 0);};
FootClass * Attached_Object(void) const;
FootClass * Detach_Object(void);
void Attach(FootClass * object);
/*
** File I/O.
*/
void Code_Pointers(void);
void Decode_Pointers(void);
private:
/*
** This is the number of objects attached to this cargo hold. For transporter
** objects, they might contain more than one object.
*/
unsigned char Quantity;
/*
** This is the target value of any attached object. A value of zero indicates
** that no object is attached.
*/
FootClass * CargoHold;
};
#endif

150
REDALERT/CARRY.CPP Normal file
View File

@ -0,0 +1,150 @@
//
// 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/CARRY.CPP 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 : CARRY.CPP *
* *
* Programmer : Joe L. Bostic *
* *
* Start Date : 02/26/96 *
* *
* Last Update : May 10, 1996 [JLB] *
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* CarryoverClass::CarryoverClass -- Constructor for carry over objects. *
* CarryoverClass::Create -- Creates a carried over object. *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "function.h"
/***********************************************************************************************
* CarryoverClass::CarryoverClass -- Constructor for carry over objects. *
* *
* This is the constructor for a carry over object. Such an object is used to record the *
* object that will be "carried over" into a new scenario at some future time. *
* *
* INPUT: techno -- Pointer to the object that will be carried over. *
* *
* OUTPUT: none *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 05/10/1996 JLB : Created. *
*=============================================================================================*/
CarryoverClass::CarryoverClass(TechnoClass * techno) :
RTTI(RTTI_NONE),
Cell(0),
Strength(0),
House(HOUSE_NONE)
{
if (techno) {
RTTI = techno->What_Am_I();
switch (RTTI) {
case RTTI_UNIT:
Type.Unit = ((UnitClass *)techno)->Class->Type;
break;
case RTTI_BUILDING:
Type.Building = ((BuildingClass *)techno)->Class->Type;
break;
case RTTI_INFANTRY:
Type.Infantry = ((InfantryClass *)techno)->Class->Type;
break;
case RTTI_VESSEL:
Type.Vessel = ((VesselClass *)techno)->Class->Type;
break;
default:
break;
}
House = techno->Owner();
Strength = techno->Strength;
Cell = Coord_Cell(techno->Coord);
}
}
/***********************************************************************************************
* CarryoverClass::Create -- Creates a carried over object. *
* *
* Use this routine to convert a carried over object into an actual object that will be *
* placed on the map. *
* *
* INPUT: none *
* *
* OUTPUT: bool; Was the object successfully created and placed on the map? *
* *
* WARNINGS: This routine might not place the object if the old map location was invalid *
* or there are other barriers to the object's creation and placement. *
* *
* HISTORY: *
* 05/10/1996 JLB : Created. *
*=============================================================================================*/
bool CarryoverClass::Create(void) const
{
TechnoClass * techno = 0;
TechnoTypeClass const * ttype = 0;
switch (RTTI) {
case RTTI_UNIT:
ttype = &UnitTypeClass::As_Reference(Type.Unit);
techno = new UnitClass(Type.Unit, House);
break;
case RTTI_INFANTRY:
ttype = &InfantryTypeClass::As_Reference(Type.Infantry);
techno = new InfantryClass(Type.Infantry, House);
break;
case RTTI_BUILDING:
ttype = &BuildingTypeClass::As_Reference(Type.Building);
techno = new BuildingClass(Type.Building, House);
break;
case RTTI_VESSEL:
ttype = &VesselTypeClass::As_Reference(Type.Vessel);
techno = new VesselClass(Type.Vessel, House);
break;
}
if (techno) {
bool oldscen = ScenarioInit;
techno->Strength = Strength;
if (RTTI == RTTI_INFANTRY) {
ScenarioInit = 0;
}
techno->Unlimbo(Cell_Coord(Cell));
if (RTTI == RTTI_INFANTRY) {
ScenarioInit = oldscen;
}
}
return(false);
}

81
REDALERT/CARRY.H Normal file
View File

@ -0,0 +1,81 @@
//
// 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/CARRY.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 : CARRY.H *
* *
* Programmer : Joe L. Bostic *
* *
* Start Date : 02/26/96 *
* *
* Last Update : February 26, 1996 [JLB] *
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef CARRY_H
#define CARRY_H
class CarryoverClass : public LinkClass {
public:
CarryoverClass(TechnoClass * techno = 0);
CarryoverClass(NoInitClass const & x) : LinkClass(x) {}
bool Create(void) const;
//protected:
/*
** What type of object this is.
*/
RTTIType RTTI;
/*
** This is the object type that is to be carried over. The exact nature of
** this type depends on the RTTI value. Only certain object types are
** recorded.
*/
union {
StructType Building;
UnitType Unit;
InfantryType Infantry;
VesselType Vessel;
} Type;
/*
** The location of the object.
*/
CELL Cell;
/*
** The strength of the object at the time is was recorded.
*/
int Strength;
/*
** This is the owner of the object.
*/
HousesType House;
};
#endif

153
REDALERT/CBN_.H Normal file
View File

@ -0,0 +1,153 @@
//
// 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
/****************************************************************************
* Error Constants, in case of values above 10 hexadecimal please call
* Marx International, Inc.
****************************************************************************/
#define PARAM_ERR 0x01
#define BOX_NOT_FOUND 0x02
#define BOX_CRYPT_ERR 0x03
#define UNI_CRYPT_ERR 0x04
#define READ_RAM_ERR 0x05
#define WRITE_RAM_ERR 0x06
#define RAM_COUNT_ERR 0x07
#define BOX_READY_ERR 0x08
/****************************************************************************
* Constants
****************************************************************************/
#define CRYPTLENG 32
#define RAM1LENG 50
#define RAM2LENG 433
#define IDEALENG 32
/****************************************************************************
* User Functions
****************************************************************************/
extern "C" {
extern short CbN_BoxReady(unsigned short iPortNr, unsigned char *pcBoxName);
extern short CbN_ReadID1(unsigned short iPortNr, unsigned char *pcSCodeId,
unsigned long *plIdReturn);
extern short CbN_ReadID2(unsigned short iPortNr, unsigned char *pcSCodeId,
unsigned long *plIdReturn);
extern short CbN_ReadID3(unsigned short iPortNr, unsigned char *pcSCodeId,
unsigned long *plIdReturn);
extern short CbN_ReadID4(unsigned short iPortNr, unsigned char *pcSCodeId,
unsigned long *plIdReturn);
extern short CbN_ReadID5(unsigned short iPortNr, unsigned char *pcSCodeId,
unsigned long *plIdReturn);
extern short CbN_ReadID6(unsigned short iPortNr, unsigned char *pcSCodeId,
unsigned long *plIdReturn);
extern short CbN_ReadID7(unsigned short iPortNr, unsigned char *pcSCodeId,
unsigned long *plIdReturn);
extern short CbN_ReadID8(unsigned short iPortNr, unsigned char *pcSCodeId,
unsigned long *plIdReturn);
extern short CbN_ReadSER(unsigned short iPortNr, unsigned char *pcSCodeSer,
unsigned long *plSerNum);
extern short CbN_ReadRAM1(unsigned short iPortNr,unsigned short iIdNr,unsigned char
*pcSCodeId,unsigned char *pcPasswRam1,unsigned short
iStartAdr,unsigned short iLength, unsigned char *pcOutData);
extern short CbN_ReadRAM2(unsigned short iPortNr,unsigned short iIdNr,unsigned char
*pcSCodeId,unsigned char *pcPasswRam2,unsigned short
iStartAdr,unsigned short iLength, unsigned char *pcOutData);
extern short CbN_WriteRAM1(unsigned short iPortNr,unsigned short iIdNr,unsigned char
*pcSCodeId,unsigned char *pcPasswRam1,unsigned short
iStartAdr,unsigned short iLength,unsigned char *pcOutData);
extern short CbN_WriteRAM2(unsigned short iPortNr,unsigned short iIdNr,unsigned char
*pcSCodeId,unsigned char *pcPasswRam2,unsigned short
iStartAdr,unsigned short iLength,unsigned char *pcOutData);
extern short CbN_IncRAM1(unsigned short iPortNr, unsigned short iIdNr, unsigned char
*pcSCodeId, unsigned char *pcPasswRam1, unsigned short
iCounterAdr, unsigned short *piNewCount);
extern short CbN_DecRAM1(unsigned short iPortNr, unsigned short iIdNr, unsigned char
*pcSCodeId, unsigned char *pcPasswRam1, unsigned short
iCounterAdr, unsigned short *piNewCount);
extern short CbN_IncRAM2(unsigned short iPortNr, unsigned short iIdNr, unsigned char
*pcSCodeId, unsigned char *pcPasswRam2, unsigned short
iCounterAdr, unsigned short *piNewCount);
extern short CbN_DecRAM2(unsigned short iPortNr, unsigned short iIdNr, unsigned char
*pcSCodeId, unsigned char *pcPasswRam2, unsigned short
iCounterAdr, unsigned short *piNewCount);
extern short CbN_Decrypt(unsigned short iPortNr,unsigned short iIdNr,unsigned char
*pcSCodeId,unsigned short iSeed, unsigned short iLength,
unsigned char *pcOutData);
extern short CbN_Encrypt(unsigned short iPortNr,unsigned short iIdNr,unsigned char
*pcSCodeId,unsigned short iSeed,unsigned short iLength,
unsigned char *pcOutData);
extern short CbN_IDEA_Encrypt(unsigned short iPortNr, unsigned short iIdNr,
unsigned char *pcSCodeId, unsigned char *pcBuff,
unsigned long lLength);
extern short CbN_IDEA_Decrypt(unsigned short iPortNr, unsigned short iIdNr,
unsigned char *pcSCodeId, unsigned char *pcBuff,
unsigned long lLength);
extern short CbN_IDEA_EncryptP(unsigned short iPortNr, unsigned short iIdNr,
unsigned char *pcSCodeId, unsigned char *pcBuff,
unsigned long lLength, unsigned long lIdeaKey);
extern short CbN_IDEA_DecryptP(unsigned short iPortNr, unsigned short iIdNr,
unsigned char *pcSCodeId, unsigned char *pcBuff,
unsigned long lLength, unsigned long lIdeaKey);
extern short CbN_SetCounterRAM1(unsigned short iPortNr, unsigned short iIdNr,
unsigned char *pcSCodeId, unsigned char
*pcPassRam, unsigned short iAdrCount, unsigned short
iNewCount);
extern short CbN_ReadCounterRAM1(unsigned short iPortNr, unsigned short iIdNr,
unsigned char *pcSCodeId, unsigned char
*pcPassRam, unsigned short iAdrCount, unsigned short
*piCurrentCount);
extern short CbN_SetCounterRAM2(unsigned short iPortNr, unsigned short iIdNr,
unsigned char *pcSCodeId, unsigned char
*pcPassRam, unsigned short iAdrCount, unsigned short
iNewCount);
extern short CbN_ReadCounterRAM2(unsigned short iPortNr, unsigned short iIdNr,
unsigned char *pcSCodeId, unsigned char
*pcPassRam, unsigned short iAdrCount, unsigned short
*piCurrentCount);
}


428
REDALERT/CCDDE.CPP Normal file
View File

@ -0,0 +1,428 @@
//
// 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
/***********************************************************************************************
*** 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 - Red Alert *
* *
* File Name : CCDDE.CPP *
* *
* Programmer : Steve Tall *
* *
* Start Date : 10/04/95 *
* *
* Last Update : August 5th, 1996 [ST] *
* *
*---------------------------------------------------------------------------------------------*
* Overview: *
* C&C's interface to the DDE class *
* *
*---------------------------------------------------------------------------------------------*
* *
* Functions: *
* DDE_Callback -- DDE server callback function *
* DDEServerClass::DDEServerClass -- class constructor *
* DDEServerClass::Enable -- Enables the DDE callback *
* DDEServerClass::Disable -- Disables the DDE callback *
* DDEServerClass::~DDEServerClass -- class destructor *
* DDESC::Callback -- callback function. Called from the DDE_Callback wrapper function *
* DDESC::Get_MPlayer_Game_Info -- returns a pointer to the multiplayer setup info from wchat *
* DDESC::Delete_MPlayer_Game_Info -- clears out multi player game setup info *
* DDESC::Time_Since_Heartbeat -- returns the time in ticks since the last heartbeat from wchat*
* *
* Send_Data_To_DDE_Server -- sends a packet to WChat *
* *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifdef WIN32
#include <WINDOWS.H>
#include "ccdde.h"
#include <stdio.h>
#include <timer.h>
DDEServerClass DDEServer; //Instance of the DDE Server class
Instance_Class *DDE_Class = NULL; // pointer for client callback
// this *must* be called DDE_Class
BOOL RA95AlreadyRunning = FALSE; //Was there an instance of Red Alert 95 already running when we started?
/*
** Misc externs so we dont have to include FUNCTION.H
*/
extern HWND MainWindow;
extern TimerClass GameTimer;
extern bool GameTimerInUse;
extern void WWDebugString (char *string);
/***********************************************************************************************
* DDE_Callback -- DDE server callback function *
* *
* Just acts as a wrapper for the DDEServerClass callback function *
* *
* INPUT: ptr to data from client *
* length of data *
* *
* OUTPUT: Nothing *
* *
* WARNINGS: None *
* *
* HISTORY: *
* 6/8/96 3:19PM ST : Created *
*=============================================================================================*/
BOOL CALLBACK DDE_Callback (unsigned char *data, long length)
{
return (DDEServer.Callback(data, length));
}
/***********************************************************************************************
* DDEServerClass::DDEServerClass -- class constructor *
* *
* *
* *
* INPUT: Nothing *
* *
* OUTPUT: Nothing *
* *
* WARNINGS: None *
* *
* HISTORY: *
* 6/8/96 3:20PM ST : Created *
*=============================================================================================*/
DDEServerClass::DDEServerClass(void)
{
MPlayerGameInfo = NULL; //Flag that we havnt received a start game info packet yet
//DDE_Class = new Instance_Class ("CONQUER", "WCHAT");
DDE_Class = new Instance_Class ("REDALERT", "WCHAT");
DDE_Class->Enable_Callback( TRUE );
IsEnabled = TRUE;
if (DDE_Class->Test_Server_Running(DDE_Class->local_name)){
RA95AlreadyRunning = TRUE;
}else{
//DDE_Class->Register_Server( DDE_Callback ); // ST - 5/8/2019
}
}
/***********************************************************************************************
* DDEServerClass::Enable -- Enables the DDE callback *
* *
* *
* *
* INPUT: Nothing *
* *
* OUTPUT: Nothing *
* *
* WARNINGS: None *
* *
* HISTORY: *
* 8/5/96 9:44PM ST : Created *
*=============================================================================================*/
void DDEServerClass::Enable(void)
{
if (!IsEnabled){
DDE_Class->Enable_Callback( TRUE );
IsEnabled = TRUE;
}
}
/***********************************************************************************************
* DDEServerClass::Disable -- Disables the DDE callback *
* *
* *
* *
* INPUT: Nothing *
* *
* OUTPUT: Nothing *
* *
* WARNINGS: None *
* *
* HISTORY: *
* 8/5/96 9:44PM ST : Created *
*=============================================================================================*/
void DDEServerClass::Disable(void)
{
if (IsEnabled){
DDE_Class->Enable_Callback( FALSE );
IsEnabled = FALSE;
}
}
/***********************************************************************************************
* DDEServerClass::~DDEServerClass -- class destructor *
* *
* *
* *
* INPUT: Nothing *
* *
* OUTPUT: Nothing *
* *
* WARNINGS: None *
* *
* HISTORY: *
* 6/8/96 3:20PM ST : Created *
*=============================================================================================*/
DDEServerClass::~DDEServerClass(void)
{
Delete_MPlayer_Game_Info();
delete( DDE_Class );
}
/***********************************************************************************************
* DDESC::Callback -- callback function. Called from the DDE_Callback wrapper function *
* *
* *
* *
* INPUT: data from DDE client *
* length of data *
* *
* OUTPUT: Nothing *
* *
* WARNINGS: Data has length and type as first 2 ints *
* *
* HISTORY: *
* 6/8/96 3:21PM ST : Created *
*=============================================================================================*/
BOOL DDEServerClass::Callback(unsigned char *data, long length)
{
/*
** If the packet length < 0 then this is a special advisory packet
*/
if ( length<0 ) {
switch( length ) {
case DDE_ADVISE_CONNECT:
WWDebugString("RA95 - DDE advisory: client connect detected.");
return TRUE;
case DDE_ADVISE_DISCONNECT:
WWDebugString("RA95 - DDE advisory: client disconnect detected.");
return TRUE;
default:
WWDebugString("RA95 - DDE advisory: Unknown DDE advise type.");
return FALSE;
}
}else{
/*
** Packet must be at least the length of the packet type & size fields to be valid
*/
if (length < 2*sizeof(int)) {
WWDebugString ("RA95 - Received invalid packet.");
return (FALSE);
}
/*
** Find out what kind of packet this is and its length.
*/
int *packet_pointer = (int *)data;
int actual_length = ntohl(*packet_pointer++);
int packet_type = ntohl(*packet_pointer++);
/*
** Strip the ID int from the start of the packet
*/
data += 2*sizeof (int);
length -= 2*sizeof (int);
actual_length -= 2*sizeof (int);
/*
** Take the appropriate action for the packet type
*/
switch ( packet_type ){
/*
** This is a packet with the info required for starting a new internet game. This is really
* just C&CSPAWN.INI sent from WChat instead of read from disk.
*/
case DDE_PACKET_START_MPLAYER_GAME:
WWDebugString("RA95 - Received start game packet.");
Delete_MPlayer_Game_Info();
MPlayerGameInfo = new char [actual_length + 1];
memcpy (MPlayerGameInfo, data, actual_length);
*(MPlayerGameInfo + actual_length) = 0; //Terminator in case we treat it as a string
MPlayerGameInfoLength = actual_length;
LastHeartbeat = 0;
break;
case DDE_TICKLE:
WWDebugString("RA95 - Received 'tickle' packet.");
//SetForegroundWindow ( MainWindow );
//ShowWindow ( MainWindow, SW_SHOWMAXIMIZED );
break;
case DDE_PACKET_HEART_BEAT:
WWDebugString("RA95 - Received heart beat packet.");
if (GameTimerInUse){
LastHeartbeat = GameTimer.Time();
}else{
LastHeartbeat = 0;
}
break;
default:
WWDebugString("RA95 - Received unrecognised packet.");
break;
}
}
return (TRUE);
}
/***********************************************************************************************
* DDESC::Get_MPlayer_Game_Info -- returns a pointer to the multiplayer setup info from wchat *
* *
* *
* *
* INPUT: Nothing *
* *
* OUTPUT: ptr to data in .INI file format *
* *
* WARNINGS: None *
* *
* HISTORY: *
* 6/8/96 3:23PM ST : Created *
*=============================================================================================*/
char *DDEServerClass::Get_MPlayer_Game_Info (void)
{
return (MPlayerGameInfo);
}
/***********************************************************************************************
* DDESC::Delete_MPlayer_Game_Info -- clears out multi player game setup info *
* *
* *
* *
* INPUT: Nothing *
* *
* OUTPUT: Nothing *
* *
* WARNINGS: None *
* *
* HISTORY: *
* 6/8/96 3:24PM ST : Created *
*=============================================================================================*/
void DDEServerClass::Delete_MPlayer_Game_Info(void)
{
if (MPlayerGameInfo){
delete [] MPlayerGameInfo;
MPlayerGameInfo = NULL;
}
}
/***********************************************************************************************
* DDESC::Time_Since_Heartbeat -- returns the time in ticks since the last heartbeat from wchat*
* *
* *
* *
* INPUT: Nothing *
* *
* OUTPUT: time since heartbeat *
* *
* WARNINGS: None *
* *
* HISTORY: *
* 6/9/96 11:05PM ST : Created *
*=============================================================================================*/
int DDEServerClass::Time_Since_Heartbeat(void)
{
return (GameTimer.Time() - LastHeartbeat);
}
/***********************************************************************************************
* Send_Data_To_DDE_Server -- sends a packet to WChat *
* *
* *
* *
* INPUT: ptr to the data to send *
* length of data *
* packet type identifier *
* *
* OUTPUT: true if packet successfully sent *
* *
* WARNINGS: None *
* *
* HISTORY: *
* 6/9/96 11:07PM ST : Created *
*=============================================================================================*/
BOOL Send_Data_To_DDE_Server (char *data, int length, int packet_type)
{
if( DDE_Class->Open_Poke_Connection(DDE_Class->remote_name) == FALSE) {
WWDebugString("RA95 - Failed to connect for POKE!");
return (FALSE);
}
char *poke_data = new char [length + 2*sizeof(int)];
int *poke_data_int = (int*)poke_data;
*poke_data_int = htonl (length + 2*sizeof(int));
*(poke_data_int+1)= htonl (packet_type);
memcpy (poke_data + 8, data, length);
if(DDE_Class->Poke_Server( (LPBYTE) poke_data, ntohl(*poke_data_int) ) == FALSE) {
WWDebugString("RA95 - POKE failed!\n");
DDE_Class->Close_Poke_Connection(); // close down the link
delete poke_data;
return (FALSE);
}
DDE_Class->Close_Poke_Connection(); // close down the link
delete poke_data;
return (TRUE);
}
#endif //WIN32

86
REDALERT/CCDDE.H Normal file
View File

@ -0,0 +1,86 @@
//
// 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
/***********************************************************************************************
*** 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 - Red Alert *
* *
* File Name : CCDDE.H *
* *
* Programmer : Steve Tall *
* *
* Start Date : 10/04/95 *
* *
* Last Update : August 5th, 1996 [ST] *
* *
*---------------------------------------------------------------------------------------------*
* Overview: *
* C&C's interface to the DDE class *
* *
*---------------------------------------------------------------------------------------------*
* *
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifdef WIN32
#include "dde.h"
class DDEServerClass {
public:
DDEServerClass (void);
~DDEServerClass (void);
char *Get_MPlayer_Game_Info (void); //Returns pointer to game info
int Get_MPlayer_Game_Info_Length(){return(MPlayerGameInfoLength);}; //Len of game info
BOOL Callback(unsigned char *data, long length); //DDE callback function
void Delete_MPlayer_Game_Info(void); //release the game info memory
void Enable(void); //Enable the DDE callback
void Disable(void); //Disable the DDE callback
int Time_Since_Heartbeat(void); //Returns the time since the last hearbeat from WChat
/*
** Enumeration for DDE packet types from WChat
*/
enum {
DDE_PACKET_START_MPLAYER_GAME, //Start game packet. This includes game options
DDE_PACKET_GAME_RESULTS, //Game results packet. The game statistics.
DDE_PACKET_HEART_BEAT, //Heart beat packet so we know WChat is still there.
DDE_TICKLE, //Message to prompt other app to take focus.
DDE_CONNECTION_FAILED
};
private:
char *MPlayerGameInfo; //Pointer to game start packet
int MPlayerGameInfoLength; //Length of game start packet.
BOOL IsEnabled; //Flag for DDE callback enable
int LastHeartbeat; // Time since last heartbeat packet was received from WChat
};
extern DDEServerClass DDEServer;
extern BOOL Send_Data_To_DDE_Server (char *data, int length, int packet_type);
#endif //WIN32

692
REDALERT/CCFILE.CPP Normal file
View File

@ -0,0 +1,692 @@
//
// 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/CCFILE.CPP 2 3/13/97 2:05p Steve_tall $ */
/***********************************************************************************************
*** 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 : CCFILE.CPP *
* *
* Programmer : Joe L. Bostic *
* *
* Start Date : August 8, 1994 *
* *
* Last Update : August 5, 1996 [JLB] *
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* CCFileClass::CCFileClass -- Default constructor for file object. *
* CCFileClass::CCFileClass -- Filename based constructor for C&C file. *
* CCFileClass::Close -- Closes the file. *
* CCFileClass::Error -- Handles displaying a file error message. *
* CCFileClass::Is_Available -- Checks for existence of file on disk or in mixfile. *
* CCFileClass::Is_Open -- Determines if the file is open. *
* CCFileClass::Open -- Opens a file from either the mixfile system or the rawfile system. *
* CCFileClass::Read -- Reads data from the file. *
* CCFileClass::Seek -- Moves the current file pointer in the file. *
* CCFileClass::Size -- Determines the size of the file. *
* CCFileClass::Write -- Writes data to the file (non mixfile files only). *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "function.h"
#include <errno.h>
#include "ccfile.h"
/***********************************************************************************************
* CCFileClass::CCFileClass -- Filename based constructor for C&C file. *
* *
* Use this constructor for a file when the filename is known at construction time. *
* *
* INPUT: filename -- Pointer to the filename to use for this file object. *
* *
* OUTPUT: none *
* *
* WARNINGS: The filename pointer is presumed to be inviolate throughout the duration of *
* the file object. If this is not guaranteed, then use the default constructor *
* and then set the name manually. *
* *
* HISTORY: *
* 03/20/1995 JLB : Created. *
*=============================================================================================*/
CCFileClass::CCFileClass(char const * filename) :
Position(0)
{
CCFileClass::Set_Name(filename);
}
/***********************************************************************************************
* CCFileClass::CCFileClass -- Default constructor for file object. *
* *
* This is the default constructor for a C&C file object. *
* *
* INPUT: none *
* *
* OUTPUT: none *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 03/20/1995 JLB : Created. *
*=============================================================================================*/
CCFileClass::CCFileClass(void) :
Position(0)
{
}
/***********************************************************************************************
* CCFileClass::Error -- Handles displaying a file error message. *
* *
* Display an error message as indicated. If it is allowed to retry, then pressing a key *
* will return from this function. Otherwise, it will exit the program with "exit()". *
* *
* INPUT: error -- The error number (same as the DOSERR.H error numbers). *
* *
* canretry -- Can this routine exit normally so that retrying can occur? If this is *
* false, then the program WILL exit in this routine. *
* *
* filename -- Optional filename to report with this error. If no filename is *
* supplied, then no filename is listed in the error message. *
* *
* OUTPUT: none, but this routine might not return at all if the "canretry" parameter is *
* false or the player pressed ESC. *
* *
* WARNINGS: This routine may not return at all. It handles being in text mode as well as *
* if in a graphic mode. *
* *
* HISTORY: *
* 10/17/1994 JLB : Created. *
*=============================================================================================*/
void CCFileClass::Error(int , int , char const * )
{
if (!Force_CD_Available(RequiredCD)) {
Prog_End("CCFileClass::Error CD not found", true);
if (!RunningAsDLL) { //PG
Emergency_Exit(EXIT_FAILURE);
}
}
}
/***********************************************************************************************
* CCFileClass::Write -- Writes data to the file (non mixfile files only). *
* *
* This routine will write data to the file, but NOT to a file that is part of a mixfile. *
* *
* INPUT: buffer -- Pointer to the buffer that holds the data to be written. *
* *
* size -- The number of bytes to write. *
* *
* OUTPUT: Returns the number of bytes actually written. *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 08/08/1994 JLB : Created. *
*=============================================================================================*/
long CCFileClass::Write(void const * buffer, long size)
{
/*
** If this is part of a mixfile, then writing is not allowed. Error out with a fatal
** message.
*/
if (Is_Resident()) {
Error(EACCES, false, File_Name());
}
return(CDFileClass::Write(buffer, size));
}
/***********************************************************************************************
* CCFileClass::Read -- Reads data from the file. *
* *
* This routine determines if the file is part of the mixfile system. If it is, then *
* the file is copied from RAM if it is located there. Otherwise it is read from disk *
* according to the correct position of the file within the parent mixfile. *
* *
* INPUT: buffer -- Pointer to the buffer to place the read data. *
* *
* size -- The number of bytes to read. *
* *
* OUTPUT: Returns the actual number of bytes read (this could be less than requested). *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 08/08/1994 JLB : Created. *
*=============================================================================================*/
long CCFileClass::Read(void * buffer, long size)
{
bool opened = false;
/*
** If the file isn't currently open, then open it.
*/
if (!Is_Open()) {
if (Open()) {
opened = true;
}
}
/*
** If the file is part of a loaded mixfile, then a mere copy is
** all that is required for the read.
*/
if (Is_Resident()) {
long maximum = Data.Get_Size() - Position;
size = maximum < size ? maximum : size;
// size = MIN(maximum, size);
if (size) {
memmove(buffer, (char *)Data + Position, size);
// Mem_Copy((char *)Pointer + Position, buffer, size);
Position += size;
}
if (opened) Close();
return(size);
}
long s = CDFileClass::Read(buffer, size);
/*
** If the file was opened by this routine, then close it at this time.
*/
if (opened) Close();
/*
** Return with the number of bytes read.
*/
return(s);
}
/***********************************************************************************************
* CCFileClass::Seek -- Moves the current file pointer in the file. *
* *
* This routine will change the current file pointer to the position specified. It follows *
* the same rules the a normal Seek() does, but if the file is part of the mixfile system, *
* then only the position value needs to be updated. *
* *
* INPUT: pos -- The position to move the file to relative to the position indicated *
* by the "dir" parameter. *
* *
* dir -- The direction to affect the position change against. This can be *
* either SEEK_CUR, SEEK_END, or SEEK_SET. *
* *
* OUTPUT: Returns with the position of the new location. *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 08/08/1994 JLB : Created. *
*=============================================================================================*/
long CCFileClass::Seek(long pos, int dir)
{
/*
** When the file is resident, a mere adjustment of the virtual file position is
** all that is required of a seek.
*/
if (Is_Resident()) {
switch (dir) {
case SEEK_END:
Position = Data.Get_Size();
break;
case SEEK_SET:
Position = 0;
break;
case SEEK_CUR:
default:
break;
}
Position += pos;
Position = Position < 0 ? 0 : Position;
Position = Position > Data.Get_Size() ? Data.Get_Size() : Position;
// Position = Bound(Position+pos, 0L, Length);
return(Position);
}
return(CDFileClass::Seek(pos, dir));
}
/***********************************************************************************************
* CCFileClass::Size -- Determines the size of the file. *
* *
* If the file is part of the mixfile system, then the size of the file is already *
* determined and available. Otherwise, go to the low level system to find the file *
* size. *
* *
* INPUT: none *
* *
* OUTPUT: Returns with the size of the file in bytes. *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 08/08/1994 JLB : Created. *
* 08/05/1996 JLB : Handles returning size of embedded file. *
*=============================================================================================*/
long CCFileClass::Size(void)
{
/*
** If the file is resident, the the size is already known. Just return the size in this
** case.
*/
if (Is_Resident()) return(Data.Get_Size());
/*
** If the file is not available as a stand alone file, then search for it in the
** mixfiles in order to get its size.
*/
if (!CDFileClass::Is_Available()) {
long length = 0;
MFCD::Offset(File_Name(), NULL, NULL, NULL, &length);
return(length);
}
return(CDFileClass::Size());
}
/***********************************************************************************************
* CCFileClass::Is_Available -- Checks for existence of file on disk or in mixfile. *
* *
* This routine will examine the mixfile system looking for the file. If the file could *
* not be found there, then the disk is examined directly. *
* *
* INPUT: none *
* *
* OUTPUT: bool; Is the file available for opening? *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 08/08/1994 JLB : Created. *
*=============================================================================================*/
int CCFileClass::Is_Available(int )
{
/*
** A file that is open is presumed available.
*/
if (Is_Open()) return(true);
/*
** A file that is part of a mixfile is also presumed available.
*/
if (MFCD::Offset(File_Name())) {
return(true);
}
/*
** Otherwise a manual check of the file system is required to
** determine if the file is actually available.
*/
return(CDFileClass::Is_Available());
}
/***********************************************************************************************
* CCFileClass::Is_Open -- Determines if the file is open. *
* *
* A mixfile is open if there is a pointer to the mixfile data. In absence of this, *
* the the file is open if the file handle is valid. *
* *
* INPUT: none *
* *
* OUTPUT: bool; Is the file open? *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 08/08/1994 JLB : Created. *
*=============================================================================================*/
int CCFileClass::Is_Open(void) const
{
/*
** If the file is part of a cached file, then return that it is opened. A closed file
** doesn't have a valid pointer.
*/
if (Is_Resident()) return(true);
/*
** Otherwise, go to a lower level to determine if the file is open.
*/
return(CDFileClass::Is_Open());
}
/***********************************************************************************************
* CCFileClass::Close -- Closes the file. *
* *
* If this is a mixfile file, then only the pointers need to be adjusted. *
* *
* INPUT: none *
* *
* OUTPUT: none *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 08/08/1994 JLB : Created. *
*=============================================================================================*/
void CCFileClass::Close(void)
{
new(&Data) ::Buffer;
Position = 0; // Starts at beginning offset.
CDFileClass::Close();
}
/***********************************************************************************************
* CCFileClass::Open -- Opens a file from either the mixfile system or the rawfile system. *
* *
* This routine will open the specified file. It examines the mixfile system to find a *
* match. If one is found then the file is "opened" in a special cached way. Otherwise *
* it is opened as a standard DOS file. *
* *
* INPUT: rights -- The access rights desired. *
* *
* OUTPUT: bool; Was the file opened successfully? *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 08/08/1994 JLB : Created. *
*=============================================================================================*/
int CCFileClass::Open(int rights)
{
/*
** Always close the file if it was open.
*/
Close();
/*
** Perform a preliminary check to see if the specified file
** exists on the disk. If it does, then open this file regardless
** of whether it also exists in RAM. This is slower, but allows
** upgrade files to work.
*/
if ((rights & WRITE) || CDFileClass::Is_Available()) {
return(CDFileClass::Open(rights));
}
/*
** Check to see if file is part of a mixfile and that mixfile is currently loaded
** into RAM.
*/
MFCD * mixfile = NULL;
void * pointer = NULL;
long length = 0;
long start = 0;
if (MFCD::Offset(File_Name(), &pointer, &mixfile, &start, &length)) {
assert(mixfile != NULL);
/*
** If the mixfile is located on disk, then fake out the file system to read from
** the mixfile, but think it is reading from a solitary file.
*/
if (pointer == NULL && mixfile != NULL) {
/*
** This is a legitimate open to the file. All access to the file through this
** file object will be appropriately adjusted for mixfile support however. Also
** note that the filename attached to this object is NOT the same as the file
** attached to the file handle.
*/
char * dupfile = strdup(File_Name());
Open(mixfile->Filename, READ);
Searching(false); // Disable multi-drive search.
Set_Name(dupfile);
Searching(true);
free(dupfile);
Bias(0);
Bias(start, length);
Seek(0, SEEK_SET);
} else {
new (&Data) ::Buffer(pointer, length);
Position = 0;
}
} else {
/*
** The file cannot be found in any mixfile, so it must reside as
** an individual file on the disk. Or else it is just plain missing.
*/
return(CDFileClass::Open(rights));
}
return(true);
}
/***********************************************************************************************
* CCFileClass::Get_Date_Time -- Gets the date and time the file was last modified. *
* *
* Use this routine to get the date and time of the file. *
* *
* INPUT: none *
* *
* OUTPUT: Returns with the file date and time as a long. *
* Use the YEAR(long), MONTH(),.... *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 11/14/1995 DRD : Created. *
*=============================================================================================*/
unsigned long CCFileClass::Get_Date_Time(void)
{
unsigned long datetime;
MFCD * mixfile;
datetime = CDFileClass::Get_Date_Time();
if ( !datetime ) {
if (MFCD::Offset(File_Name(), NULL, &mixfile, NULL, NULL)) {
//
// check for nested MIX files
//
return( CCFileClass(mixfile->Filename).Get_Date_Time() );
}
// else return 0 indicating no file
}
return( datetime );
}
/***********************************************************************************************
* CCFileClass::Set_Date_Time -- Sets the date and time the file was last modified. *
* *
* Use this routine to set the date and time of the file. *
* *
* INPUT: the file date and time as a long *
* *
* OUTPUT: successful or not if the file date and time was changed. *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 11/14/1995 DRD : Created. *
*=============================================================================================*/
bool CCFileClass::Set_Date_Time( unsigned long datetime )
{
bool status;
MFCD * mixfile;
status = CDFileClass::Set_Date_Time( datetime );
if ( !status ) {
if (MFCD::Offset(File_Name(), NULL, &mixfile, NULL, NULL)) {
//
// check for nested MIX files
//
return( CCFileClass(mixfile->Filename).Set_Date_Time( datetime ) );
}
// else return 0 indicating no file
}
return( status );
}
/***********************************************************************************
** Backward compatibility section.
*/
//extern "C" {
static CCFileClass Handles[10];
int __cdecl Open_File(char const * file_name, int mode)
{
for (int index = 0; index < ARRAY_SIZE(Handles); index++) {
if (!Handles[index].Is_Open()) {
if (Handles[index].Open(file_name, mode)) {
return(index);
}
break;
}
}
return(WWERROR);
}
void __cdecl Close_File(int handle)
{
if (handle != WWERROR && Handles[handle].Is_Open()) {
Handles[handle].Close();
}
}
long __cdecl Read_File(int handle, void * buf, unsigned long bytes)
{
if (handle != WWERROR && Handles[handle].Is_Open()) {
return(Handles[handle].Read(buf, bytes));
}
return(0);
}
long __cdecl Write_File(int handle, void const * buf, unsigned long bytes)
{
if (handle != WWERROR && Handles[handle].Is_Open()) {
return(Handles[handle].Write(buf, bytes));
}
return(0);
}
int __cdecl Find_File(char const * file_name)
{
CCFileClass file(file_name);
return(file.Is_Available());
}
#ifdef NEVER
int __cdecl Delete_File(char const * file_name)
{
return(CCFileClass(file_name).Delete());
}
int __cdecl Create_File(char const * file_name)
{
return(CCFileClass(file_name).Create());
}
unsigned long __cdecl Load_Data(char const * name, void * ptr, unsigned long size)
{
return(CCFileClass(name).Read(ptr, size));
}
#endif
void * __cdecl Load_Alloc_Data(char const * name, int )
{
CCFileClass file(name);
return(Load_Alloc_Data(file));
}
unsigned long __cdecl File_Size(int handle)
{
if (handle != WWERROR && Handles[handle].Is_Open()) {
return(Handles[handle].Size());
}
return(0);
}
#ifdef NEVER
unsigned long __cdecl Write_Data(char const * name, void const * ptr, unsigned long size)
{
return(CCFileClass(name).Write(ptr, size));
}
#endif
unsigned long __cdecl Seek_File(int handle, long offset, int starting)
{
if (handle != WWERROR && Handles[handle].Is_Open()) {
return(Handles[handle].Seek(offset, starting));
}
return(0);
}
#ifdef NEVER
bool __cdecl Multi_Drive_Search(bool on)
{
// return(CCFileClass::Multi_Drive_Search(on));
return(on);
}
void __cdecl WWDOS_Init(void)
{
}
void __cdecl WWDOS_Shutdown(void)
{
}
int __cdecl Find_Disk_Number(char const *)
{
return(0);
}
#endif
//unsigned long __cdecl Load_Uncompress(char const * file, BuffType uncomp_buff, BuffType dest_buff, void * reserved_data)
//{
// return(Load_Uncompress(CCFileClass(file), uncomp_buff, dest_buff, reserved_data));
// return(CCFileClass(file).Load_Uncompress(uncomp_buff, dest_buff, reserved_data));
//}
#ifdef WIN32
extern "C" {
int MaxDevice;
int DefaultDrive;
char CallingDOSInt;
}
#endif
void Unfragment_File_Cache(void)
{
}

104
REDALERT/CCFILE.H Normal file
View File

@ -0,0 +1,104 @@
//
// 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/CCFILE.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 : CCFILE.H *
* *
* Programmer : Joe L. Bostic *
* *
* Start Date : October 17, 1994 *
* *
* Last Update : October 17, 1994 [JLB] *
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef CCFILE_H
#define CCFILE_H
//#include <wwlib32.h>
#include <limits.h>
#include "mixfile.h"
#include "cdfile.h"
#include "buff.h"
/*
** This derived class for file access knows about mixfiles (packed files). It can handle opening
** a file that is embedded within a mixfile. This is true if the mixfile is cached or resides on
** disk. It is functionally similar to pakfiles, except much faster and less RAM intensive.
*/
class CCFileClass : public CDFileClass
{
public:
CCFileClass(char const * filename);
CCFileClass(void);
virtual ~CCFileClass(void) {Position = 0;};
// Delete should be overloaded here as well. Don't allow deletes of mixfiles.
bool Is_Resident(void) const {return(Data.Get_Buffer() != NULL);}
virtual int Is_Available(int forced=false);
virtual int Is_Open(void) const;
virtual int Open(char const * filename, int rights=READ) {Set_Name(filename);return Open(rights);};
virtual int Open(int rights=READ);
virtual long Read(void * buffer, long size);
virtual long Seek(long pos, int dir=SEEK_CUR);
virtual long Size(void);
virtual long Write(void const * buffer, long size);
virtual void Close(void);
virtual unsigned long Get_Date_Time(void);
virtual bool Set_Date_Time(unsigned long datetime);
virtual void Error(int error, int canretry = false, char const * filename=NULL);
private:
/*
** This indicates the file is actually part of a resident image of the mixfile
** itself. In this case, the embedded file handle is invalid. All file access actually
** gets routed through the cached version of the file. This is a pointer to the start
** of the RAM image of the file.
*/
::Buffer Data;
// void * Pointer;
/*
** This is the size of the file if it was embedded in a mixfile. The size must be manually
** kept track of because the DOS file size is invalid.
*/
// long Length;
/*
** This is the current seek position of the file. It is duplicated here if the file is
** part of a mixfile since the DOS seek position is not accurate. This value will
** range from zero to the size of the file in bytes.
*/
long Position;
// Force these to never be invoked.
CCFileClass const & operator = (CCFileClass const & c);
CCFileClass (CCFileClass const & );
};
template <> class MixFileClass<CDFileClass>;
#endif

1484
REDALERT/CCINI.CPP Normal file

File diff suppressed because it is too large Load Diff

117
REDALERT/CCINI.H Normal file
View File

@ -0,0 +1,117 @@
//
// 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/CCINI.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 : CCINI.H *
* *
* Programmer : Joe L. Bostic *
* *
* Start Date : 05/24/96 *
* *
* Last Update : May 24, 1996 [JLB] *
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef CCINI_H
#define CCINI_H
#include "ini.h"
#include "fixed.h"
#include "pk.h"
class TriggerTypeClass;
/*
** The advanced version of the INI database manager. It handles the C&C expansion types and
** identifiers. In addition, it automatically stores a message digest with the INI data
** so that verification can occur.
*/
class CCINIClass : public INIClass
{
public:
CCINIClass(void) : IsDigestPresent(false) {}
bool Load(FileClass & file, bool withdigest);
int Load(Straw & file, bool withdigest);
int Save(FileClass & file, bool withdigest) const;
int Save(Pipe & pipe, bool withdigest) const;
long Get_Buildings(char const * section, char const * entry, long defvalue) const;
UnitType Get_UnitType(char const * section, char const * entry, UnitType defvalue) const;
AnimType Get_AnimType(char const * section, char const * entry, AnimType defvalue) const;
ArmorType Get_ArmorType(char const * section, char const * entry, ArmorType defvalue) const;
BulletType Get_BulletType(char const * section, char const * entry, BulletType defvalue) const;
HousesType Get_HousesType(char const * section, char const * entry, HousesType defvalue) const;
LEPTON Get_Lepton(char const * section, char const * entry, LEPTON defvalue) const;
MPHType Get_MPHType(char const * section, char const * entry, MPHType defvalue) const;
OverlayType Get_OverlayType(char const * section, char const * entry, OverlayType defvalue) const;
SourceType Get_SourceType(char const * section, char const * entry, SourceType defvalue) const;
TerrainType Get_TerrainType(char const * section, char const * entry, TerrainType defvalue) const;
TheaterType Get_TheaterType(char const * section, char const * entry, TheaterType defvalue) const;
ThemeType Get_ThemeType(char const * section, char const * entry, ThemeType defvalue) const;
TriggerTypeClass * Get_TriggerType(char const * section, char const * entry) const;
VQType Get_VQType(char const * section, char const * entry, VQType defvalue) const;
VocType Get_VocType(char const * section, char const * entry, VocType defvalue) const;
WarheadType Get_WarheadType(char const * section, char const * entry, WarheadType defvalue) const;
WeaponType Get_WeaponType(char const * section, char const * entry, WeaponType defvalue) const;
long Get_Owners(char const * section, char const * entry, long defvalue) const;
CrateType Get_CrateType(char const * section, char const * entry, CrateType defvalue) const;
bool Put_Buildings(char const * section, char const * entry, long value);
bool Put_AnimType(char const * section, char const * entry, AnimType value);
bool Put_UnitType(char const * section, char const * entry, UnitType value);
bool Put_ArmorType(char const * section, char const * entry, ArmorType value);
bool Put_BulletType(char const * section, char const * entry, BulletType value);
bool Put_HousesType(char const * section, char const * entry, HousesType value);
bool Put_Lepton(char const * section, char const * entry, LEPTON value);
bool Put_MPHType(char const * section, char const * entry, MPHType value);
bool Put_VQType(char const * section, char const * entry, VQType value);
bool Put_OverlayType(char const * section, char const * entry, OverlayType value);
bool Put_Owners(char const * section, char const * entry, long value);
bool Put_SourceType(char const * section, char const * entry, SourceType value);
bool Put_TerrainType(char const * section, char const * entry, TerrainType value);
bool Put_TheaterType(char const * section, char const * entry, TheaterType value);
bool Put_ThemeType(char const * section, char const * entry, ThemeType value);
bool Put_TriggerType(char const * section, char const * entry, TriggerTypeClass * value);
bool Put_VocType(char const * section, char const * entry, VocType value);
bool Put_WarheadType(char const * section, char const * entry, WarheadType value);
bool Put_WeaponType(char const * section, char const * entry, WeaponType value);
bool Put_CrateType(char const * section, char const * entry, CrateType value);
int Get_Unique_ID(void) const;
private:
void Calculate_Message_Digest(void);
void Invalidate_Message_Digest(void);
bool IsDigestPresent:1;
/*
** This is the message digest (SHA) of the INI database that was embedded as part of
** the INI file.
*/
unsigned char Digest[20];
};
#endif

418
REDALERT/CCMPATH.CPP Normal file
View File

@ -0,0 +1,418 @@
//
// 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
/***************************************************************************
* *
* Project Name : Command & Conquer *
* *
* File Name : CCMPATH.CPP *
* *
* Programmer : Bill R. Randolph *
* *
* Start Date : 01/09/96 *
* *
* Last Update : January 11, 1996 [BRR] *
* *
*-------------------------------------------------------------------------*
* Functions: *
* Init_MPATH -- Performs MPATH-specific initialization *
* Shutdown_MPATH -- Shuts down MPATH connections *
* Connect_MPATH -- Waits for connections to other players *
* Destroy_MPATH_Connection -- Destroys the given connection *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "function.h"
/***************************************************************************
* Init_MPATH -- Performs MPATH-specific initialization *
* *
* INPUT: *
* none. *
* *
* OUTPUT: *
* 1 = OK, 0 = error *
* *
* WARNINGS: *
* none. *
* *
* HISTORY: *
* 01/09/1996 BRR : Created. *
*=========================================================================*/
int Init_MPATH(void)
{
#if(MPATH)
//------------------------------------------------------------------------
// Allocate a packet buffer for MPATH's use
//------------------------------------------------------------------------
Session.MPathPacket = new char[Session.MPathSize];
//------------------------------------------------------------------------
// Read the multiplayer settings from the CONQUER.INI file, and the game
// options from the options file.
//------------------------------------------------------------------------
Session.Read_MultiPlayer_Settings();
if (!Read_MPATH_Game_Options()) {
WWMessageBox().Process("Unable to load game settings!");
//Prog_End();
Emergency_Exit(0);
}
//------------------------------------------------------------------------
// Flush all incoming packets
//------------------------------------------------------------------------
MPath->Flush_All();
//------------------------------------------------------------------------
// Form connections to all other players
//------------------------------------------------------------------------
Connect_MPATH();
//------------------------------------------------------------------------
// Set multiplayer values for the local system, and timing values.
//------------------------------------------------------------------------
Session.CommProtocol = COMM_PROTOCOL_MULTI_E_COMP;
return (1);
#else
return (1);
#endif
} // end of Init_MPATH
/***************************************************************************
* Shutdown_MPATH -- Shuts down MPATH connections *
* *
* INPUT: *
* none. *
* *
* OUTPUT: *
* none. *
* *
* WARNINGS: *
* none. *
* *
* HISTORY: *
* 01/09/1996 BRR : Created. *
*=========================================================================*/
void Shutdown_MPATH(void)
{
#if(MPATH)
CDTimerClass<SystemTimerClass> timer;
//------------------------------------------------------------------------
// Wait a full second before exiting, to ensure all packets get sent.
//------------------------------------------------------------------------
timer = 60;
while (timer) ;
//------------------------------------------------------------------------
// Free memory
//------------------------------------------------------------------------
if (Session.MPathPacket) {
delete [] Session.MPathPacket;
Session.MPathPacket = NULL;
}
if (MPath) {
delete MPath;
MPath = NULL;
}
return;
#endif
} // end of Shutdown_MPATH
/***************************************************************************
* Connect_MPATH -- Waits for connections to other players *
* *
* INPUT: *
* none. *
* *
* OUTPUT: *
* none. *
* *
* WARNINGS: *
* none. *
* *
* HISTORY: *
* 01/10/1996 BRR : Created. *
*=========================================================================*/
void Connect_MPATH(void)
{
#if(MPATH)
typedef struct ConnectPacketTag {
NetCommandType Dummy; // packet type; set to PING
char Name[MPLAYER_NAME_MAX]; // player's name
HousesType House; // player's ActLike
unsigned char Color; // player's Color
} ConnectPacketType;
int num_players;
int num_found;
ConnectPacketType send_packet;
ConnectPacketType receive_packet;
int address;
int found;
int size;
int i;
CDTimerClass<SystemTimerClass> send_timer;
NodeNameType *who;
enum {
D_TXT6_H = 7,
D_MARGIN = 5,
};
static int x,y,w,h;
char const *buf1;
char const *buf2;
int display = 0;
RemapControlType * scheme = GadgetClass::Get_Color_Scheme();
//
// Clear the Players list
//
while (Session.Players.Count() > 0) {
delete Session.Players[0];
Session.Players.Delete(Session.Players[0]);
}
//
// Add myself to the list first thing
//
who = new NodeNameType;
strcpy(who->Name, Session.Handle);
who->Player.House = Session.House;
who->Player.Color = Session.ColorIdx;
Session.Players.Add (who);
//
// Find out how many players to wait for
//
num_players = MPath->Find_Num_Connections();
num_found = 0;
Session.NumPlayers = num_players + 1;
//
// Send out a packet announcing my presence
//
send_packet.Dummy = NET_PING;
strcpy(send_packet.Name, Session.Handle);
send_packet.House = Session.House;
send_packet.Color = Session.ColorIdx;
MPath->Send_Global_Message(&send_packet, sizeof(send_packet), 0, 0);
//
// Start our packet-sending timer
//
send_timer = 240;
//
// Wait for all players to enter the game
//
display = 1;
while (num_found < num_players) {
#ifdef WIN32
/*
** If we have just received input focus again after running in the background then
** we need to redraw.
*/
if (AllSurfaces.SurfacesRestored) {
AllSurfaces.SurfacesRestored=FALSE;
display = 1;
}
#endif
if (display) {
Fancy_Text_Print("", 0, 0, 0, 0, TPF_TEXT);
buf1 = Text_String(TXT_WAITING_FOR_CONNECTIONS);
buf2 = Text_String(TXT_PRESS_ESC);
w = MAX(String_Pixel_Width(buf1),String_Pixel_Width(buf2));
w += (D_MARGIN * 2);
h = (D_TXT6_H * 2) + (D_MARGIN * 7);
x = 160 - (w / 2);
y = 100 - (h / 2);
Hide_Mouse();
//Set_Logic_Page(SeenBuff);
Dialog_Box(x * RESFACTOR, y * RESFACTOR, w * RESFACTOR, h * RESFACTOR);
Fancy_Text_Print(buf1,
160 * RESFACTOR,
(y + (D_MARGIN * 2)) * RESFACTOR,
scheme, TBLACK, TPF_CENTER | TPF_TEXT);
Fancy_Text_Print(buf2,
160 * RESFACTOR,
(y + (D_MARGIN * 2) + D_TXT6_H + D_MARGIN) * RESFACTOR,
scheme, TBLACK, TPF_CENTER | TPF_TEXT);
Show_Mouse();
display = 0;
}
MPath->Service();
//
// Check for an incoming packet; if a PING comes in, see if we already
// have this player in our Players list. If not, add him.
//
if (MPath->Get_Global_Message (&receive_packet, &size, &address) &&
receive_packet.Dummy == NET_PING) {
found = 0;
for (i = 1; i < Session.Players.Count(); i++) {
if (Session.Players[i]->MPathAddress == address) {
found = 1;
break;
}
}
//
// Create a new connection and a new node in the list.
//
if (!found) {
who = new NodeNameType;
strcpy(who->Name, receive_packet.Name);
who->MPathAddress = address;
who->Player.House = receive_packet.House;
who->Player.Color = (PlayerColorType)receive_packet.Color;
Session.Players.Add (who);
num_found++;
MPath->Send_Global_Message(&send_packet, sizeof(send_packet), 1,
address);
}
}
//
// If the user hits ESC, bail out.
//
if (Keyboard->Check()) {
if (Keyboard->Get() == KN_ESC) {
//Prog_End();
Emergency_Exit(0);
}
}
//
// When our timer expires, re-send the packet.
//
if (!send_timer) {
send_packet.Dummy = NET_PING;
MPath->Send_Global_Message(&send_packet, sizeof(send_packet), 0, 0);
send_timer = 240;
}
}
#else
return;
#endif
}
/***************************************************************************
* Destroy_MPATH_Connection -- Destroys the given connection *
* *
* INPUT: *
* id connection ID to destroy *
* error 0 = user signed off; 1 = connection error; otherwise, *
* no error is shown. *
* *
* OUTPUT: *
* none. *
* *
* WARNINGS: *
* none. *
* *
* HISTORY: *
* 01/11/1996 BRR : Created. *
*=========================================================================*/
void Destroy_MPATH_Connection(int id, int error)
{
#if(MPATH)
int i;
HouseClass *housep;
char txt[80];
//------------------------------------------------------------------------
// Do nothing if the house isn't human.
//------------------------------------------------------------------------
housep = HouseClass::As_Pointer((HousesType)id);
if (!housep || !housep->IsHuman)
return;
/*------------------------------------------------------------------------
Create a message to display to the user
------------------------------------------------------------------------*/
txt[0] = '\0';
if (error==1) {
sprintf(txt,Text_String(TXT_CONNECTION_LOST),MPath->Connection_Name(id));
} else if (error==0) {
sprintf(txt,Text_String(TXT_LEFT_GAME),MPath->Connection_Name(id));
}
if (strlen(txt)) {
Session.Messages.Add_Message (NULL,0, txt, housep->RemapColor,
TPF_TEXT, Rule.MessageDelay * TICKS_PER_MINUTE);
Map.Flag_To_Redraw(false);
}
//------------------------------------------------------------------------
// Remove this player from the Players vector
//------------------------------------------------------------------------
for (i = 0; i < Session.Players.Count(); i++) {
if (!stricmp(Session.Players[i]->Name,housep->IniName)) {
delete Session.Players[i];
Session.Players.Delete(Session.Players[i]);
break;
}
}
/*------------------------------------------------------------------------
Delete the MPATH connection
------------------------------------------------------------------------*/
MPath->Delete_Connection(id);
//------------------------------------------------------------------------
// Turn the player's house over to the computer's AI
//------------------------------------------------------------------------
housep->IsHuman = false;
housep->IQ = Rule.MaxIQ;
strcpy (housep->IniName,Text_String(TXT_COMPUTER));
Session.NumPlayers--;
/*------------------------------------------------------------------------
If we're the last player left, tell the user.
------------------------------------------------------------------------*/
if (Session.NumPlayers == 1) {
sprintf(txt,"%s",Text_String(TXT_JUST_YOU_AND_ME));
Session.Messages.Add_Message (NULL, 0, txt, housep->RemapColor,
TPF_TEXT, Rule.MessageDelay * TICKS_PER_MINUTE);
Map.Flag_To_Redraw(false);
}
#else
id = id;
error = error;
#endif
} // end of Destroy_MPATH_Connection
/***************************** end of ccmpath.cpp **************************/

111
REDALERT/CCPTR.CPP Normal file
View File

@ -0,0 +1,111 @@
//
// 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/CCPTR.CPP 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 : CCPTR.CPP *
* *
* Programmer : Joe L. Bostic *
* *
* Start Date : 06/07/96 *
* *
* Last Update : July 6, 1996 [JLB] *
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* CCPtr<T>::operator > -- Greater than comparison operator. *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "function.h"
template class CCPtr<AircraftClass>;
template class CCPtr<AircraftTypeClass>;
template class CCPtr<AnimClass>;
template class CCPtr<AnimTypeClass>;
template class CCPtr<BuildingClass>;
template class CCPtr<BuildingTypeClass>;
template class CCPtr<BulletClass>;
template class CCPtr<BulletTypeClass>;
template class CCPtr<FactoryClass>;
template class CCPtr<HouseClass>;
template class CCPtr<HouseTypeClass>;
template class CCPtr<InfantryClass>;
template class CCPtr<InfantryTypeClass>;
template class CCPtr<OverlayClass>;
template class CCPtr<OverlayTypeClass>;
template class CCPtr<SmudgeClass>;
template class CCPtr<SmudgeTypeClass>;
template class CCPtr<TeamClass>;
template class CCPtr<TeamTypeClass>;
template class CCPtr<TemplateClass>;
template class CCPtr<TemplateTypeClass>;
template class CCPtr<TerrainClass>;
template class CCPtr<TerrainTypeClass>;
template class CCPtr<TriggerClass>;
template class CCPtr<TriggerTypeClass>;
template class CCPtr<UnitClass>;
template class CCPtr<UnitTypeClass>;
template class CCPtr<VesselClass>;
template class CCPtr<VesselTypeClass>;
template class CCPtr<WarheadTypeClass>;
template class CCPtr<WeaponTypeClass>;
template<class T> FixedIHeapClass* CCPtr<T>::Heap = NULL;
/*
** These member functions for the CCPtr class cannot be declared inside the
** class definition since they could refer to other objects that themselves
** contain CCPtr objects. The recursive nature of this type of declaration
** is not handled by Watcom, hence the body declaration is dislocated here.
*/
template<class T>
CCPtr<T>::CCPtr(T * ptr) : ID(-1)
{
if (ptr != NULL) {
ID = ptr->ID;
}
}
/***********************************************************************************************
* CCPtr<T>::operator > -- Greater than comparison operator. *
* *
* This will compare two pointer value to see if the left hand value is greater than the *
* right hand. The values are compared by comparing based on their Name() functions. *
* *
* INPUT: rvalue -- The right handle CCPtr value. *
* *
* OUTPUT: Is the left hand value greater than the right hand value? *
* *
* WARNINGS: The values pointed to by CCPtr must have a Name() function defined. *
* *
* HISTORY: *
* 07/06/1996 JLB : Created. *
*=============================================================================================*/
template<class T>
bool CCPtr<T>::operator > (CCPtr<T> const & rvalue) const
{
return (stricmp((*this)->Name(), rvalue->Name()) > 0);
}

114
REDALERT/CCPTR.H Normal file
View File

@ -0,0 +1,114 @@
//
// 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/CCPTR.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 : CCPTR.H *
* *
* Programmer : Joe L. Bostic *
* *
* Start Date : 06/07/96 *
* *
* Last Update : June 7, 1996 [JLB] *
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef CCPTR_H
#define CCPTR_H
/*
** The CCPtr class is designed for a specific purpose. It functions like a pointer except that
** it requires no fixups for saving and loading. If pointer fixups are not an issue, than using
** regular pointers would be more efficient.
*/
template<class T>
class CCPtr
{
public:
CCPtr(void) : ID(-1) {};
CCPtr(NoInitClass const & ) {};
CCPtr(T * ptr);
operator T * (void) const {
if (ID == -1) return(NULL);
assert(Heap != NULL && ID < Heap->Length());
return((T*) (*Heap)[ID]);
}
T & operator * (void) const {
assert(Heap != NULL && ID < Heap->Length());
return(*(T*)(*Heap)[ID]);
}
T * operator -> (void) const {
if (ID == -1) return(NULL);
assert(Heap != NULL && ID < Heap->Length());
return((T*) (*Heap)[ID]);
}
bool Is_Valid(void) const {return(ID != -1);}
bool operator == (CCPtr<T> const & rvalue) const {return(ID == rvalue.ID);}
bool operator != (CCPtr<T> const & rvalue) const {return(ID != rvalue.ID);}
bool operator > (CCPtr<T> const & rvalue) const;
bool operator <= (CCPtr<T> const & rvalue) const {return (rvalue > *this);}
bool operator < (CCPtr<T> const & rvalue) const {return (*this != rvalue && rvalue > *this);}
bool operator >= (CCPtr<T> const & rvalue) const {return (*this == rvalue || rvalue > *this);}
long Raw(void) const {return(ID);}
void Set_Raw(long value) {ID = value;}
static void Set_Heap(FixedIHeapClass *heap) {Heap = heap;}
private:
static FixedIHeapClass * Heap;
/*
** This is the ID number of the object it refers to. By using an ID number, this class can
** be saved and loaded without pointer fixups.
*/
int ID;
};
/*
** These template helper functions tell the compiler what to do in the
** ambiguous case of a CCPtr on one side and a regular type pointer on the
** other side. In such a case the compiler could create a temp CCPtr object
** OR call the conversion operator on the existing CCPtr object. Either way
** is technically valid, but the compiler doesn't know which is better so it
** generates an error. These routines force the conversion operator rather than
** creating a temporary object. This presumes that the conversion operator is
** cheaper than constructing a temporary and that cheaper solutions are desirable.
*/
template<class T>
int operator == (CCPtr<T> & lvalue, T * rvalue)
{
return((T*)lvalue == rvalue);
}
template<class T>
int operator == (T * lvalue, CCPtr<T> & rvalue)
{
return(lvalue == (T*)rvalue);
}
#endif

600
REDALERT/CCTEN.CPP Normal file
View File

@ -0,0 +1,600 @@
//
// 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
/***************************************************************************
* *
* Project Name : Command & Conquer *
* *
* File Name : CCTEN.CPP *
* *
* Programmer : Bill R. Randolph *
* *
* Start Date : 01/09/96 *
* *
* Last Update : November 27, 1996 [BRR] *
* *
*-------------------------------------------------------------------------*
* Functions: *
* Init_TEN -- Performs TEN-specific initialization *
* Shutdown_TEN -- Shuts down TEN connections *
* Connect_TEN -- Waits for connections to other players *
* Destroy_TEN_Connection -- Destroys the given connection *
* Debug_Mono -- Custom mono prints *
* Send_TEN_Win_Packet -- Sends a win packet to server *
* Send_TEN_Alliance -- Sends an ally/enemy packet to server *
* Send_TEN_Out_Of_Sync -- Announces this game out of sync *
* Send_TEN_Packet_Too_Late -- Announces packet-received-too-late *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "function.h"
#if(TEN)
#ifdef WIN32
#define WINDOWS
#endif
#include "ten.h"
#endif
void Connect_TEN(void);
void Debug_Mono(void);
/***************************************************************************
* Init_TEN -- Performs TEN-specific initialization *
* *
* INPUT: *
* none. *
* *
* OUTPUT: *
* 1 = OK, 0 = error *
* *
* WARNINGS: *
* none. *
* *
* HISTORY: *
* 01/09/1996 BRR : Created. *
*=========================================================================*/
int Init_TEN(void)
{
#if(TEN)
//------------------------------------------------------------------------
// Allocate a packet buffer for TEN's use
//------------------------------------------------------------------------
Session.TenPacket = new char[Session.TenSize];
//------------------------------------------------------------------------
// Read the multiplayer settings from the CONQUER.INI file, and the game
// options from the options file.
//------------------------------------------------------------------------
Session.Read_MultiPlayer_Settings();
if (!Read_TEN_Game_Options()) {
WWMessageBox().Process("Unable to load game settings!");
//Prog_End();
Emergency_Exit(0);
}
//------------------------------------------------------------------------
// Flush all incoming packets
//------------------------------------------------------------------------
Ten->Flush_All();
//------------------------------------------------------------------------
// Form connections to all other players
//------------------------------------------------------------------------
Connect_TEN();
//------------------------------------------------------------------------
// Set multiplayer values for the local system, and timing values.
//------------------------------------------------------------------------
Session.CommProtocol = COMM_PROTOCOL_MULTI_E_COMP;
return (1);
#else
return (1);
#endif
} // end of Init_TEN
/***************************************************************************
* Shutdown_TEN -- Shuts down TEN connections *
* *
* INPUT: *
* none. *
* *
* OUTPUT: *
* none. *
* *
* WARNINGS: *
* none. *
* *
* HISTORY: *
* 01/09/1996 BRR : Created. *
*=========================================================================*/
void Shutdown_TEN(void)
{
#if(TEN)
CDTimerClass<SystemTimerClass> timer;
//------------------------------------------------------------------------
// Wait a full second before exiting, to ensure all packets get sent.
//------------------------------------------------------------------------
timer = 60;
while (timer) ;
//------------------------------------------------------------------------
// Free memory
//------------------------------------------------------------------------
if (Session.TenPacket) {
delete [] Session.TenPacket;
Session.TenPacket = NULL;
}
if (Ten) {
delete Ten;
Ten = NULL;
}
return;
#endif
} // end of Shutdown_TEN
/***************************************************************************
* Connect_TEN -- Waits for connections to other players *
* *
* INPUT: *
* none. *
* *
* OUTPUT: *
* none. *
* *
* WARNINGS: *
* MPlayerCount must have been initialized at this point. *
* *
* HISTORY: *
* 01/10/1996 BRR : Created. *
*=========================================================================*/
void Connect_TEN(void)
{
#if(TEN)
typedef struct ConnectPacketTag {
NetCommandType Dummy; // packet type; set to PING
char Name[MPLAYER_NAME_MAX]; // player's name
HousesType House; // player's ActLike
unsigned char Color; // player's Color
} ConnectPacketType;
int num_players;
int num_found;
ConnectPacketType send_packet;
ConnectPacketType receive_packet;
int address;
int found;
int size;
int i;
CDTimerClass<SystemTimerClass> send_timer;
NodeNameType *who;
enum {
D_TXT6_H = 7,
D_MARGIN = 5,
};
static int x,y,w,h;
char const *buf1;
char const *buf2;
int display = 0;
RemapControlType * scheme = GadgetClass::Get_Color_Scheme();
//
// Clear the Players list
//
while (Session.Players.Count() > 0) {
delete Session.Players[0];
Session.Players.Delete(Session.Players[0]);
}
//
// Add myself to the list first thing
//
who = new NodeNameType;
strcpy(who->Name, Session.Handle);
who->Player.House = Session.House;
who->Player.Color = Session.ColorIdx;
Session.Players.Add (who);
//
// Find out how many players to wait for
//
num_players = Session.NumPlayers - 1;
num_found = 0;
//
// Send out a packet announcing my presence
//
send_packet.Dummy = NET_PING;
strcpy(send_packet.Name, Session.Handle);
send_packet.House = Session.House;
send_packet.Color = Session.ColorIdx;
Ten->Send_Global_Message(&send_packet, sizeof(send_packet), 0, -1);
//
// Start our packet-sending timer
//
send_timer = 240;
//
// Wait for all players to enter the game
//
display = 1;
while (num_found < num_players) {
#ifdef WIN32
/*
** If we have just received input focus again after running in the background then
** we need to redraw.
*/
if (AllSurfaces.SurfacesRestored) {
AllSurfaces.SurfacesRestored=FALSE;
display = 1;
}
#endif
if (display) {
Fancy_Text_Print("", 0, 0, 0, 0, TPF_TEXT);
buf1 = Text_String(TXT_WAITING_FOR_CONNECTIONS);
buf2 = Text_String(TXT_PRESS_ESC);
w = MAX(String_Pixel_Width(buf1),String_Pixel_Width(buf2));
w += (D_MARGIN * 2);
h = (D_TXT6_H * 2) + (D_MARGIN * 7);
x = 160 - (w / 2);
y = 100 - (h / 2);
Hide_Mouse();
//Set_Logic_Page(SeenBuff);
Dialog_Box(x * RESFACTOR, y * RESFACTOR, w * RESFACTOR, h * RESFACTOR);
Fancy_Text_Print(buf1,
160 * RESFACTOR,
(y + (D_MARGIN * 2)) * RESFACTOR,
scheme, TBLACK, TPF_CENTER | TPF_TEXT);
Fancy_Text_Print(buf2,
160 * RESFACTOR,
(y + (D_MARGIN * 2) + D_TXT6_H + D_MARGIN) * RESFACTOR,
scheme, TBLACK, TPF_CENTER | TPF_TEXT);
Show_Mouse();
display = 0;
}
Ten->Service();
//
// Check for an incoming packet; if a PING comes in, see if we already
// have this player in our Players list. If not, add him.
//
if (Ten->Get_Global_Message (&receive_packet, &size, &address) &&
receive_packet.Dummy == NET_PING) {
found = 0;
for (i = 1; i < Session.Players.Count(); i++) {
if (Session.Players[i]->TenAddress == address) {
found = 1;
break;
}
}
//
// Create a new connection and a new node in the list.
//
if (!found) {
who = new NodeNameType;
strcpy(who->Name, receive_packet.Name);
who->TenAddress = address;
who->Player.House = receive_packet.House;
who->Player.Color = (PlayerColorType)receive_packet.Color;
Session.Players.Add (who);
num_found++;
Ten->Send_Global_Message(&send_packet, sizeof(send_packet), 1,
address);
}
}
//
// If the user hits ESC, bail out.
//
if (Keyboard->Check()) {
if (Keyboard->Get() == KN_ESC) {
//Prog_End();
Emergency_Exit(0);
}
}
//
// When our timer expires, re-send the packet.
//
if (!send_timer) {
send_packet.Dummy = NET_PING;
Ten->Send_Global_Message(&send_packet, sizeof(send_packet), 0, -1);
send_timer = 240;
}
}
#else
return;
#endif
}
/***************************************************************************
* Destroy_TEN_Connection -- Destroys the given connection *
* *
* INPUT: *
* id connection ID to destroy (must be a HousesType) *
* error 0 = user signed off; 1 = connection error; otherwise, *
* no error is shown. *
* *
* OUTPUT: *
* none. *
* *
* WARNINGS: *
* none. *
* *
* HISTORY: *
* 01/11/1996 BRR : Created. *
*=========================================================================*/
void Destroy_TEN_Connection(int id, int error)
{
#if(TEN)
int i;
HouseClass *housep;
char txt[80];
//------------------------------------------------------------------------
// Do nothing if the house isn't human.
//------------------------------------------------------------------------
housep = HouseClass::As_Pointer((HousesType)id);
if (!housep || !housep->IsHuman)
return;
/*------------------------------------------------------------------------
Create a message to display to the user
------------------------------------------------------------------------*/
txt[0] = '\0';
if (error==1) {
sprintf(txt,Text_String(TXT_CONNECTION_LOST),Ten->Connection_Name(id));
} else if (error==0) {
sprintf(txt,Text_String(TXT_LEFT_GAME),Ten->Connection_Name(id));
}
if (strlen(txt)) {
Session.Messages.Add_Message (NULL,0, txt, housep->RemapColor,
TPF_TEXT, Rule.MessageDelay * TICKS_PER_MINUTE);
Map.Flag_To_Redraw(false);
}
//------------------------------------------------------------------------
// Remove this player from the Players vector
//------------------------------------------------------------------------
for (i = 0; i < Session.Players.Count(); i++) {
if (!stricmp(Session.Players[i]->Name,housep->IniName)) {
delete Session.Players[i];
Session.Players.Delete(Session.Players[i]);
break;
}
}
/*------------------------------------------------------------------------
Delete the TEN connection
------------------------------------------------------------------------*/
Ten->Delete_Connection(id);
//------------------------------------------------------------------------
// Turn the player's house over to the computer's AI
//------------------------------------------------------------------------
housep->IsHuman = false;
housep->IQ = Rule.MaxIQ;
strcpy (housep->IniName,Text_String(TXT_COMPUTER));
Session.NumPlayers--;
/*------------------------------------------------------------------------
If we're the last player left, tell the user.
------------------------------------------------------------------------*/
if (Session.NumPlayers == 1) {
sprintf(txt,"%s",Text_String(TXT_JUST_YOU_AND_ME));
Session.Messages.Add_Message (NULL, 0, txt, housep->RemapColor,
TPF_TEXT, Rule.MessageDelay * TICKS_PER_MINUTE);
Map.Flag_To_Redraw(false);
}
#else
id = id;
error = error;
#endif
} // end of Destroy_TEN_Connection
/***************************************************************************
* Debug_Mono -- Custom mono prints *
* *
* INPUT: *
* none. *
* *
* OUTPUT: *
* none. *
* *
* WARNINGS: *
* none. *
* *
* HISTORY: *
* 11/27/1996 BRR : Created. *
*=========================================================================*/
void Debug_Mono(void)
{
#if(TEN)
int i;
int id;
Mono_Printf("STATE: # Connections:%d\n",Ten->Num_Connections());
for (i=0;i<Ten->Num_Connections();i++) {
id = Ten->Connection_ID(i);
Mono_Printf("Connection %d: Name:%s, ID:%d, Address:%d\n",
i,
Ten->Connection_Name(id),
Ten->Connection_ID(i),
Ten->Connection_Address(id));
}
#endif
}
/***************************************************************************
* Send_TEN_Win_Packet -- Sends a win packet to server *
* *
* INPUT: *
* none. *
* *
* OUTPUT: *
* none. *
* *
* WARNINGS: *
* none. *
* *
* HISTORY: *
* 11/27/1996 BRR : Created. *
*=========================================================================*/
void Send_TEN_Win_Packet(void)
{
#if(TEN)
char winbuf[80];
char idbuf[20];
int first = 1;
HouseClass *hptr;
int i;
//
// Build a special text buffer to send to the TEN server. Format:
// "winner 'id id'", where 'id' is the Ten Player ID of each player
// on the winning team. (For TEN, the color index is the player ID.)
//
sprintf(winbuf,"winner '");
for (i = 0; i < Session.Players.Count(); i++) {
hptr = HouseClass::As_Pointer(Session.Players[i]->Player.ID);
if (!hptr->IsDefeated) {
if (!first) {
strcat(winbuf," ");
} else {
first = 0;
}
sprintf(idbuf,"%d", Session.Players[i]->Player.Color);
strcat (winbuf, idbuf);
}
}
strcat (winbuf,"' ");
tenArSetPlayerState(winbuf);
#endif // TEN
} // end of Send_TEN_Win_Packet
/***************************************************************************
* Send_TEN_Alliance -- Sends an ally/enemy packet to server *
* *
* INPUT: *
* whom name of player we're allying / enemying with *
* ally 1 = we're allying; 0 = we're breaking the alliance *
* *
* OUTPUT: *
* none. *
* *
* WARNINGS: *
* none. *
* *
* HISTORY: *
* 11/27/1996 BRR : Created. *
*=========================================================================*/
void Send_TEN_Alliance(char *whom, int ally)
{
#if(TEN)
char buf[80];
if (ally) {
sprintf(buf,"ally '%s' ",whom);
} else {
sprintf(buf,"enemy '%s' ",whom);
}
tenArSetPlayerState(buf);
#else
whom = whom;
ally = ally;
#endif // TEN
} // end of Send_TEN_Alliance
/***************************************************************************
* Send_TEN_Out_Of_Sync -- Announces this game out of sync *
* *
* INPUT: *
* none. *
* *
* OUTPUT: *
* none. *
* *
* WARNINGS: *
* none. *
* *
* HISTORY: *
* 11/27/1996 BRR : Created. *
*=========================================================================*/
void Send_TEN_Out_Of_Sync(void)
{
#if(TEN)
tenArSetPlayerState("sync '1' ");
#endif // TEN
} // end of Send_TEN_Out_Of_Sync
/***************************************************************************
* Send_TEN_Packet_Too_Late -- Announces packet-received-too-late *
* *
* INPUT: *
* none. *
* *
* OUTPUT: *
* none. *
* *
* WARNINGS: *
* none. *
* *
* HISTORY: *
* 11/27/1996 BRR : Created. *
*=========================================================================*/
void Send_TEN_Packet_Too_Late(void)
{
#if(TEN)
tenArSetPlayerState("toolate '1' ");
#endif // TEN
} // end of Send_TEN_Packet_Too_Late
/***************************** end of ccten.cpp *****************************/

3321
REDALERT/CDATA.CPP Normal file

File diff suppressed because it is too large Load Diff

746
REDALERT/CDFILE.CPP Normal file
View File

@ -0,0 +1,746 @@
//
// 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/CDFILE.CPP 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 : Westwood Library *
* *
* File Name : CDFILE.CPP *
* *
* Programmer : Joe L. Bostic *
* *
* Start Date : October 18, 1994 *
* *
* Last Update : September 22, 1995 [JLB] *
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* CDFileClass::Clear_Search_Drives -- Removes all record of a search path. *
* CDFileClass::Open -- Opens the file object -- with path search. *
* CDFileClass::Open -- Opens the file wherever it can be found. *
* CDFileClass::Set_Name -- Performs a multiple directory scan to set the filename. *
* CDFileClass::Set_Search_Drives -- Sets a list of search paths for file access. *
* Is_Disk_Inserted -- Checks to see if a disk is inserted in specified drive. *
* harderr_handler -- Handles hard DOS errors. *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "cdfile.h"
#include <stdio.h>
#include <string.h>
#ifndef WIN32
#include <wwstd.h>
#include <playcd.h>
#endif
/*
** Pointer to the first search path record.
*/
CDFileClass::SearchDriveType * CDFileClass::First = 0;
int CDFileClass::CurrentCDDrive = 0;
int CDFileClass::LastCDDrive = 0;
char CDFileClass::RawPath[512] = {0};
CDFileClass::CDFileClass(char const *filename) :
IsDisabled(false)
{
CDFileClass::Set_Name(filename);
// memset (RawPath, 0, sizeof(RawPath));
}
CDFileClass::CDFileClass(void) :
IsDisabled(false)
{
}
extern int Get_CD_Index (int cd_drive, int timeout);
/***********************************************************************************************
* harderr_handler -- Handles hard DOS errors. *
* *
* This routine will handle the low level DOS error trapper. Instead of displaying the *
* typical "Abort, Retry, Ignore" message, it simply returns with the failure code. The *
* cause of the error will fail. The likely case would be with disk I/O. *
* *
* INPUT: *
* *
* OUTPUT: Return the failure code. *
* *
* WARNINGS: Do no processing in this routine that could possibly generate another *
* hard error condition. *
* *
* HISTORY: *
* 09/22/1995 JLB : Created. *
*=============================================================================================*/
#ifdef WIN32
int harderr_handler(unsigned int , unsigned int , unsigned int *)
#else
int harderr_handler(unsigned int , unsigned int , unsigned int __far *)
#endif
{
return(0); // _HARDERR_FAIL);
}
/***********************************************************************************************
* Is_Disk_Inserted -- Checks to see if a disk is inserted in specified drive. *
* *
* This routine will examine the drive specified to see if there is a disk inserted. It *
* can be used for floppy drives as well as for the CD-ROM. *
* *
* INPUT: disk -- The drive number to examine. 0=A, 1=B, etc. *
* *
* OUTPUT: bool; Is a disk inserted into the specified drive? *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 09/20/1995 JLB : Created. *
*=============================================================================================*/
int cdecl Is_Disk_Inserted(int disk)
{
#ifndef OBSOLETE
disk;
return true;
#if (0)
struct find_t fb;
char scan[] = "?:\\*.*";
#ifndef WIN32
_harderr(harderr_handler); // BG: Install hard error handler
#endif
scan[0] = (char)('A' + disk);
return(_dos_findfirst(scan, _A_SUBDIR, &fb) == 0);
#endif
#else
struct {
struct {
char Length;
char Unit;
char Function;
char Status;
char Reserved[8];
} ReqHdr;
char MediaDescriptor; // Media descriptor byte from BPB.
void *Transfer; // Pointer to transfer address block.
short Length; // Number of bytes to transfer.
short Sector; // Starting sector number.
void *Volume; // Pointer to requested volume.
} IOCTLI;
char status[5];
memset(IOCTLI, 0, sizeof(IOCTLI));
IOCTLI.ReqHdr.Length = 26;
IOCTLI.ReqHdr.Unit = 0; // First CD-ROM controlled by this driver.
//IOCTLI.ReqHdr.Unit = 11; // Hard coded for K:
IOCTLI.ReqHdr.Function = 3; // IOCTL read
IOCTLI.Transfer = &status[0];
IOCTLI.Length = sizeof(status);
status[0] = 6; // Fetch device status code.
_AX = 0x440D;
_CX = 0x0003;
geninterrupt(0x21);
return(!(_AX & (1<<11)));
#endif
}
/***********************************************************************************************
* CDFileClass::Open -- Opens the file object -- with path search. *
* *
* This will open the file object, but since the file object could have been constructed *
* with a pathname, this routine will try to find the file first. For files opened for *
* writing, then use the existing filename without performing a path search. *
* *
* INPUT: rights -- The access rights to use when opening the file *
* *
* OUTPUT: bool; Was the open successful? *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 10/18/1994 JLB : Created. *
*=============================================================================================*/
int CDFileClass::Open(int rights)
{
return(BufferIOFileClass::Open(rights));
}
/***********************************************************************************************
* CDFC::Refresh_Search_Drives -- Updates the search path when a CD changes or is added *
* *
* *
* *
* INPUT: Nothing *
* *
* OUTPUT: Nothing *
* *
* WARNINGS: None *
* *
* HISTORY: *
* 5/22/96 9:01AM ST : Created *
*=============================================================================================*/
void CDFileClass::Refresh_Search_Drives (void)
{
Clear_Search_Drives();
Set_Search_Drives(RawPath);
}
#if 0
/***********************************************************************************************
* CDFileClass::Set_Search_Drives -- Sets a list of search paths for file access. *
* *
* This routine sets up a list of search paths to use when accessing files. The path list *
* is scanned if the file could not be found in the current directory. This is the primary *
* method of supporting CD-ROM drives, but is also useful for scanning network and other *
* directories. The pathlist as passed to this routine is of the same format as the path *
* list used by DOS -- paths are separated by semicolons and need not end in an antivirgule.*
* *
* If a path entry begins with "?:" then the question mark will be replaced with the first *
* CD-ROM drive letter available. If there is no CD-ROM driver detected, then this path *
* entry will be ignored. By using this feature, you can always pass the CD-ROM path *
* specification to this routine and it will not break if the CD-ROM is not loaded (as in *
* the case during development). *
* *
* Here is an example path specification: *
* *
* Set_Search_Drives("DATA;?:\DATA;F:\PROJECT\DATA"); *
* *
* In this example, the current directory will be searched first, followed by a the *
* subdirectory "DATA" located off of the current directory. If not found, then the CD-ROM *
* will be searched in a directory called "\DATA". If not found or the CD-ROM is not *
* present, then it will look to the hard coded path of "F:\PROJECTS\DATA" (maybe a *
* network?). If all of these searches fail, the file system will default to the current *
* directory and let the normal file error system take over. *
* *
* INPUT: pathlist -- Pointer to string of path specifications (separated by semicolons) *
* that will be used to search for files. *
* *
* OUTPUT: none *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 10/18/1994 JLB : Created. *
*=============================================================================================*/
int CDFileClass::Set_Search_Drives(char * pathlist)
{
int found = false;
int empty = false;
/*
** If there is no pathlist to add, then just return.
*/
if (!pathlist) return(0);
char const * ptr = strtok(pathlist, ";");
while (ptr) {
char path[PATH_MAX]; // Working path buffer.
SearchDriveType *srch; // Working pointer to path object.
/*
** Fixup the path to be legal. Legal is defined as all that is necessary to
** create a pathname is to append the actual filename submitted to the
** file system. This means that it must have either a trailing ':' or '\'
** character.
*/
strcpy(path, ptr);
switch (path[strlen(path)-1]) {
case ':':
case '\\':
break;
default:
strcat(path, "\\");
break;
}
/*
** If there is a drive letter specified, and this drive letter is '?', then it should
** be substituted with the CD-ROM drive letter. In the case of no CD-ROM attached, then
** merely ignore this path entry.
*/
if (strncmp(path, "?:", 2) == 0) {
#ifndef WIN32
GetCDClass temp;
int cd = temp.GetCDDrive();
#else
int cd = 10;
#endif
found = cd;
empty = !Is_Disk_Inserted(cd);
if (!found || empty) goto nextpath;
path[0] = (char)('A' + cd);
}
/*
** Allocate a record structure.
*/
srch = new SearchDriveType;
if (srch) {
found = true;
/*
** Attach the path to this structure.
*/
srch->Path = strdup(path);
srch->Next = NULL;
/*
** Attach this path record to the end of the path chain.
*/
if (!First) {
First = srch;
} else {
SearchDriveType * chain = First;
while (chain->Next) {
chain = (SearchDriveType *)chain->Next;
}
chain->Next = srch;
}
}
/*
** Find the next path string and resubmit.
*/
nextpath:
ptr = strtok(NULL, ";");
}
if (!found) return(1);
if (empty) return(2);
return(0);
}
#endif
/***********************************************************************************************
* CDFileClass::Set_Search_Drives -- Sets a list of search paths for file access. *
* *
* This routine sets up a list of search paths to use when accessing files. The path list *
* is scanned if the file could not be found in the current directory. This is the primary *
* method of supporting CD-ROM drives, but is also useful for scanning network and other *
* directories. The pathlist as passed to this routine is of the same format as the path *
* list used by DOS -- paths are separated by semicolons and need not end in an antivirgule.*
* *
* If a path entry begins with "?:" then the question mark will be replaced with the first *
* CD-ROM drive letter available. If there is no CD-ROM driver detected, then this path *
* entry will be ignored. By using this feature, you can always pass the CD-ROM path *
* specification to this routine and it will not break if the CD-ROM is not loaded (as in *
* the case during development). *
* *
* Here is an example path specification: *
* *
* Set_Search_Drives("DATA;?:\DATA;F:\PROJECT\DATA"); *
* *
* In this example, the current directory will be searched first, followed by a the *
* subdirectory "DATA" located off of the current directory. If not found, then the CD-ROM *
* will be searched in a directory called "\DATA". If not found or the CD-ROM is not *
* present, then it will look to the hard coded path of "F:\PROJECTS\DATA" (maybe a *
* network?). If all of these searches fail, the file system will default to the current *
* directory and let the normal file error system take over. *
* *
* INPUT: pathlist -- Pointer to string of path specifications (separated by semicolons) *
* that will be used to search for files. *
* *
* OUTPUT: none *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 10/18/1994 JLB : Created. *
* 05/21/1996 ST : Modified to recognise multiple CD drives *
*=============================================================================================*/
int CDFileClass::Set_Search_Drives(char * pathlist)
{
int found = FALSE;
int empty = FALSE;
/*
** If there is no pathlist to add, then just return.
*/
if (!pathlist) return(0);
/*
** Save the path as it was passed in so we can parse it again later.
** Check for the case where RawPath was passed in.
*/
if (pathlist != RawPath) {
strcat (RawPath, ";");
strcat (RawPath, pathlist);
}
char const * ptr = strtok(pathlist, ";");
while (ptr != NULL) {
if (strlen(ptr) > 0) {
char path[MAX_PATH]; // Working path buffer.
/*
** Fixup the path to be legal. Legal is defined as all that is necessary to
** create a pathname is to append the actual filename submitted to the
** file system. This means that it must have either a trailing ':' or '\'
** character.
*/
strcpy(path, ptr);
switch (path[strlen(path)-1]) {
case ':':
case '\\':
break;
default:
strcat(path, "\\");
break;
}
/*
** If there is a drive letter specified, and this drive letter is '?', then it should
** be substituted with the CD-ROM drive letter. In the case of no CD-ROM attached, then
** merely ignore this path entry.
** Adds an extra entry for each CD drive in the system that has a C&C disc inserted.
** ST - 5/21/96 4:40PM
*/
if (strncmp(path, "?:", 2) == 0) {
if (CurrentCDDrive) {
found = true;
/*
** If the drive has a C&C CD in it then add it to the path
*/
if (Get_CD_Index(CurrentCDDrive, 2*60) >= 0) {
path[0] = (char)(CurrentCDDrive + 'A');
Add_Search_Drive(path);
}
}
/*
** Find the next path string and resubmit.
*/
ptr = strtok(NULL, ";");
continue;
}
found = true;
Add_Search_Drive(path);
}
/*
** Find the next path string and resubmit.
*/
ptr = strtok(NULL, ";");
}
if (!found) return(1);
if (empty) return(2);
return(0);
}
/***********************************************************************************************
* CDFC::Add_Search_Drive -- Add a new path to the search path list *
* *
* *
* *
* INPUT: path *
* *
* OUTPUT: Nothing *
* *
* WARNINGS: None *
* *
* HISTORY: *
* 5/22/96 10:12AM ST : Created *
*=============================================================================================*/
void CDFileClass::Add_Search_Drive(char *path)
{
SearchDriveType *srch; // Working pointer to path object.
/*
** Allocate a record structure.
*/
srch = new SearchDriveType;
/*
** Attach the path to this structure.
*/
srch->Path = strdup(path);
srch->Next = NULL;
/*
** Attach this path record to the end of the path chain.
*/
if (!First) {
First = srch;
} else {
SearchDriveType * chain = First;
while (chain->Next) {
chain = (SearchDriveType *)chain->Next;
}
chain->Next = srch;
}
}
/***********************************************************************************************
* CDFC::Set_CD_Drive -- sets the current CD drive letter *
* *
* *
* *
* INPUT: Nothing *
* *
* OUTPUT: Nothing *
* *
* WARNINGS: None *
* *
* HISTORY: *
* 5/22/96 9:39AM ST : Created *
*=============================================================================================*/
void CDFileClass::Set_CD_Drive (int drive)
{
LastCDDrive = CurrentCDDrive;
CurrentCDDrive = drive;
}
/***********************************************************************************************
* CDFileClass::Clear_Search_Drives -- Removes all record of a search path. *
* *
* Use this routine to clear out any previous path(s) set with Set_Search_Drives() *
* function. *
* *
* INPUT: none *
* *
* OUTPUT: none *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 10/18/1994 JLB : Created. *
*=============================================================================================*/
void CDFileClass::Clear_Search_Drives(void)
{
SearchDriveType * chain; // Working pointer to path chain.
chain = First;
while (chain) {
SearchDriveType *next;
next = (SearchDriveType *)chain->Next;
if (chain->Path) {
free((char *)chain->Path);
}
delete chain;
chain = next;
}
First = 0;
}
/***********************************************************************************************
* CDFileClass::Set_Name -- Performs a multiple directory scan to set the filename. *
* *
* This routine will scan all the directories specified in the path list and if the file *
* was found in one of the directories, it will set the filename to a composite of the *
* correct directory and the filename. It is used to allow path searching when searching *
* for files. Typical use is to support CD-ROM drives. This routine examines the current *
* directory first before scanning through the path list. If after scanning the entire *
* path list, the file still could not be found, then the file object's name is set with *
* just the raw filename as passed to this routine. *
* *
* INPUT: filename -- Pointer to the filename to set as the name of this file object. *
* *
* OUTPUT: Returns a pointer to the final and complete filename of this file object. This *
* may have a path attached to the file. *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 10/18/1994 JLB : Created. *
*=============================================================================================*/
char const * CDFileClass::Set_Name(char const *filename)
{
/*
** Try to find the file in the current directory first. If it can be found, then
** just return with the normal file name setting process. Do the same if there is
** no multi-drive search path.
*/
BufferIOFileClass::Set_Name(filename);
if (IsDisabled || !First || BufferIOFileClass::Is_Available()) return(File_Name());
/*
** Attempt to find the file first. Check the current directory. If not found there, then
** search all the path specifications available. If it still can't be found, then just
** fall into the normal raw file filename setting system.
*/
SearchDriveType * srch = First;
while (srch) {
char path[_MAX_PATH];
/*
** Build a pathname to search for.
*/
strcpy(path, srch->Path);
strcat(path, filename);
/*
** Check to see if the file could be found. The low level Is_Available logic will
** prompt if necessary when the CD-ROM drive has been removed. In all other cases,
** it will return false and the search process will continue.
*/
BufferIOFileClass::Set_Name(path);
if (BufferIOFileClass::Is_Available()) {
return(File_Name());
}
/*
** It wasn't found, so try the next path entry.
*/
srch = (SearchDriveType *)srch->Next;
}
/*
** At this point, all path searching has failed. Just set the file name to the
** plain text passed to this routine and be done with it.
*/
BufferIOFileClass::Set_Name(filename);
return(File_Name());
}
/***********************************************************************************************
* CDFileClass::Open -- Opens the file wherever it can be found. *
* *
* This routine is similar to the RawFileClass open except that if the file is being *
* opened only for READ access, it will search all specified directories looking for the *
* file. If after a complete search the file still couldn't be found, then it is opened *
* using the normal BufferIOFileClass system -- resulting in normal error procedures. *
* *
* INPUT: filename -- Pointer to the override filename to supply for this file object. It *
* would be the base filename (sans any directory specification). *
* *
* rights -- The access rights to use when opening the file. *
* *
* OUTPUT: bool; Was the file opened successfully? If so then the filename may be different *
* than requested. The location of the file can be determined by examining the *
* filename of this file object. The filename will contain the complete *
* pathname used to open the file. *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 10/18/1994 JLB : Created. *
*=============================================================================================*/
int CDFileClass::Open(char const *filename, int rights)
{
CDFileClass::Close();
/*
** Verify that there is a filename associated with this file object. If not, then this is a
** big error condition.
*/
if (!filename) {
Error(ENOENT, false);
}
/*
** If writing is requested, then multiple drive searching is not performed.
*/
if (IsDisabled || rights == WRITE) {
BufferIOFileClass::Set_Name( filename );
return( BufferIOFileClass::Open( rights ) );
}
/*
** Perform normal multiple drive searching for the filename and open
** using the normal procedure.
*/
Set_Name(filename);
return(BufferIOFileClass::Open(rights));
}
const char *CDFileClass::Get_Search_Path(int index)
{
if (First == NULL) {
return NULL;
}
SearchDriveType *sd = First;
for (int i = 0; i <= index; i++) { // We want to loop once, even if index==0
if (i == index) {
return sd->Path;
}
sd = (SearchDriveType *)sd->Next;
if (sd == NULL) {
return NULL;
}
}
return NULL;
}
#ifdef NEVER
/*
** Get the drive letters if the CD's online */
*/
WORD cdecl GetCDDrive(VOID)
{
_ES = FP_SEG(&cdDrive[0]);
_BX = FP_OFF(&cdDrive[0]);
_AX = 0x150d;
geninterrupt(0x2F);
return((WORD)(*cdDrive));
}
#endif
#if 0
int Get_CD_Drive(void)
{
#ifdef WIN32
return(10);
#else
#ifdef NEVER
for (int index = 0; index < 26; index++) {
union REGS regs;
regs.w.ax = 0x150B;
regs.w.bx = 0;
regs.w.cx = index;
int386(0x2F, &regs, &regs);
if (regs.w.bx == 0xADAD) {
return(index);
}
}
return(0);
#else
GetCDClass temp;
return(temp.GetCDDrive());
#endif
#endif
}
#endif

116
REDALERT/CDFILE.H Normal file
View File

@ -0,0 +1,116 @@
//
// 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/CDFILE.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 : Westwood LIbrary *
* *
* File Name : CDFILE.H *
* *
* Programmer : Joe L. Bostic *
* *
* Start Date : October 18, 1994 *
* *
* Last Update : October 18, 1994 [JLB] *
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef CDFILE_H
#define CDFILE_H
#include <dos.h>
#include "bfiofile.h"
/*
** This class is derived from the BufferIOFileClass. This class adds the functionality of searching
** across multiple directories or drives. It is designed for the typical case of a CD-ROM game
** were some data exists in the current directory (hard drive) and the rest exists on the CD-ROM.
** Searching for the file occurs by first examining the current directory. If the file does not
** exist there, then all the paths available are examined in turn until the file can be found.
** For opening files to write, only the current directory is examined. The directory search order
** is controlled by the path list as submitted to Set_Search_Drives(). The format of the path
** string is the same as the DOS path string.
*/
class CDFileClass : public BufferIOFileClass
{
public:
CDFileClass(char const *filename);
CDFileClass(void);
virtual ~CDFileClass(void) {};
virtual char const * Set_Name(char const *filename);
virtual int Open(char const *filename, int rights=READ);
virtual int Open(int rights=READ);
void Searching(int on) {IsDisabled = !on;};
static bool Is_There_Search_Drives(void) {return(First != NULL);};
static int Set_Search_Drives(char * pathlist);
static void Add_Search_Drive(char *path);
static void Clear_Search_Drives(void);
static void Refresh_Search_Drives(void);
static void Set_CD_Drive(int drive);
static int Get_CD_Drive(void) {return(CurrentCDDrive);};
static int Get_Last_CD_Drive(void) {return(LastCDDrive);};
// RawPath will overflow if we keep setting the path. ST - 1/23/2019 11:12AM
static void Reset_Raw_Path(void) { RawPath[0] = 0; }
// Need to access the paths. ST - 3/15/2019 2:14PM
static const char *Get_Search_Path(int index);
private:
/*
** Is multi-drive searching disabled for this file object?
*/
unsigned IsDisabled:1;
/*
** This is the control record for each of the drives specified in the search
** path. There can be many such search paths available.
*/
typedef struct {
void * Next; // Pointer to next search record.
char const * Path; // Pointer to path string.
} SearchDriveType;
/*
** This points to the first path record.
*/
static SearchDriveType * First;
/*
** This is a copy of the unparsed search path list
*/
static char RawPath[512];
/*
** The drive letter of the current cd drive
*/
static int CurrentCDDrive;
/*
** The drive letter of the last used CD drive
*/
static int LastCDDrive;
};
#endif

3299
REDALERT/CELL.CPP Normal file

File diff suppressed because it is too large Load Diff

332
REDALERT/CELL.H Normal file
View File

@ -0,0 +1,332 @@
//
// 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/CELL.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 : CELL.H *
* *
* Programmer : Joe L. Bostic *
* *
* Start Date : April 29, 1994 *
* *
* Last Update : April 29, 1994 [JLB] *
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef CELL_H
#define CELL_H
#include "building.h"
#include "unit.h"
#include "template.h"
/****************************************************************************
** Each cell on the map is controlled by the following structure.
*/
class CellClass
{
public:
/*
** This is the ID number of this cell. By placing the ID number here, it doesn't have
** be calculated. Calculating this number requires a divide and would occur about
** 5.72031 bijillion times per second.
*/
short ID;
/*
** Does this cell need to be updated on the radar map? If something changes in the cell
** that might change the radar map imagery, then this flag will be set. It gets cleared
** when the cell graphic is updated to the radar map.
*/
unsigned IsPlot:1;
/*
** Does this cell contain the special placement cursor graphic? This graphic is
** present when selecting a site for building placement.
*/
unsigned IsCursorHere:1;
/*
** A mapped cell has some portion of it visible. Maybe it has a shroud piece
** over it and maybe not.
*/
unsigned IsMapped:1;
/*
** A visible cell means that it is completely visible with no shroud over
** it at all.
*/
unsigned IsVisible:1;
/*
** Every cell can be assigned a waypoint. A waypoint can only be assigned
** to one cell, and vice-versa. This bit simply indicates whether this
** cell is assigned a waypoint or not.
*/
unsigned IsWaypoint:1;
/*
** Is this cell currently under the radar map cursor? If so then it
** needs to be updated whenever the map is updated.
*/
unsigned IsRadarCursor:1;
/*
** If this cell contains a house flag, then this will be true. The actual house
** flag it contains is specified by the Owner field.
*/
unsigned IsFlagged:1;
/*
** This is a working flag used to help keep track of what cells should be
** shrouded. By using this flag it allows a single pass through the map
** cells for determining shadow regrowth logic.
*/
unsigned IsToShroud:1;
/*
** This records the movement zone for this map. Movement zones share the
** same number if they are contiguous (terrain consideration only). There
** are basically two kinds of zones. The difference being determined by
** walls that can be crushed by movement. A vehicle that can crush walls
** will only consider the CrushZone. All other terrestrial travellers will
** use the normal Zone.
*/
unsigned char Zones[MZONE_COUNT];
/*
** This field controls whether an area is being jammed by a gap
** generator.
*/
unsigned short Jammed;
/*
** This is the trigger ID for any trigger that might be attached to
** this cell.
*/
CCPtr<TriggerClass> Trigger;
/*
** This contains the icon number and set to use for the base
** of the terrain. All rendering on an icon occurs AFTER the icon
** specified by this element is rendered. It is the lowest of the low.
*/
TemplateType TType;
unsigned char TIcon;
/*
** The second layer of 'terrain' icons is represented by a simple
** type number and a value byte. This is sufficient for handling
** concrete and walls.
*/
OverlayType Overlay;
unsigned char OverlayData;
/*
** This is used to specify any special 'stain' overlay icon. This
** typically includes infantry bodies or other temporary marks.
*/
SmudgeType Smudge;
unsigned char SmudgeData;
/*
** Smudges and walls need to record ownership values. For walls, this
** allows adjacent building placement logic to work. For smudges, it
** allows building over smudges that are no longer attached to buildings
** in addition to fixing the adjacent placement logic.
*/
HousesType Owner;
/*
** This flag tells you what type of infantry currently occupy the
** cell or are moving into it.
*/
HousesType InfType;
/*
** These point to the object(s) that are located in this cell or overlap
** this cell.
*/
private:
ObjectClass * OccupierPtr;
public:
#ifdef SORTDRAW
ObjectClass * Overlapper[10];
#else
ObjectClass * Overlapper[6];
#endif
/*
** Per-player view of whether a cell is mapped. One bit for each house type. ST - 8/2/2019 3:00PM
*/
unsigned int IsMappedByPlayerMask;
/*
** Per-player view of whether a cell is visible. One bit for each house type. ST - 8/2/2019 3:00PM
*/
unsigned int IsVisibleByPlayerMask;
/*
** This array of bit flags is used to indicate which sub positions
** within the cell are either occupied or are soon going to be
** occupied. For vehicles, the cells that the vehicle is passing over
** will be flagged with the vehicle bit. For infantry, the the sub
** position the infantry is stopped at or headed toward will be marked.
** The sub positions it passes over will NOT be marked.
*/
union {
struct {
unsigned Center:1;
unsigned NW:1;
unsigned NE:1;
unsigned SW:1;
unsigned SE:1;
unsigned Vehicle:1; // Reserved for vehicle occupation.
unsigned Monolith:1; // Some immovable blockage is in cell.
unsigned Building:1; // A building of some time (usually blocks movement).
} Occupy;
unsigned char Composite;
} Flag;
//----------------------------------------------------------------
CellClass(void);
CellClass(NoInitClass const & x) : Trigger(x) {}
~CellClass(void) {OccupierPtr=0;}
int operator == (CellClass const & cell) const {return &cell == this;}
/*
** Query functions.
*/
bool Can_Tiberium_Germinate(void) const;
bool Can_Tiberium_Grow(void) const;
bool Can_Tiberium_Spread(void) const;
bool Is_Bridge_Here(void) const;
RTTIType What_Am_I(void) const {return(RTTI_CELL);}
BuildingClass * Cell_Building(void) const;
CELL Cell_Number(void) const {return(ID);}
COORDINATE Cell_Coord(void) const;
COORDINATE Closest_Free_Spot(COORDINATE coord, bool any=false) const;
COORDINATE Free_Spot(void) const {return Closest_Free_Spot(Cell_Coord());}
CellClass & Adjacent_Cell(FacingType face) {return (CellClass &)((*((CellClass const *)this)).Adjacent_Cell(face));}
CellClass const & Adjacent_Cell(FacingType face) const;
InfantryClass * Cell_Infantry(void) const;
LandType Land_Type(void) const {return((OverrideLand != LAND_NONE) ? OverrideLand : Land);}
ObjectClass * Cell_Find_Object(RTTIType rtti) const;
ObjectClass * Cell_Object(int x=0, int y=0) const;
ObjectClass * Cell_Occupier(void) const {return(OccupierPtr);}
ObjectClass * Fetch_Occupier(void) const;
TARGET As_Target(void) const {return ::As_Target(Cell_Number());}
TechnoClass * Cell_Techno(int x=0, int y=0) const;
TerrainClass * Cell_Terrain(void) const;
UnitClass * Cell_Unit(void) const;
VesselClass * Cell_Vessel(void) const;
bool Goodie_Check(FootClass * object);
bool Is_Clear_To_Build(SpeedType loco = SPEED_TRACK) const;
bool Is_Clear_To_Move(SpeedType loco, bool ignoreinfantry, bool ignorevehicles, int zone=-1, MZoneType check=MZONE_NORMAL) const;
bool Is_Spot_Free(int spot_index) const {return (! (Flag.Composite & (1 << spot_index)) ); }
int Cell_Color(bool override=false) const;
int Clear_Icon(void) const;
static int Spot_Index(COORDINATE coord);
bool Get_Template_Info(char *template_name, int &icon, void *&image_data);
/*
** Object placement and removal flag operations.
*/
void Occupy_Down(ObjectClass * object);
void Occupy_Up(ObjectClass * object);
void Overlap_Down(ObjectClass * object);
void Overlap_Up(ObjectClass * object);
bool Flag_Place(HousesType house);
bool Flag_Remove(void);
/*
** File I/O.
*/
bool Should_Save(void) const;
bool Save(Pipe & file) const;
bool Load(Straw & file);
void Code_Pointers(void);
void Decode_Pointers(void);
/*
** Display and rendering controls.
*/
void Draw_It(int x, int y, bool objects=false) const;
void Redraw_Objects(bool forced=false);
void Shimmer(void);
/*
** Maintenance calculation support.
*/
bool Grow_Tiberium(void);
bool Spread_Tiberium(bool forced=false);
long Tiberium_Adjust(bool pregame=false);
void Wall_Update(void);
void Concrete_Calc(void);
void Recalc_Attributes(void);
int Reduce_Tiberium(int levels);
int Reduce_Wall(int damage);
void Incoming(COORDINATE threat=0, bool forced=false, bool nokidding=false);
void Adjust_Threat(HousesType house, int threat_value);
int operator != (CellClass const &) const {return 0;}
/*
** Additional per-player functionality is needed for multiplayer. ST - 8/2/2019 3:01PM
*/
void Set_Mapped(HousesType house, bool set = true);
void Set_Mapped(HouseClass *player, bool set = true);
bool Is_Mapped(HousesType house) const;
bool Is_Mapped(HouseClass *player) const;
void Set_Visible(HousesType house, bool set = true);
void Set_Visible(HouseClass *player, bool set = true);
bool Is_Visible(HousesType house) const;
bool Is_Visible(HouseClass *player) const;
bool Is_Jamming(HousesType house) const;
bool Is_Jamming(HouseClass *player) const;
/*
** Override land type to fix passability issues on some maps
*/
void Override_Land_Type(LandType type);
private:
CellClass (CellClass const &) ;
LandType Land; // The land type of this cell.
LandType OverrideLand; // The overriden land type of this cell.
/*
** Some additional padding in case we need to add data to the class and maintain backwards compatibility for save/load
*/
unsigned char SaveLoadPadding[32];
};
#endif

99
REDALERT/CHECKBOX.CPP Normal file
View File

@ -0,0 +1,99 @@
//
// 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/CHECKBOX.CPP 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 : CHECKBOX.CPP *
* *
* Programmer : Joe L. Bostic *
* *
* Start Date : 05/26/95 *
* *
* Last Update : July 6, 1996 [JLB] *
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* CheckBoxClass::Action -- Handles a button action on a checkbox object. *
* CheckBoxClass::Draw_Me -- Draws the checkbox imagery. *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "function.h"
#include "checkbox.h"
/***********************************************************************************************
* CheckBoxClass::Draw_Me -- Draws the checkbox imagery. *
* *
* This routine will draw the checkbox either filled or empty as necessary. *
* *
* INPUT: forced -- Should the check box be drawn even if it doesn't think it needs to? *
* *
* OUTPUT: Was the check box rendered? *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 07/01/1995 JLB : Created. *
*=============================================================================================*/
int CheckBoxClass::Draw_Me(int forced)
{
if (ToggleClass::Draw_Me(forced)) {
Hide_Mouse();
Draw_Box(X, Y, Width, Height, BOXSTYLE_DOWN, false);
LogicPage->Fill_Rect(X+1, Y+1, X+Width-2, Y+Height-2, DKGREY);
if (IsOn) {
LogicPage->Fill_Rect(X+1, Y+1, X+Width-2, Y+Height-2, LTGREEN);
}
Show_Mouse();
return(true);
}
return(false);
}
/***********************************************************************************************
* CheckBoxClass::Action -- Handles a button action on a checkbox object. *
* *
* This routine will detect if the mouse has been clicked on the checkbox object. If so, *
* the check box state will be toggled. *
* *
* INPUT: flags -- The event flags that resulted in this routine being called. *
* *
* key -- The key that resulted in this routine being called. *
* *
* OUTPUT: bool; Should normal processing occur? *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 07/06/1996 JLB : Created. *
*=============================================================================================*/
int CheckBoxClass::Action(unsigned flags, KeyNumType & key)
{
if (flags & LEFTRELEASE) {
if (IsOn) {
Turn_Off();
} else {
Turn_On();
}
}
return(ToggleClass::Action(flags, key));
}

53
REDALERT/CHECKBOX.H Normal file
View File

@ -0,0 +1,53 @@
//
// 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/CHECKBOX.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 : CHECKBOX.H *
* *
* Programmer : Joe L. Bostic *
* *
* Start Date : 05/26/95 *
* *
* Last Update : May 26, 1995 [JLB] *
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef CHECKBOX_H
#define CHECKBOX_H
#include "toggle.h"
class CheckBoxClass : public ToggleClass
{
public:
CheckBoxClass(unsigned id, int x, int y) :
ToggleClass(id, x, y, 7, 7)
{};
virtual int Draw_Me(int forced=false);
virtual int Action(unsigned flags, KeyNumType & key);
protected:
};
#endif

362
REDALERT/CHEKLIST.CPP Normal file
View File

@ -0,0 +1,362 @@
//
// 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/CHEKLIST.CPP 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 : CHEKLIST.CPP *
* *
* Programmer : Joe L. Bostic *
* *
* Start Date : 07/05/96 *
* *
* Last Update : July 6, 1996 [JLB] *
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* CheckListClass::Action -- action function for this class *
* CheckListClass::Add_Item -- Adds specifies text to check list box. *
* CheckListClass::CheckListClass -- constructor *
* CheckListClass::Check_Item -- [un]checks an items *
* CheckListClass::Draw_Entry -- draws a list box entry *
* CheckListClass::Get_Item -- Fetches a pointer to the text associated with the index. *
* CheckListClass::Remove_Item -- Remove the item that matches the text pointer specified. *
* CheckListClass::Set_Selected_Index -- Set the selected index to match the text pointer spe*
* CheckListClass::~CheckListClass -- Destructor for check list object. *
* CheckListClass::~CheckListClass -- destructor *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "function.h"
/***************************************************************************
* CheckListClass::CheckListClass -- constructor *
* *
* INPUT: *
* id control ID for this list box *
* x x-coord *
* y y-coord *
* w width *
* h height *
* flags mouse event flags *
* up ptr to Up-arrow shape *
* down ptr to Down-arrow shape *
* *
* OUTPUT: *
* none. *
* *
* WARNINGS: *
* none. *
* *
* HISTORY: *
* 02/16/1995 BR : Created. *
*=========================================================================*/
CheckListClass::CheckListClass(int id, int x, int y, int w, int h, TextPrintType flags,
void const * up, void const * down) :
ListClass (id, x, y, w, h, flags, up, down),
IsReadOnly(false)
{
}
/***********************************************************************************************
* CheckListClass::~CheckListClass -- Destructor for check list object. *
* *
* This destructor will delete all entries attached to it. *
* *
* INPUT: none *
* *
* OUTPUT: none *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 07/06/1996 JLB : Created. *
*=============================================================================================*/
CheckListClass::~CheckListClass(void)
{
while (CheckListClass::Count()) {
CheckObject * obj = (CheckObject *)ListClass::Get_Item(0);
ListClass::Remove_Item(0);
delete obj;
}
}
/***********************************************************************************************
* CheckListClass::Add_Item -- Adds specifies text to check list box. *
* *
* This routine will add the specified text string to the check list. *
* *
* INPUT: text -- Pointer to the text string to add to the list box. *
* *
* OUTPUT: Returns the index number where the text object was added. *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 02/14/1996 JLB : Created. *
*=============================================================================================*/
int CheckListClass::Add_Item(char const * text)
{
CheckObject * obj = new CheckObject(text, false);
return(ListClass::Add_Item((char const *)obj));
}
char const * CheckListClass::Current_Item(void) const
{
CheckObject * obj = (CheckObject *)ListClass::Current_Item();
if (obj) {
return(obj->Text);
}
return(0);
}
/***********************************************************************************************
* CheckListClass::Get_Item -- Fetches a pointer to the text associated with the index. *
* *
* This routine will find the text associated with the entry specified and return a pointer *
* to that text. *
* *
* INPUT: index -- The entry (index) to fetch a pointer to. *
* *
* OUTPUT: Returns with the text pointer associated with the index specified. *
* *
* WARNINGS: If the index is out of range, then NULL is returned. *
* *
* HISTORY: *
* 07/06/1996 JLB : Created. *
*=============================================================================================*/
char const * CheckListClass::Get_Item(int index) const
{
CheckObject * obj = (CheckObject *)ListClass::Get_Item(index);
if (obj) {
return(obj->Text);
}
return(0);
}
/***********************************************************************************************
* CheckListClass::Remove_Item -- Remove the item that matches the text pointer specified. *
* *
* This routine will find the entry that matches the text pointer specified and then *
* delete that entry. *
* *
* INPUT: text -- The text pointer to use to find the exact match in the list. *
* *
* OUTPUT: none *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 07/06/1996 JLB : Created. *
*=============================================================================================*/
void CheckListClass::Remove_Item(char const * text)
{
for (int index = 0; index < Count(); index++) {
CheckObject * obj = (CheckObject *)ListClass::Get_Item(index);
if (obj && stricmp(obj->Text, text) == 0) {
ListClass::Remove_Item(index);
delete obj;
break;
}
}
}
/***********************************************************************************************
* CheckListClass::Set_Selected_Index -- Set the selected index to match the text pointer spec *
* *
* This routine will find the entry that exactly matches the text pointer specified. If *
* found, then that entry will be set as the currently selected index. *
* *
* INPUT: text -- Pointer to the text string to find the match for. *
* *
* OUTPUT: none *
* *
* WARNINGS: If an exact match to the specified text string could not be found, then the *
* currently selected index is not changed. *
* *
* HISTORY: *
* 07/06/1996 JLB : Created. *
*=============================================================================================*/
void CheckListClass::Set_Selected_Index(char const * text)
{
for (int index = 0; index < Count(); index++) {
CheckObject * obj = (CheckObject *)ListClass::Get_Item(index);
if (obj && stricmp(obj->Text, text) == 0) {
Set_Selected_Index(index);
break;
}
}
}
/***************************************************************************
* CheckListClass::Check_Item -- [un]checks an items *
* *
* INPUT: *
* index index of item to check or uncheck *
* checked 0 = uncheck, non-zero = check *
* *
* OUTPUT: *
* none. *
* *
* WARNINGS: *
* none. *
* *
* HISTORY: *
* 02/16/1995 BR : Created. *
* 02/14/1996 JLB : Revamped. *
*=========================================================================*/
void CheckListClass::Check_Item(int index, bool checked)
{
CheckObject * obj = (CheckObject *)ListClass::Get_Item(index);
if (obj && obj->IsChecked != checked) {
obj->IsChecked = checked;
Flag_To_Redraw();
}
}
/***************************************************************************
* CheckListClass::Is_Checked -- returns checked state of an item *
* *
* INPUT: *
* index index of item to query *
* *
* OUTPUT: *
* 0 = item is unchecked, 1 = item is checked *
* *
* WARNINGS: *
* none. *
* *
* HISTORY: *
* 02/16/1995 BR : Created. *
* 02/14/1996 JLB : Revamped. *
*=========================================================================*/
bool CheckListClass::Is_Checked(int index) const
{
CheckObject * obj = (CheckObject *)ListClass::Get_Item(index);
if (obj) {
return(obj->IsChecked);
}
return(false);
}
/***************************************************************************
* CheckListClass::Action -- action function for this class *
* *
* INPUT: *
* flags the reason we're being called *
* key the KN_number that was pressed *
* *
* OUTPUT: *
* true = event was processed, false = event not processed *
* *
* WARNINGS: *
* none. *
* *
* HISTORY: *
* 02/16/1995 BR : Created. *
*=========================================================================*/
int CheckListClass::Action(unsigned flags, KeyNumType &key)
{
int rc;
/*
** If this is a read-only list, it's a display-only device
*/
if (IsReadOnly) {
return(false);
}
/*
** Invoke parents Action first, so it can set the SelectedIndex if needed.
*/
rc = ListClass::Action(flags, key);
/*
** Now, if this event was a left-press, toggle the checked state of the
** current item.
*/
if (flags & LEFTPRESS) {
Check_Item(SelectedIndex, !Is_Checked(SelectedIndex));
}
return(rc);
}
/***************************************************************************
* CheckListClass::Draw_Entry -- draws a list box entry *
* *
* INPUT: *
* index index into List of item to draw *
* x,y x,y coords to draw at *
* width maximum width allowed for text *
* selected true = this item is selected *
* *
* OUTPUT: *
* none. *
* *
* WARNINGS: *
* none. *
* *
* HISTORY: *
* 12/14/1995 BRR : Created. *
*=========================================================================*/
void CheckListClass::Draw_Entry(int index, int x, int y, int width, int selected)
{
if (index >= Count()) return;
CheckObject * obj = (CheckObject *)ListClass::Get_Item(index);
if (obj) {
char buffer[100] = "";
if (obj->IsChecked) {
buffer[0] = CHECK_CHAR;
} else {
buffer[0] = UNCHECK_CHAR;
}
buffer[1] = ' ';
sprintf(&buffer[2], obj->Text);
TextPrintType flags = TextFlags;
RemapControlType * scheme = GadgetClass::Get_Color_Scheme();
if (selected) {
flags = flags | TPF_BRIGHT_COLOR;
LogicPage->Fill_Rect (x, y, x + width - 1, y + LineHeight - 1, scheme->Shadow);
} else {
if (!(flags & TPF_USE_GRAD_PAL)) {
flags = flags | TPF_MEDIUM_COLOR;
}
}
Conquer_Clip_Text_Print(buffer, x, y, scheme, TBLACK, flags, width, Tabs);
}
}

102
REDALERT/CHEKLIST.H Normal file
View File

@ -0,0 +1,102 @@
//
// 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/CHEKLIST.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 : CHEKLIST.H *
* *
* Programmer : Bill Randolph *
* *
* Start Date : February 16, 1995 *
* *
* Last Update : February 16, 1995 [BR] *
* *
*-------------------------------------------------------------------------*
* This class behaves just like the standard list box, except that if the *
* first character of a list entry is a space, clicking on it toggles the *
* space with a check-mark ('\3'). This makes each entry in the list box *
* "toggle-able". *
*-------------------------------------------------------------------------*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef CHEKLIST_H
#define CHEKLIST_H
#include "list.h"
class CheckObject
{
public:
CheckObject(char const * text = 0, bool checked=false) :
Text(text),
IsChecked(checked)
{};
char const * Text;
bool IsChecked;
};
class CheckListClass : public ListClass
{
public:
/*
** Constructor/Destructor
*/
CheckListClass(int id, int x, int y, int w, int h, TextPrintType flags,
void const * up, void const * down);
~CheckListClass(void);
virtual int Add_Item(int text) {return ListClass::Add_Item(text);}
virtual int Add_Item(char const * text);
virtual char const * Current_Item(void) const;
virtual char const * Get_Item(int index) const;
virtual void Remove_Item(char const * text);
virtual void Remove_Item(int text) {ListClass::Remove_Item(text);}
virtual void Set_Selected_Index(char const * text);
virtual void Set_Selected_Index(int index) {ListClass::Set_Selected_Index(index);};
/*
** Checkmark utility functions
*/
void Check_Item(int index, bool checked); // sets checked state of item
bool Is_Checked(int index) const; // gets checked state of item
void Set_Read_Only(int rdonly) {IsReadOnly = rdonly;}
/*
** This defines the ASCII value of the checkmark character & non-checkmark
** character.
*/
typedef enum CheckListClassEnum {
CHECK_CHAR = '\3',
UNCHECK_CHAR = ' '
} CheckListClassEnum;
protected:
virtual int Action(unsigned flags, KeyNumType &key);
virtual void Draw_Entry(int index, int x, int y, int width, int selected);
private:
bool IsReadOnly;
};
#endif

16
REDALERT/CLASS.CPP Normal file
View File

@ -0,0 +1,16 @@
//
// 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

275
REDALERT/COLRLIST.CPP Normal file
View File

@ -0,0 +1,275 @@
//
// 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/COLRLIST.CPP 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 : COLRLIST.CPP *
* *
* Programmer : Joe L. Bostic *
* *
* Start Date : 01/15/95 *
* *
* Last Update : April 19, 1995 [BRR] *
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* ColorListClass::Add_Item -- Adds an item to the list *
* ColorListClass::ColorListClass -- Class constructor *
* ColorListClass::Draw_Entry -- Draws one text line *
* ColorListClass::Remove_Item -- Removes an item from the list *
* ColorListClass::Set_Selected_Style -- tells how to draw selected item *
* ColorListClass::~ColorListClass -- Class destructor *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "function.h"
/***************************************************************************
* ColorListClass::ColorListClass -- class constructor *
* *
* INPUT: *
* id button ID *
* x,y upper-left corner, in pixels *
* w,h width, height, in pixels *
* list ptr to array of char strings to list *
* flags flags for mouse, style of listbox *
* up,down pointers to shapes for up/down buttons *
* *
* OUTPUT: *
* none. *
* *
* WARNINGS: *
* none. *
* *
* HISTORY: 01/05/1995 MML : Created. *
*=========================================================================*/
ColorListClass::ColorListClass (int id, int x, int y, int w, int h,
TextPrintType flags, void const * up, void const * down) :
ListClass (id, x, y, w, h, flags, up, down),
Style(SELECT_HIGHLIGHT),
SelectColor(NULL)
{
}
/***************************************************************************
* ColorListClass::~ColorListClass -- Class destructor *
* *
* INPUT: *
* none. *
* *
* OUTPUT: *
* none. *
* *
* WARNINGS: *
* none. *
* *
* HISTORY: *
* 04/19/1995 BRR : Created. *
*=========================================================================*/
ColorListClass::~ColorListClass(void)
{
Colors.Clear();
SelectColor = 0;
}
/***************************************************************************
* ColorListClass::Add_Item -- Adds an item to the list *
* *
* INPUT: *
* text text to add to list *
* color color for item *
* *
* OUTPUT: *
* position of item in the list *
* *
* WARNINGS: *
* none. *
* *
* HISTORY: *
* 04/19/1995 BRR : Created. *
*=========================================================================*/
int ColorListClass::Add_Item(char const * text, RemapControlType * color)
{
Colors.Add(color);
return(ListClass::Add_Item(text));
}
/***************************************************************************
* ColorListClass::Add_Item -- Adds an item to the list *
* *
* INPUT: *
* text text to add to list *
* color color for item *
* *
* OUTPUT: *
* position of item in the list *
* *
* WARNINGS: *
* none. *
* *
* HISTORY: *
* 04/19/1995 BRR : Created. *
*=========================================================================*/
int ColorListClass::Add_Item(int text, RemapControlType * color)
{
Colors.Add(color);
return(ListClass::Add_Item(text));
}
/***************************************************************************
* ColorListClass::Remove_Item -- Removes an item from the list *
* *
* INPUT: *
* text ptr to item to remove *
* *
* OUTPUT: *
* none. *
* *
* WARNINGS: *
* *
* HISTORY: *
* 04/19/1995 BRR : Created. *
*=========================================================================*/
void ColorListClass::Remove_Item(char const * text)
{
int index = List.ID(text);
if (index != -1) {
Colors.Delete(index);
ListClass::Remove_Item(text);
}
}
/***************************************************************************
* ColorListClass::Set_Selected_Style -- tells how to draw selected item *
* *
* INPUT: *
* style style to draw *
* color color to draw the special style in; -1 = use item's color *
* *
* OUTPUT: *
* none. *
* *
* WARNINGS: *
* none. *
* *
* HISTORY: *
* 04/19/1995 BRR : Created. *
*=========================================================================*/
void ColorListClass::Set_Selected_Style(SelectStyleType style, RemapControlType * color)
{
Style = style;
SelectColor = color;
}
/***************************************************************************
* ColorListClass::Draw_Entry -- Draws one text line *
* *
* INPUT: *
* index index into List of item to draw *
* x,y x,y coords to draw at *
* width maximum width allowed for text *
* selected true = this item is selected *
* *
* OUTPUT: *
* none. *
* *
* WARNINGS: *
* none. *
* *
* HISTORY: *
* 04/19/1995 BRR : Created. *
*=========================================================================*/
void ColorListClass::Draw_Entry(int index, int x, int y, int width, int selected)
{
RemapControlType * color;
/*
** Draw a non-selected item in its color
*/
if (!selected) {
Conquer_Clip_Text_Print(List[index], x, y, Colors[index], TBLACK, TextFlags, width, Tabs);
return;
}
/*
** For selected items, choose the right color & style:
*/
if (SelectColor == NULL) {
color = Colors[index];
} else {
color = SelectColor;
}
switch (Style) {
/*
** NONE: Just print the string in its native color
*/
case SELECT_NORMAL:
Conquer_Clip_Text_Print(List[index], x, y, Colors[index], TBLACK,
TextFlags, width, Tabs);
break;
/*
** HIGHLIGHT: Draw the string in the highlight color (SelectColor must
** be set)
*/
case SELECT_HIGHLIGHT:
if (TextFlags & TPF_6PT_GRAD) {
Conquer_Clip_Text_Print(List[index], x, y, color, TBLACK, TextFlags | TPF_BRIGHT_COLOR, width, Tabs);
} else {
Conquer_Clip_Text_Print(List[index], x, y, color, TBLACK, TextFlags, width, Tabs);
}
break;
/*
** BOX: Draw a box around the item in the current select color
*/
case SELECT_BOX:
LogicPage->Draw_Rect (x, y, x + width - 2, y + LineHeight - 2, color->Color);
Conquer_Clip_Text_Print(List[index], x, y, Colors[index], TBLACK, TextFlags, width, Tabs);
break;
/*
** BAR: draw a color bar under the text
*/
case SELECT_BAR:
if (TextFlags & TPF_6PT_GRAD) {
LogicPage->Fill_Rect(x, y, x + width - 1, y + LineHeight - 1, color->Color);
Conquer_Clip_Text_Print(List[index], x, y, Colors[index], TBLACK, TextFlags | TPF_BRIGHT_COLOR, width, Tabs);
} else {
LogicPage->Fill_Rect(x, y, x + width - 2, y + LineHeight - 2, color->Color);
Conquer_Clip_Text_Print(List[index], x, y, Colors[index], TBLACK, TextFlags, width, Tabs);
}
break;
/*
** INVERT: Draw text as the background color on foreground color
*/
case SELECT_INVERT:
LogicPage->Fill_Rect (x, y, x + width - 1, y + LineHeight - 1, Colors[index]->Color);
break;
}
}

84
REDALERT/COLRLIST.H Normal file
View File

@ -0,0 +1,84 @@
//
// 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/COLRLIST.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 : COLRLIST.H *
* *
* Programmer : Joe L. Bostic *
* *
* Start Date : 01/15/95 *
* *
* Last Update : January 15, 1995 [JLB] *
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef COLORLIST_H
#define COLORLIST_H
#include "list.h"
/***************************************************************************
** This class adds the ability for every list item to have a different color.
*/
class ColorListClass : public ListClass
{
public:
/*********************************************************************
** These enums are the ways a selected item can be drawn
*/
//lint -esym(578,SELECT_NONE)
typedef enum SelectEnum {
SELECT_NORMAL, // selected items aren't drawn differently
SELECT_HIGHLIGHT, // item is highlighted
SELECT_BOX, // draw a box around the item
SELECT_BAR, // draw a bar behind the item
SELECT_INVERT // draw the string inverted
} SelectStyleType;
ColorListClass(int id, int x, int y, int w, int h, TextPrintType flags, void const * up, void const * down);
virtual ~ColorListClass(void);
virtual int Add_Item(char const * text, RemapControlType * color = NULL);
virtual int Add_Item(int text, RemapControlType * color = NULL);
virtual void Remove_Item(char const * text);
virtual void Set_Selected_Style(SelectStyleType style, RemapControlType * color = NULL);
/*
** This is the list of colors for each item.
*/
DynamicVectorClass<RemapControlType *> Colors;
protected:
virtual void Draw_Entry(int index, int x, int y, int width, int selected);
/*
** This tells how to draw the selected item.
*/
SelectStyleType Style;
RemapControlType * SelectColor;
};
#endif

422
REDALERT/COMBAT.CPP Normal file
View File

@ -0,0 +1,422 @@
//
// 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/COMBAT.CPP 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 : COMBAT.CPP *
* *
* Programmer : Joe L. Bostic *
* *
* Start Date : September 19, 1994 *
* *
* Last Update : July 26, 1996 [JLB] *
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* Combat_Anim -- Determines explosion animation to play. *
* Explosion_Damage -- Inflict an explosion damage affect. *
* Modify_Damage -- Adjusts damage to reflect the nature of the target. *
* Wide_Area_Damage -- Apply wide area damage to the map. *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "function.h"
/***********************************************************************************************
* Modify_Damage -- Adjusts damage to reflect the nature of the target. *
* *
* This routine is the core of combat tactics. It implements the *
* affect various armor types have against various weapon types. By *
* careful exploitation of this table, tactical advantage can be *
* obtained. *
* *
* INPUT: damage -- The damage points to process. *
* *
* warhead -- The source of the damage points. *
* *
* armor -- The type of armor defending against the damage. *
* *
* distance -- The distance (in leptons) from the source of the damage. *
* *
* OUTPUT: Returns with the adjusted damage points to inflict upon the *
* target. *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 04/16/1994 JLB : Created. *
* 04/17/1994 JLB : Always does a minimum of damage. *
* 01/01/1995 JLB : Takes into account distance from damage source. *
* 04/11/1996 JLB : Changed damage fall-off formula for less damage fall-off. *
*=============================================================================================*/
int Modify_Damage(int damage, WarheadType warhead, ArmorType armor, int distance)
{
if (!damage) return(damage);
/*
** If there is no raw damage value to start with, then
** there can be no modified damage either.
*/
if (Special.IsInert || !damage || warhead == WARHEAD_NONE) return(0);
/*
** Negative damage (i.e., heal) is always applied full strength, but only if the heal
** effect is close enough.
*/
if (damage < 0) {
#ifdef FIXIT_CSII // checked - ajw 9/28/98
if (distance < 0x008) {
if(warhead != WARHEAD_MECHANICAL && armor == ARMOR_NONE) return(damage);
if(warhead == WARHEAD_MECHANICAL && armor != ARMOR_NONE) return(damage);
}
#else
if (distance < 0x008 && armor == ARMOR_NONE) return(damage);
#endif
return(0);
}
WarheadTypeClass const * whead = WarheadTypeClass::As_Pointer(warhead);
// WarheadTypeClass const * whead = &Warheads[warhead];
damage = damage * whead->Modifier[armor];
/*
** Reduce damage according to the distance from the impact point.
*/
if (damage) {
if (!whead->SpreadFactor) {
distance /= PIXEL_LEPTON_W/4;
} else {
distance /= whead->SpreadFactor * (PIXEL_LEPTON_W/2);
}
distance = Bound(distance, 0, 16);
if (distance) {
damage = damage / distance;
}
/*
** Allow damage to drop to zero only if the distance would have
** reduced damage to less than 1/4 full damage. Otherwise, ensure
** that at least one damage point is done.
*/
if (distance < 4) {
damage = max(damage, Rule.MinDamage);
}
}
damage = min(damage, Rule.MaxDamage);
return(damage);
}
/***********************************************************************************************
* Explosion_Damage -- Inflict an explosion damage affect. *
* *
* Processes the collateral damage affects typically caused by an *
* explosion. *
* *
* INPUT: coord -- The coordinate of ground zero. *
* *
* strength -- Raw damage points at ground zero. *
* *
* source -- Source of the explosion (who is responsible). *
* *
* warhead -- The kind of explosion to process. *
* *
* OUTPUT: none *
* *
* WARNINGS: This routine can consume some time and will affect the AI *
* of nearby enemy units (possibly). *
* *
* HISTORY: *
* 08/16/1991 JLB : Created. *
* 11/30/1991 JLB : Uses coordinate system. *
* 12/27/1991 JLB : Radius of explosion damage effect. *
* 04/13/1994 JLB : Streamlined. *
* 04/16/1994 JLB : Warhead damage type modifier. *
* 04/17/1994 JLB : Cleaned up. *
* 06/20/1994 JLB : Uses object pointers to distribute damage. *
* 06/20/1994 JLB : Source is a pointer. *
* 06/18/1996 JLB : Strength could be negative for healing effects. *
*=============================================================================================*/
void Explosion_Damage(COORDINATE coord, int strength, TechnoClass * source, WarheadType warhead)
{
CELL cell; // Cell number under explosion.
ObjectClass * object; // Working object pointer.
ObjectClass * objects[32]; // Maximum number of objects that can be damaged.
int distance; // Distance to unit.
int range; // Damage effect radius.
int count; // Number of vehicle IDs in list.
if (!strength || Special.IsInert || warhead == WARHEAD_NONE) return;
WarheadTypeClass const * whead = WarheadTypeClass::As_Pointer(warhead);
// WarheadTypeClass const * whead = &Warheads[warhead];
// range = ICON_LEPTON_W*2;
range = ICON_LEPTON_W + (ICON_LEPTON_W >> 1);
cell = Coord_Cell(coord);
if ((unsigned)cell >= MAP_CELL_TOTAL) return;
CellClass * cellptr = &Map[cell];
ObjectClass * impacto = cellptr->Cell_Occupier();
/*
** Fill the list of unit IDs that will have damage
** assessed upon them. The units can be lifted from
** the cell data directly.
*/
count = 0;
for (FacingType i = FACING_NONE; i < FACING_COUNT; i++) {
/*
** Fetch a pointer to the cell to examine. This is either
** an adjacent cell or the center cell. Damage never spills
** further than one cell away.
*/
if (i != FACING_NONE) {
cellptr = &Map[cell].Adjacent_Cell(i);
}
/*
** Add all objects in this cell to the list of objects to possibly apply
** damage to. The list stops building when the object pointer list becomes
** full. Do not include overlapping objects; selection state can affect
** the overlappers, and this causes multiplayer games to go out of sync.
*/
object = cellptr->Cell_Occupier();
while (object) {
if (!object->IsToDamage && object != source) {
object->IsToDamage = true;
objects[count++] = object;
if (count >= ARRAY_SIZE(objects)) break;
}
object = object->Next;
}
if (count >= ARRAY_SIZE(objects)) break;
}
/*
** Sweep through the units to be damaged and damage them. When damaging
** buildings, consider a hit on any cell the building occupies as if it
** were a direct hit on the building's center.
*/
for (int index = 0; index < count; index++) {
object = objects[index];
object->IsToDamage = false;
if (object->IsActive) {
if (object->What_Am_I() == RTTI_BUILDING && impacto == object) {
distance = 0;
} else {
distance = Distance(coord, object->Center_Coord());
}
if (object->IsDown && !object->IsInLimbo && distance < range) {
int damage = strength;
object->Take_Damage(damage, distance, warhead, source);
}
}
}
/*
** If there is a wall present at this location, it may be destroyed. Check to
** make sure that the warhead is of the kind that can destroy walls.
*/
cellptr = &Map[cell];
if (cellptr->Overlay != OVERLAY_NONE) {
OverlayTypeClass const * optr = &OverlayTypeClass::As_Reference(cellptr->Overlay);
if (optr->IsTiberium && whead->IsTiberiumDestroyer) {
cellptr->Reduce_Tiberium(strength / 10);
}
if (optr->IsWall) {
if (whead->IsWallDestroyer || (whead->IsWoodDestroyer && optr->IsWooden)) {
Map[cell].Reduce_Wall(strength);
}
}
}
/*
** If there is a bridge at this location, then it may be destroyed by the
** combat damage.
*/
if (cellptr->TType == TEMPLATE_BRIDGE1 || cellptr->TType == TEMPLATE_BRIDGE2 ||
cellptr->TType == TEMPLATE_BRIDGE1H || cellptr->TType == TEMPLATE_BRIDGE2H ||
cellptr->TType == TEMPLATE_BRIDGE_1A || cellptr->TType == TEMPLATE_BRIDGE_1B ||
cellptr->TType == TEMPLATE_BRIDGE_2A || cellptr->TType == TEMPLATE_BRIDGE_2B ||
cellptr->TType == TEMPLATE_BRIDGE_3A || cellptr->TType == TEMPLATE_BRIDGE_3B ) {
if (((warhead == WARHEAD_AP || warhead == WARHEAD_HE) && Random_Pick(1, Rule.BridgeStrength) < strength)) {
Map.Destroy_Bridge_At(cell);
}
}
}
/***********************************************************************************************
* Combat_Anim -- Determines explosion animation to play. *
* *
* This routine is called when a projectile impacts. This routine will determine what *
* animation should be played. *
* *
* INPUT: damage -- The amount of damage this warhead possess (warhead size). *
* *
* warhead -- The type of warhead. *
* *
* land -- The land type that this explosion is over. Sometimes, this makes *
* a difference (especially over water). *
* *
* OUTPUT: Returns with the animation to play. If no animation is to be played, then *
* ANIM_NONE is returned. *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 05/19/1996 JLB : Created. *
*=============================================================================================*/
AnimType Combat_Anim(int damage, WarheadType warhead, LandType land)
{
/*
** For cases of no damage or invalid warhead, don't have any
** animation effect at all.
*/
if (damage == 0 || warhead == WARHEAD_NONE) {
return(ANIM_NONE);
}
static AnimType _aplist[] = {
ANIM_VEH_HIT3, // Small fragment throwing explosion -- burn/exp mix.
ANIM_VEH_HIT2, // Small fragment throwing explosion -- pop & sparkles.
ANIM_FRAG1, // Medium fragment throwing explosion -- short decay.
ANIM_FBALL1, // Large fireball explosion (bulges rightward).
};
static AnimType _helist[] = {
ANIM_VEH_HIT1, // Small fireball explosion (bulges rightward).
ANIM_VEH_HIT2, // Small fragment throwing explosion -- pop & sparkles.
ANIM_ART_EXP1, // Large fragment throwing explosion -- many sparkles.
ANIM_FBALL1, // Large fireball explosion (bulges rightward).
};
static AnimType _firelist[] = {
ANIM_NAPALM1, // Small napalm burn.
ANIM_NAPALM2, // Medium napalm burn.
ANIM_NAPALM3, // Large napalm burn.
};
static AnimType _waterlist[] = {
ANIM_WATER_EXP3,
ANIM_WATER_EXP2,
ANIM_WATER_EXP1,
};
WarheadTypeClass const * wptr = WarheadTypeClass::As_Pointer(warhead);
// WarheadTypeClass const * wptr = &Warheads[warhead];
switch (wptr->ExplosionSet) {
case 6:
return(ANIM_ATOM_BLAST);
case 2:
if (damage > 15) {
return(ANIM_PIFFPIFF);
}
return(ANIM_PIFF);
case 4:
if (land == LAND_NONE) return(ANIM_FLAK);
// Fixed math error
if (land == LAND_WATER) return(_waterlist[(ARRAY_SIZE(_waterlist)-1) * fixed(min(damage, 90), 90)]);
return(_aplist[(ARRAY_SIZE(_aplist)-1) * fixed(min(damage, 90), 90)]);
case 5:
if (land == LAND_NONE) return(ANIM_FLAK);
if (land == LAND_WATER) return(_waterlist[(ARRAY_SIZE(_waterlist)-1) * fixed(min(damage, 130), 130)]);
return(_helist[(ARRAY_SIZE(_helist)-1) * fixed(min(damage, 130), 130)]);
case 3:
if (land == LAND_NONE) return(ANIM_FLAK);
if (land == LAND_WATER) return(_waterlist[(ARRAY_SIZE(_waterlist)-1) * fixed(min(damage, 150), 150)]);
return(_firelist[(ARRAY_SIZE(_firelist)-1) * fixed(min(damage, 150), 150)]);
case 1:
return(ANIM_PIFF);
default:
break;
}
return(ANIM_NONE);
}
/***********************************************************************************************
* Wide_Area_Damage -- Apply wide area damage to the map. *
* *
* This routine will apply damage to a very wide area on the map. The damage will be *
* spread out from the coordinate specified by the radius specified. The amount of damage *
* will attenuate according to the distance from center. *
* *
* INPUT: coord -- The coordinate that the explosion damage will center about. *
* *
* radius -- The radius of the explosion. *
* *
* damage -- The amount of damage to apply at the center location. *
* *
* source -- Pointer to the purpetrator of the damage (if any). *
* *
* warhead -- The type of warhead that is causing the damage. *
* *
* OUTPUT: none *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 07/26/1996 JLB : Created. *
*=============================================================================================*/
void Wide_Area_Damage(COORDINATE coord, LEPTON radius, int rawdamage, TechnoClass * source, WarheadType warhead)
{
int cell_radius = (radius + CELL_LEPTON_W-1) / CELL_LEPTON_W;
CELL cell = Coord_Cell(coord);
for (int x = -cell_radius; x <= cell_radius; x++) {
for (int y = -cell_radius; y <= cell_radius; y++) {
int xpos = Cell_X(cell) + x;
int ypos = Cell_Y(cell) + y;
/*
** If the potential damage cell is outside of the map bounds,
** then don't process it. This unusual check method ensures that
** damage won't wrap from one side of the map to the other.
*/
if ((unsigned)xpos > MAP_CELL_W) {
continue;
}
if ((unsigned)ypos > MAP_CELL_H) {
continue;
}
CELL tcell = XY_Cell(xpos, ypos);
if (!Map.In_Radar(tcell)) continue;
int dist_from_center = Distance(XY_Coord(x+cell_radius, y+cell_radius), XY_Coord(cell_radius, cell_radius));
int damage = rawdamage * Inverse(fixed(cell_radius, dist_from_center));
Explosion_Damage(Cell_Coord(tcell), damage, source, warhead);
if (warhead == WARHEAD_FIRE && damage > 100) {
new SmudgeClass(Random_Pick(SMUDGE_SCORCH1, SMUDGE_SCORCH6), Cell_Coord(tcell));
}
}
}
}

1161
REDALERT/COMBUF.CPP Normal file

File diff suppressed because it is too large Load Diff

190
REDALERT/COMBUF.H Normal file
View File

@ -0,0 +1,190 @@
//
// 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/COMBUF.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 : COMBUF.H *
* *
* Programmer : Bill Randolph *
* *
* Start Date : December 19, 1994 *
* *
* Last Update : April 1, 1995 [BR] *
* *
*-------------------------------------------------------------------------*
* *
* This class's job is to store outgoing messages & incoming messages, *
* and serves as a storage area for various flags for ACK & Retry logic. *
* *
* This class stores buffers in a non-sequenced order; it allows freeing *
* any entry, so the buffers can be kept clear, even if packets come in *
* out of order. *
* *
* The class also contains routines to maintain a cumulative response time *
* for this queue. It's up to the caller to call Add_Delay() whenever *
* it detects that an outgoing message has been ACK'd; this class adds *
* that delay into a computed average delay over the last few message *
* delays. *
* *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef COMBUF_H
#define COMBUF_H
/*
********************************** Defines **********************************
*/
/*---------------------------------------------------------------------------
This is one output queue entry
---------------------------------------------------------------------------*/
typedef struct {
unsigned int IsActive : 1; // 1 = this entry is ready to be processed
unsigned int IsACK : 1; // 1 = ACK received for this packet
unsigned long FirstTime; // time this packet was first sent
unsigned long LastTime; // time this packet was last sent
unsigned long SendCount; // # of times this packet has been sent
int BufLen; // size of the packet stored in this entry
char *Buffer; // the data packet
int ExtraLen; // size of extra data
char *ExtraBuffer; // extra data buffer
} SendQueueType;
/*---------------------------------------------------------------------------
This is one input queue entry
---------------------------------------------------------------------------*/
typedef struct {
unsigned int IsActive : 1; // 1 = this entry is ready to be processed
unsigned int IsRead : 1; // 1 = caller has read this entry
unsigned int IsACK : 1; // 1 = ACK sent for this packet
int BufLen; // size of the packet stored in this entry
char *Buffer; // the data packet
int ExtraLen; // size of extra data
char *ExtraBuffer; // extra data buffer
} ReceiveQueueType;
/*
***************************** Class Declaration *****************************
*/
class CommBufferClass
{
/*
---------------------------- Public Interface ----------------------------
*/
public:
/*
....................... Constructor/Destructor ........................
*/
CommBufferClass(int numsend, int numrecieve, int maxlen,
int extralen = 0);
virtual ~CommBufferClass();
void Init(void);
void Init_Send_Queue(void);
/*
......................... Send Queue routines .........................
*/
int Queue_Send(void *buf, int buflen, void *extrabuf = NULL,
int extralen = 0);
int UnQueue_Send(void *buf, int *buflen, int index,
void *extrabuf = NULL, int *extralen = NULL);
int Num_Send(void) {return (SendCount);} // # entries in queue
int Max_Send(void) { return (MaxSend);} // max # send queue entries
SendQueueType * Get_Send(int index); // random access to queue
unsigned long Send_Total(void) {return (SendTotal);}
/*
....................... Receive Queue routines ........................
*/
int Queue_Receive(void *buf, int buflen, void *extrabuf = NULL,
int extralen = 0);
int UnQueue_Receive(void *buf, int *buflen, int index,
void *extrabuf = NULL, int *extralen = NULL);
int Num_Receive(void) {return (ReceiveCount);} // # entries in queue
int Max_Receive(void) { return (MaxReceive); } // max # recv queue entries
ReceiveQueueType * Get_Receive(int index); // random access to queue
unsigned long Receive_Total(void) {return (ReceiveTotal);}
/*
....................... Response time routines ........................
*/
void Add_Delay(unsigned long delay); // accumulates response time
unsigned long Avg_Response_Time(void); // gets mean response time
unsigned long Max_Response_Time(void); // gets max response time
void Reset_Response_Time(void); // resets computations
/*
........................ Debug output routines ........................
*/
void Configure_Debug(int type_offset, int type_size, char **names,
int namestart, int namecount);
void Mono_Debug_Print(int refresh = 0);
void Mono_Debug_Print2(int refresh = 0);
/*
--------------------------- Private Interface ----------------------------
*/
private:
/*
.......................... Limiting variables .........................
*/
int MaxSend; // max # send queue entries
int MaxReceive; // max # receive queue entries
int MaxPacketSize; // max size of a packet, in bytes
int MaxExtraSize; // max size of extra bytes
/*
....................... Response time variables .......................
*/
unsigned long DelaySum; // sum of last 4 delay times
unsigned long NumDelay; // current # delay times summed
unsigned long MeanDelay; // current average delay time
unsigned long MaxDelay; // max delay ever for this queue
/*
........................ Send Queue variables .........................
*/
SendQueueType * SendQueue; // incoming packets
int SendCount; // # packets in the queue
unsigned long SendTotal; // total # added to send queue
int *SendIndex; // array of Send entry indices
/*
....................... Receive Queue variables .......................
*/
ReceiveQueueType * ReceiveQueue; // outgoing packets
int ReceiveCount; // # packets in the queue
unsigned long ReceiveTotal; // total # added to receive queue
int *ReceiveIndex; // array of Receive entry indices
/*
......................... Debugging Variables .........................
*/
int DebugOffset; // offset into app's packet for ID
int DebugSize; // size of app's ID
char **DebugNames; // ptr to array of app-specific names
int DebugNameStart; // number of 1st ID
int DebugNameCount; // # of names in array
};
#endif
/**************************** end of combuf.h ******************************/

48
REDALERT/COMINIT.CPP Normal file
View File

@ -0,0 +1,48 @@
//
// 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
//
// If you link with this it will automatically call the COM initialization stuff
//
#include "cominit.h"
//#include <stdlib.h>
//#include <stdio.h>
//#include <windows.h>
#include <objbase.h>
//#include "externs.h"
//#include "text.rh"
//#include "WolDebug.h"
ComInit::ComInit()
{
//HRESULT hRes = CoInitialize(NULL);
// if (SUCCEEDED(hRes)==FALSE)
// exit(0);
HRESULT hRes = OleInitialize(NULL);
}
ComInit::~ComInit()
{
// CoUninitialize();
// debugprint( "pre OleUninitialize\n" );
OleUninitialize();
// debugprint( "post OleUninitialize\n" );
}
// Creating this instance will setup all COM stuff & do cleanup on program exit
ComInit Global_COM_Initializer;

31
REDALERT/COMINIT.H Normal file
View File

@ -0,0 +1,31 @@
//
// 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
#ifndef COMINIT_HEADER
#define COMINIT_HEADER
//
// Link with this to automatically initialize COM at startup
// - See cominit.cpp for more info
//
class ComInit
{
public:
ComInit();
~ComInit();
};
#endif

214
REDALERT/COMPAT.H Normal file
View File

@ -0,0 +1,214 @@
//
// 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/COMPAT.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 : COMPAT.H *
* *
* Programmer : Joe L. Bostic *
* *
* Start Date : 03/02/95 *
* *
* Last Update : March 2, 1995 [JLB] *
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef COMPAT_H
#define COMPAT_H
#define BuffType BufferClass
//#define movmem(a,b,c) memmove(b,a,c)
#define ShapeBufferSize _ShapeBufferSize
/*=========================================================================*/
/* Define some equates for the different graphic routines we will install */
/* later. */
/*=========================================================================*/
#define HIDBUFF ((void *)(0xA0000))
#define Size_Of_Region(a, b) ((a)*(b))
/*=========================================================================*/
/* Define some Graphic Routines which will only be fixed by these defines */
/*=========================================================================*/
#define Set_Font_Palette(a) Set_Font_Palette_Range(a, 0, 15)
/*
** These are the Open_File, Read_File, and Seek_File constants.
*/
#define READ 1 // Read access.
#define WRITE 2 // Write access.
#ifndef SEEK_SET
#define SEEK_SET 0 // Seek from start of file.
#define SEEK_CUR 1 // Seek relative from current location.
#define SEEK_END 2 // Seek from end of file.
#endif
#define ERROR_WINDOW 1
#define ErrorWindow 1
//extern unsigned char *Palette;
extern unsigned char MDisabled; // Is mouse disabled?
extern WORD Hard_Error_Occured;
/*
** This is the menu control structures.
*/
typedef enum MenuIndexType {
MENUX,
MENUY,
ITEMWIDTH,
ITEMSHIGH,
MSELECTED,
NORMCOL,
HILITE,
MENUPADDING=0x1000
} MenuIndexType;
#ifdef NEVER
#define BITSPERBYTE 8
#define MAXSHORT 0x7FFF
#define HIBITS 0x8000
#define MAXLONG 0x7FFFFFFFL
#define HIBITL 0x80000000
#define MAXINT MAXLONG
#define HIBITI HIBITL
#define DMAXEXP 308
#define FMAXEXP 38
#define DMINEXP -307
#define FMINEXP -37
#define MAXDOUBLE 1.797693E+308
#define MAXFLOAT 3.37E+38F
#define MINDOUBLE 2.225074E-308
#define MINFLOAT 8.43E-37F
#define DSIGNIF 53
#define FSIGNIF 24
#define DMAXPOWTWO 0x3FF
#define FMAXPOWTWO 0x7F
#define DEXPLEN 11
#define FEXPLEN 8
#define EXPBASE 2
#define IEEE 1
#define LENBASE 1
#define HIDDENBIT 1
#define LN_MAXDOUBLE 7.0978E+2
#define LN_MINDOUBLE -7.0840E+2
#endif
/* These defines handle the various names given to the same color. */
#define DKGREEN GREEN
#define DKBLUE BLUE
#define GRAY GREY
#define DKGREY GREY
#define DKGRAY GREY
#define LTGRAY LTGREY
class IconsetClass;
#ifndef WIN32
typedef struct {
short Width; // Width of icons (pixels).
short Height; // Height of icons (pixels).
short Count; // Number of (logical) icons in this set.
short Allocated; // Was this iconset allocated?
short MapWidth; // Width of map (in icons).
short MapHeight; // Height of map (in icons).
long Size; // Size of entire iconset memory block.
long Icons; // Offset from buffer start to icon data.
// unsigned char * Icons; // Offset from buffer start to icon data.
long Palettes; // Offset from buffer start to palette data.
long Remaps; // Offset from buffer start to remap index data.
long TransFlag; // Offset for transparency flag table.
long ColorMap; // Offset for color control value table.
long Map; // Icon map offset (if present).
// unsigned char * Map; // Icon map offset (if present).
} IControl_Type;
#endif
inline int Get_IconSet_MapWidth(void const * data)
{
if (data) {
return(((IControl_Type *)data)->MapWidth);
}
return(0);
}
inline int Get_IconSet_MapHeight(void const * data)
{
if (data) {
return(((IControl_Type *)data)->MapHeight);
}
return(0);
}
inline unsigned char const * Get_IconSet_ControlMap(void const * data)
{
if (data) {
return((unsigned char const *)((char *)data + ((IControl_Type *)data)->ColorMap));
}
return(0);
}
class IconsetClass : protected IControl_Type
{
public:
/*
** Query functions.
*/
int Map_Width(void) const {return(MapWidth);};
int Map_Height(void) const {return(MapHeight);};
unsigned char * Control_Map(void) {return((unsigned char *)this + ColorMap);};
unsigned char const * Control_Map(void) const {return((unsigned char const *)this + ColorMap);};
int Icon_Count(void) const {return(Count);};
int Pixel_Width(void) const {return(Width);};
int Pixel_Height(void) const {return(Height);};
int Total_Size(void) const {return(Size);};
unsigned char const * Palette_Data(void) const {return((unsigned char const *)this + Palettes);};
unsigned char * Palette_Data(void) {return((unsigned char *)this + Palettes);};
unsigned char const * Icon_Data(void) const {return((unsigned char const *)this + Icons);};
unsigned char * Icon_Data(void) {return((unsigned char *)this + Icons);};
unsigned char const * Map_Data(void) const {return((unsigned char const *)this + Map);};
unsigned char * Map_Data(void) {return((unsigned char *)this + Map);};
unsigned char const * Remap_Data(void) const {return((unsigned char const *)this + Remaps);};
unsigned char * Remap_Data(void) {return((unsigned char *)this + Remaps);};
unsigned char const * Trans_Data(void) const {return((unsigned char const *)this + TransFlag);};
unsigned char * Trans_Data(void) {return((unsigned char *)this + TransFlag);};
/*
** Disallow these operations with an IconsetClass object.
*/
private:
IconsetClass & operator = (IconsetClass const &);
IconsetClass(void);
static void * operator new(size_t);
};
#endif

1002
REDALERT/COMQUEUE.CPP Normal file

File diff suppressed because it is too large Load Diff

190
REDALERT/COMQUEUE.H Normal file
View File

@ -0,0 +1,190 @@
//
// 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: F:\projects\c&c0\vcs\code\comqueue.h_v 4.1 11 Apr 1996 18:26:02 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 : COMQUEUE.H *
* *
* Programmer : Bill Randolph *
* *
* Start Date : December 19, 1994 *
* *
* Last Update : April 1, 1995 [BR] *
* *
*-------------------------------------------------------------------------*
* *
* This class's job is to queue up outgoing messages & incoming messages, *
* and serves as a storage area for various flags for ACK & Retry logic. *
* It allows the application to keep track of how many messages have *
* passed through this queue, in & out, so packets can use this as a *
* unique ID. (If packets have a unique ID, the application can use this *
* to detect re-sends.) *
* *
* The queues act as FIFO buffers (First-In, First-Out). The first entry *
* placed in a queue is the first one read from it, and so on. The *
* controlling application must ensure it places the entries on the queue *
* in the order it wants to access them. *
* *
* The queue is implemented as an array of Queue Entries. Index 0 is the *
* first element placed on the queue, and is the first retrieved. Index *
* 1 is the next, and so on. When Index 0 is retrieved, the next-available*
* entry becomes Index 1. The array is circular; when the end is reached, *
* the indices wrap around to the beginning. *
* *
* The class also contains routines to maintain a cumulative response time *
* for this queue. It's up to the caller to call Add_Delay() whenever *
* it detects that an outgoing message has been ACK'd; this class adds *
* that delay into a computed average delay over the last few message *
* delays. *
* *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef COMQUEUE_H
#define COMQUEUE_H
/*---------------------------------------------------------------------------
This is one output queue entry
---------------------------------------------------------------------------*/
typedef struct {
unsigned int IsActive : 1; // 1 = this entry is ready to be processed
unsigned int IsACK : 1; // 1 = ACK received for this packet
unsigned long FirstTime; // time this packet was first sent
unsigned long LastTime; // time this packet was last sent
unsigned long SendCount; // # of times this packet has been sent
int BufLen; // size of the packet stored in this entry
char *Buffer; // the data packet
} SendQueueType;
/*---------------------------------------------------------------------------
This is one input queue entry
---------------------------------------------------------------------------*/
typedef struct {
unsigned int IsActive : 1; // 1 = this entry is ready to be processed
unsigned int IsRead : 1; // 1 = caller has read this entry
unsigned int IsACK : 1; // 1 = ACK sent for this packet
int BufLen; // size of the packet stored in this entry
char *Buffer; // the data packet
} ReceiveQueueType;
/*
***************************** Class Declaration *****************************
*/
class CommQueueClass
{
/*
---------------------------- Public Interface ----------------------------
*/
public:
/*
....................... Constructor/Destructor ........................
*/
CommQueueClass(int numsend, int numrecieve, int maxlen);
virtual ~CommQueueClass();
void Init(void);
/*
......................... Send Queue routines .........................
*/
int Queue_Send(void *buf, int buflen); // add to Send queue
int UnQueue_Send(void *buf, int *buflen); // remove from Send queue
SendQueueType * Next_Send(void); // ptr to next avail entry
int Num_Send(void) {return (SendCount);} // # entries in queue
int Max_Send(void) { return (MaxSend);} // max # send queue entries
SendQueueType * Get_Send(int index); // random access to queue
unsigned long Send_Total(void) {return (SendTotal);}
/*
....................... Receive Queue routines ........................
*/
int Queue_Receive(void *buf, int buflen); // add to Receive queue
int UnQueue_Receive(void *buf, int *buflen); // remove from Receive queue
ReceiveQueueType * Next_Receive(void); // ptr to next avail entry
int Num_Receive(void) {return (ReceiveCount);} // # entries in queue
int Max_Receive(void) { return (MaxReceive); } // max # recv queue entries
ReceiveQueueType * Get_Receive(int index); // random access to queue
unsigned long Receive_Total(void) {return (ReceiveTotal);}
/*
....................... Response time routines ........................
*/
void Add_Delay(unsigned long delay); // accumulates response time
unsigned long Avg_Response_Time(void); // gets mean response time
unsigned long Max_Response_Time(void); // gets max response time
void Reset_Response_Time(void); // resets computations
/*
........................ Debug output routines ........................
*/
void Configure_Debug(int offset, int size, char **names, int maxnames);
void Mono_Debug_Print(int refresh = 0);
void Mono_Debug_Print2(int refresh = 0);
/*
--------------------------- Private Interface ----------------------------
*/
private:
/*
.......................... Limiting variables .........................
*/
int MaxSend; // max # send queue entries
int MaxReceive; // max # receive queue entries
int MaxPacketSize; // max size of a packet, in bytes
/*
....................... Response time variables .......................
*/
unsigned long DelaySum; // sum of last 4 delay times
unsigned long NumDelay; // current # delay times summed
unsigned long MeanDelay; // current average delay time
unsigned long MaxDelay; // max delay ever for this queue
/*
........................ Send Queue variables .........................
*/
SendQueueType * SendQueue; // incoming packets
int SendCount; // # packets in the queue
int SendNext; // next entry read from queue
int SendEmpty; // next empty spot in queue
unsigned long SendTotal; // total # added to send queue
/*
....................... Receive Queue variables .......................
*/
ReceiveQueueType * ReceiveQueue; // outgoing packets
int ReceiveCount; // # packets in the queue
int ReceiveNext; // next entry read from queue
int ReceiveEmpty; // next empty spot in queue
unsigned long ReceiveTotal; // total # added to receive queue
/*
......................... Debugging Variables .........................
*/
int DebugOffset; // offset into app's packet for ID
int DebugSize; // size of app's ID
char **DebugNames; // ptr to array of app-specific names
int DebugMaxNames; // max # of names in array
};
#endif
/*************************** end of comqueue.h *****************************/

244
REDALERT/CONFDLG.CPP Normal file
View File

@ -0,0 +1,244 @@
//
// 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: F:\projects\c&c0\vcs\code\confdlg.cpv 4.67 27 Aug 1996 15:46:52 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 : CONFDLG.CPP *
* *
* Programmer : Maria del Mar McCready Legg *
* Joe L. Bostic *
* *
* Start Date : Jan 30, 1995 *
* *
* Last Update : Jan 30, 1995 [MML] *
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* ConfirmationClass::Process -- Handles all the options graphic interface. *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "function.h"
#include "confdlg.h"
bool ConfirmationClass::Process(int text)
{
text;
return true;
//return(Process(Text_String(text)));
}
#if (0) // ST - 5/8/2019
/***********************************************************************************************
* ConfirmationClass::Process -- Handles all the options graphic interface. *
* *
* This dialog uses an edit box to confirm a deletion. *
* *
* INPUT: char * string - display in edit box. *
* *
* OUTPUT: none *
* *
* WARNINGS: none *
* *
* HISTORY: 12/31/1994 MML : Created. *
*=============================================================================================*/
bool ConfirmationClass::Process(char const * string)
{
enum {
NUM_OF_BUTTONS = 2
};
char buffer[80*3];
int result = true;
int width;
int bwidth, bheight; // button width and height
int height;
int selection = 0;
bool pressed;
int curbutton;
TextButtonClass * buttons[NUM_OF_BUTTONS];
/*
** Set up the window. Window x-coords are in bytes not pixels.
*/
strcpy(buffer, string);
Fancy_Text_Print(TXT_NONE, 0, 0, TBLACK, TBLACK, TPF_6PT_GRAD | TPF_NOSHADOW);
Format_Window_String(buffer, 200, width, height);
width += 60;
height += 60;
int x = (320 - width) / 2;
int y = (200 - height) / 2;
Set_Logic_Page(SeenBuff);
/*
** Create Buttons. Button coords are in pixels, but are window-relative.
*/
bheight = FontHeight + FontYSpacing + 2;
bwidth = max( (String_Pixel_Width( Text_String( TXT_YES ) ) + 8), 30);
TextButtonClass yesbtn(BUTTON_YES, TXT_YES,
TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW,
x + 10, y + height - (bheight + 5), bwidth );
TextButtonClass nobtn(BUTTON_NO, TXT_NO,
TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW,
x + width - (bwidth + 10),
y + height - (bheight + 5), bwidth );
nobtn.Add_Tail(yesbtn);
curbutton = 1;
buttons[0] = &yesbtn;
buttons[1] = &nobtn;
buttons[curbutton]->Turn_On();
/*
** This causes left mouse button clicking within the confines of the dialog to
** be ignored if it wasn't recognized by any other button or slider.
*/
GadgetClass dialog(x, y, width, height, GadgetClass::LEFTPRESS);
dialog.Add_Tail(yesbtn);
/*
** This causes a right click anywhere or a left click outside the dialog region
** to be equivalent to clicking on the return to options dialog.
*/
ControlClass background(BUTTON_NO, 0, 0, 320, 200, GadgetClass::LEFTPRESS|GadgetClass::RIGHTPRESS);
background.Add_Tail(yesbtn);
/*
** Main Processing Loop.
*/
bool display = true;
bool process = true;
pressed = false;
while (process) {
/*
** Invoke game callback.
*/
if (Session.Type == GAME_NORMAL) {
Call_Back();
} else {
if (Main_Loop()) {
process = false;
result = false;
}
}
/*
** Refresh display if needed.
*/
if (display) {
Hide_Mouse();
/*
** Draw the background.
*/
Dialog_Box(x, y, width, height);
Draw_Caption(TXT_CONFIRMATION, x, y, width);
Fancy_Text_Print(buffer, x+20, y+30, GadgetClass::Get_Color_Scheme(), TBLACK, TPF_6PT_GRAD|TPF_USE_GRAD_PAL|TPF_NOSHADOW);
/*
** Draw the titles.
*/
yesbtn.Draw_All();
Show_Mouse();
display = false;
}
/*
** Get user input.
*/
KeyNumType input = yesbtn.Input();
/*
** Process Input.
*/
switch (input) {
case KeyNumType(BUTTON_YES | KN_BUTTON):
selection = BUTTON_YES;
pressed = true;
break;
case (KN_ESC):
case KeyNumType(BUTTON_NO | KN_BUTTON):
selection = BUTTON_NO;
pressed = true;
break;
case (KN_LEFT):
buttons[curbutton]->Turn_Off();
buttons[curbutton]->Flag_To_Redraw();
curbutton--;
if (curbutton < 0) {
curbutton = NUM_OF_BUTTONS - 1;
}
buttons[curbutton]->Turn_On();
buttons[curbutton]->Flag_To_Redraw();
break;
case (KN_RIGHT):
buttons[curbutton]->Turn_Off();
buttons[curbutton]->Flag_To_Redraw();
curbutton++;
if (curbutton > (NUM_OF_BUTTONS - 1) ) {
curbutton = 0;
}
buttons[curbutton]->Turn_On();
buttons[curbutton]->Flag_To_Redraw();
break;
case (KN_RETURN):
selection = curbutton + BUTTON_YES;
pressed = true;
break;
default:
break;
}
if (pressed) {
switch (selection) {
case (BUTTON_YES):
result = true;
process = false;
break;
case (BUTTON_NO):
result = false;
process = false;
break;
default:
break;
}
pressed = false;
}
}
return(result);
}
#endif

53
REDALERT/CONFDLG.H Normal file
View File

@ -0,0 +1,53 @@
//
// 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: F:\projects\c&c0\vcs\code\confdlg.h_v 4.69 27 Aug 1996 15:43:36 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 : CONFDLG.H *
* *
* Programmer : Maria del Mar McCready Legg *
* Joe L. Bostic *
* *
* Start Date : Jan 30, 1995 *
* *
* Last Update : Jan 30, 1995 [MML] *
* *
*---------------------------------------------------------------------------------------------*/
#ifndef CONFDLG_H
#define CONFDLG_H
#include "gadget.h"
class ConfirmationClass
{
private:
enum ConfirmationClassEnum {
BUTTON_YES=1, // Button number for "Options menu"
BUTTON_NO // Button number for "Options menu"
};
public:
ConfirmationClass(void) { };
bool Process(char const * string);
bool Process(int text);
};
#endif

835
REDALERT/CONNECT.CPP Normal file
View File

@ -0,0 +1,835 @@
//
// 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/CONNECT.CPP 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 : CONNECT.CPP *
* *
* Programmer : Bill Randolph *
* *
* Start Date : December 20, 1994 *
* *
* Last Update : May 31, 1995 [BRR] *
*-------------------------------------------------------------------------*
* Functions: *
* ConnectionClass::ConnectionClass -- class constructor *
* ConnectionClass::~ConnectionClass -- class destructor *
* ConnectionClass::Init -- Initializes connection queue to empty *
* ConnectionClass::Send_Packet -- adds a packet to the send queue *
* ConnectionClass::Receive_Packet -- adds packet to receive queue *
* ConnectionClass::Get_Packet -- gets a packet from receive queue *
* ConnectionClass::Service -- main polling routine; services packets *
* ConnectionClass::Service_Send_Queue -- services the send queue *
* ConnectionClass::Service_Receive_Queue -- services receive queue *
* ConnectionClass::Time -- gets current time *
* ConnectionClass::Command_Name -- returns name for a packet command *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "function.h"
#include <stdio.h>
//#include <mem.h>
#include <sys\timeb.h>
#include "connect.h"
//#include "WolDebug.h"
/*
********************************* Globals ***********************************
*/
char *ConnectionClass::Commands[PACKET_COUNT] = {
"ADATA",
"NDATA",
"ACK"
};
/***************************************************************************
* ConnectionClass::ConnectionClass -- class constructor *
* *
* INPUT: *
* numsend desired # of entries for the send queue *
* numreceive desired # of entries for the receive queue *
* maxlen max length of an application packet *
* magicnum the packet "magic number" for this connection *
* retry_delta the time to wait between sends *
* max_retries the max # of retries allowed for a packet *
* (-1 means retry forever, based on this parameter) *
* timeout the max amount of time before we give up on a packet *
* (-1 means retry forever, based on this parameter) *
* extralen max size of app-specific extra bytes (optional) *
* *
* OUTPUT: *
* none. *
* *
* WARNINGS: *
* none. *
* *
* HISTORY: *
* 12/20/1994 BR : Created. *
*=========================================================================*/
ConnectionClass::ConnectionClass (int numsend, int numreceive,
int maxlen, unsigned short magicnum, unsigned long retry_delta,
unsigned long max_retries, unsigned long timeout, int extralen)
{
/*------------------------------------------------------------------------
Compute our maximum packet length
------------------------------------------------------------------------*/
MaxPacketLen = maxlen + sizeof(CommHeaderType);
/*------------------------------------------------------------------------
Assign the magic number
------------------------------------------------------------------------*/
MagicNum = magicnum;
/*------------------------------------------------------------------------
Initialize the retry time. This is the time that t2 - t1 must be greater
than before a retry will occur.
------------------------------------------------------------------------*/
RetryDelta = retry_delta;
/*------------------------------------------------------------------------
Set the maximum allowable retries.
------------------------------------------------------------------------*/
MaxRetries = max_retries;
/*------------------------------------------------------------------------
Set the timeout for this connection.
------------------------------------------------------------------------*/
Timeout = timeout;
/*------------------------------------------------------------------------
Allocate the packet staging buffer. This will be used to
------------------------------------------------------------------------*/
PacketBuf = new char[ MaxPacketLen ];
/*------------------------------------------------------------------------
Allocate the packet Queue. This will store incoming packets (placed there
by Receive_Packet), and outgoing packets (placed there by Send_Packet).
It can optionally store "extra" bytes, which are stored along with each
packet, but aren't transmitted as part of the packet. If 'extralen'
is 0, the CommBufferClass ignores this parameter.
------------------------------------------------------------------------*/
Queue = new CommBufferClass (numsend, numreceive, MaxPacketLen, extralen);
} /* end of ConnectionClass */
/***************************************************************************
* ConnectionClass::~ConnectionClass -- class destructor *
* *
* INPUT: *
* none. *
* *
* OUTPUT: *
* none. *
* *
* WARNINGS: *
* none. *
* *
* HISTORY: *
* 12/20/1994 BR : Created. *
*=========================================================================*/
ConnectionClass::~ConnectionClass ()
{
/*------------------------------------------------------------------------
Free memory.
------------------------------------------------------------------------*/
delete [] PacketBuf;
delete Queue;
} /* end of ~ConnectionClass */
/***************************************************************************
* ConnectionClass::Init -- Initializes connection queue to empty *
* *
* INPUT: *
* none. *
* *
* OUTPUT: *
* none. *
* *
* WARNINGS: *
* none. *
* *
* HISTORY: *
* 12/20/1994 BR : Created. *
*=========================================================================*/
void ConnectionClass::Init (void)
{
NumRecNoAck = 0;
NumRecAck = 0;
NumSendNoAck = 0;
NumSendAck = 0;
LastSeqID = 0xffffffff;
LastReadID = 0xffffffff;
Queue->Init();
} /* end of Init */
/***************************************************************************
* ConnectionClass::Send_Packet -- adds a packet to the send queue *
* *
* This routine prefixes the given buffer with a CommHeaderType and *
* queues the resulting packet into the Send Queue. (It's actually the *
* Service() routine that handles the hardware-dependent Send of the data).*
* The packet's MagicNumber, Code, and PacketID are set here. *
* *
* INPUT: *
* buf buffer to send *
* buflen length of buffer *
* ack_req 1 = ACK is required for this packet; 0 = isn't *
* *
* OUTPUT: *
* 1 = packet was queue'd OK, 0 = wasn't *
* *
* WARNINGS: *
* none. *
* *
* HISTORY: *
* 12/20/1994 BR : Created. *
*=========================================================================*/
int ConnectionClass::Send_Packet (void * buf, int buflen, int ack_req)
{
/*------------------------------------------------------------------------
Set the magic # for the packet
------------------------------------------------------------------------*/
((CommHeaderType *)PacketBuf)->MagicNumber = MagicNum;
/*------------------------------------------------------------------------
Set the packet Code: DATA_ACK if it requires an ACK, NOACK if it doesn't
Set the packet ID to the appropriate counter value.
------------------------------------------------------------------------*/
if (ack_req) {
((CommHeaderType *)PacketBuf)->Code = PACKET_DATA_ACK;
((CommHeaderType *)PacketBuf)->PacketID = NumSendAck;
}
else {
((CommHeaderType *)PacketBuf)->Code = PACKET_DATA_NOACK;
((CommHeaderType *)PacketBuf)->PacketID = NumSendNoAck;
}
/*------------------------------------------------------------------------
Now build the packet
------------------------------------------------------------------------*/
memcpy(PacketBuf + sizeof(CommHeaderType), buf, buflen);
/*------------------------------------------------------------------------
Add it to the queue; don't add any extra data with it.
------------------------------------------------------------------------*/
if (Queue->Queue_Send(PacketBuf,buflen + sizeof(CommHeaderType), NULL, 0)) {
if (ack_req) {
NumSendAck++;
}
else {
NumSendNoAck++;
}
return(1);
}
else {
return(0);
}
} /* end of Send_Packet */
/***************************************************************************
* ConnectionClass::Receive_Packet -- adds packet to receive queue *
* *
* INPUT: *
* buf buffer to process (already includes CommHeaderType) *
* buflen length of buffer to process *
* *
* OUTPUT: *
* 1 = packet was processed OK, 0 = error *
* *
* WARNINGS: *
* none. *
* *
* HISTORY: *
* 12/20/1994 BR : Created. *
*=========================================================================*/
int ConnectionClass::Receive_Packet (void * buf, int buflen)
{
CommHeaderType *packet; // ptr to packet header
SendQueueType *send_entry; // ptr to send entry header
ReceiveQueueType *rec_entry; // ptr to recv entry header
CommHeaderType *entry_data; // ptr to queue entry data
CommHeaderType ackpacket; // ACK packet to send
int i;
int save_packet = 1; // 0 = this is a resend
int found;
/*------------------------------------------------------------------------
Check the magic #
------------------------------------------------------------------------*/
packet = (CommHeaderType *)buf;
if (packet->MagicNumber != MagicNum) {
return(0);
}
/*------------------------------------------------------------------------
Handle an incoming ACK
------------------------------------------------------------------------*/
if (packet->Code == PACKET_ACK) {
for (i = 0; i < Queue->Num_Send(); i++) {
/*..................................................................
Get queue entry ptr
..................................................................*/
send_entry = Queue->Get_Send(i);
/*..................................................................
If ptr is valid, get ptr to its data
..................................................................*/
if (send_entry != NULL) {
entry_data = (CommHeaderType *)send_entry->Buffer;
/*...............................................................
If ACK is for this entry, mark it
...............................................................*/
if (packet->PacketID==entry_data->PacketID &&
entry_data->Code == PACKET_DATA_ACK) {
send_entry->IsACK = 1;
break;
}
}
}
return(1);
}
/*------------------------------------------------------------------------
Handle an incoming PACKET_DATA_NOACK packet
------------------------------------------------------------------------*/
else if (packet->Code == PACKET_DATA_NOACK) {
/*.....................................................................
If there's only one slot left, don't tie up the queue with this packet
.....................................................................*/
if (Queue->Max_Receive() - Queue->Num_Receive() <= 1) {
return(0);
}
/*.....................................................................
Error if we can't queue the packet
.....................................................................*/
if (!Queue->Queue_Receive (buf, buflen, NULL, 0)) {
return(0);
}
NumRecNoAck++;
return(1);
}
/*------------------------------------------------------------------------
Handle an incoming PACKET_DATA_ACK packet
------------------------------------------------------------------------*/
else if (packet->Code == PACKET_DATA_ACK) {
/*.....................................................................
If this is a packet requires an ACK, and it's ID is older than our
"oldest" ID, we know it's a resend; send an ACK, but don't queue it
.....................................................................*/
if (packet->PacketID <= LastSeqID && LastSeqID != 0xffffffff) {
save_packet = 0;
}
/*.....................................................................
Otherwise, scan the queue for this entry; if it's found, it's a
resend, so don't save it.
.....................................................................*/
else {
save_packet = 1;
for (i = 0; i < Queue->Num_Receive(); i++) {
rec_entry = Queue->Get_Receive(i);
if (rec_entry) {
entry_data = (CommHeaderType *)rec_entry->Buffer;
/*...........................................................
Packet is found; it's a resend
...........................................................*/
if (entry_data->Code == PACKET_DATA_ACK &&
entry_data->PacketID == packet->PacketID) {
save_packet = 0;
break;
}
}
}
} /* end of scan for resend */
/*.....................................................................
Queue the packet & update our LastSeqID value.
.....................................................................*/
if (save_packet) {
/*..................................................................
If there's only one slot left, make sure we only put a packet in it
if this packet will let us increment our LastSeqID; otherwise, we'll
get stuck, forever unable to increment LastSeqID.
..................................................................*/
if (Queue->Max_Receive() - Queue->Num_Receive() <= 1) {
if (packet->PacketID != (LastSeqID + 1) ) {
return(0);
}
}
/*..................................................................
If we can't queue the packet, return; don't send an ACK.
..................................................................*/
if (!Queue->Queue_Receive (buf, buflen, NULL, 0)) {
return(0);
}
NumRecAck++;
/*..................................................................
Update our LastSeqID value if we can. Anything less than LastSeqID
we'll know is a resend.
..................................................................*/
if (packet->PacketID == (LastSeqID + 1)) {
LastSeqID = packet->PacketID;
/*...............................................................
Now that we have a new 'LastSeqID', search our Queue to see if
the next ID is there; if so, keep checking for the next one;
break only when the next one isn't found. This forces
LastSeqID to be the largest possible value.
...............................................................*/
do {
found = 0;
for (i = 0; i < Queue->Num_Receive(); i++) {
rec_entry = Queue->Get_Receive(i);
if (rec_entry) {
entry_data = (CommHeaderType *)rec_entry->Buffer;
/*......................................................
Entry is found
......................................................*/
if (entry_data->Code == PACKET_DATA_ACK &&
entry_data->PacketID == (LastSeqID + 1)) {
LastSeqID = entry_data->PacketID;
found = 1;
break;
}
}
}
} while (found);
}
} /* end of save packet */
/*.....................................................................
Send an ACK, regardless of whether this was a resend or not.
.....................................................................*/
ackpacket.MagicNumber = Magic_Num();
ackpacket.Code = PACKET_ACK;
ackpacket.PacketID = packet->PacketID;
Send ((char *)&ackpacket, sizeof(CommHeaderType), NULL, 0);
return(1);
}
return(0);
} /* end of Receive_Packet */
/***************************************************************************
* ConnectionClass::Get_Packet -- gets a packet from receive queue *
* *
* INPUT: *
* buf location to store buffer *
* buflen filled in with length of 'buf' *
* *
* OUTPUT: *
* 1 = packet was read, 0 = wasn't *
* *
* WARNINGS: *
* none. *
* *
* HISTORY: *
* 12/20/1994 BR : Created. *
*=========================================================================*/
int ConnectionClass::Get_Packet (void * buf, int *buflen)
{
ReceiveQueueType *rec_entry; // ptr to receive entry header
int packetlen; // size of received packet
CommHeaderType *entry_data;
int i;
/*------------------------------------------------------------------------
Ensure that we read the packets in order. LastReadID is the ID of the
last PACKET_DATA_ACK packet we read.
------------------------------------------------------------------------*/
for (i = 0; i < Queue->Num_Receive(); i++) {
rec_entry = Queue->Get_Receive(i);
/*.....................................................................
Only read this entry if it hasn't been yet
.....................................................................*/
if (rec_entry && rec_entry->IsRead==0) {
entry_data = (CommHeaderType *)rec_entry->Buffer;
/*..................................................................
If this is a DATA_ACK packet, its ID must be one greater than
the last one we read.
..................................................................*/
if ( (entry_data->Code == PACKET_DATA_ACK) &&
(entry_data->PacketID == (LastReadID + 1))) {
LastReadID = entry_data->PacketID;
rec_entry->IsRead = 1;
packetlen = rec_entry->BufLen - sizeof(CommHeaderType);
if (packetlen > 0) {
memcpy(buf, rec_entry->Buffer + sizeof(CommHeaderType),
packetlen);
}
(*buflen) = packetlen;
return(1);
}
/*..................................................................
If this is a DATA_NOACK packet, who cares what the ID is?
..................................................................*/
else if (entry_data->Code == PACKET_DATA_NOACK) {
rec_entry->IsRead = 1;
packetlen = rec_entry->BufLen - sizeof(CommHeaderType);
if (packetlen > 0) {
memcpy(buf, rec_entry->Buffer + sizeof(CommHeaderType),
packetlen);
}
(*buflen) = packetlen;
return(1);
}
}
}
return(0);
} /* end of Get_Packet */
/***************************************************************************
* ConnectionClass::Service -- main polling routine; services packets *
* *
* INPUT: *
* none. *
* *
* OUTPUT: *
* 1 = OK, 0 = error (connection is broken!) *
* *
* WARNINGS: *
* none. *
* *
* HISTORY: *
* 12/20/1994 BR : Created. *
*=========================================================================*/
int ConnectionClass::Service (void)
{
/*------------------------------------------------------------------------
Service the Send Queue: This [re]sends packets in the Send Queue which
haven't been ACK'd yet, and if their retry timeout has expired, and
updates the FirstTime, LastTime & SendCount values in the Queue entry.
Entries that have been ACK'd should be removed.
Service the Receive Queue: This sends ACKs for packets that haven't
been ACK'd yet. Entries that the app has read, and have been ACK'd,
should be removed.
------------------------------------------------------------------------*/
if ( Service_Send_Queue() && Service_Receive_Queue() ) {
return(1);
}
else {
return(0);
}
} /* end of Service */
/***************************************************************************
* ConnectionClass::Service_Send_Queue -- services the send queue *
* *
* INPUT: *
* none. *
* *
* OUTPUT: *
* 1 = OK, 0 = error *
* *
* WARNINGS: *
* none. *
* *
* HISTORY: *
* 12/20/1994 BR : Created. *
*=========================================================================*/
int ConnectionClass::Service_Send_Queue (void)
{
int i;
int num_entries;
SendQueueType *send_entry; // ptr to send queue entry
CommHeaderType *packet_hdr; // packet header
unsigned long curtime; // current time
int bad_conn = 0;
/*------------------------------------------------------------------------
Remove any ACK'd packets from the queue
------------------------------------------------------------------------*/
for (i = 0; i < Queue->Num_Send(); i++) {
/*.....................................................................
Get this queue entry
.....................................................................*/
send_entry = Queue->Get_Send(i);
/*.....................................................................
If ACK has been received, unqueue it
.....................................................................*/
if (send_entry->IsACK) {
/*..................................................................
Update this queue's response time
..................................................................*/
packet_hdr = (CommHeaderType *)send_entry->Buffer;
if (packet_hdr->Code == PACKET_DATA_ACK) {
Queue->Add_Delay(Time() - send_entry->FirstTime);
}
/*..................................................................
Unqueue the packet
..................................................................*/
Queue->UnQueue_Send(NULL,NULL,i,NULL,NULL);
i--;
}
}
/*------------------------------------------------------------------------
Loop through all entries in the Send queue. [Re]Send any entries that
need it.
------------------------------------------------------------------------*/
num_entries = Queue->Num_Send();
for (i = 0; i < num_entries; i++) {
send_entry = Queue->Get_Send(i);
if (send_entry->IsACK) {
continue;
}
/*.....................................................................
Only send the message if time has elapsed. (The message's Time
fields are init'd to 0 when a message is queue'd or unqueue'd, so the
first time through, the delta time will appear large.)
.....................................................................*/
curtime = Time();
if (curtime - send_entry->LastTime > RetryDelta) {
/*..................................................................
Send the message
..................................................................*/
Send (send_entry->Buffer, send_entry->BufLen, send_entry->ExtraBuffer,
send_entry->ExtraLen);
/*..................................................................
Fill in Time fields
..................................................................*/
send_entry->LastTime = curtime;
if (send_entry->SendCount==0) {
send_entry->FirstTime = curtime;
/*...............................................................
If this is the 1st time we're sending this packet, and it doesn't
require an ACK, mark it as ACK'd; then, the next time through,
it will just be removed from the queue.
...............................................................*/
packet_hdr = (CommHeaderType *)send_entry->Buffer;
if (packet_hdr->Code == PACKET_DATA_NOACK) {
send_entry->IsACK = 1;
}
}
/*..................................................................
Update SendCount
..................................................................*/
send_entry->SendCount++;
/*..................................................................
Perform error detection, based on either MaxRetries or Timeout
..................................................................*/
if (MaxRetries != -1 && send_entry->SendCount > MaxRetries) {
bad_conn = 1;
}
if (Timeout != -1 &&
(send_entry->LastTime - send_entry->FirstTime) > Timeout) {
bad_conn = 1;
}
}
}
/*------------------------------------------------------------------------
If the connection is going bad, return an error
------------------------------------------------------------------------*/
if (bad_conn) {
return(0);
}
else {
return(1);
}
} /* end of Service_Send_Queue */
/***************************************************************************
* ConnectionClass::Service_Receive_Queue -- services receive queue *
* *
* INPUT: *
* none. *
* *
* OUTPUT: *
* 1 = OK, 0 = error *
* *
* WARNINGS: *
* none. *
* *
* HISTORY: *
* 12/20/1994 BR : Created. *
*=========================================================================*/
int ConnectionClass::Service_Receive_Queue (void)
{
ReceiveQueueType *rec_entry; // ptr to receive entry header
CommHeaderType *packet_hdr; // packet header
int i;
/*------------------------------------------------------------------------
Remove all dead packets.
PACKET_DATA_NOACK: if it's been read, throw it away.
PACKET_DATA_ACK: if it's been read, and its ID is older than LastSeqID,
throw it away.
------------------------------------------------------------------------*/
for (i = 0; i < Queue->Num_Receive(); i++) {
rec_entry = Queue->Get_Receive(i);
if (rec_entry->IsRead) {
packet_hdr = (CommHeaderType *)(rec_entry->Buffer);
if (packet_hdr->Code == PACKET_DATA_NOACK) {
Queue->UnQueue_Receive(NULL,NULL,i,NULL,NULL);
i--;
}
else if (packet_hdr->PacketID < LastSeqID) {
Queue->UnQueue_Receive(NULL,NULL,i,NULL,NULL);
i--;
}
}
}
return(1);
} /* end of Service_Receive_Queue */
/***************************************************************************
* ConnectionClass::Time -- gets current time *
* *
* INPUT: *
* *
* OUTPUT: *
* none. *
* *
* WARNINGS: *
* none. *
* *
* HISTORY: *
* 12/20/1994 BR : Created. *
*=========================================================================*/
unsigned long ConnectionClass::Time (void)
{
static struct timeb mytime; // DOS time
unsigned long msec;
#ifdef WWLIB32_H
/*------------------------------------------------------------------------
If the Westwood timer system has been activated, use TickCount's value
------------------------------------------------------------------------*/
if (TimerSystemOn) {
return(TickCount); // Westwood Library time
}
/*------------------------------------------------------------------------
Otherwise, use the DOS timer
------------------------------------------------------------------------*/
else {
ftime(&mytime);
msec = (unsigned long)mytime.time * 1000L + (unsigned long)mytime.millitm;
return((msec / 100) * 6);
}
#else
/*------------------------------------------------------------------------
If the Westwood library isn't being used, use the DOS timer.
------------------------------------------------------------------------*/
ftime(&mytime);
msec = (unsigned long)mytime.time * 1000L + (unsigned long)mytime.millitm;
return((msec / 100) * 6);
#endif
} /* end of Time */
/***************************************************************************
* ConnectionClass::Command_Name -- returns name for given packet command *
* *
* INPUT: *
* command packet Command value to get name for *
* *
* OUTPUT: *
* ptr to command name, NULL if invalid *
* *
* WARNINGS: *
* none. *
* *
* HISTORY: *
* 05/31/1995 BRR : Created. *
*=========================================================================*/
char *ConnectionClass::Command_Name(int command)
{
if (command >= 0 && command < PACKET_COUNT) {
return(Commands[command]);
}
else {
return(NULL);
}
} /* end of Command_Name */
/************************** end of connect.cpp *****************************/

278
REDALERT/CONNECT.H Normal file
View File

@ -0,0 +1,278 @@
//
// 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/CONNECT.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 : CONNECT.H *
* *
* Programmer : Bill Randolph *
* *
* Start Date : December 19, 1994 *
* *
* Last Update : April 1, 1995 [BR] *
* *
*-------------------------------------------------------------------------*
* *
* DESCRIPTION: *
* This class represents a single "connection" with another system. It's *
* a pure virtual base class that acts as a framework for other classes. *
* *
* This class contains a CommBufferClass member, which stores received *
* & transmitted packets. The ConnectionClass has virtual functions to *
* handle adding packets to the queue, reading them from the queue, *
* a Send routine for actually sending data, and a Receive_Packet function *
* which is used to tell the connection that a new packet has come in. *
* *
* The virtual Service routines handle all ACK & Retry logic for *
* communicating between this system & another. Thus, any class derived *
* from this class may overload the basic ACK/Retry logic. *
* *
* THE PACKET HEADER: *
* The Connection Classes prefix every packet sent with a header that's *
* local to this class. The header contains a "Magic Number" which should *
* be unique for each product, and Packet "Code", which will tell the *
* receiving end if this is DATA, or an ACK packet, and a packet ID, which *
* is a unique numerical ID for this packet (useful for detecting resends).*
* The header is stored with each packet in the send & receive Queues; *
* it's removed before it's passed back to the application, via *
* Get_Packet() *
* *
* THE CONNECTION MANAGER: *
* It is assumed that there will be a "Connection Manager" class which *
* will handle parsing incoming packets; it will then tell the connection *
* that new packets have come in, and the connection will process them in *
* whatever way it needs to for its protocol (check for resends, handle *
* ACK packets, etc). The job of the connection manager is to parse *
* incoming packets & distribute them to the connections that need to *
* store them (for multi-connection protocols). *
* *
* NOTES ON ACK/RETRY: *
* This class provides a "non-sequenced" ACK/Retry approach to packet *
* transmission. It sends out as many packets as are in the queue, whose *
* resend delta times have expired; and it ACK's any packets its received *
* who haven't been ACK'd yet. Thus, order of delivery is NOT guaranteed; *
* but, the performance is better than a "sequenced" approach. Also, the *
* Packet ID scheme (see below) ensures that the application will read *
* the packets in the proper order. Thus, this class guarantees delivery *
* and order of deliver. *
* *
* Each packet has a unique numerical ID; the ID is set to a count of the *
* number of packets sent. Different count values are provided, for both *
* DATA_ACK & DATA_NOACK packets. This ensures that the counter can be *
* used to detect resends of DATA_ACK packets; the counters for DATA_NOACK *
* packets aren't currently used. Other counters keep track of the *
* last-sequentially-received packet ID (for DATA_ACK packets), so we *
* can check for resends & missed packets, and the last-sequentially-read *
* packet ID, so we can ensure the app reads the packets in order. *
* *
* If the protocol being used already guarantees delivery of packets, *
* no ACK is required for the packets. In this case, the connection *
* class for this protocol can overload the Service routine to avoid *
* sending ACK packets, or the Connection Manager can just mark the *
* packet as ACK'd when it adds it to the Receive Queue for the connection.*
* *
* Derived classes must provide: *
* - Init: Initialization of any hardware-specific values. *
* - Send: a hardware-dependent send routine. *
* *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef CONNECTION_H
#define CONNECTION_H
/*
********************************* Includes **********************************
*/
#include "combuf.h"
/*
********************************** Defines **********************************
*/
#define CONN_DEBUG 0
/*---------------------------------------------------------------------------
This structure is the header prefixed to any packet sent by the application.
MagicNumber: This is a number unique to the application; it's up to the
Receive_Packet routine to check this value, to be sure we're
not getting data from some other product. This value should
be unique for each application.
Code: This will be one of the below-defined codes.
PacketID: This is a unique numerical ID for this packet. The Connection
sets this ID on all packets sent out.
---------------------------------------------------------------------------*/
typedef struct {
unsigned short MagicNumber;
unsigned char Code;
unsigned long PacketID;
} CommHeaderType;
/*
***************************** Class Declaration *****************************
*/
class ConnectionClass
{
/*
---------------------------- Public Interface ----------------------------
*/
public:
/*.....................................................................
These are the possible values for the Code field of the CommHeaderType:
.....................................................................*/
enum ConnectionEnum {
PACKET_DATA_ACK, // this is a data packet requiring an ACK
PACKET_DATA_NOACK, // this is a data packet not requiring an ACK
PACKET_ACK, // this is an ACK for a packet
PACKET_COUNT // for computational purposes
};
/*.....................................................................
Constructor/destructor.
.....................................................................*/
ConnectionClass (int numsend, int numrecieve, int maxlen,
unsigned short magicnum, unsigned long retry_delta,
unsigned long max_retries, unsigned long timeout, int extralen = 0);
virtual ~ConnectionClass ();
/*.....................................................................
Initialization.
.....................................................................*/
virtual void Init (void);
/*.....................................................................
Send/Receive routines.
.....................................................................*/
virtual int Send_Packet (void * buf, int buflen, int ack_req);
virtual int Receive_Packet (void * buf, int buflen);
virtual int Get_Packet (void * buf, int * buflen);
/*.....................................................................
The main polling routine for the connection. Should be called as often
as possible.
.....................................................................*/
virtual int Service (void);
/*.....................................................................
This routine is used by the retry logic; returns the current time in
60ths of a second.
.....................................................................*/
static unsigned long Time (void);
/*.....................................................................
Utility routines.
.....................................................................*/
unsigned short Magic_Num (void) { return (MagicNum); }
unsigned long Retry_Delta (void) { return (RetryDelta); }
void Set_Retry_Delta (unsigned long delta) { RetryDelta = delta;}
unsigned long Max_Retries (void) { return (MaxRetries); }
void Set_Max_Retries (unsigned long retries) { MaxRetries = retries;}
unsigned long Time_Out (void) { return (Timeout); }
void Set_TimeOut (unsigned long t) { Timeout = t;}
unsigned long Max_Packet_Len (void) { return (MaxPacketLen); }
static char * Command_Name(int command);
/*.....................................................................
The packet "queue"; this non-sequenced version isn't really much of
a queue, but more of a repository.
.....................................................................*/
CommBufferClass *Queue;
/*
-------------------------- Protected Interface ---------------------------
*/
protected:
/*.....................................................................
Routines to service the Send & Receive queues.
.....................................................................*/
virtual int Service_Send_Queue(void);
virtual int Service_Receive_Queue(void);
/*.....................................................................
This routine actually performs a hardware-dependent data send. It's
pure virtual, so it must be defined by a derived class. The routine
is protected; it's only called by the ACK/Retry logic, not the
application.
.....................................................................*/
virtual int Send(char *buf, int buflen, void *extrabuf,
int extralen) = 0;
/*.....................................................................
This is the maximum packet length, including our own internal header.
.....................................................................*/
int MaxPacketLen;
/*.....................................................................
Packet staging area; this is where the CommHeaderType gets tacked onto
the application's packet before it's sent.
.....................................................................*/
char *PacketBuf;
/*.....................................................................
This is the magic number assigned to this connection. It is the first
few bytes of any transmission.
.....................................................................*/
unsigned short MagicNum;
/*.....................................................................
This value determines the time delay before a packet is re-sent.
.....................................................................*/
unsigned long RetryDelta;
/*.....................................................................
This is the maximum number of retries allowed for a packet; if this
value is exceeded, the connection is probably broken.
.....................................................................*/
unsigned long MaxRetries;
/*.....................................................................
This is the total timeout for this connection; if this time is exceeded
on a packet, the connection is probably broken.
.....................................................................*/
unsigned long Timeout;
/*.....................................................................
Running totals of # of packets we send & receive which require an ACK,
and those that don't.
.....................................................................*/
unsigned long NumRecNoAck;
unsigned long NumRecAck;
unsigned long NumSendNoAck;
unsigned long NumSendAck;
/*.....................................................................
This is the ID of the last consecutively-received packet; anything older
than this, we know is a resend. Anything newer than this MUST be lying
around in the Queue for us to detect it as a resend.
.....................................................................*/
unsigned long LastSeqID;
/*.....................................................................
This is the ID of the PACKET_DATA_ACK packet we read last; it ensures
that the application reads that type of packet in order.
.....................................................................*/
unsigned long LastReadID;
/*.....................................................................
Names of all packet commands
.....................................................................*/
static char * Commands[PACKET_COUNT];
};
#endif
/**************************** end of connect.h *****************************/

151
REDALERT/CONNMGR.H Normal file
View File

@ -0,0 +1,151 @@
//
// 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/CONNMGR.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 : CONNMGR.H *
* *
* Programmer : Bill Randolph *
* *
* Start Date : December 19, 1994 *
* *
* Last Update : April 3, 1995 [BR] *
* *
*-------------------------------------------------------------------------*
* *
* This is the Connection Manager base class. This is an abstract base *
* class that's just a shell for more functional derived classes. *
* The main job of the Connection Manager classes is to parse a "pool" of *
* incoming packets, which may be from different computers, and distribute *
* those packets to Connection Classes via their Receive_Packet function. *
* *
* This class should be the only access to the network/modem for the *
* application, so if the app needs any functions to access the *
* connections or the queue's, the derived versions of this class should *
* provide them. *
* *
* It's up to the derived class to define: *
* - Service: polling routine; should Service each connection *
* - Init: initialization; should perform hardware-dependent *
* initialization, then Init each connection; this function *
* isn't defined in this class, since the parameters will *
* be highly protocol-dependent) *
* - Send_Message:sends a packet across the connection (this function *
* isn't defined in this class, since the parameters will *
* be highly protocol-dependent) *
* - Get_Message: gets a message from the connection (this function *
* isn't defined in this class, since the parameters will *
* be highly protocol-dependent) *
* *
* If the derived class supports multiple connections, it should provide *
* functions for creating the connections, associating them with a name *
* or ID or both, destroying them, and sending data through all or any *
* connection. *
* *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef CONNMGR_H
#define CONNMGR_H
/*
***************************** Class Declaration *****************************
*/
class ConnManClass
{
/*
---------------------------- Public Interface ----------------------------
*/
public:
/*.....................................................................
Various useful enums:
.....................................................................*/
enum IPXConnTag {
CONNECTION_NONE = -1 // value of an invalid connection ID
};
/*.....................................................................
Constructor/Destructor. These currently do nothing.
.....................................................................*/
ConnManClass (void) {};
virtual ~ConnManClass () {};
/*.....................................................................
The Service routine:
- Parses incoming packets, and adds them to the Receive Queue for the
Connection Class(s) for this protocol
- Invokes each connection's Service routine; returns an error if the
connection's Service routine indicates an error.
.....................................................................*/
virtual int Service (void) = 0;
/*.....................................................................
Sending & receiving data
.....................................................................*/
virtual int Send_Private_Message (void *buf, int buflen,
int ack_req = 1, int conn_id = CONNECTION_NONE) = 0;
virtual int Get_Private_Message (void *buf, int *buflen,
int *conn_id) = 0;
/*.....................................................................
Connection management
.....................................................................*/
virtual int Num_Connections(void) = 0;
virtual int Connection_ID(int index) = 0;
virtual int Connection_Index(int id) = 0;
/*.....................................................................
Queue utility routines
.....................................................................*/
virtual int Global_Num_Send(void) = 0;
virtual int Global_Num_Receive(void) = 0;
virtual int Private_Num_Send(int id = CONNECTION_NONE) = 0;
virtual int Private_Num_Receive(int id = CONNECTION_NONE) = 0;
/*.....................................................................
Timing management
.....................................................................*/
virtual void Reset_Response_Time(void) = 0;
virtual unsigned long Response_Time(void) = 0;
virtual void Set_Timing (unsigned long retrydelta,
unsigned long maxretries, unsigned long timeout) = 0;
/*.....................................................................
Debugging
.....................................................................*/
virtual void Configure_Debug(int index, int type_offset, int type_size,
char **names, int namestart, int namecount) = 0;
#ifdef CHEAT_KEYS
virtual void Mono_Debug_Print(int index, int refresh) = 0;
#endif
/*
--------------------------- Private Interface ----------------------------
*/
private:
/*.....................................................................
This abstract class contains no data members; but a derived class
will contain:
- An instance of one or more derived Connection Classes
- A buffer to store incoming packets
.....................................................................*/
};
#endif

5736
REDALERT/CONQUER.CPP Normal file

File diff suppressed because it is too large Load Diff

571
REDALERT/CONQUER.H Normal file
View File

@ -0,0 +1,571 @@
//
// 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
#define TXT_NONE 0 //
#define TXT_CREDIT_FORMAT 1 // %3d.%02d
#define TXT_TIME_FORMAT_HOURS 2 // Temps:%02d:%02d:%02d
#define TXT_TIME_FORMAT_NO_HOURS 3 // Temps:%02d:%02d
#define TXT_BUTTON_SELL 4 // Vente
#define TXT_SELL 5 // Vente structure
#define TXT_BUTTON_REPAIR 6 // Rparation
#define TXT_YOU 7 // Vous :
#define TXT_ENEMY 8 // Ennemi :
#define TXT_BUILD_DEST 9 // Bƒtiments dtruits par
#define TXT_UNIT_DEST 10 // Units dtruites par
#define TXT_TIB_HARV 11 // Minerai rcolt par
#define TXT_SCORE_1 12 // Score: %d
#define TXT_YES 13 // Oui
#define TXT_NO 14 // Non
#define TXT_SCENARIO_WON 15 // Mission Accomplie
#define TXT_SCENARIO_LOST 16 // Mission Echoue
#define TXT_START_NEW_GAME 17 // Nouvelle partie
#define TXT_INTRO 18 // Intro/Preview
#define TXT_CANCEL 19 // Annuler
#define TXT_ROCK 20 // Rocher
#define TXT_CIVILIAN 21 // Civil
#define TXT_JP 22 // Equipe de confinement
#define TXT_OK 23 // OK
#define TXT_TREE 24 // Arbre
#define TXT_LEFT 25 // 
#define TXT_RIGHT 26 // 
#define TXT_UP 27 // 
#define TXT_DOWN 28 // 
#define TXT_CLEAR 29 // Effacer
#define TXT_WATER 30 // Eau
#define TXT_ROAD 31 // Route
#define TXT_SLOPE 32 // Pente
#define TXT_PATCH 33 // Patch
#define TXT_RIVER 34 // RiviŠre
#define TXT_LOAD_MISSION 35 // Charger Mission
#define TXT_SAVE_MISSION 36 // Sauvegarder Mission
#define TXT_DELETE_MISSION 37 // Effacer Mission
#define TXT_LOAD_BUTTON 38 // Charger
#define TXT_SAVE_BUTTON 39 // Sauvegarder
#define TXT_DELETE_BUTTON 40 // Effacer
#define TXT_GAME_CONTROLS 41 // Contr“les
#define TXT_SOUND_CONTROLS 42 // Son
#define TXT_RESUME_MISSION 43 // Reprendre Mission
#define TXT_VISUAL_CONTROLS 44 // Affichage
#define TXT_QUIT_MISSION 45 // Abandonner Mission
#define TXT_EXIT_GAME 46 // Quitter le jeu
#define TXT_OPTIONS 47 // Options
#define TXT_SQUISH 48 // Dbris humains
#define TXT_CRATER 49 // CratŠre
#define TXT_SCORCH 50 // Marque de brlure
#define TXT_BRIGHTNESS 51 // Luminosit :
#define TXT_MUSIC 52 // Musique
#define TXT_VOLUME 53 // Effets sonores
#define TXT_TINT 54 // Teintes :
#define TXT_CONTRAST 55 // Contraste :
#define TXT_SPEED 56 // Vitesse du jeu :
#define TXT_SCROLLRATE 57 // Vitesse dfilement :
#define TXT_COLOR 58 // Couleur :
#define TXT_RETURN_TO_GAME 59 // Revenir au jeu
#define TXT_ENEMY_SOLDIER 60 // Soldat ennemi
#define TXT_ENEMY_VEHICLE 61 // Vhicule ennemi
#define TXT_ENEMY_STRUCTURE 62 // Structure ennemie
#define TXT_LTANK 63 // Tank lger
#define TXT_MTANK 64 // Tank lourd
#define TXT_MTANK2 65 // Tank moyen
#define TXT_HTANK 66 // Tank Mammouth
#define TXT_SAM 67 // Missiles SAM
#define TXT_JEEP 68 // Ranger
#define TXT_TRANS 69 // HlicoptŠre Chinook
#define TXT_HARVESTER 70 // Collecteur minerai
#define TXT_ARTY 71 // Artillerie
#define TXT_E1 72 // Mitrailleurs
#define TXT_E2 73 // Grenadiers
#define TXT_E3 74 // Bazookas
#define TXT_E4 75 // Lance-flammes
#define TXT_HELI 76 // HlicoptŠre d'assaut
#define TXT_ORCA 77 // Hind
#define TXT_APC 78 // VBT
#define TXT_GUARD_TOWER 79 // Tour de garde
#define TXT_COMMAND 80 // D“me radar
#define TXT_HELIPAD 81 // Hliport
#define TXT_AIRSTRIP 82 // Piste d'atterrissage
#define TXT_STORAGE 83 // Silo minerai
#define TXT_CONST_YARD 84 // Chantier de construction
#define TXT_REFINERY 85 // Raffinerie de minerai
#define TXT_CIV1 86 // Eglise
#define TXT_CIV2 87 // Chez Hans et Gretel
#define TXT_CIV3 88 // Manoir d'Hewitt
#define TXT_CIV4 89 // Maison de Ricktor
#define TXT_CIV5 90 // Maison de Gretchin
#define TXT_CIV6 91 // La grange
#define TXT_CIV7 92 // Pub Damon
#define TXT_CIV8 93 // Maison de Fran
#define TXT_CIV9 94 // Usine d'instruments
#define TXT_CIV10 95 // Fabricant de jouets
#define TXT_CIV11 96 // Maison de Ludwig
#define TXT_CIV12 97 // Meules de foin
#define TXT_CIV13 98 // Meule de foin
#define TXT_CIV14 99 // Champ de bl
#define TXT_CIV15 100 // Champ en friche
#define TXT_CIV16 101 // Champ de mas
#define TXT_CIV17 102 // Champ de cleri
#define TXT_CIV18 103 // Champ de pommes de terre
#define TXT_CIV20 104 // Maison de Sala
#define TXT_CIV21 105 // Maison d'Abdul
#define TXT_CIV22 106 // Le Pub Barjo de Pablo
#define TXT_CIV23 107 // Puits du village
#define TXT_CIV24 108 // Marchand de chameaux
#define TXT_CIV25 109 // Eglise
#define TXT_CIV26 110 // Maison d'Ali
#define TXT_CIV27 111 // Ted le Marchand
#define TXT_CIV28 112 // Maison de Menelik
#define TXT_CIV29 113 // Maison du pasteur John
#define TXT_CIV30 114 // Puits du village
#define TXT_CIV31 115 // Hutte du gurisseur
#define TXT_CIV32 116 // Hutte de Rikitikitembo
#define TXT_CIV33 117 // Hutte de Roarke
#define TXT_CIV34 118 // Hutte de Moubasa'
#define TXT_CIV35 119 // Hutte d'Aksoum
#define TXT_CIV36 120 // Hutte de Mambo
#define TXT_CIV37 121 // Le studio
#define TXT_CIVMISS 122 // Centre technologique
#define TXT_TURRET 123 // Tourelle
#define TXT_GUNBOAT 124 // Aviso-torpilleur
#define TXT_MCV 125 // Vhicule de construction
#define TXT_POWER 126 // Centrale lectrique
#define TXT_ADVANCED_POWER 127 // Centrale lectrique avance
#define TXT_HOSPITAL 128 // H“pital
#define TXT_BARRACKS 129 // Caserne
#define TXT_PUMP 130 // Pompe
#define TXT_TANKER 131 // Ptrolier
#define TXT_SANDBAG_WALL 132 // Sacs de sable
#define TXT_CYCLONE_WALL 133 // Cl“ture grillage
#define TXT_BRICK_WALL 134 // Mur de bton
#define TXT_BARBWIRE_WALL 135 // Cl“ture barbele
#define TXT_WOOD_WALL 136 // BarriŠre de bois
#define TXT_WEAPON_FACTORY 137 // Usine d'armement
#define TXT_AGUARD_TOWER 138 // Tour de garde avance
#define TXT_BIO_LAB 139 // Laboratoire biologique
#define TXT_FIX_IT 140 // Centre de service
#define TXT_TAB_SIDEBAR 141 // Contr“les
#define TXT_TAB_BUTTON_CONTROLS 142 // Options
#define TXT_TAB_BUTTON_DATABASE 143 // Base de donnes
#define TXT_SHADOW 144 // Terrain inconnu
#define TXT_OPTIONS_MENU 145 // Menu des options
#define TXT_STOP 146 // Stop
#define TXT_PLAY 147 // Lect
#define TXT_SHUFFLE 148 // Alat.
#define TXT_REPEAT 149 // Rpter
#define TXT_MUSIC_VOLUME 150 // Musique :
#define TXT_SOUND_VOLUME 151 // Effets sonores :
#define TXT_ON 152 // Oui
#define TXT_OFF 153 // Non
#define TXT_MULTIPLAYER_GAME 154 // Jeu Multijoueurs
#define TXT_NO_FILES 155 // Pas de fichiers disponibles
#define TXT_DELETE_SINGLE_FILE 156 // Voulez-vous effacer ce
#define TXT_DELETE_MULTIPLE_FILES 157 // Voulez-vous effacer %d
#define TXT_RESET_MENU 158 // Dfaut
#define TXT_CONFIRM_EXIT 159 // Voulez-vous abandonner la
#define TXT_MISSION_DESCRIPTION 160 // Description de la mission
#define TXT_C1 161 // Joe
#define TXT_C2 162 // Barry
#define TXT_C3 163 // Shelly
#define TXT_C4 164 // Maria
#define TXT_C5 165 // Karen
#define TXT_C6 166 // Steve
#define TXT_C7 167 // Phil
#define TXT_C8 168 // Dwight
#define TXT_C9 169 // Erik
#define TXT_EINSTEIN 170 // Prof. Einstein
#define TXT_BIB 171 // Cour
#define TXT_FASTER 172 // Rapide
#define TXT_SLOWER 173 // Lent
#define TXT_AIR_STRIKE 174 // Attaque arienne
#define TXT_STEEL_CRATE 175 // Caisse d'acier
#define TXT_WOOD_CRATE 176 // Caisse de bois
#define TXT_WATER_CRATE 177 // Caisse flottante
#define TXT_FLAG_SPOT 178 // Emplacement du drapeau
#define TXT_UNABLE_READ_SCENARIO 179 // Lecture scnario impossible
#define TXT_ERROR_LOADING_GAME 180 // Erreur de chargement !
#define TXT_OBSOLETE_SAVEGAME 181 // Sauvegarde obsolŠte
#define TXT_MUSTENTER_DESCRIPTION 182 // Vous devez entrer une
#define TXT_ERROR_SAVING_GAME 183 // Erreur de sauvegarde !
#define TXT_DELETE_FILE_QUERY 184 // Effacer ce fichier ?
#define TXT_EMPTY_SLOT 185 // [EMPLACEMENT VIDE]
#define TXT_SELECT_MPLAYER_GAME 186 // Choix du jeu Multijoueurs
#define TXT_MODEM_SERIAL 187 // Modem/Srie
#define TXT_NETWORK 188 // Rseau
#define TXT_INIT_NET_ERROR 189 // Initialisation rseau
#define TXT_JOIN_NETWORK_GAME 190 // Rejoindre jeu en rseau
#define TXT_NEW 191 // Nouveau
#define TXT_JOIN 192 // Joindre
#define TXT_SEND_MESSAGE 193 // Envoi Message
#define TXT_YOUR_NAME 194 // Votre nom :
#define TXT_SIDE_COLON 195 // Camp :
#define TXT_COLOR_COLON 196 // Couleur :
#define TXT_GAMES 197 // Parties
#define TXT_PLAYERS 198 // Joueurs
#define TXT_SCENARIO_COLON 199 // Scnario :
#define TXT_NOT_FOUND 200 // >> NON TROUVE <<
#define TXT_START_CREDITS_COLON 201 // Crdits :
#define TXT_BASES_COLON 202 // Bases :
#define TXT_TIBERIUM_COLON 203 // Minerai :
#define TXT_CRATES_COLON 204 // Caisses :
#define TXT_AI_PLAYERS_COLON 205 // Joueurs IA :
#define TXT_REQUEST_DENIED 206 // Demande refuse.
#define TXT_UNABLE_PLAY_WAAUGH 207 // Impossible de jouer,
#define TXT_NOTHING_TO_JOIN 208 // Aucune partie disponible !
#define TXT_NAME_ERROR 209 // Vous devez entrer un nom !
#define TXT_DUPENAMES_NOTALLOWED 210 // Les noms identiques ne sont
#define TXT_YOURGAME_OUTDATED 211 // La version de votre jeu est
#define TXT_DESTGAME_OUTDATED 212 // Version du jeu de
#define TXT_THATGUYS_GAME 213 // Partie de %s
#define TXT_THATGUYS_GAME_BRACKET 214 // [Partie de %s]
#define TXT_NETGAME_SETUP 215 // Configuration du jeu en
#define TXT_REJECT 216 // Rejeter
#define TXT_CANT_REJECT_SELF 217 // Vous ne pouvez pas vous
#define TXT_SELECT_PLAYER_REJECT 218 // Vous devez slectionner un
#define TXT_BASES 219 // Bases
#define TXT_CRATES 220 // Caisses
#define TXT_AI_PLAYERS 221 // Joueur IA
#define TXT_SCENARIOS 222 // Scnarios
#define TXT_CREDITS_COLON 223 // Crdits :
#define TXT_ONLY_ONE 224 // Un seul joueur ?
#define TXT_OOPS 225 // Oops !
#define TXT_TO 226 // Pour %s :
#define TXT_TO_ALL 227 // Pour tous
#define TXT_MESSAGE 228 // Message :
#define TXT_CONNECTION_LOST 229 // Perte de connexion avec %s
#define TXT_LEFT_GAME 230 // %s a quitt le jeu.
#define TXT_PLAYER_DEFEATED 231 // %s a t vaincu !
#define TXT_WAITING_CONNECT 232 // Attente de connexion...
#define TXT_NULL_CONNERR_CHECK_CABLES 233 // Erreur de connexion !
#define TXT_MODEM_CONNERR_REDIALING 234 // Erreur de connexion !
#define TXT_MODEM_CONNERR_WAITING 235 // Erreur de connexion !
#define TXT_SELECT_SERIAL_GAME 236 // Choix du jeu en srie
#define TXT_DIAL_MODEM 237 // Appel
#define TXT_ANSWER_MODEM 238 // Attente appel
#define TXT_NULL_MODEM 239 // Null Modem
#define TXT_SETTINGS 240 // ParamŠtres
#define TXT_PORT_COLON 241 // Port :
#define TXT_IRQ_COLON 242 // IRQ :
#define TXT_BAUD_COLON 243 // Bauds :
#define TXT_INIT_STRING 244 // ChaŒne d'initialisation
#define TXT_CWAIT_STRING 245 // ChaŒne d'attente d'appel
#define TXT_TONE_BUTTON 246 // Tonalit
#define TXT_PULSE_BUTTON 247 // Impulsions
#define TXT_HOST_SERIAL_GAME 248 // H“te du jeu en srie
#define TXT_OPPONENT_COLON 249 // Adversaire :
#define TXT_USER_SIGNED_OFF 250 // Utilisateur reparti !
#define TXT_JOIN_SERIAL_GAME 251 // Rejoindre jeu en srie
#define TXT_PHONE_LIST 252 // Rpertoire
#define TXT_ADD 253 // Ajouter
#define TXT_EDIT 254 // Editer
#define TXT_DIAL 255 // Appel
#define TXT_DEFAULT 256 // Dfaut
#define TXT_DEFAULT_SETTINGS 257 // Dfaut
#define TXT_CUSTOM_SETTINGS 258 // Autres paramŠtres
#define TXT_PHONE_LISTING 259 // Rpertoire
#define TXT_NAME_COLON 260 // Nom :
#define TXT_NUMBER_COLON 261 // Numro :
#define TXT_UNABLE_FIND_MODEM 262 // Modem non dtect. Vrifiez
#define TXT_NO_CARRIER 263 // Pas de porteuse.
#define TXT_LINE_BUSY 264 // Ligne occupe.
#define TXT_NUMBER_INVALID 265 // Numro incorrect.
#define TXT_SYSTEM_NOT_RESPONDING 266 // L'autre systŠme ne rpond
#define TXT_OUT_OF_SYNC 267 // Mauvaise synchronisation !
#define TXT_PACKET_TOO_LATE 268 // Paquet re‡u trop tard !
#define TXT_PLAYER_LEFT_GAME 269 // L'autre joueur a quitt le
#define TXT_FROM 270 // De %s:%s
#define TXT_SCORE_TIME 271 // TEMPS :
#define TXT_SCORE_LEAD 272 // COMMANDEMENT :
#define TXT_SCORE_EFFI 273 // EFFICACITE :
#define TXT_SCORE_TOTA 274 // SCORE TOTAL :
#define TXT_SCORE_CASU 275 // PERTES :
#define TXT_SCORE_NEUT 276 // NEUTRE :
#define TXT_SCORE_BUIL 277 // BATIMENTS PERDUS
#define TXT_SCORE_BUIL1 278 // BATIMENTS
#define TXT_SCORE_BUIL2 279 // PERDUS :
#define TXT_SCORE_TOP 280 // MEILLEURS SCORES
#define TXT_SCORE_ENDCRED 281 // CREDITS DE FIN :
#define TXT_SCORE_TIMEFORMAT1 282 // %dh %dm
#define TXT_SCORE_TIMEFORMAT2 283 // %dm
#define TXT_DIALING 284 // Appel...
#define TXT_DIALING_CANCELED 285 // Appel annul
#define TXT_WAITING_FOR_CALL 286 // Attente d'appel...
#define TXT_ANSWERING_CANCELED 287 // Attente d'appel annule
#define TXT_E6 288 // Ingnieurs
#define TXT_E8 289 // Espion
#define TXT_MODEM_OR_LOOPBACK 290 // Pas de cƒble Null Modem
#define TXT_MAP 291 // Carte
#define TXT_BLOSSOM_TREE 292 // Arbre en fleurs
#define TXT_RESTATE_MISSION 293 // Briefing
#define TXT_COMPUTER 294 // Joueur IA
#define TXT_COUNT 295 // Nombre :
#define TXT_LEVEL 296 // Niveau :
#define TXT_OPPONENT 297 // Adversaire
#define TXT_KILLS_COLON 298 // Vict.:
#define TXT_VIDEO 299 // Vido
#define TXT_C10 300 // Scientifique
#define TXT_CAPTURE_THE_FLAG 301 // Capture drapeau
#define TXT_OBJECTIVE 302 // Objectifs de mission
#define TXT_MISSION 303 // Mission
#define TXT_NO_SAVES 304 // Pas de sauvegardes
#define TXT_CIVILIAN_BUILDING 305 // Bƒtiment civil
#define TXT_TECHNICIAN 306 // Technicien
#define TXT_NO_SAVELOAD 307 // Sauvegarde interdite en
#define TXT_DELPHI 308 // Agent Spcial 1
#define TXT_TO_REPLAY 309 // Voulez-vous recommencer
#define TXT_RECONN_TO 310 // Reconnexion vers %s.
#define TXT_PLEASE_WAIT 311 // Attendez %02d secondes.
#define TXT_SURRENDER 312 // Voulez-vous vous rendre ?
#define TXT_SEL_TRANS 313 // CHOIX DE LA TRANSMISSION
#define TXT_GAMENAME_MUSTBE_UNIQUE 314 // Les sauvegardes ne peuvent
#define TXT_GAME_IS_CLOSED 315 // Partie ferme.
#define TXT_NAME_MUSTBE_UNIQUE 316 // Les noms doivent ˆtre tous
#define TXT_RECONNECTING_TO 317 // Reconnexion vers %s
#define TXT_WAITING_FOR_CONNECTIONS 318 // Attente de connexions...
#define TXT_TIME_ALLOWED 319 // Temps autoris : %02d
#define TXT_PRESS_ESC 320 // Appuyez sur Echap pour
#define TXT_JUST_YOU_AND_ME 321 // De l'ordinateur : Il ne
#define TXT_CAPTURE_THE_FLAG_COLON 322 // Capture du drapeau :
#define TXT_CHAN 323 // Agent Spcial 2
#define TXT_HAS_ALLIED 324 // %s s'est alli(e) avec %s
#define TXT_AT_WAR 325 // %s dclare la guerre … %s
#define TXT_SEL_TARGET 326 // Choisissez un cible
#define TXT_RESIGN 327 // Abandonner
#define TXT_TIBERIUM_FAST 328 // Le minerai pousse trŠs
#define TXT_ANSWERING 329 // Rponse en cours...
#define TXT_INITIALIZING_MODEM 330 // Initialisation Modem...
#define TXT_SCENARIOS_DO_NOT_MATCH 331 // Les scnarios ne
#define TXT_POWER_OUTPUT 332 // Production d'nergie
#define TXT_POWER_OUTPUT_LOW 333 // Production d'nergie
#define TXT_CONTINUE 334 // Continuer
#define TXT_QUEUE_FULL 335 // Saturation des donnes …
#define TXT_SPECIAL_WARNING 336 // %s a modifi les options de
#define TXT_CD_DIALOG_1 337 // Placez un CD d'Alerte Rouge
#define TXT_CD_DIALOG_2 338 // Placez le CD %d (%s) dans
#define TXT_CD_ERROR1 339 // Alerte Rouge n'a pas
#define TXT_NO_SOUND_CARD 340 // Pas de carte sonore
#define TXT_UNKNOWN 341 // INCONNU
#define TXT_OLD_GAME 342 // (ancien)
#define TXT_NO_SPACE 343 // Espace disque insuffisant
#define TXT_MUST_HAVE_SPACE 344 // Vous devez disposer de %d
#define TXT_RUN_SETUP 345 // Lancez d'abord le programme
#define TXT_WAITING_FOR_OPPONENT 346 // Attente adversaire
#define TXT_SELECT_SETTINGS 347 // Choisissez l'option
#define TXT_PRISON 348 // Prison
#define TXT_GAME_WAS_SAVED 349 // Mission sauvegarde
#define TXT_SPACE_CANT_SAVE 350 // Espace disque insuffisant
#define TXT_INVALID_PORT_ADDRESS 351 // Port/Adresse invalide. COM
#define TXT_INVALID_SETTINGS 352 // paramŠtres Port et/ou IRQ
#define TXT_IRQ_ALREADY_IN_USE 353 // IRQ dj… utilis
#define TXT_ABORT 354 // Oui
#define TXT_RESTART 355 // Recommencer
#define TXT_RESTARTING 356 // Mission relance. Attendez
#define TXT_LOADING 357 // Chargement de la mission.
#define TXT_ERROR_IN_INITSTRING 358 // Erreur chaŒne
#define TXT_SHADOW_COLON 359 // Ombre
#define TXT_AVMINE 360 // Mine Anti-Vhicule
#define TXT_APMINE 361 // Mine Anti-Personnel
#define TXT_NEW_MISSIONS 362 // Nouvelles missions
#define TXT_THIEF 363 // Voleur
#define TXT_MRJ 364 // Brouilleur de radar
#define TXT_GAP_GENERATOR 365 // Gnrateur d'ombre
#define TXT_PILLBOX 366 // Bunker
#define TXT_CAMOPILLBOX 367 // Bunker camoufl
#define TXT_CHRONOSPHERE 368 // ChronosphŠre
#define TXT_ENGLAND 369 // Roy. Uni
#define TXT_GERMANY 370 // Allemagne
#define TXT_SPAIN 371 // Espagne
#define TXT_USSR 372 // URSS
#define TXT_UKRAINE 373 // Ukraine
#define TXT_GREECE 374 // GrŠce
#define TXT_FRANCE 375 // France
#define TXT_TURKEY 376 // Turquie
#define TXT_SHORE 377 // Rivage
#define TXT_PLACE_OBJECT 378 // Choisir objet
#define TXT_SS 379 // Sous-marin
#define TXT_DD 380 // Contre-torpilleur
#define TXT_CA 381 // Croiseur
#define TXT_TRANSPORT 382 // Transport
#define TXT_PT 383 // Aviso-torpilleur
#define TXT_LOBBY 384 // Hall
#define TXT_CHANNEL_GAMES 385 // Parties
#define TXT_SAVING_GAME 386 // Sauvegarder partie...
#define TXT_GAME_FULL 387 // La partie est au complet.
#define TXT_MUST_SELECT_GAME 388 // Vous devez slectionner une
#define TXT_S_PLAYING_S 389 // %s joue contre %s
#define TXT_ONLY_HOST_CAN_MODIFY 390 // Seul l'h“te peut modifier
#define TXT_GAME_CANCELLED 391 // La partie a t annule.
#define TXT_S_FORMED_NEW_GAME 392 // %s a initi une nouvelle
#define TXT_GAME_NOW_IN_PROGRESS 393 // La partie de %s est
#define TXT_TESLA 394 // Bobine de Tesla
#define TXT_MGG 395 // Gnrateur d'ombre mobile
#define TXT_FLAME_TURRET 396 // Tour lance-flammes
#define TXT_AAGUN 397 // Canon Anti-Avion
#define TXT_KENNEL 398 // Niche
#define TXT_SOVIET_TECH 399 // Centre Technique
#define TXT_BADGER 400 // Bombardier
#define TXT_MIG 401 // Mig
#define TXT_YAK 402 // Yak
#define TXT_FENCE 403 // Barbels
#define TXT_MEDIC 404 // Mdecin
#define TXT_SABOTEUR 405 // Saboteur
#define TXT_GENERAL 406 // Gnral
#define TXT_E7 407 // Tanya
#define TXT_PARA_BOMB 408 // Parabombes
#define TXT_PARA_INFANTRY 409 // Parachutistes
#define TXT_PARA_SABOTEUR 410 // Saboteur parachutiste
#define TXT_SHIP_YARD 411 // Chantier naval
#define TXT_SUB_PEN 412 // Port sous-marin
#define TXT_SCENARIO_OPTIONS 413 // Options Scnario
#define TXT_SPY_MISSION 414 // Avion espion
#define TXT_U2 415 // Avion espion
#define TXT_GUARD_DOG 416 // Chien d'attaque
#define TXT_SPY_INFO 417 // Info Espion
#define TXT_BUILDNGS 418 // Bƒtiments
#define TXT_UNITS 419 // Units
#define TXT_INFANTRY 420 // Infanterie
#define TXT_AIRCRAFT 421 // Avion
#define TXT_TRUCK 422 // Camion d'approvisionnement
#define TXT_INVUL 423 // Module d'invulnrabilit
#define TXT_IRON_CURTAIN 424 // Rideau de Fer
#define TXT_ADVANCED_TECH 425 // Centre technique avanc
#define TXT_V2_LAUNCHER 426 // Lance-roquettes V2
#define TXT_FORWARD_COM 427 // Poste de commandement
#define TXT_DEMOLITIONER 428 // Bombardeur
#define TXT_MINE_LAYER 429 // Poseur de mines
#define TXT_FAKE_CONST 430 // Chantier de construction
#define TXT_FAKE_WEAP 431 // Usine d'armement leurre
#define TXT_FAKE_YARD 432 // Chantier naval leurre
#define TXT_FAKE_PEN 433 // Port sous-marin leurre
#define TXT_FAKE_RADAR 434 // D“me radar leurre
#define TXT_THEME_BIGF 435 // Bigfoot
#define TXT_THEME_CRUS 436 // La rvolte
#define TXT_THEME_FAC1 437 // A l'attaque 1
#define TXT_THEME_FAC2 438 // A l'attaque 2
#define TXT_THEME_HELL 439 // Marche de l'enfer
#define TXT_THEME_RUN1 440 // Sauve-qui-peut
#define TXT_THEME_SMSH 441 // La dbƒcle
#define TXT_THEME_TREN 442 // Tranches
#define TXT_THEME_WORK 443 // Les professionnels
#define TXT_THEME_AWAIT 444 // Attente
#define TXT_THEME_DENSE_R 445 // Dense
#define TXT_THEME_MAP 446 // Slection carte
#define TXT_THEME_FOGGER1A 447 // Fogger
#define TXT_THEME_MUD1A 448 // Boue
#define TXT_THEME_RADIO2 449 // Radio 2
#define TXT_THEME_ROLLOUT 450 // Laminage
#define TXT_THEME_SNAKE 451 // Serpent
#define TXT_THEME_TERMINAT 452 // Extermination
#define TXT_THEME_TWIN 453 // Jumeau
#define TXT_THEME_VECTOR1A 454 // Vecteur
#define TXT_TEAM_MEMBERS 455 // Equipiers
#define TXT_BRIDGE 456 // Pont
#define TXT_BARREL 457 // Baril
#define TXT_GOODGUY 458 // Amical
#define TXT_BADGUY 459 // Ennemi
#define TXT_GOLD 460 // Or
#define TXT_GEMS 461 // Gemmes
#define TXT_TEASER 462 // Film titre
#define TXT_MOVIES 463 // Films
#define TXT_INTERIOR 464 // Intrieur
#define TXT_SONAR_PULSE 465 // Signal sonar
#define TXT_MSLO 466 // Silo de missiles
#define TXT_GPS_SATELLITE 467 // Satellite GPS
#define TXT_NUCLEAR_BOMB 468 // Bombe atomique
#define TXT_EASY 469 // Facile
#define TXT_HARD 470 // Difficile
#define TXT_NORMAL 471 // Normal
#define TXT_DIFFICULTY 472 // Slectionnez un niveau de
#define TXT_ALLIES 473 // Allis
#define TXT_SOVIET 474 // Soviets
#define TXT_THEME_INTRO 475 // ThŠme Intro
#define TXT_SHADOW_REGROWS 476 // Progr. ombre
#define TXT_ORE_SPREADS 477 // Progr. minerai
#define TXT_THEME_SCORE 478 // Musiques
#define TXT_INTERNET 479 // Internet
#define TXT_ICE 480 // Glace
#define TXT_CRATE 481 // Caisses
#define TXT_SKIRMISH 482 // Escarmouche
#define TXT_CHOOSE 483 // Choisissez votre camp.
#define TXT_MINERALS 484 // Minraux prcieux
#define TXT_IGNORE 485 // Ignorer
#define TXT_ERROR_NO_RESP 486 // Erreur - le modem ne rpond
#define TXT_ERROR_NO_RESCODE 487 // Erreur - Le modem n'a pas
#define TXT_ERROR_NO_INIT 488 // Erreur - Le modem n'a pas
#define TXT_ERROR_NO_VERB 489 // Erreur - Le modem n'a pas
#define TXT_ERROR_NO_ECHO 490 // Erreur - Le modem n'a pas
#define TXT_ERROR_NO_DISABLE 491 // Erreur - Impossible de
#define TXT_ERROR_TOO_MANY 492 // Erreur - Trop d'erreurs
#define TXT_ERROR_ERROR 493 // Erreur - Le modem a
#define TXT_ERROR_TIMEOUT 494 // Erreur - Temps d'attente de
#define TXT_ACCOMPLISHED 495 // Accompli
#define TXT_CLICK_CONTINUE 496 // Cliquez pour continuer
#define TXT_RECEIVING_SCENARIO 497 // Rception du scnario de
#define TXT_SENDING_SCENARIO 498 // Envoi du scnario aux
#define TXT_NO_FLOW_CONTROL_RESPONSE 499 // Erreur - Le modem n'a pas
#define TXT_NO_COMPRESSION_RESPONSE 500 // Erreur - Le modem n'a pas
#define TXT_NO_ERROR_CORRECTION_RESPONSE 501 // Erreur - Le modem n'a pas
#define TXT_EXPLAIN_REGISTRATION 502 // Pour jouer … Alerte Rouge
#define TXT_ERROR_UNABLE_TO_RUN_WCHAT 503 // Erreur - Impossible
#define TXT_REGISTER 504 // Enregistrer
#define TXT_ORE_MINE 505 // Gisement Minerai
#define TXT_NO_REGISTERED_MODEM 506 // Aucun modem configur
#define TXT_CHRONOSHIFT 507 // Dplacement chronoporte
#define TXT_UNABLE_TO_OPEN_PORT 508 // Adresse invalide ou en
#define TXT_NO_DIAL_TONE 509 // Pas de tonalit.
#define TXT_NO_EXPANSION_SCENARIO 510 // Erreur - L'autre joueur n'a
#define TXT_STAND_BY 511 // Patientez SVP...
#define TXT_THEME_CREDITS 512 // Musique du gnrique de fin
#define TXT_POWER_AAGUN 513 // Puissance faible: Canon(s)
#define TXT_POWER_TESLA 514 // Puissance faible: Bobine(s)
#define TXT_LOW_POWER 515 // Puissance Faible
#define TXT_COMMANDER 516 // Commandant:
#define TXT_BATTLES_WON 517 // Parties gagnes:
#define TXT_MISMATCH 518 // Fichier de donnes du jeu
#define TXT_SCENARIO_ERROR 519 // Votre version de jeu
#define TXT_CONNECTING 520 // Connecting
#define TXT_MODEM_INITIALISATION 521 // Initialisation du Modem
#define TXT_DATA_COMPRESSION 522 // Compression des Donnes
#define TXT_ERROR_CORRECTION 523 // Correction d'Erreur
#define TXT_HARDWARE_FLOW_CONTROL 524 // Contr“le Matriel du Flux
#define TXT_ADVANCED 525 // Avanc
#define TXT_THEME_2ND_HAND 526 // Seconde main
#define TXT_THEME_ARAZOID 527 // Arazode
#define TXT_THEME_BACKSTAB 528 // Retour … l'envoyeur
#define TXT_THEME_CHAOS2 529 // Chaos2
#define TXT_THEME_SHUT_IT 530 // Fermez-la !
#define TXT_THEME_TWINMIX1 531 // Visite de courtoisie
#define TXT_THEME_UNDER3 532 // A couvert
#define TXT_THEME_VR2 533 // VR2
#define TXT_ASK_EMERGENCY_SAVE_NOT_RESPONDING 534 // L'autre systŠme ne rpond
#define TXT_ASK_EMERGENCY_SAVE_HUNG_UP 535 // L'autre systŠme a
#define TXT_NO_REG_APP 536 // Alerte Rouge n'a pu
#define TXT_NO_CS_SCENARIOS 537 // Un joueur de la partie n'a
#define TXT_MISSILESUB 538 // Sous-marin MS
#define TXT_SHOCKTROOPER 539 // Electrocuteur
#define TXT_MECHANIC 540 // Mcanicien
#define TXT_CHRONOTANK 541 // Chrono Tank
#define TXT_TESLATANK 542 // Tank Tesla
#define TXT_MAD 543 // Tank M.A.D.
#define TXT_DEMOTRUCK 544 // Camion de dmolition
#define TXT_PHASETRANSPORT 545 // Transport Camlon
#define TXT_THEME_BOG 546 // Marcages
#define TXT_THEME_FLOAT_V2 547 // Volutes
#define TXT_THEME_GLOOM 548 // TnŠbres
#define TXT_THEME_GRNDWIRE 549 // Terrain min
#define TXT_THEME_RPT 550 // Mcaniciens 2
#define TXT_THEME_SEARCH 551 // Battue
#define TXT_THEME_TRACTION 552 // Traction
#define TXT_THEME_WASTELND 553 // Chaos
#define TXT_CARRIER 554 // Hliport Mobile
#define TXT_INSUFFICIENT_FUNDS 555

845
REDALERT/CONST.CPP Normal file
View File

@ -0,0 +1,845 @@
//
// 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/CONST.CPP 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 : CONST.CPP *
* *
* Programmer : Joe L. Bostic *
* *
* Start Date : September 20, 1993 *
* *
* Last Update : September 20, 1993 [JLB] *
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "function.h"
/***************************************************************************
** These are the access passwords used to activate cheat mode, editor mode,
** and special game options.
*/
unsigned long const PlayCodes[] = {
0xE0792D6D, // Dwight Okahara
0x90046ECF, // Paul S. Mudra
0xC3EE9A26, // Frank Klepaki
0xED382178, // Ed Del Castillo
0L
};
unsigned long const CheatCodes[] = {
0xA0E2AB53, // Joseph Hewitt
0x00532693, // Mike Lightner
0x7DDFF824, // Joe Bostic
0x2CB5CF01, // Phil Gorrow
0xB5B63531, // Bill Randolph
0xDFABC23A, // Adam Isgreen
0x52B19A22, // Erik Yeo
0xBE79088C, // David Dettmer
0xB216AE7E, // Barry Green
0x0E07B213, // Steve Tall
0L
};
unsigned long const EditorCodes[] = {
0xA2C09326, // Erik Yeo
0x1F944BB3, // Mike Lightner
0xDE07154D, // Adam Isgreen
0x0E07B213, // Steve Tall
0x16B170B1, // Joe Bostic
0L
};
/***********************************************************************************************
** Unit order names. These names correspond to the player selectable orders
** a unit can have. The system initiated orders have no use for the ASCII name
** associated, but they are listed here for completeness sake.
*/
char const * Missions[MISSION_COUNT] = {
"Sleep",
"Attack",
"Move",
"QMove",
"Retreat",
"Guard",
"Sticky",
"Enter",
"Capture",
"Harvest",
"Area Guard",
"Return",
"Stop",
"Ambush",
"Hunt",
"Unload",
"Sabotage",
"Construction",
"Selling",
"Repair",
"Rescue",
"Missile",
"Harmless"
};
/***************************************************************************
** Special weapon names.
*/
#ifdef SCENARIO_EDITOR
char const * const SpecialWeaponName[SPC_COUNT] = {
"Sonar Pulse",
"Nuclear Missile",
"Chronosphere",
"Parachute Bomb",
"Paratroopers",
"Recon Plane",
"Iron Curtain",
"GPS Satellite"
};
#endif
int const SpecialWeaponHelp[SPC_COUNT] = {
TXT_SONAR_PULSE,
TXT_NUCLEAR_BOMB,
TXT_CHRONOSHIFT,
TXT_PARA_BOMB,
TXT_PARA_INFANTRY,
TXT_SPY_MISSION,
TXT_INVUL,
TXT_GPS_SATELLITE
};
char const * const SpecialWeaponFile[SPC_COUNT] = {
"SONR",
"ATOM",
"WARP",
"PBMB",
"PINF",
"CAM",
"INFX",
"GPSS"
};
/***************************************************************************
** Type of quarry to search out and attack. These values are used for team
** attack missions.
*/
char const * const QuarryName[QUARRY_COUNT] = {
"N/A",
"Anything",
"Buildings - any",
"Harvesters",
"Infantry",
"Vehicles - any",
"Ships - any",
"Factories",
"Base Defenses",
"Base Threats",
"Power Facilities",
"Fake Buildings"
};
/***************************************************************************
** These are the text names for the formation types.
*/
char const * const FormationName[FORMATION_COUNT] = {
"None",
"Tight",
"Loose",
"Wedge North",
"Wedge East",
"Wedge South",
"Wedge West",
"Line N/S",
"Line E/W"
};
/***************************************************************************
** These are the ASCII names for the reinforcement sources.
*/
char const * const SourceName[SOURCE_COUNT] =
{
"North",
"East",
"South",
"West",
"Air"
};
/***************************************************************************
** These are the text names for the various armor types a unit may possess.
*/
char const * const ArmorName[ARMOR_COUNT] = {
"none",
"wood",
"light",
"heavy",
"concrete"
};
// HACK ALERT! This unused text string is here to stop Watcom from crashing. There is some
// magic text heap length that causes a crash before the code executes. This dummy string
// changes the text heap length enough to stop the crash. Who knows why, but it works.
char * __test__ = "alskdfjlasdfjkajsdfkja;sldjfklasj9awutreqjfnfdkvnldzlknvadsjgflkasdjfkajsdfas";
/***************************************************************************
** The list of VQ filenames.
*/
char const * const VQName[VQ_COUNT] = {
"AAGUN",
"MIG",
"SFROZEN",
"AIRFIELD",
"BATTLE",
"BMAP",
"BOMBRUN",
"DPTHCHRG",
"GRVESTNE",
"MONTPASS",
"MTNKFACT",
"CRONTEST",
"OILDRUM",
"ALLIEND",
"RADRRAID",
"SHIPYARD", // MISSING
"SHORBOMB",
"SITDUCK",
"SLNTSRVC",
"SNOWBASE",
"EXECUTE",
"REDINTRO", // low res.
"NUKESTOK",
"V2ROCKET",
"SEARCH",
"BINOC",
"ELEVATOR",
"FROZEN",
"MCV",
"SHIPSINK",
"SOVMCV",
"TRINITY",
"ALLYMORF",
"APCESCPE",
"BRDGTILT",
"CRONFAIL",
"STRAFE",
"DESTROYR",
"DOUBLE",
"FLARE",
"SNSTRAFE",
"LANDING",
"ONTHPRWL",
"OVERRUN",
"SNOWBOMB",
"SOVCEMET",
"TAKE_OFF",
"TESLA",
"SOVIET8",
"SPOTTER",
"ALLY1",
"ALLY2",
"ALLY4",
"SOVFINAL",
"ASSESS",
"SOVIET10",
"DUD",
"MCV_LAND",
"MCVBRDGE",
"PERISCOP",
"SHORBOM1",
"SHORBOM2",
"SOVBATL",
"SOVTSTAR",
"AFTRMATH",
"SOVIET11",
"MASASSLT",
"ENGLISH", // High res. Intro
"SOVIET1",
"SOVIET2",
"SOVIET3",
"SOVIET4",
"SOVIET5",
"SOVIET6",
"SOVIET7",
"PROLOG",
"AVERTED",
"COUNTDWN",
"MOVINGIN",
"ALLY10",
"ALLY12",
"ALLY5",
"ALLY6",
"ALLY8",
"TANYA1",
"TANYA2",
"ALLY10B",
"ALLY11",
"ALLY14",
"ALLY9",
"SPY",
"TOOFAR",
"SOVIET12",
"SOVIET13",
"SOVIET9",
"BEACHEAD",
"SOVIET14",
"SIZZLE", //MISSING
"SIZZLE2", //MISSING
"ANTEND",
"ANTINTRO",
//2019/11/12 JAS - Added for Retaliation movies
"RETALIATION_ALLIED1",
"RETALIATION_ALLIED2",
"RETALIATION_ALLIED3",
"RETALIATION_ALLIED4",
"RETALIATION_ALLIED5",
"RETALIATION_ALLIED6",
"RETALIATION_ALLIED7",
"RETALIATION_ALLIED8",
"RETALIATION_ALLIED9",
"RETALIATION_ALLIED10",
"RETALIATION_SOVIET1",
"RETALIATION_SOVIET2",
"RETALIATION_SOVIET3",
"RETALIATION_SOVIET4",
"RETALIATION_SOVIET5",
"RETALIATION_SOVIET6",
"RETALIATION_SOVIET7",
"RETALIATION_SOVIET8",
"RETALIATION_SOVIET9",
"RETALIATION_SOVIET10",
"RETALIATION_WINA",
"RETALIATION_WINS",
"RETALIATION_ANTS"
};
/***************************************************************************
** Relative coordinate offsets from the center of a cell for each
** of the legal positions that an object in a cell may stop at. Only infantry
** are allowed to stop at other than the center of the cell.
*/
COORDINATE const StoppingCoordAbs[5] = {
0x00800080L, // center
0x00400040L, // upper left
0x004000C0L, // upper right
0x00C00040L, // lower left
0x00C000C0L // lower right
};
/***************************************************************************
** Converts pixel values (cell relative) into the appropriate lepton (sub cell)
** value. This is used to convert pixel (screen) coordinates into the underlying
** coordinate system.
*/
unsigned char const Pixel2Lepton[24] = {
0x00,0x0B,0x15,0x20,0x2B,0x35,0x40,0x4B,
0x55,0x60,0x6B,0x75,0x80,0x8B,0x95,0xA0,
0xAB,0xB5,0xC0,0xCB,0xD5,0xE0,0xEB,0xF5
};
/***************************************************************************
** This array is used to index a facing in order to retrieve a cell
** offset that, when added to another cell, will achieve the adjacent cell
** in the indexed direction.
*/
CELL const AdjacentCell[FACING_COUNT] = {
-(MAP_CELL_W), // North
-(MAP_CELL_W-1), // North East
1, // East
MAP_CELL_W+1, // South East
MAP_CELL_W, // South
MAP_CELL_W-1, // South West
-1, // West
-(MAP_CELL_W+1) // North West
};
COORDINATE const AdjacentCoord[FACING_COUNT] = {
0xFF000000L,
0xFF000100L,
0x00000100L,
0x01000100L,
0x01000000L,
0x0100FF00L,
0x0000FF00L,
0xFF00FF00L
};
/***************************************************************************
** This specifies the odds of receiving the various random crate power
** ups. The odds are expressed as "shares" of 100 percent.
*/
int CrateShares[CRATE_COUNT] = {
50, // CRATE_MONEY
20, // CRATE_UNIT
3, // CRATE_PARA_BOMB
1, // CRATE_HEAL_BASE
3, // CRATE_CLOAK
5, // CRATE_EXPLOSION
5, // CRATE_NAPALM
20, // CRATE_SQUAD
1, // CRATE_DARKNESS
1, // CRATE_REVEAL
3, // CRATE_SONAR
10, // CRATE_ARMOR
10, // CRATE_SPEED
10, // CRATE_FIREPOWER
1, // CRATE_ICBM
1, // CRATE_TIMEQUAKE
3, // CRATE_INVULN
5 // CRATE_VORTEX
};
AnimType CrateAnims[CRATE_COUNT] = {
ANIM_NONE, // CRATE_MONEY
ANIM_NONE, // CRATE_UNIT
ANIM_NONE, // CRATE_PARA_BOMB
ANIM_NONE, // CRATE_HEAL_BASE
ANIM_NONE, // CRATE_CLOAK
ANIM_NONE, // CRATE_EXPLOSION
ANIM_NONE, // CRATE_NAPALM
ANIM_NONE, // CRATE_SQUAD
ANIM_NONE, // CRATE_DARKNESS
ANIM_NONE, // CRATE_REVEAL
ANIM_NONE, // CRATE_SONAR
ANIM_NONE, // CRATE_ARMOR
ANIM_NONE, // CRATE_SPEED
ANIM_NONE, // CRATE_FIREPOWER
ANIM_NONE, // CRATE_ICBM
ANIM_NONE, // CRATE_TIMEQUAKE
ANIM_NONE, // CRATE_INVULN
ANIM_NONE // CRATE_VORTEX
};
int CrateData[CRATE_COUNT] = {
0, // CRATE_MONEY
0, // CRATE_UNIT
0, // CRATE_PARA_BOMB
0, // CRATE_HEAL_BASE
0, // CRATE_CLOAK
0, // CRATE_EXPLOSION
0, // CRATE_NAPALM
0, // CRATE_SQUAD
0, // CRATE_DARKNESS
0, // CRATE_REVEAL
0, // CRATE_SONAR
0, // CRATE_ARMOR
0, // CRATE_SPEED
0, // CRATE_FIREPOWER
0, // CRATE_ICBM
0, // CRATE_TIMEQUAKE
0, // CRATE_INVULN
0 // CRATE_VORTEX
};
char const * const CrateNames[CRATE_COUNT] = {
"Money",
"Unit",
"ParaBomb",
"HealBase",
"Cloak",
"Explosion",
"Napalm",
"Squad",
"Darkness",
"Reveal",
"Sonar",
"Armor",
"Speed",
"Firepower",
"ICBM",
"TimeQuake",
"Invulnerability",
"ChronalVortex"
};
/***************************************************************************
** This converts 0..255 facing values into either 8, 16, or 32 facing values.
** Note: a simple shift won't suffice because 0..255 facing values should
** be converted to the CLOSEST appropriate facing, NOT rounded down to the
** nearest facing.
*/
unsigned char const Facing8[256] = {
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
};
unsigned char const Facing16[256] = {
0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,
2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,
4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,
6,6,6,6,6,6,6,6,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,8,8,8,8,8,8,8,8,
8,8,8,8,8,8,8,8,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,10,10,10,10,10,10,10,10,
10,10,10,10,10,10,10,10,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,12,12,12,12,12,12,12,
12,12,12,12,12,12,12,12,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,14,14,14,14,14,14,14,14,
14,14,14,14,14,14,14,14,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,0,0,0,0,0,0,0,0
};
signed char const Rotation16[256] = {
0,1,2,3,4,5,6,7,-8,-7,-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6,7,-8,-7,-6,-5,-4,-3,-2,-1,
0,1,2,3,4,5,6,7,-8,-7,-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6,7,-8,-7,-6,-5,-4,-3,-2,-1,
0,1,2,3,4,5,6,7,-8,-7,-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6,7,-8,-7,-6,-5,-4,-3,-2,-1,
0,1,2,3,4,5,6,7,-8,-7,-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6,7,-8,-7,-6,-5,-4,-3,-2,-1,
0,1,2,3,4,5,6,7,-8,-7,-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6,7,-8,-7,-6,-5,-4,-3,-2,-1,
0,1,2,3,4,5,6,7,-8,-7,-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6,7,-8,-7,-6,-5,-4,-3,-2,-1,
0,1,2,3,4,5,6,7,-8,-7,-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6,7,-8,-7,-6,-5,-4,-3,-2,-1,
0,1,2,3,4,5,6,7,-8,-7,-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6,7,-8,-7,-6,-5,-4,-3,-2,-1
};
/*
** This table incorporates a compensating factor for the distortion caused
** by 3D-Studio when it tries to render 45% angles.
*/
unsigned char const Facing32[256] = {
0,0,0,0,0,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,
3,4,4,4,4,4,4,5,5,5,5,5,5,5,6,6,6,6,6,6,6,7,7,7,7,7,7,7,8,8,8,8,
8,8,8,9,9,9,9,9,9,9,10,10,10,10,10,10,10,11,11,11,11,11,11,11,12,12,12,12,12,12,12,12,
13,13,13,13,13,13,13,13,14,14,14,14,14,14,14,14,14,15,15,15,15,15,15,15,15,15,16,16,16,16,16,16,
16,16,16,16,16,17,17,17,17,17,17,17,17,17,18,18,18,18,18,18,18,18,18,19,19,19,19,19,19,19,19,19,
19,20,20,20,20,20,20,21,21,21,21,21,21,21,22,22,22,22,22,22,22,23,23,23,23,23,23,23,24,24,24,24,
24,24,24,25,25,25,25,25,25,25,26,26,26,26,26,26,26,27,27,27,27,27,27,27,28,28,28,28,28,28,28,28,
29,29,29,29,29,29,29,29,30,30,30,30,30,30,30,30,30,31,31,31,31,31,31,31,31,31,0,0,0,0,0,0
};
#ifdef OBSOLETE
unsigned char const Facing32[256] = {
0,0,0,0,
1,1,1,1,1,1,1,1,
2,2,2,2,2,2,2,2,
3,3,3,3,3,3,3,3,
4,4,4,4,4,4,4,4,
5,5,5,5,5,5,5,5,
6,6,6,6,6,6,6,6,
7,7,7,7,7,7,7,7,
8,8,8,8,8,8,8,8,
9,9,9,9,9,9,9,9,
10,10,10,10,10,10,10,10,
11,11,11,11,11,11,11,11,
12,12,12,12,12,12,12,12,
13,13,13,13,13,13,13,13,
14,14,14,14,14,14,14,14,
15,15,15,15,15,15,15,15,
16,16,16,16,16,16,16,16,
17,17,17,17,17,17,17,17,
18,18,18,18,18,18,18,18,
19,19,19,19,19,19,19,19,
20,20,20,20,20,20,20,20,
21,21,21,21,21,21,21,21,
22,22,22,22,22,22,22,22,
23,23,23,23,23,23,23,23,
24,24,24,24,24,24,24,24,
25,25,25,25,25,25,25,25,
26,26,26,26,26,26,26,26,
27,27,27,27,27,27,27,27,
28,28,28,28,28,28,28,28,
29,29,29,29,29,29,29,29,
30,30,30,30,30,30,30,30,
31,31,31,31,31,31,31,31,
0,0,0,0
};
#endif
/***************************************************************************
** These are the movement costs (in ticks at fastest speed) to enter each
** of the given terrain cells.
*/
int const GroundColor[LAND_COUNT] = {
141, // "Clear" terrain.
141, // Road terrain.
172, // Water.
21, // Impassable rock.
21, // Wall (blocks movement).
158, // Tiberium field.
141, // Beach terrain.
141, // Rocky terrain.
174 // Rocky riverbed.
};
int const SnowColor[LAND_COUNT] = {
141, // "Clear" terrain.
141, // Road terrain.
172, // Water.
21, // Impassable rock.
21, // Wall (blocks movement).
158, // Tiberium field.
141, // Beach terrain.
141, // Rocky terrain.
174 // Rocky riverbed.
};
#ifdef NEVER
int const GroundColor[LAND_COUNT] = {
46, // "Clear" terrain.
44, // Road terrain.
BLUE, // Water.
DKGREY, // Impassable rock.
DKGREY, // Wall (blocks movement).
158, // Tiberium field.
64, // Beach terrain.
DKGREY, // Rocky terrain.
DKGREY // Rocky riverbed.
};
int const SnowColor[LAND_COUNT] = {
WHITE, // "Clear" terrain.
LTGRAY, // Road terrain.
BLUE, // Water.
DKGREY, // Impassable rock.
DKGREY, // Wall (blocks movement).
158, // Tiberium field.
LTGRAY, // Beach terrain.
DKGREY, // Rocky terrain.
DKGREY // Rocky riverbed.
};
#endif
GroundType Ground[LAND_COUNT];
/***************************************************************************
** These are the names of the theaters.
*/
TheaterDataType const Theaters[THEATER_COUNT] = {
{"TEMPERATE","TEMPERAT","TEM"},
{"SNOW","SNOW","SNO"},
{"INTERIOR","INTERIOR","INT"},
};
unsigned char const RemapCiv2[256] = {
0,1,2,3,4,5,6,209,8,9,10,11,12,13,12,15, // 0..15
16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31, // 16..31
32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47, // 32..47
48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63, // 48..63
64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79, // 64..79
80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95, // 80..95
96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111, // 96..111
112,113,114,115,116,117,187,188,120,121,122,123,124,125,126,127, // 112..127
128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143, // 128..143
144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,209, // 144..159
160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175, // 160..175
176,177,178,179,180,181,182,183,184,185,186,167, 13,189,190,191, // 176..191
192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207, // 192..207
208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223, // 208..223
224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239, // 224..239
240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255 // 240..255
};
unsigned char const RemapCiv4[256] = {
0,1,2,3,4,5,6,187,8,9,10,11,12,13,14,15, // 0..15
16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31, // 16..31
32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47, // 32..47
48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63, // 48..63
64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79, // 64..79
80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95, // 80..95
96,97,98,99,100,101,102,103,104,105,106,107,108,118,110,119, // 96..111
112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127, // 112..127
128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143, // 128..143
144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159, // 144..159
160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175, // 160..175
176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191, // 176..191
192,193,194,195,196,197,198,199,200,201,202,203,204,205,188,207, // 192..207
208,209,182,211,212,213,214,215,216,217,218,219,220,221,222,223, // 208..223
224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239, // 224..239
240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255 // 240..255
};
unsigned char const RemapCiv5[256] = {
0,1,2,3,4,5,6,109,8,9,10,11,131,13,14,15, // 0..15
16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31, // 16..31
32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47, // 32..47
48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63, // 48..63
64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79, // 64..79
80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95, // 80..95
96,97,98,99,100,101,102,103,104,105,106,107,108,177,110,178, // 96..111
112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127, // 112..127
128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143, // 128..143
144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159, // 144..159
160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175, // 160..175
176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191, // 176..191
192,193,194,195,196,197,198,199,111,201,202,203,204,205,111,207, // 192..207
208,209,182,211,212,213,214,215,216,217,218,219,220,221,222,223, // 208..223
224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239, // 224..239
240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255 // 240..255
};
unsigned char const RemapCiv6[256] = {
0,1,2,3,4,5,6,120,8,9,10,11,12,13,238,15, // 0..15
16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31, // 16..31
32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47, // 32..47
48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63, // 48..63
64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79, // 64..79
80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95, // 80..95
96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111, // 96..111
112,113,114,115,116,117,236,206,120,121,122,123,124,125,126,127, // 112..127
128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143, // 128..143
144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,111, // 144..159
160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175, // 160..175
176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191, // 176..191
192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207, // 192..207
208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223, // 208..223
224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239, // 224..239
240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255 // 240..255
};
unsigned char const RemapCiv7[256] = {
0,1,2,3,4,5,6,7,8,9,10,11,12,13,131,15, // 0..15
16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31, // 16..31
32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47, // 32..47
48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63, // 48..63
64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79, // 64..79
80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95, // 80..95
96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111, // 96..111
112,113,114,115,116,117,157,212,120,121,122,123,124,125,126,127, // 112..127
128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143, // 128..143
144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,7, // 144..159
160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175, // 160..175
176,177,178,179,180,181,182,183,184,185,186,118,119,189,190,191, // 176..191
192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207, // 192..207
208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223, // 208..223
224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239, // 224..239
240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255 // 240..255
};
unsigned char const RemapCiv8[256] = {
0,1,2,3,4,5,6,182,8,9,10,11,12,13,131,15, // 0..15
16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31, // 16..31
32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47, // 32..47
48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63, // 48..63
64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79, // 64..79
80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95, // 80..95
96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111, // 96..111
112,113,114,115,116,117,215,7,120,121,122,123,124,125,126,127, // 112..127
128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143, // 128..143
144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,182, // 144..159
160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175, // 160..175
176,177,178,179,180,181,182,183,184,185,186,198,199,189,190,191, // 176..191
192,193,194,195,196,197,198,199,111,201,202,203,204,205,206,207, // 192..207
208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223, // 208..223
224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239, // 224..239
240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255 // 240..255
};
unsigned char const RemapCiv9[256] = {
0,1,2,3,4,5,6,7,8,9,10,11,12,13,7,15, // 0..15
16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31, // 16..31
32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47, // 32..47
48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63, // 48..63
64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79, // 64..79
80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95, // 80..95
96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111, // 96..111
112,113,114,115,116,117,163,165,120,121,122,123,124,125,126,127, // 112..127
128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143, // 128..143
144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,200, // 144..159
160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175, // 160..175
176,177,178,179,180,181,182,183,184,185,186,111,13,189,190,191, // 176..191
192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207, // 192..207
208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223, // 208..223
224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239, // 224..239
240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255 // 240..255
};
unsigned char const RemapCiv10[256] = {
0,1,2,3,4,5,6,137,8,9,10,11,12,13,15,15, // 0..15
16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31, // 16..31
32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47, // 32..47
48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63, // 48..63
64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79, // 64..79
80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95, // 80..95
96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111, // 96..111
112,113,114,115,116,117,129,131,120,121,122,123,124,125,126,127, // 112..127
128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143, // 128..143
144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,137, // 144..159
160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175, // 160..175
176,177,178,179,180,181,182,183,184,185,186,163,165,189,190,191, // 176..191
192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207, // 192..207
208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223, // 208..223
224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239, // 224..239
240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255 // 240..255
};
unsigned char const RemapEmber[256] = {
#define CEC CC_EMBER_COLOR
0,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,BLACK,CEC,CEC,CEC,
CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,
CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,
CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,
CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,
CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,
CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,
CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,
CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,
CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,
CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,
CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,
CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,
CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,
CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,
CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC
};
//char const Keys[] =
// "[PublicKey]\n"
// "1=AgkCbXo9sKMHOBk=\n"
//#ifdef CHEAT_KEYS
// "[PrivateKey]\n"
// "1=AggxFU55vc7LYQ==\n"
//#endif
// "\n";
char const Keys[] =
"[PublicKey]\n"
"1=AihRvNoIbTn85FZRYNZRcT+i6KpU+maCsEqr3Q5q+LDB5tH7Tz2qQ38V\n"
#ifdef CHEAT_KEYS
"[PrivateKey]\n"
"1=AigKVje8mROcR8QixnxUEF5b29Curkq01DNDWCdOG99XBqH79OaCiTCB\n"
#endif
"\n";

223
REDALERT/CONTROL.CPP Normal file
View File

@ -0,0 +1,223 @@
//
// 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/CONTROL.CPP 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 : CONTROL.CPP *
* *
* Programmer : Joe L. Bostic *
* *
* Start Date : 01/15/95 *
* *
* Last Update : December 5, 1995 [JLB] *
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* ControlClass::Action -- Normal action for control gadget objects. *
* ControlClass::ControlClass -- Constructor for control class objects. *
* ControlClass::ControlClass -- Copy constructor for control gadget. *
* ControlClass::Draw_Me -- Draw logic for the control class object. *
* ControlClass::Get_ID -- Gets the ID number for this gadget. *
* ControlClass::Make_Peer -- Assigns a peer gadget to this gadget. *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "function.h"
/***********************************************************************************************
* ControlClass::ControlClass -- Constructor for control class objects. *
* *
* This is the normal constructor for control class objects. At this level, it only needs *
* to record the ID number assigned to this button. *
* *
* INPUT: id -- The ID number for this gadget. If the ID number specified is 0, then *
* this tells the system that no special ID code should be returned. *
* *
* x,y -- Pixel coordinate of upper left corner of gadget's region. *
* *
* w,h -- Pixel dimensions of the gadget's region. *
* *
* flags -- The input event flags that this gadget recognizes. *
* *
* sticky-- This this a "sticky" gadget? A sticky gadget is one that takes over the *
* gadget list while the mouse button is held down, if the mouse button was *
* initially clicked over its region. This is the behavior of "normal" *
* buttons in Windows. *
* *
* OUTPUT: none *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 01/15/1995 JLB : Created. *
*=============================================================================================*/
ControlClass::ControlClass(unsigned id, int x, int y, int w, int h, unsigned flags, int sticky) :
GadgetClass(x, y, w, h, flags, sticky),
ID(id),
Peer(0)
{
}
/***********************************************************************************************
* ControlClass::ControlClass -- Copy constructor for control gadget. *
* *
* This copy constructor for a control gadget is used create a duplicate gadget that *
* is functionally similar. *
* *
* INPUT: control -- Reference to the gadget that is to be copied. *
* *
* OUTPUT: none *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 12/05/1995 JLB : Created. *
*=============================================================================================*/
ControlClass::ControlClass(ControlClass const & control) :
GadgetClass(control),
ID(control.ID),
Peer(control.Peer)
{
}
/***********************************************************************************************
* ControlClass::Action -- Normal action for control gadget objects. *
* *
* This function gets called when the input event that this control gadget is looking for *
* occurs. In such a case, the return key code value is changed to the gadget's ID number *
* with the special button bit flag attached. *
* *
* INPUT: flags -- The event that triggered this function call. If this value is NULL, then *
* this is a forced (probably due to the sticky flag) call and the key code *
* is not altered. *
* *
* key -- Reference to the key code that will be returned by the controlling *
* Input() function. *
* *
* OUTPUT: bool; Should further list processing be aborted? *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 01/15/1995 JLB : Created. *
*=============================================================================================*/
int ControlClass::Action(unsigned flags, KeyNumType & key)
{
/*
** Only if the flags indicate that a recognized action has occurred, do the
** normal processing of this gadget and set return value to the gadget ID.
*/
if (flags) {
if (ID) {
key = (KeyNumType)(ID | KN_BUTTON);
} else {
key = KN_NONE;
}
}
/*
** If there is a peer link established, inform that gadget of this
** action call.
*/
if (Peer) {
Peer->Peer_To_Peer(flags, key, *this);
}
return(GadgetClass::Action(flags, key));
}
/***********************************************************************************************
* ControlClass::Make_Peer -- Assigns a peer gadget to this gadget. *
* *
* This function will assign another gadget to this one. That other gadget will receive *
* notification of any Action() call to this gadget. Presumably, this is how one gadget *
* can automatically adapt to changes in another. Say for example, a slider bar can affect *
* the list box it is attached to. *
* *
* INPUT: gadget -- The gadget to inform when any Action() function is called. *
* *
* OUTPUT: none *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 01/16/1995 JLB : Created. *
*=============================================================================================*/
void ControlClass::Make_Peer(GadgetClass & gadget)
{
Peer = &gadget;
}
/***********************************************************************************************
* ControlClass::Get_ID -- Gets the ID number for this gadget. *
* *
* This function will query and return with the ID number for this gadget. It is primarily *
* used by the Extract_Gadget() function. *
* *
* INPUT: none *
* *
* OUTPUT: Returns with the ID number for this gadget. If zero is returned, this means that *
* no ID was assigned to this gadget. This is a special case since a zero value will *
* never be returned as a pseudo-key as is done with non-zero values. *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 01/16/1995 JLB : Created. *
*=============================================================================================*/
unsigned ControlClass::Get_ID(void) const
{
return(ID);
}
/***********************************************************************************************
* ControlClass::Draw_Me -- Draw logic for the control class object. *
* *
* This is called when the control object might need to be redrawn or when redrawing is *
* necessary. Since at this level of the class hierarchy, no actual drawing occurs, this *
* routine doesn't perform any rendering. It does, however, inform any peer attached *
* object that a Draw_Me function has been called. Presumably, the attached peer gadget *
* might very well need to be redrawn as a result of some action by this gadget. Since this *
* gadget might, more than likely, be of the "sticky" variety, a normal call to Draw_Me *
* for the other gadget will not occur. It must rely on the call by this routine in order *
* to update correctly. A typical example of this would be a slider that is attached to *
* a list box. As the slider is being drug around, the attached list box must be redrawn. *
* *
* INPUT: forced -- Should the redraw be forced regardless of the redraw flag? *
* *
* OUTPUT: bool; Was the gadget redrawn? *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 01/16/1995 JLB : Created. *
*=============================================================================================*/
int ControlClass::Draw_Me(int forced)
{
if (Peer) {
Peer->Draw_Me();
}
return(GadgetClass::Draw_Me(forced));
}

87
REDALERT/CONTROL.H Normal file
View File

@ -0,0 +1,87 @@
//
// 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/CONTROL.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 : CONTROL.H *
* *
* Programmer : Joe L. Bostic *
* *
* Start Date : 01/15/95 *
* *
* Last Update : January 15, 1995 [JLB] *
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef CONTROL_H
#define CONTROL_H
#include "gadget.h"
/***************************************************************************
* ControlClass -- Region tracking class *
* *
* INPUT: int x -- x position of gadget *
* int y -- y position of gadget *
* int w -- width of gadget *
* int h -- height of gadget *
* UWORD flags -- see enumeration choices *
* *
* OUTPUT: 0 = new scenario created, -1 = not *
* WARNINGS: This class is Abstract (cannot make an instance of it) *
* *
* HISTORY: *
* 01/03/1995 MML : Created. *
*=========================================================================*/
class ControlClass : public GadgetClass
{
public:
ControlClass(NoInitClass const & x) : GadgetClass(x) {};
ControlClass(unsigned id, int x, int y, int w, int h, unsigned flags=LEFTPRESS|RIGHTPRESS, int sticky=false);
ControlClass(ControlClass const & control);
virtual void Make_Peer(GadgetClass & gadget);
/*
** Render support function.
*/
virtual int Draw_Me(int forced=false);
/*
** This is the ID number for this control gadget. This number is used to generate
** a special pseudo-key when the gadget detects valid input.
*/
unsigned ID;
protected:
virtual unsigned Get_ID(void) const;
virtual int Action(unsigned flags, KeyNumType & key);
/*
** This points to the peer button to inform when something happens to this
** gadget.
*/
GadgetClass * Peer;
};
#endif

704
REDALERT/COORD.CPP Normal file
View File

@ -0,0 +1,704 @@
//
// 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/COORD.CPP 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 : COORD.CPP *
* *
* Programmer : Joe L. Bostic *
* *
* Start Date : September 10, 1993 *
* *
* Last Update : July 22, 1996 [JLB] *
* *
* Support code to handle the coordinate system is located in this module. *
* Routines here will be called QUITE frequently during play and must be *
* as efficient as possible. *
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* Cardinal_To_Fixed -- Converts cardinal numbers into a fixed point number. *
* Coord_Cell -- Convert a coordinate into a cell number. *
* Coord_Move -- Moves a coordinate an arbitrary direction for an arbitrary distance *
* Coord_Scatter -- Determines a random coordinate from an anchor point. *
* Coord_Spillage_List -- Calculate a spillage list for the dirty rectangle specified. *
* Coord_Spillage_List -- Determines the offset list for cell spillage/occupation. *
* Distance -- Determines the cell distance between two cells. *
* Distance -- Determines the lepton distance between two coordinates. *
* Distance -- Fetch distance between two target values. *
* Fixed_To_Cardinal -- Converts a fixed point number into a cardinal number. *
* Normal_Move_Point -- Moves point with tilt compensation. *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "function.h"
/***********************************************************************************************
* Coord_Cell -- Convert a coordinate into a cell number. *
* *
* This routine will convert the specified coordinate value into a cell number. This is *
* useful to determine the map index number into the cell array that corresponds to a *
* particular coordinate. *
* *
* INPUT: coord -- The coordinate to convert into a cell number. *
* *
* OUTPUT: Returns with the cell number that corresponds to the coordinate specified. *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 06/17/1996 JLB : Created. *
*=============================================================================================*/
CELL Coord_Cell(COORDINATE coord)
{
CELL_COMPOSITE cell;
cell.Cell = 0;
cell.Sub.X = ((COORD_COMPOSITE &)coord).Sub.X.Sub.Cell;
cell.Sub.Y = ((COORD_COMPOSITE &)coord).Sub.Y.Sub.Cell;
return(cell.Cell);
// return(XY_Cell(((COORD_COMPOSITE)coord).Sub.X, ((COORD_COMPOSITE)composite).Sub.Y));
}
/***********************************************************************************************
* Distance -- Fetch distance between two target values. *
* *
* This routine will determine the lepton distance between the two specified target *
* values. *
* *
* INPUT: target1 -- First target value. *
* *
* target2 -- Second target value. *
* *
* OUTPUT: Returns with the lepton distance between the two target values. *
* *
* WARNINGS: Be sure that the targets are legal before calling this routine. Otherwise, the *
* return value is meaningless. *
* *
* HISTORY: *
* 06/17/1996 JLB : Created. *
*=============================================================================================*/
int Distance(TARGET target1, TARGET target2)
{
return(Distance(As_Coord(target1), As_Coord(target2)));
}
/***********************************************************************************************
* Distance -- Determines the lepton distance between two coordinates. *
* *
* This routine is used to determine the distance between two coordinates. It uses the *
* Dragon Strike method of distance determination and thus it is very fast. *
* *
* INPUT: coord1 -- First coordinate. *
* *
* coord2 -- Second coordinate. *
* *
* OUTPUT: Returns the lepton distance between the two coordinates. *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 05/27/1994 JLB : Created. *
*=============================================================================================*/
int Distance(COORDINATE coord1, COORDINATE coord2)
{
int diff1, diff2;
diff1 = Coord_Y(coord1) - Coord_Y(coord2);
if (diff1 < 0) diff1 = -diff1;
diff2 = Coord_X(coord1) - Coord_X(coord2);
if (diff2 < 0) diff2 = -diff2;
if (diff1 > diff2) {
return(diff1 + ((unsigned)diff2 / 2));
}
return(diff2 + ((unsigned)diff1 / 2));
}
/***********************************************************************************************
* Coord_Spillage_List -- Determines the offset list for cell spillage/occupation. *
* *
* This routine will take an arbitrary position and object size and return with a list of *
* cell offsets from the current cell for all cells that are overlapped by the object. The *
* first cell offset is always zero, so to just get the adjacent spill cell list, add one *
* to the return pointer. *
* *
* INPUT: coord -- The coordinate to examine. *
* *
* maxsize -- The maximum width/height of the object (pixels). *
* *
* OUTPUT: Returns with a pointer to a spillage list. *
* *
* WARNINGS: The algorithm is limited to working with a maxsize of 48 or less. Larger values *
* will generate an incomplete overlap list. *
* *
* HISTORY: *
* 11/06/1993 JLB : Created. *
* 03/25/1994 JLB : Added width optimization. *
* 04/29/1994 JLB : Converted to C. *
* 06/03/1994 JLB : Converted to general purpose spillage functionality. *
* 01/07/1995 JLB : Manually calculates spillage list for large objects. *
*=============================================================================================*/
short const * Coord_Spillage_List(COORDINATE coord, int maxsize)
{
static short const _MoveSpillage[(int)FACING_COUNT+1][5] = {
{0, -MAP_CELL_W, REFRESH_EOL, 0, 0}, // N
{0, -MAP_CELL_W, 1, -(MAP_CELL_W-1), REFRESH_EOL}, // NE
{0, 1, REFRESH_EOL, 0, 0}, // E
{0, 1, MAP_CELL_W, MAP_CELL_W+1, REFRESH_EOL}, // SE
{0, MAP_CELL_W, REFRESH_EOL, 0, 0}, // S
{0, -1, MAP_CELL_W, MAP_CELL_W-1, REFRESH_EOL}, // SW
{0, -1, REFRESH_EOL, 0, 0}, // W
{0, -1, -MAP_CELL_W, -(MAP_CELL_W+1), REFRESH_EOL}, // NW
{0, REFRESH_EOL, 0, 0, 0} // non-moving.
};
static short _manual[10];
//; 00 = on axis
//; 01 = below axis
//; 10 = above axis
//; 11 = undefined
static signed char const _SpillTable[16] = {8,6,2,-1,0,7,1,-1,4,5,3,-1,-1,-1,-1,-1};
int index=0;
int x,y;
/*
** For mondo-enourmo-gigundo objects, use a prebuilt mammoth table
** that covers a 5x5 square region.
*/
if (maxsize > ICON_PIXEL_W * 2) {
static short const _gigundo[] = {
-((2*MAP_CELL_W)-2),-((2*MAP_CELL_W)-1),-((2*MAP_CELL_W)),-((2*MAP_CELL_W)+1),-((2*MAP_CELL_W)+2),
-((1*MAP_CELL_W)-2),-((1*MAP_CELL_W)-1),-((1*MAP_CELL_W)),-((1*MAP_CELL_W)+1),-((1*MAP_CELL_W)+2),
-((0*MAP_CELL_W)-2),-((0*MAP_CELL_W)-1),-((0*MAP_CELL_W)),-((0*MAP_CELL_W)+1),-((0*MAP_CELL_W)+2),
((1*MAP_CELL_W)-2),((1*MAP_CELL_W)-1),((1*MAP_CELL_W)),((1*MAP_CELL_W)+1),((1*MAP_CELL_W)+2),
+((2*MAP_CELL_W)-2),+((2*MAP_CELL_W)-1),+((2*MAP_CELL_W)),+((2*MAP_CELL_W)+1),+((2*MAP_CELL_W)+2),
REFRESH_EOL
};
return(&_gigundo[0]);
}
/*
** For very large objects, build the overlap list by hand. This is time consuming, but
** not nearly as time consuming as drawing even a single cell unnecessarily.
*/
if (maxsize > ICON_PIXEL_W) {
maxsize = min(maxsize, (ICON_PIXEL_W*2))/2;
x = (ICON_PIXEL_W * Coord_XLepton(coord)) / ICON_LEPTON_W;
y = (ICON_PIXEL_H * Coord_YLepton(coord)) / ICON_LEPTON_H;
int left = x-maxsize;
int right = x+maxsize;
int top = y-maxsize;
int bottom = y+maxsize;
_manual[index++] = 0;
if (left < 0) _manual[index++] = -1;
if (right >= ICON_PIXEL_W) _manual[index++] = 1;
if (top < 0) _manual[index++] = -MAP_CELL_W;
if (bottom >= ICON_PIXEL_H) _manual[index++] = MAP_CELL_W;
if (left < 0 && top < 0) _manual[index++] = -(MAP_CELL_W+1);
if (right >= ICON_PIXEL_W && bottom >= ICON_PIXEL_H) _manual[index++] = MAP_CELL_W+1;
if (left < 0 && bottom >= ICON_PIXEL_H) _manual[index++] = MAP_CELL_W-1;
if (right >= ICON_PIXEL_H && top < 0) _manual[index++] = -(MAP_CELL_W-1);
_manual[index] = REFRESH_EOL;
return(&_manual[0]);
}
/*
** Determine the number of leptons "leeway" allowed this unit.
*/
int posval = Pixel2Lepton[(ICON_PIXEL_W-maxsize)/2];
x = Coord_XLepton(coord) - 0x0080;
y = Coord_YLepton(coord) - 0x0080;
if (y > posval) index |= 0x08; // Spilling South.
if (y < -posval) index |= 0x04; // Spilling North.
if (x > posval) index |= 0x02; // Spilling East.
if (x < -posval) index |= 0x01; // Spilling West.
return(&_MoveSpillage[_SpillTable[index]][0]);
}
/***********************************************************************************************
* Coord_Spillage_List -- Calculate a spillage list for the dirty rectangle specified. *
* *
* Given a center coordinate and a dirty rectangle, calcuate a cell offset list for *
* determining such things as overlap and redraw logic. Optionally, the center cell *
* location will not be part of the list. *
* *
* INPUT: coord -- The center coordinate that the dirty rectangle is based off of. *
* *
* rect -- Reference to the dirty rectangle. *
* *
* nocenter -- If true, then the center cell offset will not be part of the spillage *
* list returned. This is handy when the center cell is known to be *
* processed by some other method and it can be safely and efficiently *
* ignored by the list generated. *
* *
* OUTPUT: Returns with a pointer to the spillage list that corresponds to the data *
* specified. This is a pointer to a static buffer and as such it will only be valid *
* until the next time that this routine is called. *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 07/22/1996 JLB : Created. *
*=============================================================================================*/
short const * Coord_Spillage_List(COORDINATE coord, Rect const & rect, bool nocenter)
{
if (!rect.Is_Valid()) {
static short const _list[] = {REFRESH_EOL};
return(_list);
}
CELL coordcell = Coord_Cell(coord);
LEPTON x = Coord_X(coord);
LEPTON y = Coord_Y(coord);
/*
** Add the rectangle values to the coordinate in order to normalize the start and end
** corners of the rectangle. The values are now absolute to the real game world rather
** than relative to the coordinate.
*/
LEPTON_COMPOSITE startx;
LEPTON_COMPOSITE starty;
LEPTON_COMPOSITE endx;
LEPTON_COMPOSITE endy;
startx.Raw = (int)x + (short)Pixel_To_Lepton(rect.X);
starty.Raw = (int)y + (short)Pixel_To_Lepton(rect.Y);
endx.Raw = startx.Raw + Pixel_To_Lepton(rect.Width-1);
endy.Raw = starty.Raw + Pixel_To_Lepton(rect.Height-1);
/*
** Determine the upper left and lower right cell indexes. This is a simple conversion from
** their lepton counterpart. These cells values are used to form the bounding box for the
** map offset list.
*/
int cellx = startx.Sub.Cell;
int cellx2 = endx.Sub.Cell;
int celly = starty.Sub.Cell;
int celly2 = endy.Sub.Cell;
/*
** Generate the spillage list by counting off the rows and colums of the cells
** that are affected. This is easy since the upper left and lower right corner cells
** are known.
*/
int count = 0;
static short _spillagelist[128];
short * ptr = _spillagelist;
for (int yy = celly; yy <= celly2; yy++) {
for (int xx = cellx; xx <= cellx2; xx++) {
short offset = (XY_Cell(xx, yy) - coordcell);
if (!nocenter || offset != 0) {
*ptr++ = offset;
count++;
if (count+2 >= ARRAY_SIZE(_spillagelist)) break;
}
}
if (count+2 >= ARRAY_SIZE(_spillagelist)) break;
}
/*
** Cap the list with the end of list marker and then return a pointer
** to the completed list.
*/
*ptr = REFRESH_EOL;
return(_spillagelist);
}
/***********************************************************************************************
* Coord_Move -- Moves a coordinate an arbitrary direction for an arbitrary distance *
* *
* This function will move a coordinate in a using SIN and COS arithmetic. *
* *
* INPUT: start -- The starting coordinate. *
* *
* dir -- The direction to move the coordinate. *
* *
* distance -- The distance to move the coordinate position (in leptons). *
* *
* OUTPUT: Returns the new coordinate position. *
* *
* WARNINGS: This routine uses multiplies -- use with caution. *
* *
* HISTORY: *
* 05/27/1994 JLB : Created. *
*=============================================================================================*/
COORDINATE Coord_Move(COORDINATE start, register DirType dir, unsigned short distance)
{
#ifdef NEVER
short x = Coord_X(start);
short y = Coord_Y(start);
Move_Point(x, y, dir, distance);
return(XY_Coord(x,y));
#endif
Move_Point(*(short *)&start, *(((short *)&start)+1), dir, distance);
return(start);
}
/***********************************************************************************************
* Coord_Scatter -- Determines a random coordinate from an anchor point. *
* *
* This routine will perform a scatter algorithm on the specified *
* anchor point in order to return with another coordinate that is *
* randomly nearby the original. Typical use of this would be for *
* missile targeting. *
* *
* INPUT: coord -- This is the anchor coordinate. *
* *
* distance -- This is the distance in pixels that the scatter *
* should fall within. *
* *
* lock -- bool; Convert the new coordinate into a center *
* cell based coordinate? *
* *
* OUTPUT: Returns with a new coordinate that is nearby the original. *
* *
* WARNINGS: Maximum pixel scatter distance is 255. *
* *
* HISTORY: *
* 02/01/1992 JLB : Created. *
* 05/13/1992 JLB : Only uses Random(). *
*=============================================================================================*/
COORDINATE Coord_Scatter(COORDINATE coord, unsigned distance, bool lock)
{
COORDINATE newcoord;
newcoord = Coord_Move(coord, Random_Pick(DIR_N, DIR_MAX), distance);
if (newcoord & HIGH_COORD_MASK) newcoord = coord;
if (lock) {
newcoord = Coord_Snap(newcoord);
}
return(newcoord);
}
int __cdecl calcx(signed short param1, short distance)
{
__asm {
//#pragma aux calcx parm [ax] [bx] \
movzx eax, [param1]
mov bx, [distance]
imul bx
shl ax, 1
rcl dx, 1
mov al, ah
mov ah, dl
cwd
}
}
int __cdecl calcy(signed short param1, short distance)
{
__asm {
//#pragma aux calcy parm [ax] [bx] \
movzx eax, [param1]
mov bx, [distance]
imul bx
shl ax, 1
rcl dx, 1
mov al, ah
mov ah, dl
cwd
neg eax
}
}
#if (0)
extern int calcx(signed short, short distance);
#pragma aux calcx parm [ax] [bx] \
modify [eax dx] \
value [eax] = \
"imul bx" \
"shl ax,1" \
"rcl dx,1" \
"mov al,ah" \
"mov ah,dl" \
"cwd" \
// "and eax,0FFFFh";
extern int calcy(signed short, short distance);
#pragma aux calcy parm [ax] [bx] \
modify [eax dx] \
value [eax] = \
"imul bx" \
"shl ax,1" \
"rcl dx,1" \
"mov al,ah" \
"mov ah,dl" \
"cwd" \
"neg eax";
// "and eax,0FFFFh" \
#endif
void Move_Point(short &x, short &y, register DirType dir, unsigned short distance)
{
static unsigned char const CosTable[256] = {
0x00,0x03,0x06,0x09,0x0c,0x0f,0x12,0x15,
0x18,0x1b,0x1e,0x21,0x24,0x27,0x2a,0x2d,
0x30,0x33,0x36,0x39,0x3b,0x3e,0x41,0x43,
0x46,0x49,0x4b,0x4e,0x50,0x52,0x55,0x57,
0x59,0x5b,0x5e,0x60,0x62,0x64,0x65,0x67,
0x69,0x6b,0x6c,0x6e,0x6f,0x71,0x72,0x74,
0x75,0x76,0x77,0x78,0x79,0x7a,0x7b,0x7b,
0x7c,0x7d,0x7d,0x7e,0x7e,0x7e,0x7e,0x7e,
0x7f,0x7e,0x7e,0x7e,0x7e,0x7e,0x7d,0x7d,
0x7c,0x7b,0x7b,0x7a,0x79,0x78,0x77,0x76,
0x75,0x74,0x72,0x71,0x70,0x6e,0x6c,0x6b,
0x69,0x67,0x66,0x64,0x62,0x60,0x5e,0x5b,
0x59,0x57,0x55,0x52,0x50,0x4e,0x4b,0x49,
0x46,0x43,0x41,0x3e,0x3b,0x39,0x36,0x33,
0x30,0x2d,0x2a,0x27,0x24,0x21,0x1e,0x1b,
0x18,0x15,0x12,0x0f,0x0c,0x09,0x06,0x03,
0x00,0xfd,0xfa,0xf7,0xf4,0xf1,0xee,0xeb,
0xe8,0xe5,0xe2,0xdf,0xdc,0xd9,0xd6,0xd3,
0xd0,0xcd,0xca,0xc7,0xc5,0xc2,0xbf,0xbd,
0xba,0xb7,0xb5,0xb2,0xb0,0xae,0xab,0xa9,
0xa7,0xa5,0xa2,0xa0,0x9e,0x9c,0x9a,0x99,
0x97,0x95,0x94,0x92,0x91,0x8f,0x8e,0x8c,
0x8b,0x8a,0x89,0x88,0x87,0x86,0x85,0x85,
0x84,0x83,0x83,0x82,0x82,0x82,0x82,0x82,
0x82,0x82,0x82,0x82,0x82,0x82,0x83,0x83,
0x84,0x85,0x85,0x86,0x87,0x88,0x89,0x8a,
0x8b,0x8c,0x8e,0x8f,0x90,0x92,0x94,0x95,
0x97,0x99,0x9a,0x9c,0x9e,0xa0,0xa2,0xa5,
0xa7,0xa9,0xab,0xae,0xb0,0xb2,0xb5,0xb7,
0xba,0xbd,0xbf,0xc2,0xc5,0xc7,0xca,0xcd,
0xd0,0xd3,0xd6,0xd9,0xdc,0xdf,0xe2,0xe5,
0xe8,0xeb,0xee,0xf1,0xf4,0xf7,0xfa,0xfd,
};
static unsigned char const SinTable[256] = {
0x7f,0x7e,0x7e,0x7e,0x7e,0x7e,0x7d,0x7d,
0x7c,0x7b,0x7b,0x7a,0x79,0x78,0x77,0x76,
0x75,0x74,0x72,0x71,0x70,0x6e,0x6c,0x6b,
0x69,0x67,0x66,0x64,0x62,0x60,0x5e,0x5b,
0x59,0x57,0x55,0x52,0x50,0x4e,0x4b,0x49,
0x46,0x43,0x41,0x3e,0x3b,0x39,0x36,0x33,
0x30,0x2d,0x2a,0x27,0x24,0x21,0x1e,0x1b,
0x18,0x15,0x12,0x0f,0x0c,0x09,0x06,0x03,
0x00,0xfd,0xfa,0xf7,0xf4,0xf1,0xee,0xeb,
0xe8,0xe5,0xe2,0xdf,0xdc,0xd9,0xd6,0xd3,
0xd0,0xcd,0xca,0xc7,0xc5,0xc2,0xbf,0xbd,
0xba,0xb7,0xb5,0xb2,0xb0,0xae,0xab,0xa9,
0xa7,0xa5,0xa2,0xa0,0x9e,0x9c,0x9a,0x99,
0x97,0x95,0x94,0x92,0x91,0x8f,0x8e,0x8c,
0x8b,0x8a,0x89,0x88,0x87,0x86,0x85,0x85,
0x84,0x83,0x83,0x82,0x82,0x82,0x82,0x82,
0x82,0x82,0x82,0x82,0x82,0x82,0x83,0x83,
0x84,0x85,0x85,0x86,0x87,0x88,0x89,0x8a,
0x8b,0x8c,0x8e,0x8f,0x90,0x92,0x94,0x95,
0x97,0x99,0x9a,0x9c,0x9e,0xa0,0xa2,0xa5,
0xa7,0xa9,0xab,0xae,0xb0,0xb2,0xb5,0xb7,
0xba,0xbd,0xbf,0xc2,0xc5,0xc7,0xca,0xcd,
0xd0,0xd3,0xd6,0xd9,0xdc,0xdf,0xe2,0xe5,
0xe8,0xeb,0xee,0xf1,0xf4,0xf7,0xfa,0xfd,
0x00,0x03,0x06,0x09,0x0c,0x0f,0x12,0x15,
0x18,0x1b,0x1e,0x21,0x24,0x27,0x2a,0x2d,
0x30,0x33,0x36,0x39,0x3b,0x3e,0x41,0x43,
0x46,0x49,0x4b,0x4e,0x50,0x52,0x55,0x57,
0x59,0x5b,0x5e,0x60,0x62,0x64,0x65,0x67,
0x69,0x6b,0x6c,0x6e,0x6f,0x71,0x72,0x74,
0x75,0x76,0x77,0x78,0x79,0x7a,0x7b,0x7b,
0x7c,0x7d,0x7d,0x7e,0x7e,0x7e,0x7e,0x7e,
};
distance = distance; // Keep LINT quiet.
#ifdef OBSOLETE
/*
** Calculate and add in the X component of the move.
*/
_AX = CosTable[dir];
asm imul word ptr distance
asm shl ax,1
asm rcl dx,1
asm mov al,ah
asm mov ah,dl
_DX = _AX;
x += _DX;
#else
//
// Have to declare table as unsigned otherwise MSVC complains, but we need to treat the actual values as signed.
//
static const char *_cos_table = (char*)&CosTable[0];
x += calcx(_cos_table[dir], distance);
#endif
// asm add [word ptr start],ax
#ifdef OBSOLETE
/*
** Calculate and add in the Y component of the move.
*/
_AX = SinTable[dir];
asm imul word ptr distance
asm shl ax,1
asm rcl dx,1
asm mov al,ah
asm mov ah,dl
asm neg ax // Subtraction needed because of inverted sine table.
_DX = _AX;
y += _DX;
#else
//
// Have to declare table as unsigned otherwise MSVC complains, but we need to treat the actual values as signed.
//
static const char *_sin_table = (char*)&SinTable[0];
y += calcy(_sin_table[dir], distance);
#endif
// asm add [word ptr start+2],ax
}
/***********************************************************************************************
* Normal_Move_Point -- Moves point with tilt compensation. *
* *
* This routine will move the point in the direction and distance specified but it will *
* take into account the tilt of the playing field. Typical use of this routine is to *
* determine positioning as it relates to the playfield. Turrets are a good example of *
* this. *
* *
* INPUT: x,y -- References to the coordinates to adjust. *
* *
* dir -- The direction of the desired movement. *
* *
* distance -- The distance (in coordinate units) to move the point. *
* *
* OUTPUT: none *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 12/19/1995 JLB : Created. *
*=============================================================================================*/
// Loss of precision in initializations (8 bits to 7 bits) warning. Hmmm.. can this be fixed?
//lint -e569
void Normal_Move_Point(short &x, short &y, register DirType dir, unsigned short distance)
{
static unsigned char const CosTable[256] = {
0x00,0x03,0x06,0x09,0x0c,0x0f,0x12,0x15,
0x18,0x1b,0x1e,0x21,0x24,0x27,0x2a,0x2d,
0x30,0x33,0x36,0x39,0x3b,0x3e,0x41,0x43,
0x46,0x49,0x4b,0x4e,0x50,0x52,0x55,0x57,
0x59,0x5b,0x5e,0x60,0x62,0x64,0x65,0x67,
0x69,0x6b,0x6c,0x6e,0x6f,0x71,0x72,0x74,
0x75,0x76,0x77,0x78,0x79,0x7a,0x7b,0x7b,
0x7c,0x7d,0x7d,0x7e,0x7e,0x7e,0x7e,0x7e,
0x7f,0x7e,0x7e,0x7e,0x7e,0x7e,0x7d,0x7d,
0x7c,0x7b,0x7b,0x7a,0x79,0x78,0x77,0x76,
0x75,0x74,0x72,0x71,0x70,0x6e,0x6c,0x6b,
0x69,0x67,0x66,0x64,0x62,0x60,0x5e,0x5b,
0x59,0x57,0x55,0x52,0x50,0x4e,0x4b,0x49,
0x46,0x43,0x41,0x3e,0x3b,0x39,0x36,0x33,
0x30,0x2d,0x2a,0x27,0x24,0x21,0x1e,0x1b,
0x18,0x15,0x12,0x0f,0x0c,0x09,0x06,0x03,
0x00,0xfd,0xfa,0xf7,0xf4,0xf1,0xee,0xeb,
0xe8,0xe5,0xe2,0xdf,0xdc,0xd9,0xd6,0xd3,
0xd0,0xcd,0xca,0xc7,0xc5,0xc2,0xbf,0xbd,
0xba,0xb7,0xb5,0xb2,0xb0,0xae,0xab,0xa9,
0xa7,0xa5,0xa2,0xa0,0x9e,0x9c,0x9a,0x99,
0x97,0x95,0x94,0x92,0x91,0x8f,0x8e,0x8c,
0x8b,0x8a,0x89,0x88,0x87,0x86,0x85,0x85,
0x84,0x83,0x83,0x82,0x82,0x82,0x82,0x82,
0x82,0x82,0x82,0x82,0x82,0x82,0x83,0x83,
0x84,0x85,0x85,0x86,0x87,0x88,0x89,0x8a,
0x8b,0x8c,0x8e,0x8f,0x90,0x92,0x94,0x95,
0x97,0x99,0x9a,0x9c,0x9e,0xa0,0xa2,0xa5,
0xa7,0xa9,0xab,0xae,0xb0,0xb2,0xb5,0xb7,
0xba,0xbd,0xbf,0xc2,0xc5,0xc7,0xca,0xcd,
0xd0,0xd3,0xd6,0xd9,0xdc,0xdf,0xe2,0xe5,
0xe8,0xeb,0xee,0xf1,0xf4,0xf7,0xfa,0xfd,
};
static unsigned char const SinTable[256] = {
0x7f,0x7e,0x7e,0x7e,0x7e,0x7e,0x7d,0x7d,
0x7c,0x7b,0x7b,0x7a,0x79,0x78,0x77,0x76,
0x75,0x74,0x72,0x71,0x70,0x6e,0x6c,0x6b,
0x69,0x67,0x66,0x64,0x62,0x60,0x5e,0x5b,
0x59,0x57,0x55,0x52,0x50,0x4e,0x4b,0x49,
0x46,0x43,0x41,0x3e,0x3b,0x39,0x36,0x33,
0x30,0x2d,0x2a,0x27,0x24,0x21,0x1e,0x1b,
0x18,0x15,0x12,0x0f,0x0c,0x09,0x06,0x03,
0x00,0xfd,0xfa,0xf7,0xf4,0xf1,0xee,0xeb,
0xe8,0xe5,0xe2,0xdf,0xdc,0xd9,0xd6,0xd3,
0xd0,0xcd,0xca,0xc7,0xc5,0xc2,0xbf,0xbd,
0xba,0xb7,0xb5,0xb2,0xb0,0xae,0xab,0xa9,
0xa7,0xa5,0xa2,0xa0,0x9e,0x9c,0x9a,0x99,
0x97,0x95,0x94,0x92,0x91,0x8f,0x8e,0x8c,
0x8b,0x8a,0x89,0x88,0x87,0x86,0x85,0x85,
0x84,0x83,0x83,0x82,0x82,0x82,0x82,0x82,
0x82,0x82,0x82,0x82,0x82,0x82,0x83,0x83,
0x84,0x85,0x85,0x86,0x87,0x88,0x89,0x8a,
0x8b,0x8c,0x8e,0x8f,0x90,0x92,0x94,0x95,
0x97,0x99,0x9a,0x9c,0x9e,0xa0,0xa2,0xa5,
0xa7,0xa9,0xab,0xae,0xb0,0xb2,0xb5,0xb7,
0xba,0xbd,0xbf,0xc2,0xc5,0xc7,0xca,0xcd,
0xd0,0xd3,0xd6,0xd9,0xdc,0xdf,0xe2,0xe5,
0xe8,0xeb,0xee,0xf1,0xf4,0xf7,0xfa,0xfd,
0x00,0x03,0x06,0x09,0x0c,0x0f,0x12,0x15,
0x18,0x1b,0x1e,0x21,0x24,0x27,0x2a,0x2d,
0x30,0x33,0x36,0x39,0x3b,0x3e,0x41,0x43,
0x46,0x49,0x4b,0x4e,0x50,0x52,0x55,0x57,
0x59,0x5b,0x5e,0x60,0x62,0x64,0x65,0x67,
0x69,0x6b,0x6c,0x6e,0x6f,0x71,0x72,0x74,
0x75,0x76,0x77,0x78,0x79,0x7a,0x7b,0x7b,
0x7c,0x7d,0x7d,0x7e,0x7e,0x7e,0x7e,0x7e,
};
distance = distance; // Keep LINT quiet.
//
// Have to declare table as unsigned otherwise MSVC complains, but we need to treat the actual values as signed.
//
static const char *_sin_table = (char*)&SinTable[0];
static const char *_cos_table = (char*)&CosTable[0];
x += calcx(_cos_table[dir], distance);
y += calcy(_sin_table[dir] / 2, distance);
}

126
REDALERT/COORDA.ASM Normal file
View File

@ -0,0 +1,126 @@
;
; 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]>.
;***************************************************************************
;** 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 I N C **
;***************************************************************************
;* *
;* Project Name : Command & Conquer *
;* *
;* File Name : COORDA.ASM *
;* *
;* Programmer : Barry W. Green *
;* *
;* Start Date : February 17, 1995 *
;* *
;* Last Update : February 17, 1995 [BWG] *
;* *
;*-------------------------------------------------------------------------*
;* Functions: *
;* Cardinal_To_Fixed -- Converts cardinal numbers into a fixed point number. *
;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
IDEAL
P386
MODEL USE32 FLAT
global C Cardinal_To_Fixed :NEAR
global C Fixed_To_Cardinal :NEAR
CODESEG
;***********************************************************************************************
;* Cardinal_To_Fixed -- Converts cardinal numbers into a fixed point number. *
;* *
;* This utility function will convert cardinal numbers into a fixed point fraction. The *
;* use of fixed point numbers occurs throughout the product -- since it is a convenient *
;* tool. The fixed point number is based on the formula: *
;* *
;* result = cardinal / base *
;* *
;* The accuracy of the fixed point number is limited to 1/65536 as the lowest and up to *
;* 65536 as the largest. *
;* *
;* INPUT: base -- The key number to base the fraction about. *
;* *
;* cardinal -- The other number (hey -- what do you call it?) *
;* *
;* OUTPUT: Returns with the fixed point number of the "cardinal" parameter as it relates *
;* to the "base" parameter. *
;* *
;* WARNINGS: none *
;* *
;* HISTORY: *
;* 02/17/1995 BWG : Created. *
;*=============================================================================================*/
;unsigned int Cardinal_To_Fixed(unsigned base, unsigned cardinal);
PROC Cardinal_To_Fixed C near
USES ebx, edx
ARG base:DWORD
ARG cardinal:DWORD
mov eax,0FFFFFFFFh ; establish default return value
mov ebx,[base]
or ebx,ebx
jz near ??retneg1 ; if base==0, return 4294967295
mov eax,[cardinal] ; otherwise, return (cardinal*65536)/base
shl eax,16
xor edx,edx
div ebx
??retneg1:
ret
ENDP Cardinal_To_Fixed
;***********************************************************************************************
;* Fixed_To_Cardinal -- Converts a fixed point number into a cardinal number. *
;* *
;* Use this routine to convert a fixed point number into a cardinal number. *
;* *
;* INPUT: base -- The base number that the original fixed point number was created from. *
;* *
;* fixed -- The fixed point number to convert. *
;* *
;* OUTPUT: Returns with the reconverted number. *
;* *
;* WARNINGS: none *
;* *
;* HISTORY: *
;* 02/17/1995 BWG : Created. *
;*=============================================================================================*/
;unsigned int Fixed_To_Cardinal(unsigned base, unsigned fixed);
PROC Fixed_To_Cardinal C near
USES edx
ARG base:DWORD
ARG fixed:DWORD
mov eax,[base]
mul [fixed]
add eax,08000h ; eax = (base * fixed) + 0x8000
shr eax,16 ; return eax/65536
ret
ENDP Fixed_To_Cardinal
END

141
REDALERT/COORDA.h Normal file
View File

@ -0,0 +1,141 @@
//
// 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
/*
;***************************************************************************
;** 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 I N C **
;***************************************************************************
;* *
;* Project Name : Command & Conquer *
;* *
;* File Name : COORDA.ASM *
;* *
;* Programmer : Barry W. Green *
;* *
;* Start Date : February 17, 1995 *
;* *
;* Last Update : February 17, 1995 [BWG] *
;* *
;*-------------------------------------------------------------------------*
;* Functions: *
;* Cardinal_To_Fixed -- Converts cardinal numbers into a fixed point number. *
;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
*/
#ifndef COORD_A_H
//IDEAL
//P386
//MODEL USE32 FLAT
//global C Cardinal_To_Fixed :NEAR
//global C Fixed_To_Cardinal :NEAR
// CODESEG
/*
;***********************************************************************************************
;* Cardinal_To_Fixed -- Converts cardinal numbers into a fixed point number. *
;* *
;* This utility function will convert cardinal numbers into a fixed point fraction. The *
;* use of fixed point numbers occurs throughout the product -- since it is a convenient *
;* tool. The fixed point number is based on the formula: *
;* *
;* result = cardinal / base *
;* *
;* The accuracy of the fixed point number is limited to 1/256 as the lowest and up to *
;* 256 as the largest. *
;* *
;* INPUT: base -- The key number to base the fraction about. *
;* *
;* cardinal -- The other number (hey -- what do you call it?) *
;* *
;* OUTPUT: Returns with the fixed point number of the "cardinal" parameter as it relates *
;* to the "base" parameter. *
;* *
;* WARNINGS: none *
;* *
;* HISTORY: *
;* 02/17/1995 BWG : Created. *
;*=============================================================================================*/
unsigned int __cdecl Cardinal_To_Fixed(unsigned base, unsigned cardinal);
#if (0)
PROC Cardinal_To_Fixed C near
USES ebx, edx
ARG base:DWORD
ARG cardinal:DWORD
mov eax,0FFFFh ; establish default return value
mov ebx,[base]
or ebx,ebx
jz near ??retneg1 ; if base==0, return 65535
mov eax,[cardinal] ; otherwise, return (cardinal*256)/base
shl eax,8
xor edx,edx
div ebx
??retneg1:
ret
ENDP Cardinal_To_Fixed
#endif
/*
;***********************************************************************************************
;* Fixed_To_Cardinal -- Converts a fixed point number into a cardinal number. *
;* *
;* Use this routine to convert a fixed point number into a cardinal number. *
;* *
;* INPUT: base -- The base number that the original fixed point number was created from. *
;* *
;* fixed -- The fixed point number to convert. *
;* *
;* OUTPUT: Returns with the reconverted number. *
;* *
;* WARNINGS: none *
;* *
;* HISTORY: *
;* 02/17/1995 BWG : Created. *
;*=============================================================================================*/
unsigned int __cdecl Fixed_To_Cardinal(unsigned base, unsigned fixed);
#if (0)
mov eax,[base]
mul [fixed]
add eax,080h ; eax = (base * fixed) + 0x80
test eax,0FF000000h ; if high byte set, return FFFF
jnz ??rneg1
shr eax,8 ; else, return eax/256
ret
??rneg1 :
mov eax,0FFFFh ; establish default return value
ret
ENDP Fixed_To_Cardinal
END
#endif
#endif COORD_A_H

182
REDALERT/CPUID.ASM Normal file
View File

@ -0,0 +1,182 @@
;
; 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: F:\projects\c&c0\vcs\code\cpuid.asv 5.0 11 Nov 1996 09:40:28 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 I N C **
;***************************************************************************
;* *
;* Project Name : Command & Conquer *
;* *
;* File Name : MMX.ASM *
;* *
;* Programmer : Steve Tall *
;* *
;* Start Date : May 19th, 1996 *
;* *
;* Last Update : May 19th 1996 [ST] *
;* *
;*-------------------------------------------------------------------------*
;* Functions: *
;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
.586
.model flat
;
; Variables externs
;
GLOBAL C CPUType:byte
;externdef C CPUType:byte
GLOBAL C VendorID:byte
;externdef C VendorID:byte
;
; Function externs
;
GLOBAL C Detect_MMX_Availability:near
;externdef C Detect_MMX_Availability:near
.code
;*********************************************************************************************
;* Detect_MMX_Availability -- Detect the presence of MMX technology. *
;* *
;* *
;* INPUT: Nothing *
;* *
;* OUTPUT: True if MMX technology is available. *
;* *
;* Warnings: *
;* *
;* Note: Based in part on CPUID32.ASM by Intel *
;* *
;* HISTORY: *
;* 05/19/96 ST : Created. *
;*===========================================================================================*
Detect_MMX_Availability proc C
local idflag:byte
local cputype:byte
;assume processor is at least 386
;
;check whether AC bit in eflags can be toggled.
;If not then processor is 386
mov [idflag],0
pushfd ;get Eflags in EAX
pop eax
mov ecx,eax ;save eflags
xor eax,40000h ;toggle AC bit in eflags
push eax ;new eflags on stack
popfd ;move new value into eflags
pushfd ;get new eflags back into eax
pop eax
xor eax,ecx ;if AC bit not toggled then CPU=386
mov [cputype],3
jz @@end_get_cpu ;cpu is 386
push ecx
popfd ;restore AC bit in eflags
;processor is at least 486
;
;Check for ability to set/clear ID flag in EFLAGS
;ID flag indicates ability of processor to execute the CPUID instruction.
;486 not guaranteed to have CPUID inst?
;
mov [cputype],4
mov eax,ecx ;original EFLAGS
xor eax,200000h ;toggle ID bit
push eax
popfd
pushfd
pop eax
xor eax,ecx ;check if still toggled
jz @@end_get_cpu
; Execute CPUID instruction to determine vendor, family,
; model and stepping.
;
mov [idflag],1 ;flag ID is available
xor eax,eax
cpuid
mov dword ptr [VendorID],ebx
mov dword ptr [VendorID+4],edx
mov dword ptr [VendorID+8],ecx
mov dword ptr [VendorID+12]," "
cmp eax,1 ;check if 1 is valid
jl @@end_get_cpu ;inp for cpuid inst.
xor eax,eax
inc eax
cpuid ;get stepping, model and family
and ax,0f00H
shr ax,08H
mov [cputype],al
@@end_get_cpu: mov al,[cputype]
mov [CPUType],al
;
; We have the CPU type in al now.
; If we arent on at least a pentium then we can assume there is no MMX
;
cmp al,5
jl @@no_mmx
mov eax,1
cpuid
test edx,00800000h
jz @@no_mmx
;
; MMX detected - return true
;
mov eax,1
ret
@@no_mmx: xor eax,eax
ret
Detect_MMX_Availability endp
.data
CPUType db 0
VendorID db "Not available",0,0,0,0,0,0
end

182
REDALERT/CRATE.CPP Normal file
View File

@ -0,0 +1,182 @@
//
// 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/CRATE.CPP 3 3/04/97 3:12p 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 : CRATE.CPP *
* *
* Programmer : Joe L. Bostic *
* *
* Start Date : 08/26/96 *
* *
* Last Update : October 14, 1996 [JLB] *
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* CrateClass::Create_Crate -- Create a crate in the cell specified. *
* CrateClass::Get_Crate -- Pick up a crate from the cell specified. *
* CrateClass::Put_Crate -- Generates crate overlay at cell specified. *
* CrateClass::Remove_It -- Removes the crate from wherever it is. *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "function.h"
/***********************************************************************************************
* CrateClass::Remove_It -- Removes the crate from wherever it is. *
* *
* This routine will remove the crate from whereever it happens to be. *
* *
* INPUT: none *
* *
* OUTPUT: bool; Was the crate found and removed? *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 08/26/1996 JLB : Created. *
*=============================================================================================*/
bool CrateClass::Remove_It(void)
{
if (Is_Valid()) {
Get_Crate(Cell);
Make_Invalid();
return(true);
}
return(false);
}
/***********************************************************************************************
* CrateClass::Create_Crate -- Create a crate in the cell specified. *
* *
* This will create a crate in the cell specified. If the crate could not be crated there *
* then 'false' will be returned. *
* *
* INPUT: cell -- The desired cell to place the crate in. *
* *
* OUTPUT: bool; Was the crate created and placed in the cell? *
* *
* WARNINGS: It is quite possible for the crate not to have been placed. Only the most clear *
* locations are valid for crate placement. *
* *
* HISTORY: *
* 08/26/1996 JLB : Created. *
*=============================================================================================*/
bool CrateClass::Create_Crate(CELL cell)
{
/*
** Remove any existing crate that this crate class is tracking.
*/
Remove_It();
/*
** Try to place a new crate at the cell specified.
*/
if (Put_Crate(cell)) {
Cell = cell;
Timer = Random_Pick(Rule.CrateTime * (TICKS_PER_MINUTE/2), Rule.CrateTime * (TICKS_PER_MINUTE*2));
Timer.Start();
return(true);
}
return(false);
}
/***********************************************************************************************
* CrateClass::Put_Crate -- Generates crate overlay at cell specified. *
* *
* This helpter routine will examine the cell and place the appropriate crate type into *
* the cell specified. If the overlay could not be generated, then 'false' is returned. *
* *
* INPUT: cell -- The cell to generate the crate overlay in. *
* *
* OUTPUT: bool; Was the crate overlay generated? *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 08/26/1996 JLB : Created. *
* 10/14/1996 JLB : Takes reference to cell so that tracking can occur. *
*=============================================================================================*/
bool CrateClass::Put_Crate(CELL & cell)
{
int old = ScenarioInit;
ScenarioInit = 0;
if (Map.In_Radar(cell)) {
CellClass * cellptr = &Map[cell];
while (cellptr->Overlay != OVERLAY_NONE && !cellptr->Is_Clear_To_Build(SPEED_FLOAT) && !cellptr->Is_Clear_To_Build(SPEED_FOOT)) {
cell = Map.Pick_Random_Location();
if (Percent_Chance(100 * Rule.WaterCrateChance)) {
cell = Map.Nearby_Location(cell, SPEED_FLOAT);
} else {
cell = Map.Nearby_Location(cell, SPEED_TRACK);
}
cellptr = &Map[cell];
}
if (cellptr->Is_Clear_To_Build(SPEED_FLOAT)) {
new OverlayClass(OVERLAY_WATER_CRATE, cell);
} else {
new OverlayClass(OVERLAY_WOOD_CRATE, cell);
}
ScenarioInit = old;
return(true);
}
ScenarioInit = old;
return(false);
}
/***********************************************************************************************
* CrateClass::Get_Crate -- Pick up a crate from the cell specified. *
* *
* This will remove the crate from the cell specified. *
* *
* INPUT: cell -- The cell to examine and remove any crate overlays present. *
* *
* OUTPUT: bool; Was a crate overlay found and removed? *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 08/26/1996 JLB : Created. *
*=============================================================================================*/
bool CrateClass::Get_Crate(CELL cell)
{
if (Map.In_Radar(cell)) {
CellClass * cellptr = &Map[cell];
if (cellptr->Overlay == OVERLAY_WOOD_CRATE ||
cellptr->Overlay == OVERLAY_STEEL_CRATE ||
cellptr->Overlay == OVERLAY_WATER_CRATE) {
cellptr->Overlay = OVERLAY_NONE;
cellptr->OverlayData = 0;
cellptr->Redraw_Objects();
return(true);
}
}
return(false);
}

76
REDALERT/CRATE.H Normal file
View File

@ -0,0 +1,76 @@
//
// 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/CRATE.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 : CRATE.H *
* *
* Programmer : Joe L. Bostic *
* *
* Start Date : 08/26/96 *
* *
* Last Update : August 26, 1996 [JLB] *
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef CRATE_H
#define CRATE_H
#include "ftimer.h"
#include "jshell.h"
/*
** The "bool" integral type was defined by the C++ comittee in
** November of '94. Until the compiler supports this, use the following
** definition.
*/
#ifndef __BORLANDC__
#ifndef TRUE_FALSE_DEFINED
#define TRUE_FALSE_DEFINED
enum {false=0,true=1};
typedef int bool;
#endif
#endif
class CrateClass {
public:
CrateClass(void) : Timer(NoInitClass()), Cell(-1) {}
void Init(void) {Make_Invalid();}
bool Create_Crate(CELL cell);
bool Is_Here(CELL cell) const {return(Is_Valid() && cell == Cell);}
bool Remove_It(void);
bool Is_Expired(void) const {return(Is_Valid() && Timer == 0);}
bool Is_Valid(void) const {return(Cell != -1);}
private:
static bool Put_Crate(CELL & cell);
static bool Get_Crate(CELL cell);
void Make_Invalid(void) {Cell = -1;Timer.Stop();}
CDTimerClass<FrameTimerClass> Timer;
CELL Cell;
};
#endif

133
REDALERT/CRC.CPP Normal file
View File

@ -0,0 +1,133 @@
//
// 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/CRC.CPP 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 : CRC.CPP *
* *
* Programmer : Joe L. Bostic *
* *
* Start Date : 03/02/96 *
* *
* Last Update : March 2, 1996 [JLB] *
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* CRCEngine::operator() -- Submits one byte of data to the CRC engine. *
* CRCEngine::operator() -- Submits an arbitrary data block to the CRC engine. *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "crc.h"
/***********************************************************************************************
* CRCEngine::operator() -- Submits one byte of data to the CRC engine. *
* *
* This routine will take the specified byte of data and submit it to the CRC engine *
* for processing. This routine is designed to be as fast as possible since the typical *
* use of this routine is to feed one of presumably many byte sized chunks of data to the *
* CRC engine. *
* *
* INPUT: datum -- One byte of data to submit to the CRC engine. *
* *
* OUTPUT: none *
* *
* WARNINGS: If possible, use the buffer/size operator to submit data rather than repeated *
* calls to this routine. *
* *
* HISTORY: *
* 03/02/1996 JLB : Created. *
*=============================================================================================*/
void CRCEngine::operator() (char datum)
{
StagingBuffer.Buffer[Index++] = datum;
if (Index == sizeof(long)) {
CRC = Value();
StagingBuffer.Composite = 0;
Index = 0;
}
}
/***********************************************************************************************
* CRCEngine::operator() -- Submits an arbitrary data block to the CRC engine. *
* *
* This routine will submit the specified block to the CRC engine. The block can be of *
* arbitrary length. *
* *
* INPUT: buffer -- Pointer to the buffer that contains the data. The buffer will not *
* be modified. *
* *
* length -- The length of the buffer (in bytes). *
* *
* OUTPUT: Returns with the current CRC value accumulated so far. *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 03/02/1996 JLB : Created. *
*=============================================================================================*/
long CRCEngine::operator() (void const * buffer, int length)
{
if (buffer != NULL && length > 0) {
char const * dataptr = (char const *)buffer;
int bytes_left = length;
/*
** If there are any leader bytes (needed to fill the staging buffer)
** then process those by first using them to fill up the staging
** buffer. The bulk of the data block will be processed by the high
** speed longword processing loop.
*/
while (bytes_left && Buffer_Needs_Data()) {
operator()(*dataptr);
dataptr++;
bytes_left--;
}
/*
** Perform the fast 'bulk' processing by reading long word sized
** data blocks.
*/
long const * longptr = (long const *)dataptr;
int longcount = bytes_left / sizeof(long); // Whole 'long' elements remaining.
while (longcount--) {
CRC = _lrotl(CRC, 1) + *longptr++;
bytes_left -= sizeof(long);
}
/*
** If there are remainder bytes, then process these by adding them
** to the staging buffer.
*/
dataptr = (char const *)longptr;
while (bytes_left) {
operator()(*dataptr);
dataptr++;
bytes_left--;
}
}
/*
** Return the current CRC value.
*/
return(Value());
}

Some files were not shown because too many files have changed in this diff Show More