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

795
TIBERIANDAWN/AADATA.CPP Normal file
View File

@@ -0,0 +1,795 @@
//
// 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&c\vcs\code\aadata.cpv 2.18 16 Oct 1995 16:49:50 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 *
* name in *
* File Name : AADATA.CPP *
* *
* Programmer : Joe L. Bostic *
* *
* Start Date : July 22, 1994 *
* *
* Last Update : August 7, 1995 [JLB] *
* Determines *
*---------------------------------------------------------------------------------------------*
* Functions: *
* AircraftTypeClass::AircraftTypeClass -- Constructor for aircraft objects. *
* 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 ASCIIto an aircraft type number. *
* 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 -- the overlap list for a landed aircraft. *
* AircraftTypeClass::Prep_For_Add -- Prepares the scenario editor for adding an aircraft objec*
* AircraftTypeClass::Repair_Cost -- Fetchs the cost per repair step. *
* AircraftTypeClass::Repair_Step -- Fetches the number of health points per repair. *
* AircraftTypeClass::Who_Can_Build_Me -- Determines which object can build the aircraft obje*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "function.h"
void const * AircraftTypeClass::LRotorData = NULL;
void const * AircraftTypeClass::RRotorData = NULL;
// A-10 attack plane
static AircraftTypeClass const AttackPlane(
AIRCRAFT_A10, // What kind of aircraft is this.
TXT_A10, // Translated text number for aircraft.
"A10", // INI name of aircraft.
99, // Build level.
STRUCTF_NONE, // Building prerequisite.
false, // Is a leader type?
false, // Does it fire a pair of shots in quick succession?
false, // Is this a typical transport vehicle?
true, // Fixed wing aircraft?
false, // Equipped with a rotor?
false, // Custom rotor sets for each facing?
false, // Can this aircraft land on clear terrain?
false, // Can the aircraft be crushed by a tracked vehicle?
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?
false, // Theater specific graphic image?
false, // Can it be repaired in a repair facility?
false, // Can the player construct or order this unit?
true, // Is there a crew inside?
3, // Number of shots it has (default).
60, // The strength of this unit.
0, // The range that it reveals terrain around itself.
800, // Credit cost to construct.
0, // The scenario this becomes available.
10,1, // Risk, reward when calculating AI.
HOUSEF_MULTI1|
HOUSEF_MULTI2|
HOUSEF_MULTI3|
HOUSEF_MULTI4|
HOUSEF_MULTI5|
HOUSEF_MULTI6|
HOUSEF_JP|
HOUSEF_GOOD|
HOUSEF_BAD, // Who can own this aircraft type.
WEAPON_NAPALM,WEAPON_NONE,
ARMOR_ALUMINUM, // Armor type of this aircraft.
MPH_FAST, // Maximum speed of aircraft.
5, // Rate of turn.
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.
6, // Build level.
STRUCTF_HELIPAD, // Building prerequisite.
false, // Is a leader type?
false, // Does it fire a pair of shots in quick succession?
true, // Is this a typical transport vehicle?
false, // Fixed wing aircraft?
true, // Equipped with a rotor?
true, // Custom rotor sets for each facing?
true, // Can this aircraft land on clear terrain?
false, // Can the aircraft be crushed by a tracked vehicle?
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, // Theater specific graphic image?
false, // Is it equipped with a combat turret?
false, // Can it be repaired in a repair facility?
true, // Can the player construct or order this unit?
true, // Is there a crew inside?
0, // Number of shots it has (default).
90, // The strength of this unit.
0, // The range that it reveals terrain around itself.
1500, // Credit cost to construct.
98, // The scenario this becomes available.
10,80, // Risk, reward when calculating AI.
HOUSEF_MULTI1|
HOUSEF_MULTI2|
HOUSEF_MULTI3|
HOUSEF_MULTI4|
HOUSEF_MULTI5|
HOUSEF_MULTI6|
HOUSEF_JP|
HOUSEF_BAD|
HOUSEF_GOOD, // Who can own this aircraft type.
WEAPON_NONE,WEAPON_NONE,
ARMOR_ALUMINUM, // Armor type of this aircraft.
MPH_MEDIUM_FAST, // Maximum speed of aircraft.
5, // Rate of turn.
MISSION_HUNT // Default mission for aircraft.
);
// Apache attach helicopter.
static AircraftTypeClass const AttackHeli(
AIRCRAFT_HELICOPTER, // What kind of aircraft is this.
TXT_HELI, // Translated text number for aircraft.
"HELI", // INI name of aircraft.
6, // Build level.
STRUCTF_HELIPAD, // Building prerequisite.
true, // Is a leader type?
true, // Does it fire a pair of shots in quick succession?
false, // Is this a typical transport vehicle?
false, // Fixed wing aircraft?
true, // Equipped with a rotor?
false, // Custom rotor sets for each facing?
false, // Can this aircraft land on clear terrain?
false, // Can the aircraft be crushed by a tracked vehicle?
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?
false, // Theater specific graphic image?
false, // Can it be repaired in a repair facility?
true, // Can the player construct or order this unit?
true, // Is there a crew inside?
15, // Number of shots it has (default).
125, // The strength of this unit.
0, // The range that it reveals terrain around itself.
1200, // Credit cost to construct.
10, // The scenario this becomes available.
10,80, // Risk, reward when calculating AI.
HOUSEF_MULTI1|
HOUSEF_MULTI2|
HOUSEF_MULTI3|
HOUSEF_MULTI4|
HOUSEF_MULTI5|
HOUSEF_MULTI6|
HOUSEF_JP|
HOUSEF_BAD, // Who can own this aircraft type.
WEAPON_CHAIN_GUN,WEAPON_NONE,
ARMOR_STEEL, // Armor type of this aircraft.
MPH_FAST, // Maximum speed of aircraft.
4, // Rate of turn.
MISSION_HUNT // Default mission for aircraft.
);
// Orca attack helicopter.
static AircraftTypeClass const OrcaHeli(
AIRCRAFT_ORCA, // What kind of aircraft is this.
TXT_ORCA, // Translated text number for aircraft.
"ORCA", // INI name of aircraft.
6, // Build level.
STRUCTF_HELIPAD, // Building prerequisite.
true, // Is a leader type?
true, // Does it fire a pair of shots in quick succession?
false, // Is this a typical transport vehicle?
false, // Fixed wing aircraft?
false, // Equipped with a rotor?
false, // Custom rotor sets for each facing?
false, // Can this aircraft land on clear terrain?
false, // Can the aircraft be crushed by a tracked vehicle?
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?
false, // Theater specific graphic image?
false, // Can it be repaired in a repair facility?
true, // Can the player construct or order this unit?
true, // Is there a crew inside?
6, // Number of shots it has (default).
125, // The strength of this unit.
0, // The range that it reveals terrain around itself.
1200, // Credit cost to construct.
10, // The scenario this becomes available.
10,80, // Risk, reward when calculating AI.
HOUSEF_MULTI1|
HOUSEF_MULTI2|
HOUSEF_MULTI3|
HOUSEF_MULTI4|
HOUSEF_MULTI5|
HOUSEF_MULTI6|
HOUSEF_JP|
HOUSEF_GOOD, // Who can own this aircraft type.
WEAPON_DRAGON,WEAPON_NONE,
ARMOR_STEEL, // Armor type of this aircraft.
MPH_FAST, // Maximum speed of aircraft.
4, // Rate of turn.
MISSION_HUNT // Default mission for aircraft.
);
// C-17 transport plane.
static AircraftTypeClass const CargoPlane(
AIRCRAFT_CARGO, // What kind of aircraft is this.
TXT_C17, // Translated text number for aircraft.
"C17", // INI name of aircraft.
99, // Build level.
STRUCTF_NONE, // Building prerequisite.
false, // Is a leader type?
false, // Does it fire a pair of shots in quick succession?
true, // Is this a typical transport vehicle?
true, // Fixed wing aircraft?
false, // Equipped with a rotor?
false, // Custom rotor sets for each facing?
false, // Can this aircraft land on clear terrain?
false, // Can the aircraft be crushed by a tracked vehicle?
true, // Is it invisible on radar?
false, // Can the player select it so as to give it orders?
false, // 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?
false, // Theater specific graphic image?
false, // Can it be repaired in a repair facility?
false, // Can the player construct or order this unit?
true, // Is there a crew inside?
0, // Number of shots it has (default).
25, // The strength of this unit.
0, // The range that it reveals terrain around itself.
800, // Credit cost to construct.
0, // The scenario this becomes available.
10,1, // Risk, reward when calculating AI.
HOUSEF_MULTI1|
HOUSEF_MULTI2|
HOUSEF_MULTI3|
HOUSEF_MULTI4|
HOUSEF_MULTI5|
HOUSEF_MULTI6|
HOUSEF_JP|
HOUSEF_GOOD|
HOUSEF_BAD, // Who can own this aircraft type.
WEAPON_NONE,WEAPON_NONE,
ARMOR_ALUMINUM, // Armor type of this aircraft.
MPH_FAST, // Maximum speed of aircraft.
5, // Rate of turn.
MISSION_HUNT // Default mission for aircraft.
);
AircraftTypeClass const * const AircraftTypeClass::Pointers[AIRCRAFT_COUNT] = {
&TransportHeli,
&AttackPlane,
&AttackHeli,
&CargoPlane,
&OrcaHeli,
};
/***********************************************************************************************
* 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,
unsigned char level,
long pre,
bool is_leader,
bool is_twoshooter,
bool is_transporter,
bool is_fixedwing,
bool is_rotorequipped,
bool is_rotorcustom,
bool is_landable,
bool is_crushable,
bool is_stealthy,
bool is_selectable,
bool is_legal_target,
bool is_insignificant,
bool is_immune,
bool is_theater,
bool is_repairable,
bool is_buildable,
bool is_crew,
int ammo,
unsigned short strength,
int sightrange,
int cost,
int scenario,
int risk,
int reward,
int ownable,
WeaponType primary,
WeaponType secondary,
ArmorType armor,
MPHType maxspeed,
int rot,
MissionType deforder) :
TechnoTypeClass(name,
ininame,
level,
pre,
is_leader,
false,
false,
is_transporter,
false,
is_crushable,
is_stealthy,
is_selectable,
is_legal_target,
is_insignificant,
is_immune,
is_theater,
is_twoshooter,
false,
is_repairable,
is_buildable,
is_crew,
ammo,
strength,
maxspeed,
sightrange,
cost,
scenario,
risk,
reward,
ownable,
primary,
secondary,
armor)
{
IsRotorEquipped = is_rotorequipped;
IsRotorCustom = is_rotorcustom;
IsLandable = is_landable;
IsFixedWing = is_fixedwing;
Type = airtype;
ROT = rot;
Mission = deforder;
}
/***********************************************************************************************
* 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) {
for (AircraftType classid = AIRCRAFT_FIRST; classid < AIRCRAFT_COUNT; classid++) {
if (stricmp(Pointers[classid]->IniName, name) == 0) {
return(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)
{
AircraftType index;
for (index = AIRCRAFT_FIRST; index < AIRCRAFT_COUNT; index++) {
char fullname[_MAX_FNAME+_MAX_EXT];
AircraftTypeClass const & uclass = As_Reference(index);
/*
** Fetch the supporting data files for the unit.
*/
char buffer[_MAX_FNAME];
if ( Get_Resolution_Factor() ) {
sprintf(buffer, "%sICNH", uclass.IniName);
} else {
sprintf(buffer, "%sICON", uclass.IniName);
}
_makepath(fullname, NULL, NULL, buffer, ".SHP");
((void const *&)uclass.CameoData) = MixFileClass::Retrieve(fullname);
/*
** Generic shape for all houses load method.
*/
_makepath(fullname, NULL, NULL, uclass.IniName, ".SHP");
((void const *&)uclass.ImageData) = MixFileClass::Retrieve(fullname);
}
LRotorData = MixFileClass::Retrieve("LROTOR.SHP");
RRotorData = MixFileClass::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 house) const
{
int shape = 0;
void const * ptr = Get_Cameo_Data();
if (!ptr) {
ptr = Get_Image_Data();
shape = 5;
}
CC_Draw_Shape(ptr, shape, x, y, window, SHAPE_CENTER|SHAPE_WIN_REL|SHAPE_FADING, HouseClass::As_Pointer(house)->Remap_Table(false, true));
}
#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::Who_Can_Build_Me -- Determines which object can build the aircraft objec *
* *
* Use this routine to determine which object (factory) can build the aircraft. It *
* determines this by scanning through the available factories, looking for one that is *
* of the proper ownership and is available. *
* *
* INPUT: intheory -- When true, it doesn't consider if the factory is currently busy. It *
* only considers that it is the right type. *
* *
* legal -- Should building prerequisite legality checks be performed as well? *
* For building placements, this is usually false. For sidebar button *
* adding, this is usually true. *
* *
* house -- The house of the desired aircraft to be built. *
* *
* OUTPUT: Returns with a pointer to the object that can build the aircraft. *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 11/30/1994 JLB : Created. *
*=============================================================================================*/
BuildingClass * AircraftTypeClass::Who_Can_Build_Me(bool , bool legal, HousesType house) const
{
BuildingClass * anybuilding = NULL;
for (int index = 0; index < Buildings.Count(); index++) {
BuildingClass * building = Buildings.Ptr(index);
if (building &&
!building->IsInLimbo &&
building->House->Class->House == house &&
building->Mission != MISSION_DECONSTRUCTION &&
((1L << building->ActLike) & Ownable) &&
(!legal || building->House->Can_Build(Type, building->ActLike)) &&
building->Class->ToBuild == RTTI_AIRCRAFTTYPE) {
if (building->IsLeader) return(building);
anybuilding = building;
}
}
return(anybuilding);
}
/***********************************************************************************************
* AircraftTypeClass::Repair_Cost -- Fetchs the cost per repair step. *
* *
* This routine will return the cost for every repair step. *
* *
* INPUT: none *
* *
* OUTPUT: Returns with the credit expense for every repair step. *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 06/26/1995 JLB : Created. *
*=============================================================================================*/
int AircraftTypeClass::Repair_Cost(void) const
{
return(Fixed_To_Cardinal(Cost/(MaxStrength/REPAIR_STEP), REPAIR_PERCENT));
}
/***********************************************************************************************
* AircraftTypeClass::Repair_Step -- Fetches the number of health points per repair. *
* *
* For every repair event, the returned number of health points is acquired. *
* *
* INPUT: none *
* *
* OUTPUT: Returns with the number of health points to recover each repair step. *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 06/26/1995 JLB : Created. *
*=============================================================================================*/
int AircraftTypeClass::Repair_Step(void) const
{
return(REPAIR_STEP);
}
/***********************************************************************************************
* 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 (IsTransporter) {
return(Max_Passengers());
} else {
if (Primary != WEAPON_NONE) {
return(5);
}
}
return(0);
}
/***********************************************************************************************
* 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);
}
/***********************************************************************************************
* ATC::Init -- load up terrain set dependant sidebar icons *
* *
* *
* *
* INPUT: theater type *
* *
* OUTPUT: Nothing *
* *
* WARNINGS: None *
* *
* HISTORY: *
* 4/25/96 0:33AM ST : Created *
*=============================================================================================*/
void AircraftTypeClass::Init(TheaterType theater)
{
if (theater != LastTheater){
if ( Get_Resolution_Factor() ) {
AircraftType index;
char buffer[_MAX_FNAME];
char fullname[_MAX_FNAME+_MAX_EXT];
void const * cameo_ptr;
for (index = AIRCRAFT_FIRST; index < AIRCRAFT_COUNT; index++) {
AircraftTypeClass const & uclass = As_Reference(index);
((void const *&)uclass.CameoData) = NULL;
sprintf(buffer, "%.4sICNH", uclass.IniName);
_makepath (fullname, NULL, NULL, buffer, Theaters[theater].Suffix);
cameo_ptr = MixFileClass::Retrieve(fullname);
if (cameo_ptr){
((void const *&)uclass.CameoData) = cameo_ptr;
}
}
}
}
}
/***********************************************************************************************
* 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
{
width = 21;
height = 20;
}
RTTIType AircraftTypeClass::What_Am_I(void) const {return RTTI_AIRCRAFTTYPE;};

133
TIBERIANDAWN/ABSTRACT.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: F:\projects\c&c\vcs\code\abstract.cpv 2.20 16 Oct 1995 16:49:04 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 : May 22, 1995 [JLB] *
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* AbstractClass::Distance -- Determines distance to target. *
* AbstractTypeClass::AbstractTypeClass -- Constructor for abstract type objects. *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "function.h"
/***********************************************************************************************
* 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(int name, char const * ini)
{
Name = name;
strncpy((char *)IniName, ini, sizeof(IniName));
((char &)IniName[sizeof(IniName)-1]) = '\0';
}
RTTIType AbstractTypeClass::What_Am_I(void) const {return RTTI_ABSTRACTTYPE;};
COORDINATE AbstractTypeClass::Coord_Fixup(COORDINATE coord) const {return coord;}
int AbstractTypeClass::Full_Name(void) const {return Name;};
unsigned short AbstractTypeClass::Get_Ownable(void) const {return 0xffff;};
void AbstractClass::Delete_This(void)
{
/*
** Apparently Watcom preserved the vtable through the virtual destructor chain, otherwise C&C would crash all the time.
**
** MSVC doesn't. It overwrites the vtable pointer with the vtable of the class currently being destructed - presumably to
** prevent virtual functions of the classes already destructed from being called.
**
** So this is a hacky workaround to restore the original vtable pointer after the destructor chain has finished, for when the
** C&C code wants to call a virtual function on an object it just 'deleted'.
**
** ST - 1/9/2019 6:02PM
*/
unsigned long *this_ptr = (unsigned long*) this;
unsigned long vtable_ptr = *this_ptr;
/*
** delete this calls the operator delete, it doesn't actually deallocate the memory.
*/
delete this;
*this_ptr = vtable_ptr;
}

127
TIBERIANDAWN/ABSTRACT.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: F:\projects\c&c\vcs\code\abstract.h_v 2.20 16 Oct 1995 16:46:30 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);
int Distance(CELL coord1, CELL coord2);
COORDINATE As_Coord(TARGET target);
class AbstractTypeClass;
class AbstractClass
{
public:
/*
** The coordinate location of the unit. For vehicles, this is the center
** point. For buildings, it is the upper left corner.
*/
COORDINATE Coord;
/*
** 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;
/*
** Some additional padding in case we need to add data to the class and maintain backwards compatibility for save/load
*/
unsigned char SaveLoadPadding[8];
/*-----------------------------------------------------------------------------------
** Constructor & destructors.
*/
AbstractClass(void) {Coord = 0L;};
virtual ~AbstractClass(void) {};
/*
** Query functions.
*/
virtual HousesType Owner(void) const {return HOUSE_NONE;};
/*
** 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(CELL cell) const {return ::Distance(Coord_Cell(Center_Coord()), cell);};
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) {};
/*
** Workaround for difference between watcom and VC destructor behavior
*/
void Delete_This(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

2550
TIBERIANDAWN/ADATA.CPP Normal file

File diff suppressed because it is too large Load Diff

3539
TIBERIANDAWN/AIRCRAFT.CPP Normal file

File diff suppressed because it is too large Load Diff

256
TIBERIANDAWN/AIRCRAFT.H Normal file
View File

@@ -0,0 +1,256 @@
//
// 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&c\vcs\code\aircraft.h_v 2.17 16 Oct 1995 16:47:48 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"
class AircraftClass : public FootClass, public FlyClass
{
public:
/*
** This is a pointer to the class control structure for the aircraft.
*/
AircraftTypeClass const * const Class;
//-----------------------------------------------------------------------------
void * operator new(size_t);
void operator delete(void *);
operator AircraftType(void) const {return Class->Type;};
AircraftClass(void) : Class(0) {};
AircraftClass(AircraftType classid, HousesType house);
virtual ~AircraftClass(void);
virtual RTTIType What_Am_I(void) const {return RTTI_AIRCRAFT;};
static void Init(void);
enum {FLIGHT_LEVEL=24};
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);
/*
** State machine support routines.
*/
bool Process_Take_Off(void);
bool Process_Landing(void);
int Process_Fly_To(bool slowdown);
/*
** Query functions.
*/
virtual int Threat_Range(int control) const;
virtual int Rearm_Delay(bool second) const;
virtual MoveType Can_Enter_Cell(CELL cell, FacingType facing=FACING_NONE) const;
virtual LayerType In_Which_Layer(void) const;
virtual ObjectTypeClass const & Class_Of(void) const {return *Class;};
virtual ActionType What_Action(ObjectClass * 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;
/*
** Landing zone support functionality.
*/
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;
virtual COORDINATE Fire_Coord(int which) const;
virtual COORDINATE Target_Coord(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 int Exit_Object(TechnoClass *);
virtual bool Mark(MarkType mark=MARK_CHANGE);
virtual short const * Overlap_List(void) const;
virtual void Draw_It(int x, int y, WindowNumberType window);
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 bool Target_Something_Nearby(ThreatType threat=THREAT_NORMAL);
virtual ResultType Take_Damage(int & damage, int distance, WarheadType warhead, TechnoClass * source);
virtual BulletClass * Fire_At(TARGET target, int which);
virtual TARGET As_Target(void) const;
/*
** AI.
*/
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(char *buffer);
static void Write_INI(char *buffer);
static char * INI_Name(void) {return "AIRCRAFT";};
bool Load(FileClass & file);
bool Save(FileClass & file);
virtual void Code_Pointers(void);
virtual void Decode_Pointers(void);
/*
** Dee-buggin' support.
*/
int Validate(void) 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;
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 noticable when the helicopter is hovering.
*/
unsigned char Jitter;
public:
/*
** This is the altitude of the aircraft. It is expressed in pixels that
** the shadow is offset to the south. If the altitude reaches zero, then
** the aircraft has landed. The altitude for normal aircraft is at
** Flight_Level().
*/
int Altitude;
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.
*/
TCountDownTimerClass 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];
/*
** This contains the value of the Virtual Function Table Pointer
*/
static void * VTable;
};
#endif

590
TIBERIANDAWN/ALLOC.CPP Normal file
View File

@@ -0,0 +1,590 @@
//
// 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 A S S O C I A T E S **
***************************************************************************
* *
* Project Name : Westwood Library *
* *
* File Name : ALLOC.CPP *
* *
* Programmer : Joe L. Bostic *
* *
* Start Date : February 1, 1992 *
* *
* Last Update : March 9, 1995 [JLB] *
* *
*-------------------------------------------------------------------------*
* Functions: *
* Alloc -- Allocates system RAM. *
* Ram_Free -- Determines the largest free chunk of RAM. *
* Free -- Free an Alloc'ed block of RAM. *
* Resize_Alloc -- Change the size of an allocated block. *
* Heap_Size -- Size of the heap we have. *
* Total_Ram_Free -- Total amount of free RAM. *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#if (0)
#include <malloc.h>
#include <string.h>
#include <stdlib.h>
#include <dos.h>
#include <bios.h>
#include <stdio.h>
#ifndef WWMEM_H
#include "wwmem.h"
#endif
extern "C" unsigned long Largest_Mem_Block ( void ) ;
//
// use double-word alignment for allocs
//
#define LONG_ALIGNMENT 1
/*
** Define the equates necessary to call a DPMI interrupt.
*/
#define DPMI_INT 0x0031
#define DPMI_LOCK_MEM 0x0600
#define DPMI_UNLOCK_MEM 0x0601
#define LOGGING FALSE
/*=========================================================================*/
/* The following PRIVATE functions are in this file: */
/*=========================================================================*/
/*= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =*/
unsigned long MinRam=0L; // Record of least memory at worst case.
unsigned long MaxRam=0L; // Record of total allocated at worst case.
static unsigned long TotalRam = 0L;
static unsigned long Memory_Calls = 0L;
static unsigned long RequestedSystemRam = 8*1024*1024;
static unsigned long LargestRamBlock = 0L;
void (*Memory_Error)(void) = NULL;
void (*Memory_Error_Exit)(char *string) = NULL;
/***************************************************************************
* DPMI_LOCK -- handles locking a block of DPMI memory *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 06/23/1995 PWG : Created. *
*=========================================================================*/
#include"mono.h"
void DPMI_Lock(VOID const *ptr, long const size)
{
union REGS regs;
struct SREGS sregs;
/*
** Lock memory
** AX = 0x600
** BX:CX = starting linear address of memory to lock
** SI:DI = size of region to lock (in bytes)
** - If Failure, carry flag is set.
*/
memset (&regs, 0 ,sizeof(regs));
segread (&sregs);
regs.x.eax = DPMI_LOCK_MEM;
regs.x.ebx = ((long)ptr & 0xffff0000) >> 16;
regs.x.ecx = ((long)ptr & 0x0000ffff);
regs.x.esi = ((long)size & 0xffff0000) >> 16;
regs.x.edi = ((long)size & 0x0000ffff);
int386x (DPMI_INT, &regs, &regs, &sregs); // call DPMI
// if (regs.x.cflag) {
// }
#if(0)
char *temp = (char *)ptr;
char hold;
for (int lp = 0; lp < size; lp += 2048) {
hold = *temp;
temp += 2048;
}
#endif
}
/***************************************************************************
* DPMI_UNLOCK -- Handles unlocking a locked block of DPMI *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 06/23/1995 PWG : Created. *
*=========================================================================*/
void DPMI_Unlock(void const *ptr, long const size)
{
union REGS regs;
struct SREGS sregs;
/*
** Unlock the memory
*/
memset (&regs, 0 ,sizeof(regs));
segread (&sregs);
regs.x.eax = DPMI_UNLOCK_MEM; // DPMI function to call
regs.x.ebx = ((long)ptr & 0xffff0000) >> 16;
regs.x.ecx = ((long)ptr & 0x0000ffff);
regs.x.esi = ((long)size & 0xffff0000) >> 16;
regs.x.edi = ((long)size & 0x0000ffff);
int386x (DPMI_INT, &regs, &regs, &sregs); // call DPMI
// if (regs.x.cflag) {
// }
}
/***************************************************************************
* Alloc -- Allocates system RAM. *
* *
* This is the basic RAM allocation function. It is used for all *
* memory allocations needed by the system or the main program. *
* *
* INPUT: bytes_to_alloc -- LONG value of the number of bytes to alloc. *
* *
* flags -- Memory allocation control flags. *
* MEM_NORMAL: No special flags. *
* MEM_CLEAR: Zero out memory block. *
* MEM_NEW: Called by a new. *
* *
* OUTPUT: Returns with pointer to allocated block. If NULL was returned *
* it indicates a failure to allocate. Note: NULL will never be *
* returned if the standard library allocation error routine is *
* used. *
* *
* WARNINGS: If you replace the standard memory allocation error routine *
* and make it so that Alloc CAN return with a NULL, be sure *
* and check for this in your code. *
* *
* HISTORY: *
* 09/03/1991 JLB : Documented. *
* 08/09/1993 JLB : Updated with EMS memory support. *
* 04/28/1994 JAW : Updated to 32bit Protected mode. *
* 03/09/1995 JLB : Fixed *
*=========================================================================*/
void *Alloc(unsigned long bytes_to_alloc, MemoryFlagType flags)
{
union REGS regs ;
struct SREGS sregs ;
unsigned char *retval=NULL; // Pointer to allocated block.
unsigned long original_size; // Original allocation size.
unsigned long bytesfree; // Number of free bytes.
long *longptr=NULL; // Pointer used to store selector
static unsigned char _allocinit=0;
//
// Init memory system by finding largest block to alloc
// then allocate it to get one large heap and free it.
// There may be more memory available from DPMI but we only are
// for now allocating and freeing the first largest block.
//
if ( !_allocinit ) {
unsigned long largestblock = Largest_Mem_Block();
largestblock -= 1024; // subtract for heap header and misc
largestblock &= 0xffff0000; // forcing to 64K boundary
if ( largestblock ) {
LargestRamBlock = MIN( largestblock, RequestedSystemRam );
unsigned char *lptr = (unsigned char *)malloc( LargestRamBlock );
if ( lptr ) {
free( (void *)lptr );
}
}
/*
** Initialize the total ram available value.
*/
TotalRam = Total_Ram_Free(MEM_NORMAL);
_allocinit = 1;
}
/*
** Save the original allocated space size so that we can clear the
** exact amount of RAM if they specified MEM_CLEAR.
*/
original_size = bytes_to_alloc;
/*
** Reserve one byte for the header of the memory we allocated.
** We will store the flags variable there for later use.
*/
#if (LONG_ALIGNMENT)
bytes_to_alloc += (flags & MEM_LOCK) ? 8 : 4;
#else
bytes_to_alloc += (flags & MEM_LOCK) ? 5 : 1;
#endif
// Try to allocate the memory out of the protected mode memory
// chain if we did not require a real mode allocation. If this
// fails we will have to try to allocate it out of real mode memory.
// Real mode memory is a last resort because some types of applications
// require real mode memory.
if (!(flags & MEM_REAL)) {
retval = (unsigned char*)malloc(bytes_to_alloc);
}
// Try to allocate the memory out of the real mode memory using DPMI
// service 0x100. Note that retval will be null if we are requesting
// real mode memory so that we do not have to explicitly check for the
// real mode flag. Remember we need to reserve room for the dos
// selector value at the beginning of our allocated block so rather than
// adding fifteen and rounding, we need to add 19 and round.
if (!retval) {
flags = (MemoryFlagType)(flags | MEM_REAL);
regs.x.eax = 0x100;
regs.x.ebx = (bytes_to_alloc + 19) >> 4;
if (regs.x.ebx & 0xFFFF0000) {
retval = NULL;
} else {
segread ( & sregs ) ;
int386x ( 0x31 , & regs, & regs , & sregs ) ;
if (regs.x.cflag)
retval = NULL;
else {
#if (LONG_ALIGNMENT)
longptr = (long *)(((regs.x.eax & 0xFFFF) << 4)+ 4);
#else
longptr = (long *)(((regs.x.eax & 0xFFFF) << 4)+ 1);
#endif
*longptr++ = regs.x.edx & 0xFFFF;
retval = (unsigned char *)longptr;
}
}
}
// If the alloc failed then we need to signify a memory error.
if (retval == NULL) {
if (Memory_Error != NULL)
Memory_Error();
return NULL;
}
// If the memory needs to be DPMI locked then we should store the
// original size in the header before we store the flags.
if (flags & MEM_LOCK) {
longptr = (long *)retval;
*longptr++ = original_size;
retval = (unsigned char *)longptr;
}
// Now that we know the alloc was sucessful (and for an extra byte
// more than the user wanted) we need to stick in the memory flags.
#if (LONG_ALIGNMENT)
if ( !(flags & (MEM_LOCK|MEM_REAL)) ) {
//
// WARNING!!!!!!!!!!
// USE this only with the WATCOM malloc ALLOCATION!!!!!!!!!
// it reads the actual block size before the ptr returned.
// then eors and uses the upper word for a validation later on free.
//
longptr = (long *)retval;
*longptr = ((*(longptr - 1)) ^ 0xffffffff) & 0xffff0000;
*retval++ = flags;
*retval++ = (unsigned char)(flags ^ 0xff);
retval += 2;
}
else {
*retval++ = flags;
*retval++ = (unsigned char)(flags ^ 0xff);
*retval++ = 0;
*retval++ = 0;
}
#else
*retval++ = (unsigned char)(flags | (((flags ^ 0x07) & 0x07) << 5));
#endif
// If the memory needed to be DPMI locked then set it up so it
// is locked.
if (flags & MEM_LOCK) {
DPMI_Lock(retval, original_size);
}
/* Clear the space if they wanted it clear */
if (flags & MEM_CLEAR) {
unsigned char *ptr; // Working memory block pointer.
ptr = retval;
memset(ptr, '\0', original_size);
}
bytesfree = Total_Ram_Free(MEM_NORMAL);
if (bytesfree < MinRam) {
MinRam = bytesfree;
}
if (TotalRam-bytesfree > MaxRam) {
MaxRam = TotalRam-bytesfree;
}
Memory_Calls++;
#if(LOGGING)
int val = _heapchk();
FILE *file = fopen("mem.txt","at");
fprintf(file, "%P Alloc size = %d, Actual Size = %d, flags = %d, heap = %d\n",
retval,
original_size,
bytes_to_alloc,
flags,
val);
fclose(file);
#endif
return(retval);
}
/***************************************************************************
* Free -- Free an Alloc'ed block of RAM. *
* *
* FUNCTION: *
* *
* INPUT: A pointer to a block of RAM from Alloc. *
* *
* OUTPUT: None. *
* *
* WARNINGS: Don't use this for an Alloc_Block'ed RAM block. *
* *
* HISTORY: *
* 05/25/1990 : Created. *
***************************************************************************/
void Free(void const *pointer)
{
union REGS regs ;
struct SREGS sregs ;
void const *original = pointer;
char string[80];
if (pointer) {
/*
** Get a pointer to the flags that we stored off.
*/
#if (LONG_ALIGNMENT)
unsigned char *byteptr = ((unsigned char *)pointer) - 4;
//
// validate the flags with and eor of the flags
//
if ( *byteptr != ((*(byteptr + 1)) ^ 0xff) ) {
if (Memory_Error_Exit != NULL) {
sprintf( string, "Error freeing pointer %p. Header invalid!!!\n", pointer );
Memory_Error_Exit( string );
}
}
else {
if ( !(*byteptr & (MEM_LOCK|MEM_REAL)) ) {
unsigned short *wordptr = (unsigned short *)(byteptr - 2);
//
// WARNING!!!!!!!!!!
// USE this only with the WATCOM malloc ALLOCATION!!!!!!!!!
// it reads the actual block size before the ptr to be freed.
// then compares with the EOR to the value stored during allocation.
//
if ( *wordptr != ((*(wordptr + 2)) ^ 0xffff) ) {
if (Memory_Error_Exit != NULL) {
sprintf( string, "Error freeing pointer %p. Header invalid!!!\n", pointer );
Memory_Error_Exit( string );
}
}
}
else if ( *(byteptr + 2) || *(byteptr + 3) ) {
if (Memory_Error_Exit != NULL) {
sprintf( string, "Error freeing pointer %p. Header invalid!!!\n", pointer );
Memory_Error_Exit( string );
}
}
}
// if ( *byteptr != (*(byteptr + 1) ^ 0xff) ||
// *(byteptr + 2) || *(byteptr + 3) ) {
// if (Memory_Error_Exit != NULL) {
// sprintf( string, "Error freeing pointer %p. Header invalid!!!\n", pointer );
// Memory_Error_Exit( string );
// }
// }
#else
unsigned char *byteptr = ((unsigned char *)pointer) - 1;
if ( (*byteptr & 0xe0) != (((*byteptr ^ 0x07) & 0x07) << 5) ) {
if (Memory_Error_Exit != NULL) {
sprintf( string, "Error freeing pointer %p. Header invalid!!!\n", pointer );
Memory_Error_Exit( string );
}
}
#endif
/*
** Check to see if this was locked me and if it was unlock it.
*/
if (*byteptr & MEM_LOCK) {
long *longptr = ((long *)byteptr) - 1;
DPMI_Unlock(pointer, *longptr);
pointer = (void *)longptr;
} else
pointer = (void *)byteptr;
#if(LOGGING)
int val = _heapchk();
FILE *file = fopen("mem.txt","at");
fprintf(file, "%P Free flags = %d, Heap = %d\n",
original,
*byteptr,
val);
fclose(file);
#endif
// If the pointer is a real mode pointer than it will point to the
// first megabyte of system memory. If it does than we need to
// use DPMI to free it.
if (*byteptr & MEM_REAL) {
regs.x.eax = 0x101;
regs.x.edx = *(((long *)pointer) - 1);
segread ( & sregs ) ;
int386x(0x31, &regs, &regs, &sregs);
} else {
free((void *)pointer);
}
Memory_Calls--;
}
}
/***************************************************************************
* Resize_Alloc -- Change the size of an allocated block. *
* *
* This routine will take a previously allocated block and change its *
* size without unnecessarily altering its contents. *
* *
* INPUT: pointer -- Pointer to the original memory allocation. *
* *
* new_size -- Size in bytes that it will be converted to. *
* *
* OUTPUT: Returns with a pointer to the new allocation. *
* *
* WARNINGS: ??? *
* *
* HISTORY: *
* 02/01/1992 JLB : Commented. *
*=========================================================================*/
void *Resize_Alloc(void *original_ptr, unsigned long new_size_in_bytes)
{
unsigned long *temp;
// unsigned long diff, flags;
temp = (unsigned long*)original_ptr;
/* ReAlloc the space */
temp = (unsigned long *)realloc(temp, new_size_in_bytes);
if (temp == NULL) {
if (Memory_Error != NULL)
Memory_Error();
return NULL;
}
return(temp);
}
/***************************************************************************
* Ram_Free -- Determines the largest free chunk of RAM. *
* *
* Use this routine to determine the largest free chunk of available *
* RAM for allocation. It also performs a check of the memory chain. *
* *
* INPUT: none *
* *
* OUTPUT: Returns with the size of the largest free chunk of RAM. *
* *
* WARNINGS: This does not return the TOTAL memory free, only the *
* largest free chunk. *
* *
* HISTORY: *
* 09/03/1991 JLB : Commented. *
*=========================================================================*/
long Ram_Free(MemoryFlagType)
{
return(_memmax());
// return Largest_Mem_Block();
}
/***************************************************************************
* Heap_Size -- Size of the heap we have. *
* *
* *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 06/21/1994 SKB : Created. *
*=========================================================================*/
long Heap_Size(MemoryFlagType )
{
if (!TotalRam) {
TotalRam = Total_Ram_Free(MEM_NORMAL);
}
return(TotalRam);
}
/***************************************************************************
* Total_Ram_Free -- Total amount of free RAM. *
* *
* *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 06/21/1994 SKB : Created. *
* 03/09/1995 JLB : Uses prerecorded heap size maximum. *
*=========================================================================*/
long Total_Ram_Free(MemoryFlagType )
{
return(_memavl());
// return Largest_Mem_Block () ;
}
#endif

1263
TIBERIANDAWN/ANIM.CPP Normal file

File diff suppressed because it is too large Load Diff

202
TIBERIANDAWN/ANIM.H Normal file
View File

@@ -0,0 +1,202 @@
//
// 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&c\vcs\code\anim.h_v 2.20 16 Oct 1995 16:45:40 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, private StageClass {
public:
static void * AnimClass::operator new(size_t size);
static void AnimClass::operator delete(void *ptr);
AnimClass(void) : Class(0) {Owner=HOUSE_NONE;Object=0;}; // Default constructor does nothing.
AnimClass(AnimType animnum, COORDINATE coord, unsigned char timedelay=0, unsigned char loop=1, bool alt=false);
virtual ~AnimClass(void);
operator AnimType(void) const {return Class->Type;};
virtual RTTIType What_Am_I(void) const {return RTTI_ANIM;};
/*---------------------------------------------------------------------
** 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;};
/*
** 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);
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(void) const;
virtual short const * Overlap_List(void) const;
virtual void Draw_It(int x, int y, WindowNumberType window);
virtual void AI(void);
virtual TARGET As_Target(void) const;
virtual void Detach(TARGET target, bool all);
/*
** File I/O.
*/
bool Load(FileClass & file);
bool Save(FileClass & file);
virtual void Code_Pointers(void);
virtual void Decode_Pointers(void);
/*
** Dee-buggin' support.
*/
int Validate(void) const;
/*
** 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.
*/
ObjectClass * Object;
/*
** 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 Owner;
/*
** 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:
/*
** Define a function to make adjustments for where special animations
** are going to render.
*/
COORDINATE Adjust_Coord(COORDINATE coord);
/*
** 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;
// Use alternate color when drawing?
unsigned IsAlternate: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 syncronised. It will not be displayed.
*/
unsigned IsInvisible:1;
/*
** 2019/09/19 JAS
** Flags storing which players can see this anim.
*/
unsigned VisibleFlags;
/*
** This points to the type of animation object this is.
*/
AnimTypeClass const * const Class;
/*
** Is this animation in a temporary suspended state? If so, then it won't
** be rendered until this flag is false. The flag will be set to false
** after the first countdown timer reaches 0.
*/
unsigned char 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.
*/
unsigned char Accum;
/*
** This contains the value of the Virtual Function Table Pointer
*/
static void * VTable;
/*
** This points to the virtual animation.
*/
AnimClass * VirtualAnim;
/*
** 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

636
TIBERIANDAWN/AUDIO.CPP Normal file
View File

@@ -0,0 +1,636 @@
//
// 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&c\vcs\code\audio.cpv 2.17 16 Oct 1995 16:50:20 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 : May 4, 1995 [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. *
* Stop_Speaking -- Forces the EVA voice to stop talking. *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#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_JUV, // Juvenile sound effect alternate option.
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] = {
/*
** Special voices (typically associated with the commando).
*/
{"BOMBIT1", 20, IN_NOVAR}, // VOC_RAMBO_PRESENT "I've got a present for ya"
{"CMON1", 20, IN_NOVAR}, // VOC_RAMBO_CMON "c'mon"
{"GOTIT1", 20, IN_NOVAR}, // VOC_RAMBO_UGOTIT "you got it" *
{"KEEPEM1", 20, IN_NOVAR}, // VOC_RAMBO_COMIN "keep 'em commin'"
{"LAUGH1", 20, IN_NOVAR}, // VOC_RAMBO_LAUGH "hahaha"
{"LEFTY1", 20, IN_NOVAR}, // VOC_RAMBO_LEFTY "that was left handed" *
{"NOPRBLM1", 20, IN_NOVAR}, // VOC_RAMBO_NOPROB "no problem"
// {"OHSH1", 20, IN_NOVAR}, // VOC_RAMBO_OHSH "oh shiiiiii...."
{"ONIT1", 20, IN_NOVAR}, // VOC_RAMBO_ONIT "I'm on it"
{"RAMYELL1", 20, IN_NOVAR}, // VOC_RAMBO_YELL "ahhhhhhh"
{"ROKROLL1", 20, IN_NOVAR}, // VOC_RAMBO_ROCK "time to rock and roll"
{"TUFFGUY1", 20, IN_NOVAR}, // VOC_RAMBO_TUFF "real tuff guy" *
{"YEAH1", 20, IN_NOVAR}, // VOC_RAMBO_YEA "yea" *
{"YES1", 20, IN_NOVAR}, // VOC_RAMBO_YES "yes" *
{"YO1", 20, IN_NOVAR}, // VOC_RAMBO_YO "yo"
/*
** 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
/*
** Infantry and vehicle responses.
*/
{"2DANGR1", 10, IN_VAR}, // VOC_2DANGER "negative, too dangerous"
{"ACKNO", 10, IN_VAR}, // VOC_ACKNOWL "acknowledged"
{"AFFIRM1", 10, IN_VAR}, // VOC_AFFIRM "affirmative"
{"AWAIT1", 10, IN_VAR}, // VOC_AWAIT1 "awaiting orders"
// {"BACKUP", 10, IN_VAR}, // VOC_BACKUP "send backup"
// {"HELP", 10, IN_VAR}, // VOC_HELP "send help"
{"MOVOUT1", 10, IN_VAR}, // VOC_MOVEOUT "movin' out"
{"NEGATV1", 10, IN_VAR}, // VOC_NEGATIVE "negative"
{"NOPROB", 10, IN_VAR}, // VOC_NO_PROB "not a problem"
{"READY", 10, IN_VAR}, // VOC_READY "ready and waiting"
{"REPORT1", 10, IN_VAR}, // VOC_REPORT "reporting"
{"RITAWAY", 10, IN_VAR}, // VOC_RIGHT_AWAY "right away sir"
{"ROGER", 10, IN_VAR}, // VOC_ROGER "roger"
// {"SIR1", 10, IN_VAR}, // VOC_SIR1 "sir?"
// {"SQUAD1", 10, IN_VAR}, // VOC_SQUAD1 "squad reporting"
// {"TARGET1", 10, IN_VAR}, // VOC_PRACTICE "target practice"
{"UGOTIT", 10, IN_VAR}, // VOC_UGOTIT "you got it"
{"UNIT1", 10, IN_VAR}, // VOC_UNIT1 "unit reporting"
{"VEHIC1", 10, IN_VAR}, // VOC_VEHIC1 "vehicle reporting"
{"YESSIR1", 10, IN_VAR}, // VOC_YESSIR "yes sir"
/*
** Sound effects that have a juvenile counterpart.
*/
{"BAZOOK1", 1, IN_JUV}, // VOC_BAZOOKA Gunfire
{"BLEEP2", 1, IN_JUV}, // VOC_BLEEP Clean metal bing
{"BOMB1", 1, IN_JUV}, // VOC_BOMB1 Crunchy parachute bomb type explosion
{"BUTTON", 1, IN_JUV}, // VOC_BUTTON Dungeon Master button click
{"COMCNTR1", 10, IN_JUV}, // VOC_RADAR_ON Elecronic static with beeps
{"CONSTRU2", 10, IN_JUV}, // VOC_CONSTRUCTION construction sounds
{"CRUMBLE", 1, IN_JUV}, // VOC_CRUMBLE muffled crumble sound
{"FLAMER2", 4, IN_JUV}, // VOC_FLAMER1 flame thrower
{"GUN18", 4, IN_JUV}, // VOC_RIFLE rifle shot
{"GUN19", 4, IN_JUV}, // VOC_M60 machine gun burst -- 6 rounds
{"GUN20", 4, IN_JUV}, // VOC_GUN20 bat hitting heavy metal door
{"GUN5", 4, IN_JUV}, // VOC_M60A medium machine gun burst
{"GUN8", 4, IN_JUV}, // VOC_MINI mini gun burst
{"GUNCLIP1", 1, IN_JUV}, // VOC_RELOAD gun clip reload
{"HVYDOOR1", 5, IN_JUV}, // VOC_SLAM metal plates slamming together
{"HVYGUN10", 1, IN_JUV}, // VOC_HVYGUN10 loud sharp cannon
{"ION1", 1, IN_JUV}, // VOC_ION_CANNON partical beam
{"MGUN11", 1, IN_JUV}, // VOC_MGUN11 alternate tripple burst
{"MGUN2", 1, IN_JUV}, // VOC_MGUN2 M-16 tripple burst
{"NUKEMISL", 1, IN_JUV}, // VOC_NUKE_FIRE long missile sound
{"NUKEXPLO", 1, IN_JUV}, // VOC_NUKE_EXPLODE long but not loud explosion
{"OBELRAY1", 1, IN_JUV}, // VOC_LASER humming laser beam
{"OBELPOWR", 1, IN_JUV}, // VOC_LASER_POWER warming-up sound of laser beam
{"POWRDN1", 1, IN_JUV}, // VOC_RADAR_OFF doom door slide
{"RAMGUN2", 1, IN_JUV}, // VOC_SNIPER silenced rifle fire
{"ROCKET1", 1, IN_JUV}, // VOC_ROCKET1 rocket launch variation #1
{"ROCKET2", 1, IN_JUV}, // VOC_ROCKET2 rocket launch variation #2
{"SAMMOTR2", 1, IN_JUV}, // VOC_MOTOR dentists drill
{"SCOLD2", 1, IN_JUV}, // VOC_SCOLD cannot perform action feedback tone
{"SIDBAR1C", 1, IN_JUV}, // VOC_SIDEBAR_OPEN xylophone clink
{"SIDBAR2C", 1, IN_JUV}, // VOC_SIDEBAR_CLOSE xylophone clink
{"SQUISH2", 1, IN_JUV}, // VOC_SQUISH2 crushing infantry
{"TNKFIRE2", 1, IN_JUV}, // VOC_TANK1 sharp tank fire with recoil
{"TNKFIRE3", 1, IN_JUV}, // VOC_TANK2 sharp tank fire
{"TNKFIRE4", 1, IN_JUV}, // VOC_TANK3 sharp tank fire
{"TNKFIRE6", 1, IN_JUV}, // VOC_TANK4 big gun tank fire
{"TONE15", 0, IN_JUV}, // VOC_UP credits counting up
{"TONE16", 0, IN_JUV}, // VOC_DOWN credits counting down
{"TONE2", 1, IN_JUV}, // VOC_TARGET target sound
{"TONE5", 10, IN_JUV}, // VOC_SONAR sonar echo
{"TOSS", 1, IN_JUV}, // VOC_TOSS air swish
{"TRANS1", 1, IN_JUV}, // VOC_CLOAK stealth tank
{"TREEBRN1", 1, IN_JUV}, // VOC_BURN burning crackle
{"TURRFIR5", 1, IN_JUV}, // VOC_TURRET muffled gunfire
{"XPLOBIG4", 5, IN_JUV}, // VOC_XPLOBIG4 very long muffled explosion
{"XPLOBIG6", 5, IN_JUV}, // VOC_XPLOBIG6 very long muffled explosion
{"XPLOBIG7", 5, IN_JUV}, // VOC_XPLOBIG7 very long muffled explosion
{"XPLODE", 1, IN_JUV}, // VOC_XPLODE long soft muffled explosion
{"XPLOS", 4, IN_JUV}, // VOC_XPLOS short crunchy explosion
{"XPLOSML2", 5, IN_JUV}, // VOC_XPLOSML2 muffled mechanical explosion
/*
** Generic sound effects (no variations).
*/
{"NUYELL1", 10, IN_NOVAR}, // VOC_SCREAM1 short infantry scream
{"NUYELL3", 10, IN_NOVAR}, // VOC_SCREAM3 short infantry scream
{"NUYELL4", 10, IN_NOVAR}, // VOC_SCREAM4 short infantry scream
{"NUYELL5", 10, IN_NOVAR}, // VOC_SCREAM5 short infantry scream
{"NUYELL6", 10, IN_NOVAR}, // VOC_SCREAM6 short infantry scream
{"NUYELL7", 10, IN_NOVAR}, // VOC_SCREAM7 short infantry scream
{"NUYELL10", 10, IN_NOVAR}, // VOC_SCREAM10 short infantry scream
{"NUYELL11", 10, IN_NOVAR}, // VOC_SCREAM11 short infantry scream
{"NUYELL12", 10, IN_NOVAR}, // VOC_SCREAM12 short infantry scream
{"YELL1", 1, IN_NOVAR}, // VOC_YELL1 long infantry scream
{"MYES1", 10, IN_NOVAR}, // VOC_YES "Yes?"
{"MCOMND1", 10, IN_NOVAR}, // VOC_COMMANDER "Commander?"
{"MHELLO1", 10, IN_NOVAR}, // VOC_HELLO "Hello?"
{"MHMMM1", 10, IN_NOVAR}, // VOC_HMMM "Hmmm?"
// {"MHASTE1", 10, IN_NOVAR}, // VOC_PROCEED1 "I will proceed, post haste."
// {"MONCE1", 10, IN_NOVAR}, // VOC_PROCEED2 "I will proceed, at once."
// {"MIMMD1", 10, IN_NOVAR}, // VOC_PROCEED3 "I will proceed, immediately."
// {"MPLAN1", 10, IN_NOVAR}, // VOC_EXCELLENT1 "That is an excellent plan."
// {"MPLAN2", 10, IN_NOVAR}, // VOC_EXCELLENT2 "Yes, that is an excellent plan."
{"MPLAN3", 10, IN_NOVAR}, // VOC_EXCELLENT3 "A wonderful plan."
// {"MACTION1", 10, IN_NOVAR}, // VOC_EXCELLENT4 "Astounding plan of action commander."
// {"MREMARK1", 10, IN_NOVAR}, // VOC_EXCELLENT5 "Remarkable contrivance."
{"MCOURSE1", 10, IN_NOVAR}, // VOC_OF_COURSE "Of course."
{"MYESYES1", 10, IN_NOVAR}, // VOC_YESYES "Yes yes yes."
{"MTIBER1", 10, IN_NOVAR}, // VOC_QUIP1 "Mind the Tiberium."
// {"MMG1", 10, IN_NOVAR}, // VOC_QUIP2 "A most remarkable Metasequoia Glyptostroboides."
{"MTHANKS1", 10, IN_NOVAR}, // VOC_THANKS "Thank you."
{"CASHTURN", 1, IN_NOVAR}, // VOC_CASHTURN Sound of money being piled up.
{"BLEEP2", 10, IN_NOVAR}, // VOC_BLEEPY3 Clean computer bleep sound.
{"DINOMOUT", 10, IN_NOVAR}, // VOC_DINOMOUT Movin' out in dino-speak.
{"DINOYES", 10, IN_NOVAR}, // VOC_DINOYES Yes Sir in dino-speak.
{"DINOATK1", 10, IN_NOVAR}, // VOC_DINOATK1 Dino attack sound.
{"DINODIE1", 10, IN_NOVAR}, // VOC_DINODIE1 Dino die sound.
#ifdef PETROGLYPH_EXAMPLE_MOD
{"NUKE_LOB", 10, IN_NOVAR} // VOC_NUKE_LOB Mod expansion unit firing sound
#endif //PETROGLYPH_EXAMPLE_MOD
};
//
// External handlers. ST - 2/20/2019 3:41PM
//
extern void On_Sound_Effect(int sound_index, int variation, COORDINATE coord);
// 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);
/***********************************************************************************************
* 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. *
* *
* OUTPUT: none *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 11/12/1994 JLB : Created. *
* 01/05/1995 JLB : Reduces sound more dramatically when off screen. *
*=============================================================================================*/
void Sound_Effect(VocType voc, COORDINATE coord, int variation)
{
//
// Intercept sound effect calls. ST - 2/20/2019 3:37PM
//
On_Sound_Effect((int)voc, variation, coord);
#if (0)
unsigned distance;
CELL cell_pos;
int pan_value;
if (!Options.Volume || voc == VOC_NONE || !SoundOn || SampleType == SAMPLE_NONE) {
return;
}
if (coord) {
cell_pos = Coord_Cell(coord);
}
distance = 0xFF;
pan_value = 0;
if (coord && !Map.In_View(cell_pos)) {
distance = Map.Cell_Distance(cell_pos, Coord_Cell(Map.TacticalCoord));
distance = (unsigned int)MIN((int)distance, (int)MAP_CELL_W);
distance = Cardinal_To_Fixed(MAP_CELL_W, distance);
distance = MIN(distance, 0xFFu);
distance ^= 0xFF;
distance /= 2;
distance = MAX(distance, 25U);
pan_value = Cell_X(cell_pos);
pan_value -= Coord_XCell(Map.TacticalCoord) + (Lepton_To_Cell(Map.TacLeptonWidth) >> 1);
if (ABS(pan_value) > Lepton_To_Cell(Map.TacLeptonWidth >> 1)) {
pan_value *= 0x8000;
pan_value /= (MAP_CELL_W >> 2);
pan_value = Bound(pan_value, -0x7FFF, 0x7FFF);
// pan_value = MAX((int)pan_value, (int)-0x7FFF);
// pan_value = MIN((int)pan_value, 0x7FFF);
} else {
pan_value = 0;
}
}
Sound_Effect(voc, (VolType)Fixed_To_Cardinal(distance, Options.Volume), variation, pan_value);
#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. *
* *
* 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. *
*=============================================================================================*/
int Sound_Effect(VocType voc, VolType volume, int variation, signed short pan_value)
{
char name[_MAX_FNAME+_MAX_EXT]; // Working filename of sound effect.
if (!Options.Volume || voc == VOC_NONE || !SoundOn || SampleType == SAMPLE_NONE) {
return(-1);
}
/*
** Fetch a pointer to the sound effect data. Modify the sound as appropriate and desired.
*/
char const * ext = ".AUD";
if (Special.IsJuvenile && SoundEffectName[voc].Where == IN_JUV) {
ext = ".JUV";
} else {
if (SoundEffectName[voc].Where == IN_VAR) {
/*
** 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";
}
}
}
}
_makepath(name, NULL, NULL, SoundEffectName[voc].Name, ext);
void const * ptr = MixFileClass::Retrieve(name);
/*
** If the sound data pointer is not null, then presume that it is valid.
*/
if (ptr) {
return(Play_Sample(ptr, Fixed_To_Cardinal(SoundEffectName[voc].Priority, (int)volume), (int)volume, pan_value));
}
return(-1);
}
/*
** This elaborates all the EVA speech voices.
*/
char const * Speech[VOX_COUNT] = {
"ACCOM1", // mission accomplished
"FAIL1", // your mission has failed
"BLDG1", // unable to comply, building in progress
"CONSTRU1", // construction complete
"UNITREDY", // unit ready
"NEWOPT1", // new construction options
"DEPLOY1", // cannot deploy here
"GDIDEAD1", // GDI unit destroyed
"NODDEAD1", // Nod unit destroyed
"CIVDEAD1", // civilian killed
// "EVAYES1", // affirmative
// "EVANO1", // negative
// "UPUNIT1", // upgrade complete, new unit available
// "UPSTRUC1", // upgrade complete, new structure available
"NOCASH1", // insufficient funds
"BATLCON1", // battle control terminated
"REINFOR1", // reinforcements have arrived
"CANCEL1", // canceled
"BLDGING1", // building
"LOPOWER1", // low power
"NOPOWER1", // insufficient power
"MOCASH1", // need more funds
"BASEATK1", // our base is under attack
"INCOME1", // incoming missile
"ENEMYA", // enemy planes approaching
"NUKE1", // nuclear warhead approaching - VOX_INCOMING_NUKE
// "RADOK1", // radiation levels are acceptable
// "RADFATL1", // radiation levels are fatal
"NOBUILD1", // unable to build more
"PRIBLDG1", // primary building selected
// "REPDONE1", // repairs completed
"NODCAPT1", // Nod building captured
"GDICAPT1", // GDI building captured
// "SOLD1", // structure sold
"IONCHRG1", // ion cannon charging
"IONREDY1", // ion cannon ready
"NUKAVAIL", // nuclear weapon available
"NUKLNCH1", // nuclear weapon launched - VOX_NUKE_LAUNCHED
"UNITLOST", // unit lost
"STRCLOST", // structure lost
"NEEDHARV", // need harvester
"SELECT1", // select target
"AIRREDY1", // airstrike ready
"NOREDY1", // not ready
"TRANSSEE", // Nod transport sighted
"TRANLOAD", // Nod transport loaded
"ENMYAPP1", // enemy approaching
"SILOS1", // silos needed
"ONHOLD1", // on hold
"REPAIR1", // repairing
"ESTRUCX", // enemy structure destroyed
"GSTRUC1", // GDI structure destroyed
"NSTRUC1", // NOD structure destroyed
"ENMYUNIT", // Enemy unit destroyed
// "GUKILL1", // gold unit destroyed
// "GSTRUD1", // gold structure destroyed
// "GONLINE1", // gold player online
// "GLEFT1", // gold player has departed
// "GOLDKILT", // gold player destroyed
// "GOLDWIN", // gold player is victorious
// "RUKILL1", // red unit destroyed
// "RSTRUD1", // red structure destroyed
// "RONLINE1", // red player online
// "RLEFT1", // red player has departed
// "REDKILT", // red player destroyed
// "REDWIN", // red player is victorious
// "GYUKILL1", // grey unit destroyed
// "GYSTRUD1", // grey structure destroyed
// "GYONLINE", // grey player online
// "GYLEFT1", // grey player has departed
// "GREYKILT", // grey player destroyed
// "GREYWIN", // grey player is victorious
// "OUKILL1", // orange unit destroyed
// "OSTRUD1", // orange structure destroyed
// "OONLINE1", // orange player online
// "OLEFT1", // orange player has departed
// "ORANKILT", // orange player destroyed
// "ORANWIN", // orange player is victorious
// "GNUKILL1", // green unit destroyed
// "GNSTRUD1", // green structure destroyed
// "GNONLINE", // green player online
// "GNLEFT1", // green player has departed
// "GRENKILT", // green player destroyed
// "GRENWIN", // green player is victorious
// "BUKILL1", // blue unit destroyed
// "BSTRUD1", // blue structure destroyed
// "BONLINE1", // blue player online
// "BLEFT1", // blue player has departed
// "BLUEKILT", // blue player destroyed
// "BLUEWIN" // blue player is victorious
};
static VoxType CurrentVoice = VOX_NONE;
/***********************************************************************************************
* 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, HouseClass *house, COORDINATE coord)
{
// MBL 02.22.2019
if (voice == VOX_NONE)
{
return;
}
//
// Intercept speech calls. ST - 2/20/2019 3:37PM
//
// On_Speech((int)voice); // MBL 02.06.2020
On_Speech((int)voice, house);
if (coord) {
On_Ping(house, coord);
}
#if (0)
if (Options.Volume && SampleType != 0 && voice != VOX_NONE && voice != SpeakQueue && voice != CurrentVoice && SpeakQueue == VOX_NONE) {
SpeakQueue = voice;
}
#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. *
*=============================================================================================*/
void Speak_AI(void)
{
// MBL 06.17.2019 KO
#if 0
static VoxType _last = VOX_NONE;
if (SampleType == 0) return;
if (!Is_Sample_Playing(SpeechBuffer)) {
CurrentVoice = VOX_NONE;
if (SpeakQueue != VOX_NONE) {
if (SpeakQueue != _last) {
char name[_MAX_FNAME+_MAX_EXT];
_makepath(name, NULL, NULL, Speech[SpeakQueue], ".AUD");
if (CCFileClass(name).Read(SpeechBuffer, SPEECH_BUFFER_SIZE)) {
Play_Sample(SpeechBuffer, 254, Options.Volume);
}
_last = SpeakQueue;
} else {
Play_Sample(SpeechBuffer, 254, Options.Volume);
}
SpeakQueue = VOX_NONE;
}
}
#endif
}
/***********************************************************************************************
* 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;
if (SampleType != 0) {
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 (SampleType != 0 && (SpeakQueue != VOX_NONE || Is_Sample_Playing(SpeechBuffer))) {
return(true);
}
return(false);
}

96
TIBERIANDAWN/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&c\vcs\code\audio.h_v 2.18 16 Oct 1995 16:45:34 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

521
TIBERIANDAWN/BASE.CPP Normal file
View File

@@ -0,0 +1,521 @@
//
// 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&c\vcs\code\base.cpv 1.9 16 Oct 1995 16:48:56 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 : March 27, 1995 *
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* BaseClass::Get_Building -- Returns ptr to the built building for the given node *
* 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 -- INI writing routine *
* 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 && Coord == node.Coord);
}
/***********************************************************************************************
* 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(Type != node.Type || Coord != node.Coord);
}
/***********************************************************************************************
* 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::Read_INI -- INI reading routine *
* *
* INI entry format: *
* BLDG=COORD *
* BLDG=COORD *
* ... *
* *
* 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. *
*=============================================================================================*/
void BaseClass::Read_INI(char *buffer)
{
char buf[128];
char uname[10];
BaseNodeClass node; // node to add to list
/*
** First, determine the house of the human player, and set the Base's house
** accordingly.
*/
WWGetPrivateProfileString("BASIC", "Player", "GoodGuy", buf, 20, buffer);
if (HouseTypeClass::From_Name(buf) == HOUSE_GOOD) {
House = HOUSE_BAD;
} else {
House = HOUSE_GOOD;
}
/*
** Read the number of buildings that will go into the base node list
*/
int count = WWGetPrivateProfileInt (INI_Name(),"Count",0,buffer);
/*
** 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);
WWGetPrivateProfileString(INI_Name(), uname, NULL, buf, sizeof(buf)-1, buffer);
/*
** Set the node's building type
*/
node.Type = BuildingTypeClass::From_Name(strtok(buf,","));
/*
** Read & set the node's coordinate
*/
node.Coord = atol(strtok(NULL,","));
/*
** Add this node to the Base's list
*/
Nodes.Add(node);
}
}
/***********************************************************************************************
* BaseClass::Write_INI -- INI writing routine *
* *
* INI entry format: *
* BLDG=COORD *
* BLDG=COORD *
* ... *
* *
* INPUT: *
* buffer pointer to loaded INI file staging area *
* *
* OUTPUT: *
* none. *
* *
* WARNINGS: *
* This routines assumes there is only one base defined for the scenario. *
* *
* HISTORY: *
* 03/24/1995 BRR : Created. *
*=============================================================================================*/
void BaseClass::Write_INI(char *buffer)
{
char buf[128];
char uname[10];
/*
** Clear out all existing teamtype data from the INI file.
*/
WWWritePrivateProfileString(INI_Name(), NULL, NULL, buffer);
/*
** 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.
*/
WWWritePrivateProfileInt (INI_Name(),"Count",Nodes.Count(),buffer);
/*
** Write each entry into the INI
*/
for (int i = 0; i < Nodes.Count(); i++) {
sprintf(uname,"%03d",i);
sprintf(buf,"%s,%d",
BuildingTypeClass::As_Reference(Nodes[i].Type).IniName,
Nodes[i].Coord);
WWWritePrivateProfileString(INI_Name(), uname, buf, buffer);
}
}
/***********************************************************************************************
* 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. *
*=============================================================================================*/
bool BaseClass::Load(FileClass &file)
{
int num_struct;
int i;
BaseNodeClass node;
/*
** Read in & check the size of this class
*/
if (file.Read(&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.Read(&House,sizeof(House)) != sizeof(House)) {
return(false);
}
if (file.Read(&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.Read(&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. *
*=============================================================================================*/
bool BaseClass::Save(FileClass &file)
{
int num_struct;
int i;
BaseNodeClass node;
/*
** Write the size of this class
*/
i = sizeof(*this);
if (file.Write(&i,sizeof(i)) != sizeof(i)) {
return(false);
}
/*
** Write the House & the number of structures in the base
*/
if (file.Write(&House,sizeof(House)) != sizeof(House)) {
return(false);
}
num_struct = Nodes.Count();
if (file.Write(&num_struct,sizeof(num_struct)) != sizeof(num_struct)) {
return(false);
}
/*
** Write each node entry
*/
for (i = 0; i < num_struct; i++) {
node = Nodes[i];
if (file.Write(&node,sizeof(node)) != sizeof(node)) {
return(false);
}
}
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)
{
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. *
*=============================================================================================*/
BuildingClass * BaseClass::Get_Building(int index)
{
BuildingClass *bldg;
ObjectClass *obj[4];
/*
** Check the location on the map where this building should be; if it's
** there, return a pointer to it.
*/
CELL cell = Coord_Cell(Nodes[index].Coord);
obj[0] = Map[cell].Cell_Building();
obj[1] = Map[cell].Overlapper[0];
obj[2] = Map[cell].Overlapper[1];
obj[3] = Map[cell].Overlapper[2];
bldg = NULL;
for (int i = 0; i < 4; i++) {
if (obj[i] &&
obj[i]->Coord == Nodes[index].Coord &&
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 *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 *obj)
{
for (int i = 0; i < Nodes.Count(); i++) {
if (obj->Class->Type == Nodes[i].Type && obj->Coord == Nodes[i].Coord) {
return(&Nodes[i]);
}
}
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);
}

124
TIBERIANDAWN/BASE.H Normal file
View File

@@ -0,0 +1,124 @@
//
// 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&c\vcs\code\base.h_v 1.12 16 Oct 1995 16:46:38 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 COORD to build it at.
*/
class BaseNodeClass
{
public:
BaseNodeClass(void) {};
int operator == (BaseNodeClass const & node);
int operator != (BaseNodeClass const & node);
int operator > (BaseNodeClass const & node);
StructType Type;
COORDINATE Coord;
};
/****************************************************************************
** 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) {Nodes.Clear();}
/**********************************************************************
** The standard suite of load/save support routines
*/
void Read_INI(char *buffer);
void Write_INI(char *buffer);
static char *INI_Name(void) {return "Base";}
bool Load(FileClass & file);
bool Save(FileClass & file);
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);
/**********************************************************************
** Returns a pointer to the object for the given node
*/
BuildingClass * Get_Building(int index);
/**********************************************************************
** Tells if the given building ptr is a node in this base's list.
*/
bool Is_Node (BuildingClass *obj);
/**********************************************************************
** Returns a pointer to the requested node.
*/
BaseNodeClass * Get_Node(BuildingClass *obj);
BaseNodeClass * Get_Node(int index) { return (&Nodes[index]); }
/**********************************************************************
** 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

636
TIBERIANDAWN/BBDATA.CPP Normal file
View File

@@ -0,0 +1,636 @@
//
// 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&c\vcs\code\bbdata.cpv 2.17 16 Oct 1995 16:49:46 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 : October 17, 1994 [JLB] *
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* BulletTypeClass::BulletTypeClass -- Constructor for bullet type objects. *
* BulletTypeClass::Load_Shapes -- Load shape data for bullet types. *
* BulletTypeClass::One_Time -- Performs the one time processing for bullets. *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "function.h"
/***************************************************************************
** Detailed information about each class of bullet (projectile) in the game.
*/
static BulletTypeClass const ClassSniper(
BULLET_BULLET,
"50cal", // NAME: Text name of this unit type.
false, // Flies over tall walls?
false, // Homes in on target?
false, // Projectile arcs to the target?
false, // Is this a dropping bomb-like object?
true, // Is this projectile invisible?
false, // Will it blow up even if it gets just NEAR to target?
false, // Does it have flickering flame animation?
false, // Can it run out of fuel?
true, // Is there no visual difference between projectile facings?
false, // Is projectile inherently inaccurate?
false, // Translucent colors are used?
false, // Good against aircraft?
0, // ARMING: Time to arm projectile after launch.
0, // RANGE: Inherent override range factor.
MPH_LIGHT_SPEED, // SPEED: Miles per hour.
0, // ROT: Rate of turn (degrees per tick).
WARHEAD_HOLLOW_POINT, // WARHEAD: If fires weapon, warhead type
ANIM_PIFF // Explosion to use upon impact.
);
static BulletTypeClass const ClassBullet(
BULLET_BULLET,
"50cal", // NAME: Text name of this unit type.
false, // Flies over tall walls?
false, // Homes in on target?
false, // Projectile arcs to the target?
false, // Is this a dropping bomb-like object?
true, // Is this projectile invisible?
false, // Will it blow up even if it gets just NEAR to target?
false, // Does it have flickering flame animation?
false, // Can it run out of fuel?
true, // Is there no visual difference between projectile facings?
false, // Is projectile inherently inaccurate?
false, // Translucent colors are used?
false, // Good against aircraft?
0, // ARMING: Time to arm projectile after launch.
0, // RANGE: Inherent override range factor.
MPH_LIGHT_SPEED, // SPEED: Miles per hour.
0, // ROT: Rate of turn (degrees per tick).
WARHEAD_SA, // WARHEAD: If fires weapon, warhead type
ANIM_PIFF // Explosion to use upon impact.
);
static BulletTypeClass const ClassSpreadfire(
BULLET_SPREADFIRE,
"50cal", // NAME: Text name of this unit type.
true, // Flies over tall walls?
false, // Homes in on target?
false, // Projectile arcs to the target?
false, // Is this a dropping bomb-like object?
true, // Is this projectile invisible?
false, // Will it blow up even if it gets just NEAR to target?
false, // Does it have flickering flame animation?
false, // Can it run out of fuel?
true, // Is there no visual difference between projectile facings?
false, // Is projectile inherently inaccurate?
false, // Translucent colors are used?
false, // Good against aircraft?
0, // ARMING: Time to arm projectile after launch.
0, // RANGE: Inherent override range factor.
MPH_LIGHT_SPEED, // SPEED: Miles per hour.
0, // ROT: Rate of turn (degrees per tick).
WARHEAD_HE, // WARHEAD: If fires weapon, warhead type
ANIM_PIFFPIFF // Explosion to use upon impact.
);
static BulletTypeClass const ClassAPDS(
BULLET_APDS,
"120mm", // NAME: Text name of this unit type.
false, // Flies over tall walls?
false, // Homes in on target?
false, // Projectile arcs to the target?
false, // Is this a dropping bomb-like object?
false, // Is this projectile invisible?
false, // Will it blow up even if it gets just NEAR to target?
false, // Does it have flickering flame animation?
false, // Can it run out of fuel?
true, // Is there no visual difference between projectile facings?
false, // Is projectile inherently inaccurate?
false, // Translucent colors are used?
false, // Good against aircraft?
0, // ARMING: Time to arm projectile after launch.
0, // RANGE: Inherent override range factor.
MPH_VERY_FAST, // SPEED: Miles per hour.
0, // ROT: Rate of turn (degrees per tick).
WARHEAD_AP, // WARHEAD: If fires weapon, warhead type
ANIM_VEH_HIT3 // Explosion to use upon impact.
);
static BulletTypeClass const Class120mm(
BULLET_HE,
"120mm", // NAME: Text name of this unit type.
true, // Flies over tall walls?
false, // Homes in on target?
true, // Projectile arcs to the target?
false, // Is this a dropping bomb-like object?
false, // Is this projectile invisible?
false, // Will it blow up even if it gets just NEAR to target?
false, // Does it have flickering flame animation?
false, // Can it run out of fuel?
true, // Is there no visual difference between projectile facings?
true, // Is projectile inherently inaccurate?
false, // Translucent colors are used?
false, // Good against aircraft?
0, // ARMING: Time to arm projectile after launch.
0, // RANGE: Inherent override range factor.
MPH_MEDIUM_FAST, // SPEED: Miles per hour.
0, // ROT: Rate of turn (degrees per tick).
WARHEAD_HE, // WARHEAD: If fires weapon, warhead type
ANIM_ART_EXP1 // Explosion to use upon impact.
);
static BulletTypeClass const ClassMissile(
BULLET_SSM,
"DRAGON", // NAME: Text name of this unit type.
true, // Flies over tall walls?
true, // Homes in on target?
false, // Projectile arcs to the target?
false, // Is this a dropping bomb-like object?
false, // Is this projectile invisible?
true, // Will it blow up even if it gets just NEAR to target?
true, // Does it have flickering flame animation?
true, // Can it run out of fuel?
false, // Is there no visual difference between projectile facings?
true, // Is projectile inherently inaccurate?
true, // Translucent colors are used?
true, // Good against aircraft?
7, // ARMING: Time to arm projectile after launch.
0, // RANGE: Inherent override range factor.
MPH_ROCKET, // SPEED: Miles per hour.
5, // ROT: Rate of turn (degrees per tick).
WARHEAD_HE, // WARHEAD: If fires weapon, warhead type
ANIM_FRAG1 // Explosion to use upon impact.
);
static BulletTypeClass const ClassMissile2(
BULLET_SSM2,
"DRAGON", // NAME: Text name of this unit type.
true, // Flies over tall walls?
true, // Homes in on target?
false, // Projectile arcs to the target?
false, // Is this a dropping bomb-like object?
false, // Is this projectile invisible?
true, // Will it blow up even if it gets just NEAR to target?
true, // Does it have flickering flame animation?
true, // Can it run out of fuel?
false, // Is there no visual difference between projectile facings?
true, // Is projectile inherently inaccurate?
true, // Translucent colors are used?
true, // Good against aircraft?
9, // ARMING: Time to arm projectile after launch.
0, // RANGE: Inherent override range factor.
MPH_ROCKET, // SPEED: Miles per hour.
7, // ROT: Rate of turn (degrees per tick).
WARHEAD_HE, // WARHEAD: If fires weapon, warhead type
ANIM_FRAG1 // Explosion to use upon impact.
);
static BulletTypeClass const ClassPatriot(
BULLET_SAM,
"MISSILE", // NAME: Text name of this unit type.
true, // Flies over tall walls?
true, // Homes in on target?
false, // Projectile arcs to the target?
false, // Is this a dropping bomb-like object?
false, // Is this projectile invisible?
true, // Will it blow up even if it gets just NEAR to target?
true, // Does it have flickering flame animation?
true, // Can it run out of fuel?
false, // Is there no visual difference between projectile facings?
false, // Is projectile inherently inaccurate?
false, // Translucent colors are used?
true, // Good against aircraft?
0, // ARMING: Time to arm projectile after launch.
0, // RANGE: Inherent override range factor.
MPH_VERY_FAST, // SPEED: Miles per hour.
10, // ROT: Rate of turn (degrees per tick).
WARHEAD_AP, // WARHEAD: If fires weapon, warhead type
ANIM_VEH_HIT1 // Explosion to use upon impact.
);
static BulletTypeClass const ClassDragon(
BULLET_TOW,
"DRAGON", // NAME: Text name of this unit type.
true, // Flies over tall walls?
true, // Homes in on target?
false, // Projectile arcs to the target?
false, // Is this a dropping bomb-like object?
false, // Is this projectile invisible?
true, // Will it blow up even if it gets just NEAR to target?
true, // Does it have flickering flame animation?
true, // Can it run out of fuel?
false, // Is there no visual difference between projectile facings?
false, // Is projectile inherently inaccurate?
true, // Translucent colors are used?
true, // Good against aircraft?
3, // ARMING: Time to arm projectile after launch.
0, // RANGE: Inherent override range factor.
MPH_ROCKET, // SPEED: Miles per hour.
5, // ROT: Rate of turn (degrees per tick).
WARHEAD_AP, // WARHEAD: If fires weapon, warhead type
ANIM_VEH_HIT2 // Explosion to use upon impact.
);
static BulletTypeClass const ClassFlame(
BULLET_FLAME,
"FLAME", // NAME: Text name of this unit type.
false, // Flies over tall walls?
false, // Homes in on target?
false, // Projectile arcs to the target?
false, // Is this a dropping bomb-like object?
true, // Is this projectile invisible?
false, // Will it blow up even if it gets just NEAR to target?
false, // Does it have flickering flame animation?
true, // Can it run out of fuel?
false, // Is there no visual difference between projectile facings?
false, // Is projectile inherently inaccurate?
false, // Translucent colors are used?
false, // Good against aircraft?
12, // ARMING: Time to arm projectile after launch.
12, // RANGE: Inherent override range factor.
MPH_FAST, // SPEED: Miles per hour.
0, // ROT: Rate of turn (degrees per tick).
WARHEAD_FIRE, // WARHEAD: If fires weapon, warhead type
ANIM_NONE // Explosion to use upon impact.
);
static BulletTypeClass const ClassChem(
BULLET_CHEMSPRAY,
"FLAME", // NAME: Text name of this unit type.
false, // Flies over tall walls?
false, // Homes in on target?
false, // Projectile arcs to the target?
false, // Is this a dropping bomb-like object?
true, // Is this projectile invisible?
false, // Will it blow up even if it gets just NEAR to target?
false, // Does it have flickering flame animation?
true, // Can it run out of fuel?
false, // Is there no visual difference between projectile facings?
false, // Is projectile inherently inaccurate?
false, // Translucent colors are used?
false, // Good against aircraft?
12, // ARMING: Time to arm projectile after launch.
12, // RANGE: Inherent override range factor.
MPH_FAST, // SPEED: Miles per hour.
0, // ROT: Rate of turn (degrees per tick).
WARHEAD_HE, // WARHEAD: If fires weapon, warhead type
ANIM_NONE // Explosion to use upon impact.
);
static BulletTypeClass const ClassNapalm(
BULLET_NAPALM,
"BOMBLET", // NAME: Text name of this unit type.
true, // Flies over tall walls?
false, // Homes in on target?
false, // Projectile arcs to the target?
true, // Is this a dropping bomb-like object?
false, // Is this projectile invisible?
false, // Will it blow up even if it gets just NEAR to target?
false, // Does it have flickering flame animation?
false, // Can it run out of fuel?
true, // Is there no visual difference between projectile facings?
false, // Is projectile inherently inaccurate?
true, // Translucent colors are used?
false, // Good against aircraft?
24, // ARMING: Time to arm projectile after launch.
24, // RANGE: Inherent override range factor.
MPH_MEDIUM_SLOW, // SPEED: Miles per hour.
0, // ROT: Rate of turn (degrees per tick).
WARHEAD_FIRE, // WARHEAD: If fires weapon, warhead type
ANIM_NAPALM2 // Explosion to use upon impact.
);
static BulletTypeClass const ClassGrenade(
BULLET_GRENADE,
"BOMB", // NAME: Text name of this unit type.
true, // Flies over tall walls?
false, // Homes in on target?
true, // Projectile arcs to the target?
false, // Is this a dropping bomb-like object?
false, // Is this projectile invisible?
false, // Will it blow up even if it gets just NEAR to target?
false, // Does it have flickering flame animation?
false, // Can it run out of fuel?
true, // Is there no visual difference between projectile facings?
true, // Is projectile inherently inaccurate?
true, // Translucent colors are used?
false, // Good against aircraft?
0, // ARMING: Time to arm projectile after launch.
0, // RANGE: Inherent override range factor.
MPH_MEDIUM_SLOW, // SPEED: Miles per hour.
0, // ROT: Rate of turn (degrees per tick).
WARHEAD_HE, // WARHEAD: If fires weapon, warhead type
ANIM_VEH_HIT2 // Explosion to use upon impact.
);
static BulletTypeClass const ClassLaser(
BULLET_LASER,
"Laser", // NAME: Text name of this unit type.
true, // Flies over tall walls?
false, // Homes in on target?
false, // Projectile arcs to the target?
false, // Is this a dropping bomb-like object?
true, // Is this projectile invisible?
false, // Will it blow up even if it gets just NEAR to target?
false, // Does it have flickering flame animation?
false, // Can it run out of fuel?
true, // Is there no visual difference between projectile facings?
false, // Is projectile inherently inaccurate?
false, // Translucent colors are used?
false, // Good against aircraft?
0, // ARMING: Time to arm projectile after launch.
0, // RANGE: Inherent override range factor.
MPH_LIGHT_SPEED, // SPEED: Miles per hour.
0, // ROT: Rate of turn (degrees per tick).
WARHEAD_LASER, // WARHEAD: If fires weapon, warhead type
ANIM_NONE // Explosion to use upon impact.
);
static BulletTypeClass const ClassNukeUp(
BULLET_NUKE_UP,
"ATOMICUP", // NAME: Text name of this unit type.
true, // Flies over tall walls?
false, // Homes in on target?
false, // Projectile arcs to the target?
false, // Is this a dropping bomb-like object?
false, // Is this projectile invisible?
true, // Will it blow up even if it gets just NEAR to target?
false, // Does it have flickering flame animation?
false, // Can it run out of fuel?
true, // Is there no visual difference between projectile facings?
false, // Is projectile inherently inaccurate?
false, // Translucent colors are used?
false, // Good against aircraft?
0, // ARMING: Time to arm projectile after launch.
0, // RANGE: Inherent override range factor.
MPH_VERY_FAST, // SPEED: Miles per hour.
0, // ROT: Rate of turn (degrees per tick).
WARHEAD_HE, // WARHEAD: If fires weapon, warhead type
ANIM_FRAG1 // Explosion to use upon impact.
);
static BulletTypeClass const ClassNukeDown(
BULLET_NUKE_DOWN,
"ATOMICDN", // NAME: Text name of this unit type.
true, // Flies over tall walls?
false, // Homes in on target?
false, // Projectile arcs to the target?
false, // Is this a dropping bomb-like object?
false, // Is this projectile invisible?
true, // Will it blow up even if it gets just NEAR to target?
false, // Does it have flickering flame animation?
false, // Can it run out of fuel?
true, // Is there no visual difference between projectile facings?
false, // Is projectile inherently inaccurate?
false, // Translucent colors are used?
false, // Good against aircraft?
0, // ARMING: Time to arm projectile after launch.
0, // RANGE: Inherent override range factor.
MPH_VERY_FAST, // SPEED: Miles per hour.
0, // ROT: Rate of turn (degrees per tick).
WARHEAD_HE, // WARHEAD: If fires weapon, warhead type
ANIM_ATOM_BLAST // Explosion to use upon impact.
);
static BulletTypeClass const ClassHonestJohn(
BULLET_HONEST_JOHN,
"MISSILE", // NAME: Text name of this unit type.
true, // Flies over tall walls?
false, // Homes in on target?
false, // Projectile arcs to the target?
false, // Is this a dropping bomb-like object?
false, // Is this projectile invisible?
true, // Will it blow up even if it gets just NEAR to target?
true, // Does it have flickering flame animation?
true, // Can it run out of fuel?
false, // Is there no visual difference between projectile facings?
false, // Is projectile inherently inaccurate?
false, // Translucent colors are used?
false, // Good against aircraft?
10, // ARMING: Time to arm projectile after launch.
0, // RANGE: Inherent override range factor.
MPH_FAST, // SPEED: Miles per hour.
10, // ROT: Rate of turn (degrees per tick).
WARHEAD_FIRE, // WARHEAD: If fires weapon, warhead type
ANIM_NAPALM3 // Explosion to use upon impact.
);
static BulletTypeClass const ClassHeadButt(
BULLET_HEADBUTT,
"GORE", // NAME: Text name of this unit type.
false, // Flies over tall walls?
false, // Homes in on target?
false, // Projectile arcs to the target?
false, // Is this a dropping bomb-like object?
true, // Is this projectile invisible?
false, // Will it blow up even if it gets just NEAR to target?
false, // Does it have flickering flame animation?
false, // Can it run out of fuel?
true, // Is there no visual difference between projectile facings?
false, // Is projectile inherently inaccurate?
false, // Translucent colors are used?
false, // Good against aircraft?
0, // ARMING: Time to arm projectile after launch.
0, // RANGE: Inherent override range factor.
MPH_LIGHT_SPEED, // SPEED: Miles per hour.
0, // ROT: Rate of turn (degrees per tick).
WARHEAD_HEADBUTT, // WARHEAD: If fires weapon, warhead type
ANIM_NONE // Explosion to use upon impact.
);
static BulletTypeClass const ClassTRexBite(
BULLET_TREXBITE,
"CHEW", // NAME: Text name of this unit type.
false, // Flies over tall walls?
false, // Homes in on target?
false, // Projectile arcs to the target?
false, // Is this a dropping bomb-like object?
true, // Is this projectile invisible?
false, // Will it blow up even if it gets just NEAR to target?
false, // Does it have flickering flame animation?
false, // Can it run out of fuel?
true, // Is there no visual difference between projectile facings?
false, // Is projectile inherently inaccurate?
false, // Translucent colors are used?
false, // Good against aircraft?
0, // ARMING: Time to arm projectile after launch.
0, // RANGE: Inherent override range factor.
MPH_LIGHT_SPEED, // SPEED: Miles per hour.
0, // ROT: Rate of turn (degrees per tick).
WARHEAD_FEEDME, // WARHEAD: If fires weapon, warhead type
ANIM_NONE // Explosion to use upon impact.
);
#ifdef PETROGLYPH_EXAMPLE_MOD
static BulletTypeClass const NukeLob(
BULLET_NUKE_LOB,
"BOMB", // NAME: Text name of this unit type.
true, // Flies over tall walls?
false, // Homes in on target?
true, // Projectile arcs to the target?
false, // Is this a dropping bomb-like object?
false, // Is this projectile invisible?
false, // Will it blow up even if it gets just NEAR to target?
false, // Does it have flickering flame animation?
false, // Can it run out of fuel?
true, // Is there no visual difference between projectile facings?
true, // Is projectile inherently inaccurate?
false, // Translucent colors are used?
false, // Good against aircraft?
0, // ARMING: Time to arm projectile after launch.
0, // RANGE: Inherent override range factor.
MPH_MEDIUM_FAST, // SPEED: Miles per hour.
0, // ROT: Rate of turn (degrees per tick).
WARHEAD_HE, // WARHEAD: If fires weapon, warhead type
ANIM_ATOM_BLAST // Explosion to use upon impact.
);
#endif //PETROGLYPH_EXAMPLE_MOD
/*
** This is the array of pointers to the static data associated with
** each bullet (projectile) type.
*/
BulletTypeClass const * const BulletTypeClass::Pointers[BULLET_COUNT] = {
&ClassSniper, // BULLET_SNIPER
&ClassBullet, // BULLET_BULLET
&ClassAPDS, // BULLET_APDS
&Class120mm, // BULLET_HE
&ClassMissile, // BULLET_SSM
&ClassMissile2, // BULLET_SSM2
&ClassPatriot, // BULLET_SAM
&ClassDragon, // BULLET_TOW
&ClassFlame, // BULLET_FLAME
&ClassChem, // BULLET_CHEMSPRAY
&ClassNapalm, // BULLET_NAPALM
&ClassGrenade, // BULLET_GRENADE
&ClassLaser, // BULLET_LASER
&ClassNukeUp, // BULLET_NUKE_UP
&ClassNukeDown, // BULLET_NUKE_DOWN
&ClassHonestJohn, // BULLET_HONEST_JOHN
&ClassSpreadfire, // BULLET_SPREADFIRE
&ClassHeadButt, // BULLET_HEADBUTT
&ClassTRexBite, // BULLET_TREXBITE
#ifdef PETROGLYPH_EXAMPLE_MOD
&NukeLob, // BULLET_NUKE_LOB
#endif //PETROGLYPH_EXAMPLE_MOD
};
/***********************************************************************************************
* 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. *
*=============================================================================================*/
BulletTypeClass::BulletTypeClass(
BulletType type,
char const *ininame,
bool is_high,
bool is_homing,
bool is_arcing,
bool is_dropping,
bool is_invisible,
bool is_proximity_armed,
bool is_flame_equipped,
bool is_fueled,
bool is_faceless,
bool is_inaccurate,
bool is_translucent,
bool is_antiaircraft,
int arming, int range, MPHType maxspeed, unsigned rot,
WarheadType warhead, AnimType explosion) :
ObjectTypeClass(true, false, false, true, false, false, true, true, TXT_NONE, ininame, ARMOR_NONE, 0)
{
Explosion = explosion;
IsHigh = is_high;
IsAntiAircraft = is_antiaircraft;
IsTranslucent = is_translucent;
IsArcing = is_arcing;
IsHoming = is_homing;
IsDropping = is_dropping;
IsInvisible = is_invisible;
IsProximityArmed = is_proximity_armed;
IsFlameEquipped = is_flame_equipped;
IsFueled = is_fueled;
IsFaceless = is_faceless;
IsInaccurate = is_inaccurate;
Type = type;
Warhead = warhead;
MaxSpeed = maxspeed;
ROT = rot;
Arming = arming;
Range = range;
}
/***********************************************************************************************
* 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)
{
BulletType index;
/*
** Load the bullet shapes.
*/
for (index = BULLET_FIRST; index < BULLET_COUNT; index++) {
BulletTypeClass const & bullet = As_Reference(index);
char fullname[_MAX_FNAME+_MAX_EXT];
if (!bullet.IsInvisible) {
_makepath(fullname, NULL, NULL, bullet.IniName, ".SHP");
RawFileClass file(fullname);
if (file.Is_Available()) {
((void const *&)bullet.ImageData) = Load_Alloc_Data(file);
} else {
((void const *&)bullet.ImageData) = MixFileClass::Retrieve(fullname);
}
}
}
}

4938
TIBERIANDAWN/BDATA.CPP Normal file

File diff suppressed because it is too large Load Diff

5429
TIBERIANDAWN/BUILDING.CPP Normal file

File diff suppressed because it is too large Load Diff

307
TIBERIANDAWN/BUILDING.H Normal file
View File

@@ -0,0 +1,307 @@
//
// 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&c\vcs\code\building.h_v 2.20 16 Oct 1995 16:47:54 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 "tarcom.h"
#include "radio.h"
#include "cargo.h"
#include "mission.h"
#include "bullet.h"
#include "target.h"
#include "factory.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:
BuildingTypeClass const * const Class;
operator StructType(void) const {return Class->Type;};
/*
** If this building is in the process of producing something, then this
** will point to the factory manager.
*/
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;
/*
** 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 oblisk 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 subsiquently gets captured back.
*/
unsigned IsCaptured: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.
*/
TCountDownTimerClass 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
** discrepency, then the owner power is adjusted accordingly.
*/
int LastStrength;
/*
** This is the countdown timer that regulates placement retry logic
** for factory type buildings.
*/
TCountDownTimerClass PlacementDelay;
/*---------------------------------------------------------------------
** Constructors, Destructors, and overloaded operators.
*/
static void * BuildingClass::operator new(size_t size);
static void BuildingClass::operator delete(void *ptr);
BuildingClass(void) : Class(0) {};
BuildingClass(StructType type, HousesType house);
virtual ~BuildingClass(void);
virtual RTTIType What_Am_I(void) const {return RTTI_BUILDING;};
/*---------------------------------------------------------------------
** 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 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 * 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 int Refund_Amount(void) const;
virtual DirType Fire_Direction(void) const;
int Power_Output(void) const;
/*
** Coordinate inquiry functions. These are used for both display and
** combat purposes.
*/
virtual COORDINATE Docking_Coord(void) const;
virtual COORDINATE Fire_Coord(int which) const;
virtual COORDINATE Center_Coord(void) const;
virtual COORDINATE Sort_Y(void) const;
virtual COORDINATE Target_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);
bool Passes_Proximity_Check(CELL homecell);
/*
** 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);
virtual bool Mark(MarkType mark);
virtual void Look(bool incremental=false);
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);
virtual TARGET As_Target(void) const;
virtual bool Captured(HouseClass * newowner);
/*
** AI.
*/
virtual void Hidden(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);
/*
** Scenario and debug support.
*/
#ifdef CHEAT_KEYS
virtual void Debug_Dump(MonoClass *mono) const;
#endif
/*
** File I/O.
*/
static void Read_INI(char *buffer);
static void Write_INI(char *buffer);
static char *INI_Name(void) {return "STRUCTURES";};
bool Load(FileClass & file);
bool Save(FileClass & file);
virtual void Code_Pointers(void);
virtual void Decode_Pointers(void);
void Update_Specials(void);
/*
** Dee-buggin' support.
*/
int Validate(void) const;
private:
void Drop_Debris(TARGET source = TARGET_NONE);
virtual BulletClass * Fire_At(TARGET target, int which);
/*
** 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];
/*
** This contains the value of the Virtual Function Table Pointer
*/
static void * VTable;
};
#endif

795
TIBERIANDAWN/BULLET.CPP Normal file
View File

@@ -0,0 +1,795 @@
//
// 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&c\vcs\code\bullet.cpv 2.18 16 Oct 1995 16:50:00 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.CPP *
* *
* Programmer : Joe L. Bostic *
* *
* Start Date : April 23, 1994 *
* *
* Last Update : March 18, 1995 [JLB] *
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* BulletClass::AI -- Logic processing for bullet. *
* BulletClass::As_Target -- Converts the bullet into a target value. *
* BulletClass::BulletClass -- Bullet constructor. *
* BulletClass::BulletClass -- Default constructor for bullet objects. *
* BulletClass::Detach -- Removes specified target from this bullet's targeting system. *
* BulletClass::Draw_It -- Displays the bullet at location specified. *
* BulletClass::Init -- Clears the bullets array for scenario preparation. *
* BulletClass::Mark -- Performs related map refreshing under bullet. *
* BulletClass::Occupy_List -- Determines the bullet occupation list. *
* BulletClass::Unlimbo -- Transitions a bullet object into the game render/logic system. *
* BulletClass::delete -- Bullet memory delete. *
* BulletClass::new -- Allocates memory for bullet object. *
* BulletClass::Validate -- validates bullet pointer *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "function.h"
#define GRAVITY 3
/*
** This contains the value of the Virtual Function Table Pointer
*/
void * BulletClass::VTable;
/***********************************************************************************************
* BulletClass::Validate -- validates bullet pointer *
* *
* INPUT: *
* none. *
* *
* OUTPUT: *
* 1 = ok, 0 = error *
* *
* WARNINGS: *
* none. *
* *
* HISTORY: *
* 08/09/1995 BRR : Created. *
*=============================================================================================*/
#ifdef CHEAT_KEYS
int BulletClass::Validate(void) const
{
int num;
num = Bullets.ID(this);
if (num < 0 || num >= BULLET_MAX) {
Validate_Error("BULLET");
return (0);
}
else
return (1);
}
#else
#define Validate()
#endif
/***********************************************************************************************
* BulletClass::BulletClass -- Default constructor for bullet objects. *
* *
* This is the default constructor for bullet objects. A bullet constructed by this routine *
* is not in a usable state for game purposes. It must be constructed by the full *
* (parameterized) constructor -- usually called as part of the overloaded "new" operator. *
* *
* INPUT: none *
* *
* OUTPUT: none *
* *
* WARNINGS: Do not use bullets that were constructed solely by this routine. *
* *
* HISTORY: *
* 09/24/1994 JLB : Created. *
*=============================================================================================*/
BulletClass::BulletClass(void) :
Class(0)
{
Payback = NULL;
IsToAnimate = false;
Altitude = 0;
Riser = 0;
TarCom = TARGET_NONE;
Strength = 0;
IsLocked = true;
IsInaccurate = false;
}
/***********************************************************************************************
* BulletClass::new -- Allocates memory for bullet object. *
* *
* This function will "allocate" a block of memory for a bullet object. *
* This memory block is merely lifted from a fixed pool of blocks. *
* *
* INPUT: size -- The size of the memory block needed. *
* *
* OUTPUT: Returns with a pointer to an available bullet object block. *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 05/02/1994 JLB : Created. *
*=============================================================================================*/
void * BulletClass::operator new(size_t )
{
void * ptr = Bullets.Allocate();
if (ptr) {
((BulletClass *)ptr)->Set_Active();
}
return(ptr);
}
/***********************************************************************************************
* BulletClass::delete -- Bullet memory delete. *
* *
* Since bullets memory is merely "allocated" out of a pool, it never *
* actually gets deleted. *
* *
* INPUT: ptr -- Generic pointer to bullet object. *
* *
* OUTPUT: none *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 05/02/1994 JLB : Created. *
*=============================================================================================*/
void BulletClass::operator delete(void *ptr)
{
if (ptr) {
((BulletClass *)ptr)->IsActive = false;
}
Bullets.Free((BulletClass *)ptr);
}
/***********************************************************************************************
* BulletClass::BulletClass -- Bullet constructor. *
* *
* This is the constructor for the bullet class. It handles all *
* initialization of the bullet and starting it in motion toward its *
* target. *
* *
* INPUT: id -- The type of bullet this is (could be missile). *
* *
* OUTPUT: none *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 05/02/1994 JLB : Created. *
* 06/20/1994 JLB : Firer is a base class pointer. *
* 12/10/1994 JLB : Auto calculate range optional. *
* 12/12/1994 JLB : Handles small arms as an instantaneous effect. *
* 12/23/1994 JLB : Fixed scatter algorithm for non-homing projectiles. *
* 12/31/1994 JLB : Removed range parameter (not needed). *
*=============================================================================================*/
BulletClass::BulletClass(BulletType id) :
Class(&BulletTypeClass::As_Reference(id))
{
Altitude = 0;
IsInaccurate = false;
IsLocked = true;
// IsLocked = false;
IsToAnimate = false;
Payback = 0;
Riser = 0;
Strength = Class->MaxStrength;
TarCom = TARGET_NONE;
}
/***********************************************************************************************
* BulletClass::Occupy_List -- Determines the bullet occupation list. *
* *
* This function will determine the cell occupation list and return a pointer to it. Most *
* bullets are small and the list is usually short, but on occasion, it can be a list that *
* rivals the size of regular vehicles. *
* *
* INPUT: none *
* *
* OUTPUT: Returns with a pointer to the cell offset list that covers all the cells a bullet *
* is over. *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 06/20/1994 JLB : Created. *
* 01/05/1995 JLB : Handles projectiles with altitude. *
*=============================================================================================*/
short const *BulletClass::Occupy_List(void) const
{
Validate();
switch (*this) {
case BULLET_FLAME:
return(Coord_Spillage_List(Coord, 25));
case BULLET_NUKE_UP:
case BULLET_NUKE_DOWN:
return(Coord_Spillage_List(Coord, 48));
default:
if (Altitude) {
static CELL _list[10];
const short * ptr = Coord_Spillage_List(Coord, 5);
int index = 0;
CELL cell1 = Coord_Cell(Coord);
while (ptr[index] != REFRESH_EOL) {
_list[index] = ptr[index];
index++;
}
COORDINATE coord = XY_Coord(0, Altitude);
coord = Coord_Sub(Coord, coord);
CELL cell2 = Coord_Cell(coord);
ptr = Coord_Spillage_List(coord, 5);
while (*ptr != REFRESH_EOL) {
_list[index++] = (*ptr++) + (cell2 - cell1);
}
_list[index] = REFRESH_EOL;
return(_list);
}
}
return(Coord_Spillage_List(Coord, 10));
}
/***********************************************************************************************
* BulletClass::Mark -- Performs related map refreshing under bullet. *
* *
* This routine marks the objects under the bullet so that they will *
* be redrawn. This is necessary as the bullet moves -- objects under *
* its path need to be restored. *
* *
* INPUT: none *
* *
* OUTPUT: none *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 05/02/1994 JLB : Created. *
*=============================================================================================*/
bool BulletClass::Mark(MarkType mark)
{
Validate();
if (ObjectClass::Mark(mark)) {
if (!Class->IsInvisible) {
Map.Refresh_Cells(Coord_Cell(Coord), Occupy_List());
}
return(true);
}
return(false);
}
/***********************************************************************************************
* BulletClass::AI -- Logic processing for bullet. *
* *
* This routine will perform all logic (flight) logic on the bullet. *
* Primarily this is motion, fuse tracking, and detonation logic. Call *
* this routine no more than once per bullet per game tick. *
* *
* INPUT: none *
* *
* OUTPUT: none *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 05/02/1994 JLB : Created. *
*=============================================================================================*/
void BulletClass::AI(void)
{
Validate();
COORDINATE coord;
ObjectClass::AI();
/*
** Balistic objects are handled here.
*/
bool forced = false; // Forced explosion.
if (Class->IsArcing) {
Altitude += Riser;
if (Altitude <= 0) {
forced = true;
}
if (Riser > -100) {
Riser -= GRAVITY;
}
}
if (Class->IsDropping) {
Altitude += Riser;
if (Altitude <= 0) {
forced = true;
}
if (Riser > -100) {
Riser -= 1;
}
}
/*
** Homing projectiles constantly change facing to face toward the target but
** they only do so every other game frame (improves game speed and makes
** missiles not so deadly).
*/
if ((Frame & 0x01) && Class->IsHoming && Target_Legal(TarCom)) {
PrimaryFacing.Set_Desired(Direction256(Coord, ::As_Coord(TarCom)));
}
/*
** Move the projectile forward according to its speed
** and direction.
*/
coord = Coord;
if (Class->IsFlameEquipped) {
if (IsToAnimate) {
new AnimClass(ANIM_SMOKE_PUFF, coord, 1);
}
IsToAnimate = !IsToAnimate;
}
/*
** Handle any body rotation at this time. This process must
** occur every game fame in order to achieve smooth rotation.
*/
if (PrimaryFacing.Is_Rotating()) {
PrimaryFacing.Rotation_Adjust(Class->ROT);
}
switch (Physics(coord, PrimaryFacing)) {
/*
** When a projectile reaches the edge of the world, it
** vanishes from existence -- presumed to explode off
** map.
*/
case IMPACT_EDGE:
// if (IsLocked) {
Mark();
Delete_This();
// }
break;
default:
case IMPACT_NONE:
/*
** The projectile has moved. Check its fuse. If detonation
** is signaled, then do so. Otherwise, just move.
*/
case IMPACT_NORMAL:
Mark();
// IsLocked = true;
if (!Class->IsHigh) {
CellClass * cellptr = &Map[Coord_Cell(coord)];
if (cellptr->Overlay != OVERLAY_NONE && OverlayTypeClass::As_Reference(cellptr->Overlay).IsHigh) {
forced = true;
Coord = coord = Cell_Coord(Coord_Cell(coord));
}
}
/*
** Bullets are generaly more effective when they are fired at aircraft.
*/
if (Class->IsAntiAircraft && As_Aircraft(TarCom) && Distance(TarCom) < 0x0080) {
forced = true;
if (*this == BULLET_TOW) {
Strength += Strength/3;
} else {
Strength += Strength/2;
}
}
if (!forced && (Class->IsDropping || !Fuse_Checkup(coord))) {
Coord = coord;
Mark();
/*
** Certain projectiles loose strength when they travel.
*/
if (*this == BULLET_BULLET) {
if (Strength > 5) Strength--;
}
} else {
/*
** When the target is reached, explode and do the damage
** required of it. For homing objects, don't force the explosion to
** match the target position. Non-homing projectiles adjust position so
** that they hit the target. This compensates for the error in line of
** flight logic.
*/
Mark();
if (!forced && !Class->IsArcing && !Class->IsHoming && Fuse_Target()) {
Coord = Fuse_Target();
}
/*
** Non-aircraft targets apply damage to the ground.
*/
if (!Is_Target_Aircraft(TarCom) || As_Aircraft(TarCom)->In_Which_Layer() == LAYER_GROUND) {
Explosion_Damage(Coord, Strength, Payback, Class->Warhead);
} else {
/*
** Special damage apply for SAM missiles. This is the only way that missile
** damage affects the aircraft target.
*/
if (Distance(TarCom) < 0x0080) {
AircraftClass * object = As_Aircraft(TarCom);
int str = Strength;
if (object) object->Take_Damage(str, 0, Class->Warhead, Payback);
}
}
/*
** For projectiles that are invisible while travelling toward the target,
** allow scatter effect for the impact animation.
*/
if (Class->IsInvisible) {
Coord = Coord_Scatter(Coord, 0x0020);
}
if (Class->Explosion != ANIM_NONE) {
AnimClass * newanim = new AnimClass(Class->Explosion, Coord);
if (newanim) {
newanim->Sort_Above(TarCom);
}
// MBL 05.20.2020
// Fix for Nuke or Atom Bomb killing structures and units during animation sequence and not getting kills tracked
// Per https://jaas.ea.com/browse/TDRA-6610
//
if (newanim && Class->Explosion == ANIM_ATOM_BLAST && newanim->Owner == HOUSE_NONE) {
if (Payback && Payback->House && Payback->House->Class) {
newanim->Owner = Payback->House->Class->House;
}
}
}
Delete_This();
return;
}
break;
}
}
/***********************************************************************************************
* BulletClass::Draw_It -- Displays the bullet at location specified. *
* *
* This routine displays the bullet visual at the location specified. *
* *
* INPUT: x,y -- The center coordinate to render the bullet at. *
* *
* window -- The window to clip to. *
* *
* OUTPUT: none *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 06/20/1994 JLB : Created. *
* 06/27/1994 JLB : Takes a window clipping parameter. *
* 01/08/1995 JLB : Handles translucent colors if necessary. *
*=============================================================================================*/
void BulletClass::Draw_It(int x, int y, WindowNumberType window)
{
Validate();
int facing = Facing_To_32(PrimaryFacing);
/*
** Certain projectiles aren't visible. This includes small bullets (which are actually
** invisible) and flame thrower flames (which are rendered as an animation instead of a projectile).
*/
if (Class->IsInvisible) return;
/*
** If there is no shape loaded for this object, then
** it obviously can't be rendered -- just bail.
*/
void const * shapeptr = Class->Get_Image_Data();
if (!shapeptr) return;
/*
** Get the basic shape number for this projectile.
*/
int shapenum = 0;
if (!Class->IsFaceless) {
shapenum = UnitClass::BodyShape[facing];
}
/*
** For tumbling projectiles, fetch offset stage.
*/
if (*this == BULLET_NAPALM) {
shapenum += Frame % 6;
}
if (*this == BULLET_GRENADE) {
shapenum += Frame % 8;
// Timer++;
}
/*
** For flying projectiles, draw the shadow and adjust the actual projectile body
** render position.
*/
if (Altitude) {
CC_Draw_Shape(shapeptr, shapenum, x, y, window, SHAPE_PREDATOR|SHAPE_CENTER|SHAPE_WIN_REL|SHAPE_FADING, NULL, Map.FadingShade);
y -= Lepton_To_Pixel(Altitude);
}
/*
** Draw the main body of the projectile.
*/
ShapeFlags_Type flags = SHAPE_NORMAL;
if (Class->IsTranslucent) {
flags = SHAPE_GHOST;
}
CC_Draw_Shape(this, shapeptr, shapenum, x, y, window, flags|SHAPE_CENTER|SHAPE_WIN_REL, NULL, Map.UnitShadow);
}
/***********************************************************************************************
* BulletClass::Init -- Clears the bullets array for scenario preparation. *
* *
* This routine will zero out the bullet tracking list and object array in preparation for *
* the start of a new scenario. All bullets cease to exists after this function is *
* called. *
* *
* INPUT: none *
* *
* OUTPUT: none *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 08/15/1994 JLB : Created. *
*=============================================================================================*/
void BulletClass::Init(void)
{
BulletClass *ptr;
Bullets.Free_All();
ptr = new BulletClass();
VTable = ((void **)(((char *)ptr) + sizeof(AbstractClass) - 4))[0];
delete ptr;
}
/***********************************************************************************************
* BulletClass::Detach -- Removes specified target from this bullet's targeting system. *
* *
* When an object is removed from the game system, it must be removed all targeting and *
* tracking systems as well. This routine is used to remove the specified object from the *
* bullet. If the object isn't part of this bullet's tracking system, then no action is *
* performed. *
* *
* INPUT: target -- The target to remove from this tracking system. *
* *
* all -- Is the target going away for good as opposed to just cloaking/hiding? *
* *
* OUTPUT: none *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 09/24/1994 JLB : Created. *
*=============================================================================================*/
void BulletClass::Detach(TARGET target, bool all)
{
Validate();
ObjectClass * obj = As_Object(target);
if (obj == Payback) {
Payback = 0;
}
if (all && target == TarCom) {
TarCom = TARGET_NONE;
}
}
/***********************************************************************************************
* BulletClass::Unlimbo -- Transitions a bullet object into the game render/logic system. *
* *
* This routine is used to take a bullet object that is in limbo and transition it to the *
* game system. A bullet object so transitioned, will be drawn and logic processing *
* performed. In effect, it comes into existance. *
* *
* INPUT: coord -- The location where the bullet object is to appear. *
* *
* dir -- The initial facing for the bullet object. *
* *
* OUTPUT: bool; Was the unlimbo successful? *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 01/10/1995 JLB : Created. *
*=============================================================================================*/
bool BulletClass::Unlimbo(COORDINATE coord, DirType dir)
{
Validate();
/*
** Try to unlimbo the bullet as far as the base class is concerned. Use the already
** set direction and strength if the "punt" values were passed in. This allows a bullet
** to be setup prior to being launched.
*/
if (ObjectClass::Unlimbo(coord)) {
COORDINATE tcoord = As_Coord(TarCom);
/*
** Homing projectiles (missiles) do NOT override facing. They just fire in the
** direction specified and let the chips fall where they may.
*/
if (!Class->IsHoming && !Class->IsDropping) {
dir = Direction(tcoord);
}
/*
** Possibly adjust the target if this projectile is inaccurate. This occurs whenever
** certain weapons are trained upon targets they were never designed to attack. Example: when
** turrets or anti-tank missiles are fired at infantry. Indirect
** fire is inherently inaccurate.
*/
if (IsInaccurate || Class->IsInaccurate ||
((Is_Target_Cell(TarCom) || Is_Target_Infantry(TarCom)) && (Class->Warhead == WARHEAD_AP || Class->IsFueled))) {
/*
** Inaccuracy for low velocity or homing projectiles manifests itself as a standard
** Cicular Error of Probability (CEP) algorithm. High speed projectiles usually
** just overshoot the target by extending the straight line flight.
*/
if (Class->IsHoming || Class->IsArcing) {
int scatterdist = ::Distance(coord, tcoord)/3;
scatterdist = MIN(scatterdist, 0x0200);
if (*this == BULLET_GRENADE) {
scatterdist = ::Distance(coord, tcoord)/4;
scatterdist = MIN(scatterdist, 0x0080);
}
dir = (DirType)((dir + (Random_Pick(0, 10)-5)) & 0x00FF);
tcoord = Coord_Scatter(tcoord, Random_Pick(0, scatterdist));
} else {
tcoord = Coord_Move(tcoord, dir, Random_Pick(0, 0x0100));
}
/*
** Limit scatter to the weapon range of the firer.
*/
if (Payback) {
if (!Payback->In_Range(tcoord, 0) && !Payback->In_Range(tcoord, 1)) {
tcoord = Coord_Move(tcoord, ::Direction(tcoord, Coord), Distance(tcoord) - MAX(Payback->Weapon_Range(0), Payback->Weapon_Range(1)));
}
}
}
/*
** For very fast and invisible projectiles, just make the projectile exist at the target
** location and dispense with the actual flight.
*/
if (Class->MaxSpeed == MPH_LIGHT_SPEED && Class->IsInvisible) {
Coord = tcoord;
}
/*
** Set the range equal to either the class defined range or the calculated
** number of game frames it would take for the projectile to reach the target.
*/
int range = 0xFF;
if (!Class->Range) {
if (!Class->IsDropping) {
range = (::Distance(tcoord, Coord) / Class->MaxSpeed) + 4;
}
} else {
range = Class->Range;
}
/*
** Projectile speed is usually the default value for that projectile, but
** certian projectiles alter speed according to the distance to the
** target.
*/
int speed = Class->MaxSpeed;
if (speed == MPH_LIGHT_SPEED) speed = MPH_IMMOBILE;
if (Class->IsArcing) {
speed = Class->MaxSpeed + (Distance(tcoord)>>5);
/*
** Set minimum speed (i.e., distance) for arcing projectiles.
*/
speed = MAX(speed, 25);
}
if (!Class->IsDropping) {
Fly_Speed(255, (MPHType)speed);
}
/*
** Arm the fuse.
*/
Arm_Fuse(Coord, tcoord, range, ((As_Aircraft(TarCom)!=0) ? 0 : Class->Arming));
/*
** Projectiles that make a ballistic flight to impact point must determine a
** vertical component for the projectile launch. This is crudely simulated
** by biasing ground speed according to target distance and then giving
** enough vertical velocity to keep the projectile airborne for the
** desired amount of time. The mathematically correct solution would be to
** calculate launch angle (given fixed projectile velocity) and then derive
** the vertical and horizontal components. This solution would require a
** of square root and an arcsine lookup table. OUCH!
*/
Altitude = 0;
Riser = 0;
if (Class->IsArcing) {
Altitude = 1;
Riser = ((Distance(tcoord)/2) / (speed+1))*GRAVITY;
Riser = MAX(Riser, (signed char)10);
}
if (Class->IsDropping) {
Altitude = Pixel_To_Lepton(24);
Riser = 0;
}
PrimaryFacing = dir;
return(true);
}
return(false);
}
/***********************************************************************************************
* BulletClass::As_Target -- Converts the bullet into a target value. *
* *
* This support routine is used to convert the bullet (as a pointer) into a target *
* value (which is a number). *
* *
* INPUT: none *
* *
* OUTPUT: Returns the bullet as a target value. *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 09/08/1994 JLB : Created. *
*=============================================================================================*/
TARGET BulletClass::As_Target(void) const
{
Validate();
return(Build_Target(KIND_BULLET, Bullets.ID(this)));
}

155
TIBERIANDAWN/BULLET.H Normal file
View File

@@ -0,0 +1,155 @@
//
// 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&c\vcs\code\bullet.h_v 2.18 16 Oct 1995 16:47:40 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.
*/
BulletTypeClass const * const Class;
operator BulletType(void) const {return Class->Type;};
/*
** 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;
/*---------------------------------------------------------------------
** Constructors, Destructors, and overloaded operators.
*/
static void * BulletClass::operator new(size_t size);
static void BulletClass::operator delete(void *ptr);
BulletClass(void);
BulletClass(BulletType id);
virtual ~BulletClass(void) {if (GameActive) BulletClass::Limbo();};
virtual RTTIType What_Am_I(void) const {return RTTI_BULLET;};
/*---------------------------------------------------------------------
** Member function prototypes.
*/
static void Init(void);
virtual void Assign_Target(TARGET target) {TarCom = target;};
virtual bool Unlimbo(COORDINATE , DirType facing = DIR_N);
virtual LayerType In_Which_Layer(void) const {return LAYER_TOP;};
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);
virtual bool Mark(MarkType mark=MARK_CHANGE);
virtual void AI(void);
virtual short const * Occupy_List(void) const;
virtual short const * Overlap_List(void) const {return Occupy_List();};
virtual TARGET As_Target(void) const;
/*
** File I/O.
*/
bool Load(FileClass & file);
bool Save(FileClass & file);
virtual void Code_Pointers(void);
virtual void Decode_Pointers(void);
/*
** Dee-buggin' support.
*/
int Validate(void) const;
/*
** 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;
/*
** This is the height of the projectile. It starts at a low height, rises to an
** apogee and then drops to explode upon impact. The height is used to render
** the bullet's vertical offset.
*/
int Altitude;
/*
** This is a modifier for the altitude that rises and falls in order to simulate
** the arc of the projectile. This value is added to the height every game tick
** while simultaneously being reduced itself. The net effect, is a rising
** projectile that slows and then eventually drops.
*/
signed char Riser;
/*
** This is the target of the projectile. It is especially significant for those projectiles
** that home in on a target.
*/
TARGET TarCom;
/*
** Is this missle allowed to come in from out of bounds?
*/
unsigned IsLocked:1;
/*
** Some additional padding in case we need to add data to the class and maintain backwards compatibility for save/load
*/
unsigned char SaveLoadPadding[32];
/*
** This contains the value of the Virtual Function Table Pointer
*/
static void * VTable;
};
#endif

180
TIBERIANDAWN/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: F:\projects\c&c\vcs\code\cargo.cpv 2.18 16 Oct 1995 16:49:50 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::Detach_Object -- Removes a unit from the cargo hold. *
* CargoClass::Debug_Dump -- Displays the cargo value to the monochrome screen. *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#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) 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) {
if (!o->Next) break;
o = o->Next;
}
if (o) {
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) {
Quantity++;
object = (FootClass *)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)
{
FootClass * unit = Attached_Object();
if (unit) {
CargoHold = (FootClass *)unit->Next;
unit->Next = 0;
Quantity--;
}
return(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);
}

88
TIBERIANDAWN/CARGO.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: F:\projects\c&c\vcs\code\cargo.h_v 2.20 16 Oct 1995 16:45:14 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;};
/*---------------------------------------------------------------------
** 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

419
TIBERIANDAWN/CCDDE.CPP Normal file
View File

@@ -0,0 +1,419 @@
//
// 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 *
* *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#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 CC95AlreadyRunning = FALSE; //Was there an instance of C&C 95 already running when we started?
extern HWND MainWindow;
extern TimerClass GameTimer;
extern bool GameTimerInUse;
extern void CCDebugString (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->Enable_Callback( TRUE );
IsEnabled = TRUE;
if (DDE_Class->Test_Server_Running(DDE_Class->local_name)){
CC95AlreadyRunning = TRUE;
}else{
//ST - 12/20/2018 2:27PM
//DDE_Class->Register_Server( DDE_Callback );
}
}
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:
CCDebugString("C&C95 - DDE advisory: client connect detected.");
return TRUE;
case DDE_ADVISE_DISCONNECT:
CCDebugString("C&C95 - DDE advisory: client disconnect detected.");
return TRUE;
default:
CCDebugString("C&C95 - 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)) {
CCDebugString ("C&C95 - 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:
CCDebugString("C&C95 - 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:
CCDebugString("C&C95 - Received 'tickle' packet.");
//SetForegroundWindow ( MainWindow );
//ShowWindow ( MainWindow, SW_SHOWMAXIMIZED );
break;
case DDE_PACKET_HEART_BEAT:
CCDebugString("C&C95 - Received heart beat packet.");
if (GameTimerInUse){
LastHeartbeat = GameTimer.Time();
}else{
LastHeartbeat = 0;
}
break;
default:
CCDebugString("C&C95 - 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 (0)
BOOL app_exists;
app_exists = DDE_Class->Test_Server_Running(DDE_Class->remote_name);
if (app_exists != TRUE) {
CCDebugString("Connection to server failed!");
return(FALSE);
}
#endif //(0)
if( DDE_Class->Open_Poke_Connection(DDE_Class->remote_name) == FALSE) {
CCDebugString("C&C95 - 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) {
CCDebugString("C&C95 - 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);
}

86
TIBERIANDAWN/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

626
TIBERIANDAWN/CCFILE.CPP Normal file
View File

@@ -0,0 +1,626 @@
//
// 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 *
* *
* File Name : CCFILE.CPP *
* *
* Programmer : Joe L. Bostic *
* *
* Start Date : August 8, 1994 *
* *
* Last Update : March 20, 1995 [JLB] *
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* CCFileClass::CCFileClass -- Default constructor for file object. *
* CCFileClass::CCFileClass -- Filename based constructor for C&C file. *
* CCFileClass::Close -- Closes the file. *
* 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). *
* CCFileClass::Error -- Handles displaying a file error message. *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "function.h"
//#include <direct.h>
//#include <fcntl.h>
//#include <io.h>
//#include <dos.h>
//#include <errno.h>
//#include <share.h>
//#include "ccfile.h"
/***********************************************************************************************
* 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 * )
{
#ifdef DEMO
if (strstr(File_Name(), "\\")) {
if (!Force_CD_Available(-1)) {
Prog_End();
if (!RunningAsDLL) {
exit(EXIT_FAILURE);
}
}
}
#else
if (!Force_CD_Available(RequiredCD)) {
Prog_End("CCFileClass::Error CD not found", true);
if (!RunningAsDLL) {
exit(EXIT_FAILURE);
}
}
#endif
}
/***********************************************************************************************
* 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) :
CDFileClass(),
FromDisk(false),
Pointer(0),
Position(0),
Length(0),
Start(0)
{
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)
{
FromDisk = false;
Pointer = 0;
Position = 0;
Length = 0;
Start = 0;
}
/***********************************************************************************************
* 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 (Pointer || FromDisk) {
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)
{
int opened = false;
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 (Pointer) {
long maximum = Length - Position;
size = MIN(maximum, size);
if (size) {
Mem_Copy(Add_Long_To_Pointer(Pointer, Position), buffer, size);
Position += size;
}
if (opened) Close();
return(size);
}
/*
** If the file is part of a mixfile, but the mixfile is located
** on disk, then a special read operation is necessary.
*/
if (FromDisk) {
long maximum = Length - Position;
size = MIN(maximum, size);
if (size > 0) {
CDFileClass::Seek(Start + Position, SEEK_SET);
size = CDFileClass::Read(buffer, size);
Position += size;
}
if (opened) Close();
return(size);
}
long s = CDFileClass::Read(buffer, size);
if (opened) Close();
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)
{
if (Pointer || FromDisk) {
switch (dir) {
case SEEK_END:
Position = Length;
break;
case SEEK_SET:
Position = 0;
break;
case SEEK_CUR:
default:
break;
}
Position += pos;
if (Position < 0) Position = 0;
if (Position > Length) Position = 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. *
*=============================================================================================*/
long CCFileClass::Size(void)
{
if (Pointer || FromDisk) 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 )
{
if (MixFileClass::Offset(File_Name())) {
return(true);
}
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 (Pointer) return(true);
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)
{
FromDisk = false;
Pointer = 0;
Position = 0; // Starts at beginning offset.
Start = 0;
Length = 0;
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.
*/
MixFileClass *mixfile = 0;
if (MixFileClass::Offset(File_Name(), &Pointer, &mixfile, &Start, &Length)) {
/*
** 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) {
long start = Start;
long length = Length;
/*
** 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 const * dupfile = strdup(File_Name());
Open(mixfile->Filename, READ);
Searching(false); // Disable multi-drive search.
Set_Name(dupfile);
Searching(true);
if (dupfile) free((void *)dupfile);
Start = start;
Length = length;
FromDisk = true;
}
} 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);
}
/***********************************************************************************
** Backward compatibility section.
*/
//extern "C" {
static CCFileClass Handles[10];
#ifdef NEVER
bool __cdecl Set_Search_Drives(char const *)
{
CCFileClass::Set_Search_Path(path);
return(true);
}
#endif
int __cdecl Open_File(char const *file_name, int mode)
{
for (int index = 0; index < sizeof(Handles)/sizeof(Handles[0]); index++) {
if (!Handles[index].Is_Open()) {
Handles[index].Set_Name(file_name);
if (Handles[index].Open(mode)) {
// if (Handles[index].Open(file_name, mode)) {
return(index);
}
break;
}
}
return(WW_ERROR);
}
VOID __cdecl Close_File(int handle)
{
if (handle != WW_ERROR && Handles[handle].Is_Open()) {
Handles[handle].Close();
}
}
LONG __cdecl Read_File(int handle, VOID *buf, ULONG bytes)
{
if (handle != WW_ERROR && Handles[handle].Is_Open()) {
return(Handles[handle].Read(buf, bytes));
}
return(0);
}
LONG __cdecl Write_File(int handle, VOID const *buf, ULONG bytes)
{
if (handle != WW_ERROR && 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());
}
ULONG __cdecl Load_Data(char const *name, VOID *ptr, ULONG 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));
}
ULONG __cdecl File_Size(int handle)
{
if (handle != WW_ERROR && Handles[handle].Is_Open()) {
return(Handles[handle].Size());
}
return(0);
}
#ifdef NEVER
ULONG __cdecl Write_Data(char const *name, VOID const *ptr, ULONG size)
{
return(CCFileClass(name).Write(ptr, size));
}
#endif
ULONG __cdecl Seek_File(int handle, LONG offset, int starting)
{
if (handle != WW_ERROR && Handles[handle].Is_Open()) {
return(Handles[handle].Seek(offset, starting));
}
return(0);
}
void WWDOS_Shutdown(void)
{
for (int index = 0; index < 10; index++) {
Handles[index].Set_Name(NULL);
}
}
#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
//ULONG cdecl Load_Uncompress(BYTE 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));
//}
//extern "C" {
//int MaxDevice;
//int DefaultDrive;
//char CallingDOSInt;
//}
void Unfragment_File_Cache(void)
{
}

111
TIBERIANDAWN/CCFILE.H 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: F:\projects\c&c\vcs\code\ccfile.h_v 2.18 16 Oct 1995 16:45: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 ***
***********************************************************************************************
* *
* 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"
/*
** 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) {};
// Delete should be overloaded here as well. Don't allow deletes of mixfiles.
virtual int Open(char const *filename, int rights=READ) {Set_Name(filename);return Open(rights);};
virtual int Open(int rights=READ);
virtual int Is_Open(void) const;
virtual int Is_Available(int forced=false);
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 void Error(int error, int canretry = false, char const * filename=NULL);
private:
/*
** This flag indicates that the file is part of a mixfile and the mixfile resides on
** disk. The file handle for this file is a legitimate DOS handle, although special
** handling is necessary that takes into account the embedded nature of the file.
*/
bool FromDisk;
/*
** 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.
*/
void * Pointer;
/*
** This is the starting offset of the beginning of the file. This value is only valid
** if the file is part of a mixfile that resides on disk. It serves as the counterpart
** to the "Pointer" variable.
*/
long Start;
/*
** 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;
/*
** 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;
// Force these to never be invoked.
CCFileClass const operator = (CCFileClass const & c);
CCFileClass (CCFileClass const & ) {};
};
#endif

16
TIBERIANDAWN/CC_ICON.RC Normal file
View File

@@ -0,0 +1,16 @@
/****************************************************************************
CC_ICON.RC
produced by Borland Resource Workshop
*****************************************************************************/
#include "cc_icon.rh"
ICON_1 ICON "conquer.ico"

2770
TIBERIANDAWN/CDATA.CPP Normal file

File diff suppressed because it is too large Load Diff

534
TIBERIANDAWN/CDFILE.CPP Normal file
View File

@@ -0,0 +1,534 @@
//
// 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&c\vcs\code\cdfile.cpv 2.18 16 Oct 1995 16:48: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 : Westwood Library *
* *
* File Name : CDFILE.CPP *
* *
* Programmer : Joe L. Bostic *
* *
* Start Date : October 18, 1994 *
* *
* Last Update : October 18, 1994 [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. *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "function.h"
//#include "cdfile.h"
/*
** Pointer to the first search path record.
*/
CDFileClass::SearchDriveType * CDFileClass::First = 0;
int CDFileClass::CurrentCDDrive = 0;
int CDFileClass::LastCDDrive = 0;
char CDFileClass::RawPath[512];
int __cdecl Is_Disk_Inserted(int disk)
{
return true;
#if (0) // ST - 12/17/2018 5:31PM
struct find_t fb;
char scan[] = "?:\\*.*";
scan[0] = 'A' + disk;
return(_dos_findfirst(scan, _A_SUBDIR, &fb) == 0);
#endif
}
CDFileClass::CDFileClass(char const *filename) :
IsDisabled(false)
{
Set_Name(filename);
memset (RawPath, 0, sizeof(RawPath));
}
CDFileClass::CDFileClass(void) :
IsDisabled(false)
{
}
/***********************************************************************************************
* 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(RawFileClass::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);
}
/***********************************************************************************************
* 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) {
if (strlen(ptr)){
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.
*/
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] = 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::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;
}
/***********************************************************************************************
* 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;
}
}
/***********************************************************************************************
* 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.
*/
RawFileClass::Set_Name(filename);
if (IsDisabled || !First || RawFileClass::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.
*/
RawFileClass::Set_Name(path);
if (RawFileClass::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.
*/
RawFileClass::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 RawFileClass 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)
{
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) {
return(RawFileClass::Open(filename, rights));
}
/*
** Perform normal multiple drive searching for the filename and open
** using the normal procedure.
*/
Set_Name(filename);
return(RawFileClass::Open(rights));
}
#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
int Get_CD_Drive(void)
{
#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());
return (0);
#endif
}
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;
}

117
TIBERIANDAWN/CDFILE.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: F:\projects\c&c\vcs\code\cdfile.h_v 2.20 16 Oct 1995 16:45:58 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 "rawfile.h"
/*
** This class is derived from the raw file class. 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 RawFileClass
{
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

2735
TIBERIANDAWN/CELL.CPP Normal file

File diff suppressed because it is too large Load Diff

295
TIBERIANDAWN/CELL.H Normal file
View File

@@ -0,0 +1,295 @@
//
// 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&c\vcs\code\cell.h_v 2.20 16 Oct 1995 16:45: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 : 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:
/*
** 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;
/*
** Is this cell mapped by the player? A mapped cell is visible. An unmapped cell
** is covered in a dark shroud. In addition to visibility, mapped cells are the only
** legal place for transports to land.
*/
unsigned IsMapped:1;
/*
** If any part of this cell is visible (even just peeking out from under the shadow),
** this this flag will be true. Mapped cells always have this flag set, but unmapped
** cells might not -- it depends on where the shadow edge is located.
*/
unsigned IsVisible:1;
/*
** Every cell can be assigned a trigger. The same trigger can be assigned to
** multiple cells. This bitflag indicates whether this cell has a trigger.
** The trigger pointers for all cells must be stored elsewhere.
*/
unsigned IsTrigger: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 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.
*/
ObjectClass *OccupierPtr;
ObjectClass *Overlapper[3];
/*
** Per-player view of whether a cell is mapped. One bit for each house type. ST - 3/5/2019 3:00PM
*/
unsigned int IsMappedByPlayerMask;
/*
** Per-player view of whether a cell is visible. One bit for each house type. ST - 3/5/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(void) {};
int operator == (CellClass const & cell) const {return &cell == this;};
/*
** Query functions.
*/
ObjectClass * Cell_Occupier(void) const;
static int Spot_Index(COORDINATE coord);
bool Is_Spot_Free(int spot_index) const {return (! (Flag.Composite & (1 << spot_index)) ); }
COORDINATE Closest_Free_Spot(COORDINATE coord, bool any=false) const;
COORDINATE Free_Spot(void) const {return Closest_Free_Spot(Cell_Coord());};
bool Is_Generally_Clear(bool ignore_cloaked = false) const;
TARGET As_Target(void) const {return ::As_Target(Cell_Number());};
BuildingClass * Cell_Building(void) const;
CellClass const & Adjacent_Cell(FacingType face) const;
CellClass & Adjacent_Cell(FacingType face) {return (CellClass &)((*((CellClass const *)this)).Adjacent_Cell(face));};
COORDINATE Cell_Coord(void) const;
int Cell_Color(bool override=false) const;
CELL Cell_Number(void) const;
LandType Land_Type(void) const {return((OverrideLand != LAND_COUNT) ? OverrideLand : Land);};
ObjectClass * Cell_Find_Object(RTTIType rtti) const;
ObjectClass * Cell_Object(int x=0, int y=0) const;
TechnoClass * Cell_Techno(int x=0, int y=0) const;
TerrainClass * Cell_Terrain(void) const;
UnitClass * Cell_Unit(void) const;
InfantryClass * Cell_Infantry(void) const;
TriggerClass * Get_Trigger(void) const;
int Clear_Icon(void) const;
bool Goodie_Check(FootClass * object);
ObjectClass * Fetch_Occupier(void) const;
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(FileClass & file);
bool Load(FileClass & file);
void Code_Pointers(void);
void Decode_Pointers(void);
/*
** Display and rendering controls.
*/
void Draw_It(int x, int y, int draw_flags = 0) const;
void Redraw_Objects(bool forced=false);
void Shimmer(void);
/*
** Maintenance calculation support.
*/
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;};
int Validate(void) const;
/*
** Additional per-player functionality is needed for multiplayer. ST - 3/5/2019 3:03PM
*/
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;
/*
** Override land type to fix passability issues on some maps
*/
void Override_Land_Type(LandType type);
#ifdef USE_RA_AI
/*
** Imported from RA for AI. ST - 7/24/2019 5:36PM
*/
bool Is_Clear_To_Move(bool ignoreinfantry, bool ignorevehicles) const;
#endif
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

69
TIBERIANDAWN/CHECKBOX.CPP Normal file
View File

@@ -0,0 +1,69 @@
//
// 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&c\vcs\code\checkbox.cpv 1.6 16 Oct 1995 16:49: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 : CHECKBOX.CPP *
* *
* Programmer : Joe L. Bostic *
* *
* Start Date : 05/26/95 *
* *
* Last Update : July 1, 1995 [JLB] *
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* 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_GREEN_DOWN, false);
LogicPage->Fill_Rect(X+1, Y+1, X+Width-2, Y+Height-2, DKGREY);
if (IsOn) {
LogicPage->Draw_Line(X+1, Y+1, X+Width-2, Y+Height-2, BLACK);
LogicPage->Draw_Line(X+Width-2, Y+1, X+1, Y+Height-2, BLACK);
}
Show_Mouse();
return(true);
}
return(false);
}

52
TIBERIANDAWN/CHECKBOX.H Normal file
View File

@@ -0,0 +1,52 @@
//
// 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&c\vcs\code\checkbox.h_v 1.6 16 Oct 1995 16:46:00 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);
protected:
};
#endif

165
TIBERIANDAWN/CHEKLIST.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: F:\projects\c&c\vcs\code\cheklist.cpv 2.18 16 Oct 1995 16:48: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 : CHEKLIST.CPP *
* *
* Programmer : Bill Randolph *
* *
* Start Date : February 16, 1995 *
* *
* Last Update : February 16, 1995 [BR] *
* *
*-------------------------------------------------------------------------*
* Functions: *
* CheckListClass::Action -- action function for this class *
* CheckListClass::CheckListClass -- constructor *
* CheckListClass::Check_Item -- [un]checks an items *
* 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::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. *
*=========================================================================*/
void CheckListClass::Check_Item(int index, int checked)
{
if (List[index]) {
((char &)List[index][0]) = checked ? CHECK_CHAR : UNCHECK_CHAR;
}
}
/***************************************************************************
* 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. *
*=========================================================================*/
int CheckListClass::Is_Checked(int index) const
{
if (List[index]) {
return(List[index][0] == CHECK_CHAR);
}
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) {
if (Is_Checked(SelectedIndex)) {
Check_Item(SelectedIndex,0);
} else {
Check_Item(SelectedIndex,1);
}
}
return(rc);
}

83
TIBERIANDAWN/CHEKLIST.H Normal file
View File

@@ -0,0 +1,83 @@
//
// 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&c\vcs\code\cheklist.h_v 2.19 16 Oct 1995 16:46:20 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 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) {};
/*---------------------------------------------------------------------
Checkmark utility functions
---------------------------------------------------------------------*/
void Check_Item(int index, int checked); // sets checked state of item
int Is_Checked(int index) const; // gets checked state of item
/*---------------------------------------------------------------------
This defines the ASCII value of the checkmark character & non-checkmark
character.
---------------------------------------------------------------------*/
enum CheckListClassEnum {
CHECK_CHAR = '\3',
UNCHECK_CHAR = ' ',
};
void Set_Read_Only(int rdonly) {IsReadOnly = rdonly ? true : false;}
protected:
virtual int Action(unsigned flags, KeyNumType &key);
private:
bool IsReadOnly;
};
#endif
/************************** end of cheklist.h ******************************/

280
TIBERIANDAWN/COLRLIST.CPP Normal file
View File

@@ -0,0 +1,280 @@
//
// 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&c\vcs\code\colrlist.cpv 1.9 16 Oct 1995 16:50: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 : LIST.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 = -1;
}
/***************************************************************************
* ColorListClass::~ColorListClass -- Class destructor *
* *
* INPUT: *
* none. *
* *
* OUTPUT: *
* none. *
* *
* WARNINGS: *
* none. *
* *
* HISTORY: *
* 04/19/1995 BRR : Created. *
*=========================================================================*/
ColorListClass::~ColorListClass(void)
{
Colors.Clear();
}
/***************************************************************************
* 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, char 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, char 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, int 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)
{
int 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==-1) {
color = Colors[index];
} else {
color = SelectColor;
}
switch (Style) {
/*
** NONE: Just print the string in its native color
*/
case SELECT_NONE:
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);
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, SelectColor);
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, SelectColor);
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:
if (TextFlags & TPF_6PT_GRAD) {
LogicPage->Fill_Rect (x, y, x + width - 1, y + LineHeight - 1, Colors[index]);
Conquer_Clip_Text_Print(List[index], x, y, BLACK, TBLACK, TextFlags, width, Tabs);
} else {
LogicPage->Fill_Rect (x, y, x + width - 2, y + LineHeight - 2, Colors[index]);
Conquer_Clip_Text_Print(List[index], x, y, LTGREY, TBLACK, TextFlags, width, Tabs);
}
break;
}
}

84
TIBERIANDAWN/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: F:\projects\c&c\vcs\code\colrlist.h_v 1.10 16 Oct 1995 16:47:16 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
*/
typedef enum SelectEnum {
SELECT_NONE, // 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, char color = WHITE);
virtual int Add_Item(int text, char color = WHITE);
virtual void Remove_Item(char const * text);
virtual void Set_Selected_Style(SelectStyleType style, int color = -1);
/*
** This is the list of colors for each item.
*/
DynamicVectorClass<char> 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;
int SelectColor;
};
#endif

232
TIBERIANDAWN/COMBAT.CPP Normal file
View File

@@ -0,0 +1,232 @@
//
// 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&c\vcs\code\combat.cpv 2.17 16 Oct 1995 16:48:32 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 : January 1, 1995 [JLB] *
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* Explosion_Damage -- Inflict an explosion damage affect. *
* Modify_Damage -- Adjusts damage to reflect the nature of the target. *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "function.h"
int Modify_Damage(int damage, WarheadType warhead, ArmorType armor);
void Explosion_Damage(COORDINATE coord, unsigned strength, TechnoClass *source, WarheadType warhead);
/***********************************************************************************************
* 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. *
*=============================================================================================*/
int Modify_Damage(int damage, WarheadType warhead, ArmorType armor, int distance)
{
/*
** 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);
WarheadTypeClass const * whead = &Warheads[warhead];
damage = Fixed_To_Cardinal(damage, whead->Modifier[armor]);
/*
** Reduce damage according to the distance from the impact point.
*/
if (damage) {
// if (distance < 0x0010) damage *= 2; // Double damage for direct hits.
distance >>= whead->SpreadFactor;
distance = Bound(distance, 0, 16);
damage >>= distance;
}
/*
** If damage was indicated, then it should never drop below one damage point regardless
** of modifiers. This allows a very weak attacker to eventually destroy anything it
** fires upon, given enough time.
*/
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. *
*=============================================================================================*/
void Explosion_Damage(COORDINATE coord, unsigned 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 index;
int count; // Number of vehicle IDs in list.
if (!strength || Special.IsInert || warhead == WARHEAD_NONE) return;
WarheadTypeClass const * whead = &Warheads[warhead];
range = ICON_LEPTON_W + (ICON_LEPTON_W >> 1);
cell = Coord_Cell(coord);
if ((unsigned)cell >= MAP_CELL_TOTAL) return;
// if (!Map.In_Radar(cell)) 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 >= (sizeof(objects)/sizeof(objects[0]))) break;
}
object = object->Next;
}
if (count >= (sizeof(objects)/sizeof(objects[0]))) 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 (index = 0; index < count; index++) {
object = objects[index];
object->IsToDamage = false;
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;
/*
** High explosive does double damage against aircraft.
*/
if (warhead == WARHEAD_HE && object->What_Am_I() == RTTI_AIRCRAFT) {
damage *= 2;
}
/*
** Apply the damage to the object.
*/
if (damage) {
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];
cellptr->Reduce_Tiberium(strength / 10);
if (cellptr->Overlay != OVERLAY_NONE) {
OverlayTypeClass const * optr = &OverlayTypeClass::As_Reference(cellptr->Overlay);
if (optr->IsWall) {
if (whead->IsWallDestroyer || (whead->IsWoodDestroyer && optr->IsWooden)) {
Map[cell].Reduce_Wall(strength);
}
}
}
}

1036
TIBERIANDAWN/COMBUF.CPP Normal file

File diff suppressed because it is too large Load Diff

178
TIBERIANDAWN/COMBUF.H Normal file
View File

@@ -0,0 +1,178 @@
//
// 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&c\vcs\code\combuf.h_v 1.6 16 Oct 1995 16:46:00 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
} 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 CommBufferClass
{
/*
---------------------------- Public Interface ----------------------------
*/
public:
/*
....................... Constructor/Destructor ........................
*/
CommBufferClass(int numsend, int numrecieve, int maxlen);
virtual ~CommBufferClass();
void Init(void);
void Init_Send_Queue(void);
/*
......................... Send Queue routines .........................
*/
int Queue_Send(void *buf, int buflen); // add to Send queue
int UnQueue_Send(void *buf, int *buflen, int index); // remove from Send queue
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, int index); // remove from Receive queue
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
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 DebugMaxNames; // max # of names in array
};
#endif
/**************************** end of combuf.h ******************************/

170
TIBERIANDAWN/COMPAT.H Normal file
View File

@@ -0,0 +1,170 @@
//
// 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&c\vcs\code\compat.h_v 2.19 16 Oct 1995 16:46: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 : COMPAT.H *
* *
* Programmer : Joe L. Bostic *
* *
* Start Date : 03/02/95 *
* *
* Last Update : March 2, 1995 [JLB] *
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef COMPAT_H
#define COMPAT_H
//#include "i86.h"
#define KeyNumType int
#define KeyASCIIType int
#define BuffType BufferClass
#define movmem(a,b,c) memmove(b,a,c)
#define ShapeBufferSize _ShapeBufferSize
extern "C" {
extern long ShapeBufferSize;
extern char *ShapeBuffer;
}
/*=========================================================================*/
/* 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;
#define BITSPERBYTE 8
#define MAXSHORT 0x7fff
#define HIBITS 0x8000
//#define MAXLONG 0x7fffffffL
#define HIBITL 0x80000000
//PG_TO_FIX
#ifndef MAXINT
#define MAXINT MAXLONG
#endif
#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
/* 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
#if 0
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?
long Size; // Size of entire iconset memory block.
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.
unsigned char * Map; // Icon map offset (if present).
} IControl_Type;
#endif
void Stuff_Key_Num ( int );
extern "C"{
extern int MouseQX;
extern int MouseQY;
}
#endif

1009
TIBERIANDAWN/COMQUEUE.CPP Normal file

File diff suppressed because it is too large Load Diff

190
TIBERIANDAWN/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&c\vcs\code\comqueue.h_v 1.12 16 Oct 1995 16:45:08 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 *****************************/

247
TIBERIANDAWN/CONFDLG.CPP Normal file
View File

@@ -0,0 +1,247 @@
//
// 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&c\vcs\code\confdlg.cpv 2.17 16 Oct 1995 16:49: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)
{
return(Process(Text_String(text)));
}
/***********************************************************************************************
* 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)
{
int factor = (SeenBuff.Get_Width() == 320) ? 1 : 2;
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;
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*factor, width, height);
width += 60*factor;
height += 60*factor;
int x = (320*factor - width) / 2;
int y = (200*factor - 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), 30U);
TextButtonClass yesbtn(BUTTON_YES, TXT_YES,
TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW,
x + 10*factor, y + height - (bheight + 5*factor), bwidth );
TextButtonClass nobtn(BUTTON_NO, TXT_NO,
TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW,
x + width - (bwidth + 10*factor),
y + height - (bheight + 5*factor), 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, SeenBuff.Get_Width(), SeenBuff.Get_Height(), 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 (GameToPlay == GAME_NORMAL) {
Call_Back();
} else {
if (Main_Loop()) {
process = false;
result = false;
}
}
/*
** 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=TRUE;
}
/*
** 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*factor, y+30*factor, CC_GREEN, 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 (BUTTON_YES | KN_BUTTON):
selection = BUTTON_YES;
pressed = true;
break;
case (KN_ESC):
case (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;
}
pressed = false;
}
}
return(result);
}

53
TIBERIANDAWN/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&c\vcs\code\confdlg.h_v 2.18 16 Oct 1995 16:46:06 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

248
TIBERIANDAWN/CONNECT.CPP Normal file
View File

@@ -0,0 +1,248 @@
//
// 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&c\vcs\code\connect.cpv 1.9 16 Oct 1995 16:48:56 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::Service -- main polling routine; services packets *
* ConnectionClass::Time -- gets current time *
* ConnectionClass::Command_Name -- returns name for a packet command *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "function.h"
#ifdef WWLIB32_H
#include "TIMER.H"
#else
#include <sys\timeb.h>
#endif
/*
********************************* Globals ***********************************
*/
char *ConnectionClass::Commands[PACKET_COUNT] = {
"ADATA",
"NDATA",
"ACK"
};
/***************************************************************************
* ConnectionClass::ConnectionClass -- class constructor *
* *
* If either max_retries or timeout is -1, that parameter is ignored in *
* timeout computations. If both are -1, the connection will just keep *
* retrying forever. *
* *
* INPUT: *
* numsend desired # of entries for the send queue *
* numreceive desired # of entries for the recieve 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) *
* *
* OUTPUT: *
* none. *
* *
* WARNINGS: *
* none. *
* *
* HISTORY: *
* 12/20/1994 BR : Created. *
*=========================================================================*/
ConnectionClass::ConnectionClass (int maxlen, unsigned short magicnum,
unsigned long retry_delta, unsigned long max_retries, unsigned long timeout)
{
/*------------------------------------------------------------------------
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 ];
} /* 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;
} /* end of ~ConnectionClass */
/***************************************************************************
* 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.
------------------------------------------------------------------------*/
// if (!Service_Send_Queue())
// return(0);
/*------------------------------------------------------------------------
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_Receive_Queue())
// return(0);
// return(1);
if ( Service_Send_Queue() && Service_Receive_Queue() ) {
return(1);
} else {
return(0);
}
} /* end of Service */
// ST = 12/17/2018 5:44PM
#ifndef TickCount
extern TimerClass TickCount;
#endif
/***************************************************************************
* ConnectionClass::Time -- gets current time *
* *
* INPUT: *
* *
* OUTPUT: *
* none. *
* *
* WARNINGS: *
* none. *
* *
* HISTORY: *
* 12/20/1994 BR : Created. *
*=========================================================================*/
unsigned long ConnectionClass::Time (void)
{
#ifdef WWLIB32_H
return(TickCount.Time()); // Westwood Library time
#else
static struct timeb mytime; // DOS time
unsigned long msec;
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);
}
}

340
TIBERIANDAWN/CONNECT.H Normal file
View File

@@ -0,0 +1,340 @@
//
// 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&c\vcs\code\connect.h_v 1.12 16 Oct 1995 16:46:04 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 CommQueueClass 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 routine will handle all ACK & Retry logic for *
* communicating between this system & another. Thus, any class derived *
* from this class must provide the basic ACK/Retry logic. *
* *
* THE 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: *
* The packet's ID is used to check for re-sends. The ID is set to the *
* Queue's total Send Count; if the receiving system checks this value, *
* and it's less than that system's Receive Count, this is a resend. *
* (ie packet 0 will be the 1st packet sent, since the Send Queue's count *
* is 0 when it's sent; as soon as it's received, the Receive Count goes *
* up to 1, and an ID of 0 then means a resend.) This scheme keeps the *
* application from seeing the same packet twice. All the Connection *
* Manager has to do is mark the resent packet as non-ACK'd. Of course, *
* the Manager doesn't have to use this value at all. *
* *
* Both DATA_ACK packets and DATA_NOACK packets must go through the Send *
* Queue when "sent", so that the SendTotal value for this system *
* will still match the ReceiveTotal value for the other system; this is *
* why a NOACK packet can't just be sent immediately; it must go through *
* the queue. *
* *
* 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 a version of Init that gives the connection *
* access to any hardware-specific values it needs *
* Must chain to the parent's Init routine. *
* - Send_Packet adds the CommHeaderType header, adds the packet *
* to the out-going queue *
* - Receive_Packet processes incoming ACK packets, detects resends,*
* adds new packets to the in-coming queue *
* - Get_Packet reads the next-available packet from the *
* receive queue *
* - Send the hardware-dependent data-sending routine *
* - Service_Send_Queue services the send queue; handles re-sends, *
* detects when outgoing packets have been ACK'd; *
* cleans out the queue of old packets *
* - Service_Receive_Queue services the receive queue; handles sending *
* ACK's for new or re-sent packets; cleans out *
* the queue of old packets *
* *
* Any other routines can be overloaded as the derived class needs. *
* *
* CLASS HIERARCHY: *
* ConnectionClass *
* | *
* | *
* -------------------------------------- *
* | | *
* | | *
* SequencedConnClass NonSequencedConnClass *
* | | *
* | | *
* IPXConnClass ------------------------ *
* | | | *
* | | | *
* IPXGlobalConnClass NullModemConnClass ModemConnClass *
* *
* *
* ConnectionClass: *
* Abstract base class. *
* Provides: Queue for sent/recv'd packets *
* PacketBuf for preparing packets *
* Timeout variables *
* Service() routine *
* *
* SequencedConnClass: *
* Abstract base class *
* Provides: * "Sequenced" ACK/Retry logic, in Service_Send_Queue() & *
* Service_Receive_Queue() routines *
* * Send_Packet(): adds header to packet, adds it to Queue *
* * Receive_Packet(): adds incoming packet to receive Queue, *
* handles incoming ACK's & resends *
* * Get_Packet(): gets packet from the receive queue *
* *
* NonSequencedConnClass: *
* Abstract base class *
* Provides: * "Non-Sequenced" ACK/Retry logic, in Service_Send_Queue() *
* & Service_Receive_Queue() routines *
* * Send_Packet(): adds header to packet, adds it to Queue *
* * Receive_Packet(): adds incoming packet to receive Queue, *
* handles incoming ACK's & resends *
* * Get_Packet(): gets packet from the receive queue *
* *
* IPXConnClass: *
* Provides: * Hardware-dependent IPX interface routines, which allow *
* Service_Send_Queue() & Service_Receive_Queue() to do *
* their job *
* * Ability to associate an IPX Address, a numerical ID, and *
* a character-string Name with a connection *
* Inherits: * Sequenced ACK/Retry logic, Service routines, Queue & *
* PacketBuf, timeout variables *
* *
* IPXGlobalConnClass: *
* Special type of IPX Connection; supports receiving packets from *
* multiple systems at once, and sending packets via Broadcast or *
* to a specific address. *
* Provides: * Specialized Receive_Packet() routine, which handles *
* receiving packets from multiple systems *
* * Specialized Send_Packet() & Get_Packet() routines, *
* which pass IPX address of destination through to *
* the application, giving the application control over *
* whether the packet will be Broadcast or sent to a *
* specific destination (embeds destination address within *
* the packet itself) *
* * Specialized Send routine, which extracts the destination *
* address from the packet *
* Inherits: * Sequenced ACK/Retry logic, Service routines, Queue & *
* PacketBuf, timeout variables, IPX-specific routines *
* *
* NullModemConnClass: *
* Provides: * Hardware-dependent Serial-communication routines, which *
* allow Service_Send_Queue() & Service_Receive_Queue() to *
* do their job *
* Inherits: * Non-Sequenced ACK/Retry logic, Service routines, Queue & *
* PacketBuf, timeout variables *
* *
* ModemConnClass: *
* Provides: * Hardware-dependent Modem-communication routines, which *
* allow Service_Send_Queue() & Service_Receive_Queue() to *
* do their job *
* Inherits: * Non-Sequenced ACK/Retry logic, Service routines, Queue & *
* PacketBuf, timeout variables *
* *
* So, do ya think this header is long enough, or what? *
* *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef CONNECTION_H
#define CONNECTION_H
#define CONN_DEBUG 0
/*
********************************** Defines **********************************
*/
/*---------------------------------------------------------------------------
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 maxlen, unsigned short magicnum,
unsigned long retry_delta, unsigned long max_retries,
unsigned long timeout);
virtual ~ConnectionClass ();
/*.....................................................................
Initialization.
.....................................................................*/
virtual void Init (void) {};
/*.....................................................................
Send/Receive routines.
.....................................................................*/
virtual int Send_Packet (void * buf, int buflen, int ack_req) = 0;
virtual int Receive_Packet (void * buf, int buflen) = 0;
virtual int Get_Packet (void * buf, int * buflen) = 0;
/*.....................................................................
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);
/*
-------------------------- Protected Interface ---------------------------
*/
protected:
/*.....................................................................
Routines to service the Send & Receive queues.
.....................................................................*/
virtual int Service_Send_Queue(void) = 0;
virtual int Service_Receive_Queue(void) = 0;
/*.....................................................................
This routine actually performs a hardware-dependent data send. It's
pure virtual, so it >must< be defined by a derived class.
.....................................................................*/
virtual int Send(char *buf, int buflen) = 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;
/*.....................................................................
Names of all packet commands
.....................................................................*/
static char *ConnectionClass::Commands[PACKET_COUNT];
};
#endif

148
TIBERIANDAWN/CONNMGR.H Normal file
View File

@@ -0,0 +1,148 @@
//
// 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\connmgr.h_v 1.25 02 Jan 1996 11:14:54 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 maxnames) = 0;
virtual void Mono_Debug_Print(int index, int refresh) = 0;
/*
--------------------------- 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

4259
TIBERIANDAWN/CONQUER.CPP Normal file

File diff suppressed because it is too large Load Diff

772
TIBERIANDAWN/CONQUER.H Normal file
View File

@@ -0,0 +1,772 @@
//
// 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_BUTTON_UPGRADE 2 // Upgrade
#define TXT_UPGRADE 3 // Upgrade Structure
#define TXT_UPGRADE_BUTTON 4 // Upgrade
#define TXT_BUTTON_SELL 5 // Sell
#define TXT_SELL 6 // Sell Structure
#define TXT_DEMOLISH 7 // Demolish Structure
#define TXT_BUTTON_REPAIR 8 // Repair
#define TXT_REPAIR 9 // Repair Structure
#define TXT_REPAIR_BUTTON 10 // Repair
#define TXT_YOU 11 // You:
#define TXT_ENEMY 12 // Enemy:
#define TXT_BUILD_DEST 13 // Buildings Destroyed By
#define TXT_UNIT_DEST 14 // Units Destroyed By
#define TXT_TIB_HARV 15 // Tiberium Harvested By
#define TXT_SCORE_1 16 // Score: %d
#define TXT_RANK_OF 17 // You have attained the rank
#define TXT_YES 18 // Yes
#define TXT_NO 19 // No
#define TXT_READY 20 // Ready
#define TXT_HOLDING 21 // Holding
#define TXT_SCENARIO_WON 22 // Accomplished
#define TXT_SCENARIO_LOST 23 // Failed
#define TXT_CHOOSE_SIDE 24 // Choose Your Side
#define TXT_START_NEW_GAME 25 // Start New Game
#define TXT_INTRO 26 // Intro & Sneak Peek
#define TXT_CANCEL 27 // Cancel
#define TXT_ROCK 28 // Rock
#define TXT_CHOAM_RESUME 29 // Resume Game
#define TXT_CHOAM_BUILD_THIS 30 // Build This
#define TXT_THANK_YOU 31 // Thank you for playing
#define TXT_FAME 32 // Hall of Fame
#define TXT_GDI 33 // Global Defense Initiative
#define TXT_NOD 34 // Brotherhood of Nod
#define TXT_CIVILIAN 35 // Civilian
#define TXT_JP 36 // Containment Team
#define TXT_OK 37 // OK
#define TXT_TREE 38 // Tree
#define TXT_LEFT 39 // 
#define TXT_RIGHT 40 // 
#define TXT_UP 41 // 
#define TXT_DOWN 42 // 
#define TXT_CLEAR_MAP 43 // Clear the map
#define TXT_INHERIT_MAP 44 // Inherit previous map
#define TXT_CLEAR 45 // Clear
#define TXT_WATER 46 // Water
#define TXT_ROAD 47 // Road
#define TXT_TILE 48 // Tile Object
#define TXT_SLOPE 49 // Slope
#define TXT_BRUSH 50 // Brush
#define TXT_PATCH 51 // Patch
#define TXT_RIVER 52 // River
#define TXT_LOAD_MISSION 53 // Load Mission
#define TXT_SAVE_MISSION 54 // Save Mission
#define TXT_DELETE_MISSION 55 // Delete Mission
#define TXT_LOAD_BUTTON 56 // Load
#define TXT_SAVE_BUTTON 57 // Save
#define TXT_DELETE_BUTTON 58 // Delete
#define TXT_GAME_CONTROLS 59 // Game Controls
#define TXT_SOUND_CONTROLS 60 // Sound Controls
#define TXT_RESUME_MISSION 61 // Resume Mission
#define TXT_VISUAL_CONTROLS 62 // Visual Controls
#define TXT_QUIT_MISSION 63 // Abort Mission
#define TXT_EXIT_GAME 64 // Exit Game
#define TXT_OPTIONS 65 // Options
#define TXT_TIBERIUM 66 // Tiberium
#define TXT_TIBERIUM_ON 67 // Tiberium On
#define TXT_TIBERIUM_OFF 68 // Tiberium Off
#define TXT_SQUISH 69 // Squish mark
#define TXT_CRATER 70 // Crater
#define TXT_SCORCH 71 // Scorch Mark
#define TXT_BRIGHTNESS 72 // BRIGHTNESS:
#define TXT_MUSIC 73 // MUSIC VOLUME
#define TXT_VOLUME 74 // SOUND VOLUME
#define TXT_TINT 75 // TINT:
#define TXT_CONTRAST 76 // CONTRAST:
#define TXT_SPEED 77 // GAME SPEED:
#define TXT_SCROLLRATE 78 // SCROLL RATE:
#define TXT_COLOR 79 // COLOR:
#define TXT_RETURN_TO_GAME 80 // Return to game
#define TXT_ENEMY_SOLDIER 81 // Enemy Soldier
#define TXT_ENEMY_VEHICLE 82 // Enemy Vehicle
#define TXT_ENEMY_STRUCTURE 83 // Enemy Structure
#define TXT_FTANK 84 // Flame Tank
#define TXT_STANK 85 // Stealth Tank
#define TXT_LTANK 86 // Light Tank
#define TXT_MTANK 87 // Med. Tank
#define TXT_HTANK 88 // Mammoth Tank
#define TXT_DUNE_BUGGY 89 // Nod Buggy
#define TXT_SAM 90 // SAM Site
#define TXT_EYE 91 // Advanced Com. Center
#define TXT_MLRS 92 // Rocket Launcher
#define TXT_MHQ 93 // Mobile HQ
#define TXT_JEEP 94 // Hum-vee
#define TXT_TRANS 95 // Transport Helicopter
#define TXT_A10 96 // A10
#define TXT_C17 97 // C17
#define TXT_HARVESTER 98 // Harvester
#define TXT_ARTY 99 // Artillery
#define TXT_MSAM 100 // S.S.M. Launcher
#define TXT_E1 101 // Minigunner
#define TXT_E2 102 // Grenadier
#define TXT_E3 103 // Bazooka
#define TXT_E4 104 // Flamethrower
#define TXT_E5 105 // Chem-warrior
#define TXT_RAMBO 106 // Commando
#define TXT_HOVER 107 // Hovercraft
#define TXT_HELI 108 // Attack Helicopter
#define TXT_ORCA 109 // Orca
#define TXT_APC 110 // APC
#define TXT_GUARD_TOWER 111 // Guard Tower
#define TXT_COMMAND 112 // Communications Center
#define TXT_HELIPAD 113 // Helicopter Pad
#define TXT_AIRSTRIP 114 // Airstrip
#define TXT_STORAGE 115 // Tiberium Silo
#define TXT_CONST_YARD 116 // Construction Yard
#define TXT_REFINERY 117 // Tiberium Refinery
#define TXT_CIV1 118 // Church
#define TXT_CIV2 119 // Han's and Gretel's
#define TXT_CIV3 120 // Hewitt's Manor
#define TXT_CIV4 121 // Ricktor's House
#define TXT_CIV5 122 // Gretchin's House
#define TXT_CIV6 123 // The Barn
#define TXT_CIV7 124 // Damon's pub
#define TXT_CIV8 125 // Fran's House
#define TXT_CIV9 126 // Music Factory
#define TXT_CIV10 127 // Toymaker's
#define TXT_CIV11 128 // Ludwig's House
#define TXT_CIV12 129 // Haystacks
#define TXT_CIV13 130 // Haystack
#define TXT_CIV14 131 // Wheat Field
#define TXT_CIV15 132 // Fallow Field
#define TXT_CIV16 133 // Corn Field
#define TXT_CIV17 134 // Celery Field
#define TXT_CIV18 135 // Potato Field
#define TXT_CIV20 136 // Sala's House
#define TXT_CIV21 137 // Abdul's House
#define TXT_CIV22 138 // Pablo's Wicked Pub
#define TXT_CIV23 139 // Village Well
#define TXT_CIV24 140 // Camel Trader
#define TXT_CIV25 141 // Church
#define TXT_CIV26 142 // Ali's House
#define TXT_CIV27 143 // Trader Ted's
#define TXT_CIV28 144 // Menelik's House
#define TXT_CIV29 145 // Prestor John's House
#define TXT_CIV30 146 // Village Well
#define TXT_CIV31 147 // Witch Doctor's Hut
#define TXT_CIV32 148 // Rikitikitembo's Hut
#define TXT_CIV33 149 // Roarke's Hut
#define TXT_CIV34 150 // Mubasa's Hut
#define TXT_CIV35 151 // Aksum's Hut
#define TXT_CIV36 152 // Mambo's Hut
#define TXT_CIV37 153 // The Studio
#define TXT_CIVMISS 154 // Technology Center
#define TXT_TURRET 155 // Gun Turret
#define TXT_GUNBOAT 156 // Gun Boat
#define TXT_MCV 157 // Mobile Construction Yard
#define TXT_BIKE 158 // Recon Bike
#define TXT_POWER 159 // Power Plant
#define TXT_ADVANCED_POWER 160 // Advanced Power Plant
#define TXT_HOSPITAL 161 // Hospital
#define TXT_BARRACKS 162 // Barracks
#define TXT_CONCRETE 163 // Concrete
#define TXT_PUMP 164 // Oil Pump
#define TXT_TANKER 165 // Oil Tanker
#define TXT_SANDBAG_WALL 166 // Sandbag Wall
#define TXT_CYCLONE_WALL 167 // Chain Link Fence
#define TXT_BRICK_WALL 168 // Concrete Wall
#define TXT_BARBWIRE_WALL 169 // Barbwire Fence
#define TXT_WOOD_WALL 170 // Wood Fence
#define TXT_WEAPON_FACTORY 171 // Weapons Factory
#define TXT_AGUARD_TOWER 172 // Advanced Guard Tower
#define TXT_OBELISK 173 // Obelisk Guard Tower
#define TXT_BIO_LAB 174 // Bio-Research Laboratory
#define TXT_HAND 175 // Hand of Nod
#define TXT_TEMPLE 176 // Temple of Nod
#define TXT_FIX_IT 177 // Repair Bay
#define TXT_TAB_SIDEBAR 178 // Sidebar
#define TXT_TAB_BUTTON_CONTROLS 179 // Options
#define TXT_TAB_BUTTON_DATABASE 180 // Database
#define TXT_SHADOW 181 // Unrevealed Terrain
#define TXT_OPTIONS_MENU 182 // Options Menu
#define TXT_STOP 183 // STOP
#define TXT_PLAY 184 // PLAY
#define TXT_SHUFFLE 185 // SHUFFLE
#define TXT_REPEAT 186 // REPEAT
#define TXT_MUSIC_VOLUME 187 // Music volume:
#define TXT_SOUND_VOLUME 188 // Sound volume:
#define TXT_ON 189 // On
#define TXT_OFF 190 // Off
#define TXT_THEME_AOI 191 // Act On Instinct
#define TXT_THEME_TROUBLE 192 // Looks Like Trouble
#define TXT_THEME_IND 193 // Industrial
#define TXT_THEME_ROUT 194 // Reaching Out
#define TXT_THEME_OTP 195 // On The Prowl
#define TXT_THEME_PRP 196 // Prepare For Battle
#define TXT_THEME_JUSTDOIT 197 // Just Do It!
#define TXT_THEME_LINEFIRE 198 // In The Line Of Fire
#define TXT_THEME_MARCH 199 // March To Doom
#define TXT_THEME_STOPTHEM 200 // Deception
#define TXT_THEME_CCTHANG 201 // C&C Thang
#define TXT_THEME_BEFEARED 202 // Enemies To Be Feared
#define TXT_THEME_WARFARE 203 // Warfare
#define TXT_THEME_FWP 204 // Fight, Win, Prevail
#define TXT_THEME_DIE 205 // Die!!
#define TXT_THEME_NOMERCY 206 // No Mercy
#define TXT_THEME_TARGET 207 // Mechanical Man
#define TXT_THEME_IAM 208 // I Am
#define TXT_THEME_WIN1 209 // Great Shot!
#define TXT_MULTIPLAYER_GAME 210 // Multiplayer Game
#define TXT_NO_FILES 211 // No files available
#define TXT_DELETE_SINGLE_FILE 212 // Do you want to delete this
#define TXT_DELETE_MULTIPLE_FILES 213 // Do you want to delete %d
#define TXT_RESET_MENU 214 // Reset Values
#define TXT_CONFIRMATION 215 // Confirmation
#define TXT_CONFIRM_EXIT 216 // Do you want to abort the
#define TXT_MISSION_DESCRIPTION 217 // Mission Description
#define TXT_C1 218 // Joe
#define TXT_C2 219 // Bill
#define TXT_C3 220 // Shelly
#define TXT_C4 221 // Maria
#define TXT_C5 222 // Eydie
#define TXT_C6 223 // Dave
#define TXT_C7 224 // Phil
#define TXT_C8 225 // Dwight
#define TXT_C9 226 // Erik
#define TXT_MOEBIUS 227 // Dr. Moebius
#define TXT_BIB 228 // Road Bib
#define TXT_FASTER 229 // Faster
#define TXT_SLOWER 230 // Slower
#define TXT_ION_CANNON 231 // Ion Cannon
#define TXT_NUKE_STRIKE 232 // Nuclear Strike
#define TXT_AIR_STRIKE 233 // Air Strike
#define TXT_TREX 234 // Tyrannosaurus Rex
#define TXT_TRIC 235 // Triceratops
#define TXT_RAPT 236 // Velociraptor
#define TXT_STEG 237 // Stegasaurus
#define TXT_STEEL_CRATE 238 // Steel Crate
#define TXT_WOOD_CRATE 239 // Wood Crate
#define TXT_FLAG_SPOT 240 // Flag Location
#define TXT_G_D_I 241 // GDI
#define TXT_N_O_D 242 // NOD
#define TXT_UNABLE_READ_SCENARIO 243 // Unable to read scenario!
#define TXT_ERROR_LOADING_GAME 244 // Error loading game!
#define TXT_OBSOLETE_SAVEGAME 245 // Obsolete saved game.
#define TXT_MUSTENTER_DESCRIPTION 246 // You must enter a
#define TXT_ERROR_SAVING_GAME 247 // Error saving game!
#define TXT_DELETE_FILE_QUERY 248 // Delete this file?
#define TXT_EMPTY_SLOT 249 // [EMPTY SLOT]
#define TXT_SELECT_MPLAYER_GAME 250 // Select Multiplayer Game
#define TXT_MODEM_SERIAL 251 // Modem/Serial
#define TXT_NETWORK 252 // Network
#define TXT_INIT_NET_ERROR 253 // Unable to initialize
#define TXT_JOIN_NETWORK_GAME 254 // Join Network Game
#define TXT_NEW 255 // New
#define TXT_JOIN 256 // Join
#define TXT_SEND_MESSAGE 257 // Send Message
#define TXT_YOUR_NAME 258 // Your Name:
#define TXT_SIDE_COLON 259 // Side:
#define TXT_COLOR_COLON 260 // Color:
#define TXT_GAMES 261 // Games
#define TXT_PLAYERS 262 // Players
#define TXT_SCENARIO_COLON 263 // Scenario:
#define TXT_NOT_FOUND 264 // >> NOT FOUND <<
#define TXT_START_CREDITS_COLON 265 // Starting Credits:
#define TXT_BASES_COLON 266 // Bases:
#define TXT_TIBERIUM_COLON 267 // Tiberium:
#define TXT_CRATES_COLON 268 // Crates:
#define TXT_AI_PLAYERS_COLON 269 // AI Players:
#define TXT_REQUEST_DENIED 270 // Request denied.
#define TXT_UNABLE_PLAY_WAAUGH 271 // Unable to play; scenario
#define TXT_NOTHING_TO_JOIN 272 // Nothing to join!
#define TXT_NAME_ERROR 273 // You must enter a name!
#define TXT_DUPENAMES_NOTALLOWED 274 // Duplicate names are not
#define TXT_YOURGAME_OUTDATED 275 // Your game version is
#define TXT_DESTGAME_OUTDATED 276 // Destination game version is
#define TXT_THATGUYS_GAME 277 // %s's Game
#define TXT_THATGUYS_GAME_BRACKET 278 // [%s's Game]
#define TXT_NETGAME_SETUP 279 // Network Game Setup
#define TXT_REJECT 280 // Reject
#define TXT_CANT_REJECT_SELF 281 // You can't reject yourself!
#define TXT_SELECT_PLAYER_REJECT 282 // You must select a player to
#define TXT_BASES_ON 283 // Bases On
#define TXT_BASES_OFF 284 // Bases Off
#define TXT_CRATES_ON 285 // Crates On
#define TXT_CRATES_OFF 286 // Crates Off
#define TXT_AI_PLAYERS_ON 287 // AI Players On
#define TXT_AI_PLAYERS_OFF 288 // AI Players Off
#define TXT_SCENARIOS 289 // Scenarios
#define TXT_START_CREDITS 290 // Starting Credits
#define TXT_ONLY_ONE 291 // Only one player?
#define TXT_OOPS 292 // Oops!
#define TXT_TO 293 // To %s:
#define TXT_TO_ALL 294 // To All:
#define TXT_MESSAGE 295 // Message:
#define TXT_CONNECTION_LOST 296 // Connection to %s lost!
#define TXT_LEFT_GAME 297 // %s has left the game.
#define TXT_PLAYER_DEFEATED 298 // %s has been defeated!
#define TXT_WAITING_CONNECT 299 // Waiting to Connect...
#define TXT_NULL_CONNERR_CHECK_CABLES 300 // Connection error! Check
#define TXT_MODEM_CONNERR_REDIALING 301 // Connection
#define TXT_MODEM_CONNERR_WAITING 302 // Connection error! Waiting
#define TXT_SELECT_SERIAL_GAME 303 // Select Serial Game
#define TXT_DIAL_MODEM 304 // Dial Modem
#define TXT_ANSWER_MODEM 305 // Answer Modem
#define TXT_NULL_MODEM 306 // Null Modem
#define TXT_SETTINGS 307 // Settings
#define TXT_PORT_COLON 308 // Port:
#define TXT_IRQ_COLON 309 // IRQ:
#define TXT_BAUD_COLON 310 // Baud:
#define TXT_INIT_STRING 311 // Init String:
#define TXT_CWAIT_STRING 312 // Call Waiting String:
#define TXT_TONE_BUTTON 313 // Tone Dialing
#define TXT_PULSE_BUTTON 314 // Pulse Dialing
#define TXT_HOST_SERIAL_GAME 315 // Host Serial Game
#define TXT_OPPONENT_COLON 316 // Opponent:
#define TXT_USER_SIGNED_OFF 317 // User signed off!
#define TXT_JOIN_SERIAL_GAME 318 // Join Serial Game
#define TXT_PHONE_LIST 319 // Phone List
#define TXT_ADD 320 // Add
#define TXT_EDIT 321 // Edit
#define TXT_DIAL 322 // Dial
#define TXT_DEFAULT 323 // Default
#define TXT_DEFAULT_SETTINGS 324 // Default Settings
#define TXT_CUSTOM_SETTINGS 325 // Custom Settings
#define TXT_PHONE_LISTING 326 // Phone Listing
#define TXT_NAME_COLON 327 // Name:
#define TXT_NUMBER_COLON 328 // Number:
#define TXT_UNABLE_FIND_MODEM 329 // Unable to find modem. Check
#define TXT_NO_CARRIER 330 // No carrier.
#define TXT_LINE_BUSY 331 // Line busy.
#define TXT_NUMBER_INVALID 332 // Number invalid.
#define TXT_SYSTEM_NOT_RESPONDING 333 // Other system not
#define TXT_OUT_OF_SYNC 334 // Games are out of sync!
#define TXT_PACKET_TOO_LATE 335 // Packet received too late!
#define TXT_PLAYER_LEFT_GAME 336 // Other player has left the
#define TXT_FROM 337 // From %s:%s
#define TXT_MAP_P01 338 // 2,728,000
#define TXT_MAP_P02 339 // 38,385,000
#define TXT_MAP_P03 340 // 10,373,000
#define TXT_MAP_P04 341 // 51,994,000
#define TXT_MAP_P05 342 // 80,387,000
#define TXT_MAP_P06 343 // 10,400,000
#define TXT_MAP_P07 344 // 5,300,000
#define TXT_MAP_P08 345 // 7,867,000
#define TXT_MAP_P09 346 // 10,333,000
#define TXT_MAP_P10 347 // 1,974,000
#define TXT_MAP_P11 348 // 23,169,000
#define TXT_MAP_P12 349 // 10,064,000
#define TXT_MAP_P13 350 // 3,285,000
#define TXT_MAP_P14 351 // 8,868,000
#define TXT_MAP_P15 352 // 10,337,000
#define TXT_MAP_P16 353 // 4,365,000
#define TXT_MAP_P17 354 // 1,607,000
#define TXT_MAP_P18 355 // 4,485,000
#define TXT_MAP_P19 356 // 56,386,000
#define TXT_MAP_P20 357 // 28,305,000
#define TXT_MAP_P21 358 // 5,238,000
#define TXT_MAP_P22 359 // 2,059,000
#define TXT_MAP_P23 360 // 13,497,000
#define TXT_MAP_P24 361 // 4,997,000
#define TXT_MAP_P25 362 // 88,500,000
#define TXT_MAP_P26 363 // 1,106,000
#define TXT_MAP_P27 364 // 12,658,000
#define TXT_MAP_P28 365 // 3,029,000
#define TXT_MAP_P29 366 // 39,084,000
#define TXT_MAP_P30 367 // 23,154,000
#define TXT_MAP_P31 368 // 8,902,000
#define TXT_MAP_P32 369 // 27,791,000
#define TXT_MAP_P33 370 // 1,574,000
#define TXT_MAP_P34 371 // 15,469,000
#define TXT_MAP_P35 372 // 1,300,000
#define TXT_MAP_P36 373 // 41,688,000
#define TXT_MAP_A00 374 // 24,900 SQ. MI.
#define TXT_MAP_A01 375 // 120,727 SQ. MI.
#define TXT_MAP_A02 376 // 80,134 SQ. MI.
#define TXT_MAP_A03 377 // 233,100 SQ. MI.
#define TXT_MAP_A04 378 // 137,838 SQ. MI.
#define TXT_MAP_A05 379 // 30,449 SQ. MI.
#define TXT_MAP_A06 380 // 18,932 SQ. MI.
#define TXT_MAP_A07 381 // 32,377 SQ. MI.
#define TXT_MAP_A08 382 // 35,919 SQ. MI.
#define TXT_MAP_A09 383 // 7,819 SQ. MI.
#define TXT_MAP_A10 384 // 91,699 SQ. MI.
#define TXT_MAP_A11 385 // 51,146 SQ. MI.
#define TXT_MAP_A12 386 // 11,100 SQ. MI.
#define TXT_MAP_A13 387 // 44,365 SQ. MI.
#define TXT_MAP_A14 388 // 39,449 SQ. MI.
#define TXT_MAP_A15 389 // 19,741 SQ. MI.
#define TXT_MAP_A16 390 // 17,413 SQ. MI.
#define TXT_MAP_C00 391 // RIGA
#define TXT_MAP_C01 392 // WARSAW
#define TXT_MAP_C02 393 // MINSK
#define TXT_MAP_C03 394 // KIEV
#define TXT_MAP_C04 395 // BERLIN
#define TXT_MAP_C05 396 // PRAGUE
#define TXT_MAP_C06 397 // BRATISLAVA
#define TXT_MAP_C07 398 // VIENNA
#define TXT_MAP_C08 399 // BUDAPEST
#define TXT_MAP_C09 400 // LJUBLJANA
#define TXT_MAP_C10 401 // BUCHAREST
#define TXT_MAP_C11 402 // ATHENS
#define TXT_MAP_C12 403 // TIRANA
#define TXT_MAP_C13 404 // SOFIA
#define TXT_MAP_C14 405 // BELGRADE
#define TXT_MAP_C15 406 // SARAJEVO
#define TXT_MAP_C16 407 // TALLINN
#define TXT_MAP_C17 408 // TRIPOLI
#define TXT_MAP_C18 409 // CAIRO
#define TXT_MAP_C19 410 // KHARTOUM
#define TXT_MAP_C20 411 // N'DJAMENA
#define TXT_MAP_C21 412 // NOUAKCHOTT
#define TXT_MAP_C22 413 // YAMOUSSOUKRO
#define TXT_MAP_C23 414 // PORTO-NOVO
#define TXT_MAP_C24 415 // ABUJA
#define TXT_MAP_C25 416 // LIBREVILLE
#define TXT_MAP_C26 417 // YAOUNDE
#define TXT_MAP_C27 418 // BANGUI
#define TXT_MAP_C28 419 // KINSHASA
#define TXT_MAP_C29 420 // CAIRO
#define TXT_MAP_C30 421 // LUANDA
#define TXT_MAP_C31 422 // DAR-ES-SALAAM
#define TXT_MAP_C32 423 // WINDHOEK
#define TXT_MAP_C33 424 // MAPUTO
#define TXT_MAP_C34 425 // GABARONE
#define TXT_MAP_C35 426 // CAPE TOWN
#define TXT_MAP_GDP00 427 // NEGLIGIBLE
#define TXT_MAP_GDP01 428 // $162.7 BLN
#define TXT_MAP_GDP02 429 // $47.6 BLN
#define TXT_MAP_GDP03 430 // $1,131 BLN
#define TXT_MAP_GDP04 431 // $120 BLN
#define TXT_MAP_GDP05 432 // $164 BLN
#define TXT_MAP_GDP06 433 // $60.1 BLN
#define TXT_MAP_GDP07 434 // $21 BLN
#define TXT_MAP_GDP08 435 // $71.9 BLN
#define TXT_MAP_GDP09 436 // $77 BLN
#define TXT_MAP_GDP10 437 // $4.0 BLN
#define TXT_MAP_GDP11 438 // $47.3 BLN
#define TXT_MAP_GDP12 439 // $120.1 BLN
#define TXT_MAP_GDP13 440 // $14.0 BLN
#define TXT_MAP_GDP14 441 // $28.9 BLN
#define TXT_MAP_GDP15 442 // $39.2 BLN
#define TXT_MAP_GDP16 443 // $12.1 BLN
#define TXT_MAP_GDP17 444 // $1.0 BLN
#define TXT_MAP_GDP18 445 // $10.0 BLN
#define TXT_MAP_GDP19 446 // $1.7 BLN
#define TXT_MAP_GDP20 447 // $28.0 BLN
#define TXT_MAP_GDP21 448 // $5.3 BLN
#define TXT_MAP_GDP22 449 // $11.6 BLN
#define TXT_MAP_GDP23 450 // $1.3 BLN
#define TXT_MAP_GDP24 451 // $6.6 BLN
#define TXT_MAP_GDP25 452 // $8.3 BLN
#define TXT_MAP_GDP26 453 // $6.9 BLN
#define TXT_MAP_GDP27 454 // $2.0 BLN
#define TXT_MAP_GDP28 455 // $3.1 BLN
#define TXT_MAP_GDP29 456 // $104.0 BLN
#define TXT_MAP_PC00 457 // JELGAVA
#define TXT_MAP_PC01 458 // GDANSK
#define TXT_MAP_PC02 459 // BYELISTOK
#define TXT_MAP_PC03 460 // BOBYRUSK
#define TXT_MAP_PC04 461 // IVANO-FRANKOVSK
#define TXT_MAP_PC05 462 // HANOVER
#define TXT_MAP_PC06 463 // DRESDEN
#define TXT_MAP_PC07 464 // OSTRAVA
#define TXT_MAP_PC08 465 // BRATISLAVA
#define TXT_MAP_PC09 466 // SALZBURG
#define TXT_MAP_PC10 467 // BUDAPEST
#define TXT_MAP_PC11 468 // TRIESTE
#define TXT_MAP_PC12 469 // ARAD
#define TXT_MAP_PC13 470 // CORINTH
#define TXT_MAP_PC14 471 // SHKODER
#define TXT_MAP_PC15 472 // SOFIA
#define TXT_MAP_PC16 473 // NIS
#define TXT_MAP_PC17 474 // BELGRADE
#define TXT_MAP_PC18 475 // ?
#define TXT_MAP_PC19 476 // PARNU
#define TXT_MAP_PC20 477 // TMASSAH
#define TXT_MAP_PC21 478 // AL-ALAMYN
#define TXT_MAP_PC22 479 // AL-KHARIJAH
#define TXT_MAP_PC23 480 // AL-UBAYYID
#define TXT_MAP_PC24 481 // KAFIA-KINGI
#define TXT_MAP_PC25 482 // OUM HADJER
#define TXT_MAP_PC26 483 // MAO
#define TXT_MAP_PC27 484 // TIDJIKDJA
#define TXT_MAP_PC28 485 // ABIDJAN
#define TXT_MAP_PC29 486 // PORTO-NOVO
#define TXT_MAP_PC30 487 // ABUJA
#define TXT_MAP_PC31 488 // KOULA-MOUTOU
#define TXT_MAP_PC32 489 // BERTOUA
#define TXT_MAP_PC33 490 // BANGASSOU
#define TXT_MAP_PC34 491 // LODJA
#define TXT_MAP_PC35 492 // KINSHASA
#define TXT_MAP_PC36 493 // LUXOR
#define TXT_MAP_PC37 494 // CAIUNDO
#define TXT_MAP_PC38 495 // MZUZU
#define TXT_MAP_PC39 496 // KEETMANSHOOP
#define TXT_MAP_PC40 497 // XAI-XAI
#define TXT_MAP_PC41 498 // GHANZI
#define TXT_MAP_PC42 499 // CAPE TOWN
#define TXT_MAP_GDI 500 // GDI PROGRESSION
#define TXT_MAP_NOD 501 // NOD PROGRESSION
#define TXT_MAP_LOCATE 502 // LOCATING COORDINATES
#define TXT_MAP_NEXT_MISSION 503 // OF NEXT MISSION
#define TXT_MAP_SELECT 504 // SELECT TERRITORY
#define TXT_MAP_TO_ATTACK 505 // TO ATTACK
#define TXT_MAP_GDISTAT0 506 // POPULATION:
#define TXT_MAP_GDISTAT1 507 // GEOGRAPHIC AREA:
#define TXT_MAP_GDISTAT2 508 // CAPITAL:
#define TXT_MAP_GDISTAT3 509 // GOVERNMENT:
#define TXT_MAP_GDISTAT4 510 // GROSS DOMESTIC PRODUCT:
#define TXT_MAP_GDISTAT5 511 // POINT OF CONFLICT:
#define TXT_MAP_GDISTAT6 512 // MILITARY POWER:
#define TXT_MAP_NODSTAT0 513 // EXPENDABILITY:
#define TXT_MAP_NODSTAT1 514 // GOVT CORRUPTABILITY:
#define TXT_MAP_NODSTAT2 515 // NET WORTH:
#define TXT_MAP_NODSTAT3 516 // MILITARY STRENGTH:
#define TXT_MAP_NODSTAT4 517 // MILITARY RESISTANCE:
#define TXT_MAP_COUNTRYNAME0 518 // LATVIA
#define TXT_MAP_COUNTRYNAME1 519 // POLAND
#define TXT_MAP_COUNTRYNAME2 520 // BELARUS
#define TXT_MAP_COUNTRYNAME3 521 // UKRAINE
#define TXT_MAP_COUNTRYNAME4 522 // GERMANY
#define TXT_MAP_COUNTRYNAME5 523 // CZECH REPUBLIC
#define TXT_MAP_COUNTRYNAME6 524 // SLOVAKIA
#define TXT_MAP_COUNTRYNAME7 525 // AUSTRIA
#define TXT_MAP_COUNTRYNAME8 526 // HUNGARY
#define TXT_MAP_COUNTRYNAME9 527 // SLOVENIA
#define TXT_MAP_COUNTRYNAME10 528 // ROMANIA
#define TXT_MAP_COUNTRYNAME11 529 // GREECE
#define TXT_MAP_COUNTRYNAME12 530 // ALBANIA
#define TXT_MAP_COUNTRYNAME13 531 // BULGARIA
#define TXT_MAP_COUNTRYNAME14 532 // YUGOSLAVIA
#define TXT_MAP_COUNTRYNAME15 533 // BOSNIA/HERZOGOVINA
#define TXT_MAP_COUNTRYNAME16 534 // LIBYA
#define TXT_MAP_COUNTRYNAME17 535 // EGYPT
#define TXT_MAP_COUNTRYNAME18 536 // SUDAN
#define TXT_MAP_COUNTRYNAME19 537 // CHAD
#define TXT_MAP_COUNTRYNAME20 538 // MAURITANIA
#define TXT_MAP_COUNTRYNAME21 539 // IVORY COAST
#define TXT_MAP_COUNTRYNAME22 540 // BENIN
#define TXT_MAP_COUNTRYNAME23 541 // NIGERIA
#define TXT_MAP_COUNTRYNAME24 542 // GABON
#define TXT_MAP_COUNTRYNAME25 543 // CAMEROON
#define TXT_MAP_COUNTRYNAME26 544 // CENTRAL AFRICAN REPUBLIC
#define TXT_MAP_COUNTRYNAME27 545 // ZAIRE
#define TXT_MAP_COUNTRYNAME28 546 // ANGOLA
#define TXT_MAP_COUNTRYNAME29 547 // TANZANIA
#define TXT_MAP_COUNTRYNAME30 548 // NAMIBIA
#define TXT_MAP_COUNTRYNAME31 549 // MOZAMBIQUE
#define TXT_MAP_COUNTRYNAME32 550 // BOTSWANA
#define TXT_MAP_COUNTRYNAME33 551 // SOUTH AFRICA
#define TXT_MAP_COUNTRYNAME34 552 // ESTONIA
#define TXT_MAP_GOVT0 553 // REPUBLIC
#define TXT_MAP_GOVT1 554 // DEMOCRATIC STATE
#define TXT_MAP_GOVT2 555 // FEDERAL REPUBLIC
#define TXT_MAP_GOVT3 556 // CONST. REPUBLIC
#define TXT_MAP_GOVT4 557 // PARL. DEMOCRACY
#define TXT_MAP_GOVT5 558 // PRES. PARL. REPUBLIC
#define TXT_MAP_GOVT6 559 // DEMOCRACY
#define TXT_MAP_GOVT7 560 // IN TRANSITION
#define TXT_MAP_GOVT8 561 // ISLAMIC SOCIALIST
#define TXT_MAP_GOVT9 562 // MILITARY
#define TXT_MAP_GOVT10 563 // ISLAMIC REPUBLIC
#define TXT_MAP_GOVT11 564 // PARL. REPUBLIC
#define TXT_MAP_ARMY0 565 // LOCAL MILITIA
#define TXT_MAP_ARMY1 566 // STATE MILITIA
#define TXT_MAP_ARMY2 567 // NATIONAL GUARD
#define TXT_MAP_ARMY3 568 // FREE STANDING ARMY
#define TXT_MAP_ARMY4 569 // ?
#define TXT_MAP_ARMY5 570 // NATIONAL POWER
#define TXT_MAP_MILITARY0 571 // RESPECTABLE
#define TXT_MAP_MILITARY1 572 // FORMIDABLE
#define TXT_MAP_MILITARY2 573 // LAUGHABLE
#define TXT_MAP_MILITARY3 574 // REASONABLE
#define TXT_MAP_MILITARY4 575 // INSIGNIFICANT
#define TXT_MAP_CLICK2 576 // CLICK TO CONTINUE
#define TXT_MAP_LMH0 577 // LOW
#define TXT_MAP_LMH1 578 // MEDIUM
#define TXT_MAP_LMH2 579 // HIGH
#define TXT_SCORE_TIME 580 // TIME:
#define TXT_SCORE_LEAD 581 // LEADERSHIP:
#define TXT_SCORE_EFFI 582 // EFFICIENCY:
#define TXT_SCORE_TOTA 583 // TOTAL SCORE:
#define TXT_SCORE_CASU 584 // CASUALTIES:
#define TXT_SCORE_NEUT 585 // NEUTRAL:
#define TXT_SCORE_GDI 586 // GDI:
#define TXT_SCORE_BUIL 587 // BUILDINGS LOST
#define TXT_SCORE_BUIL1 588 // BUILDINGS
#define TXT_SCORE_BUIL2 589 // LOST:
#define TXT_SCORE_TOP 590 // TOP SCORES
#define TXT_SCORE_ENDCRED 591 // ENDING CREDITS:
#define TXT_SCORE_TIMEFORMAT1 592 // %dh %dm
#define TXT_SCORE_TIMEFORMAT2 593 // %dm
#define TXT_SCORE_NOD 594 // NOD:
#define TXT_DIALING 595 // Dialing...
#define TXT_DIALING_CANCELED 596 // Dialing Canceled
#define TXT_WAITING_FOR_CALL 597 // Waiting for Call...
#define TXT_ANSWERING_CANCELED 598 // Answering Canceled
#define TXT_E7 599 // Engineer
#define TXT_SPECIAL_OPTIONS 600 // Special Options
#define TXT_VISIBLE_TARGET 601 // Targeting flash visible to
#define TXT_TREE_TARGET 602 // Allow targeting of trees.
#define TXT_MCV_DEPLOY 603 // Allow undeploy of
#define TXT_SMART_DEFENCE 604 // Employ smarter self defense
#define TXT_SLOW_BUILD 605 // Moderate production speed.
#define TXT_THREE_POINT 606 // Use three point turn logic.
#define TXT_TIBERIUM_GROWTH 607 // Tiberium will grow.
#define TXT_TIBERIUM_SPREAD 608 // Tiberium will spread.
#define TXT_ROAD_PIECES 609 // Disable building "bib"
#define TXT_SCATTER 610 // Allow running from
#define TXT_MODEM_OR_LOOPBACK 611 // Not a Null Modem Cable
#define TXT_MAP 612 // Map
#define TXT_FROM_COMPUTER 613 // From Computer:
#define TXT_COMP_MSG1 614 // Prepare to die!
#define TXT_COMP_MSG2 615 // How about a bullet
#define TXT_COMP_MSG3 616 // Incoming!
#define TXT_COMP_MSG4 617 // I see you!
#define TXT_COMP_MSG5 618 // Hey, I'm over here!
#define TXT_COMP_MSG6 619 // Come get some!
#define TXT_COMP_MSG7 620 // I got you!
#define TXT_COMP_MSG8 621 // You humans are never a
#define TXT_COMP_MSG9 622 // Abort, Retry, Ignore? (Ha
#define TXT_COMP_MSG10 623 // Format another? (Just
#define TXT_COMP_MSG11 624 // Beat me and I'll reboot!
#define TXT_COMP_MSG12 625 // You're artificial
#define TXT_COMP_MSG13 626 // My AI is better than your
#define TXT_THEME_AIRSTRIKE 627 // Air Strike
#define TXT_THEME_HEAVYG 628 // Demolition
#define TXT_THEME_J1 629 // Untamed Land
#define TXT_THEME_JDI_V2 630 // Take 'em Out
#define TXT_THEME_RADIO 631 // Radio
#define TXT_THEME_RAIN 632 // Rain In The Night
#define TXT_THEME_IND2 633 // Canyon Chase
#define TXT_THEME_HEART 634 // Heartbreak
#define TXT_BLOSSOM_TREE 635 // Blossom Tree
#define TXT_RESTATE_MISSION 636 // Restate
#define TXT_COMPUTER 637 // Computer
#define TXT_COUNT 638 // Unit Count:
#define TXT_LEVEL 639 // Tech Level:
#define TXT_OPPONENT 640 // Opponent
#define TXT_KILLS_COLON 641 // Kills:
#define TXT_VIDEO 642 // Video
#define TXT_C10 643 // Nikoomba
#define TXT_CAPTURE_THE_FLAG 644 // Capture The Flag
#define TXT_THEME_VALK 645 // Ride of the Valkyries
#define TXT_OBJECTIVE 646 // Mission Objective
#define TXT_MISSION 647 // Mission
#define TXT_NO_SAVES 648 // No saved games available.
#define TXT_CIVILIAN_BUILDING 649 // Civilian Building
#define TXT_TECHNICIAN 650 // Technician
#define TXT_VISCEROID 651 // Visceroid
#define TXT_NO_SAVELOAD 652 // Save game options are not
#define TXT_DEFENDER_ADVANTAGE 653 // Defender has the advantage.
#define TXT_SHOW_NAMES 654 // Show true object names.
#define TXT_DELPHI 655 // Agent Delphi
#define TXT_TO_REPLAY 656 // Would you like to replay
#define TXT_RECONN_TO 657 // Reconnecting to %s.
#define TXT_PLEASE_WAIT 658 // Please wait %02d seconds.
#define TXT_SURRENDER 659 // Do you wish to surrender?
#define TXT_GDI_NAME 660 // GLOBAL DEFENSE INITIATIVE
#define TXT_NOD_NAME 661 // BROTHERHOOD OF NOD
#define TXT_SEL_TRANS 662 // SELECT TRANSMISSION
#define TXT_GAMENAME_MUSTBE_UNIQUE 663 // Your game name must be
#define TXT_GAME_IS_CLOSED 664 // Game is closed.
#define TXT_NAME_MUSTBE_UNIQUE 665 // Your name must be unique.
#define TXT_RECONNECTING_TO 666 // Reconnecting to %s
#define TXT_WAITING_FOR_CONNECTIONS 667 // Waiting for connections...
#define TXT_TIME_ALLOWED 668 // Time allowed: %02d seconds
#define TXT_PRESS_ESC 669 // Press ESC to cancel.
#define TXT_JUST_YOU_AND_ME 670 // From Computer: It's just
#define TXT_CAPTURE_THE_FLAG_COLON 671 // Capture the Flag:
#define TXT_CHAN 672 // Dr. Chan
#define TXT_HAS_ALLIED 673 // %s has allied with %s
#define TXT_AT_WAR 674 // %s declares war on %s
#define TXT_SEL_TARGET 675 // Select a target
#define TXT_SEPARATE_HELIPAD 676 // Allow separate helipad
#define TXT_RESIGN 677 // Resign Game
#define TXT_TIBERIUM_FAST 678 // Tiberium grows quickly.
#define TXT_ANSWERING 679 // Answering...
#define TXT_INITIALIZING_MODEM 680 // Initializing Modem...
#define TXT_SCENARIOS_DO_NOT_MATCH 681 // Scenarios don't match.
#define TXT_POWER_OUTPUT 682 // Power Output
#define TXT_POWER_OUTPUT_LOW 683 // Power Output (low)
#define TXT_CONTINUE 684 // Continue
#define TXT_QUEUE_FULL 685 // Data Queue Overflow
#define TXT_SPECIAL_WARNING 686 // %s changed game options!
#define TXT_CD_DIALOG_1 687 // Please insert a Command &
#define TXT_CD_DIALOG_2 688 // Please insert CD %d (%s)
#define TXT_CD_ERROR1 689 // Command & Conquer is unable
#define TXT_NO_SOUND_CARD 690 // No Sound Card Detected
#define TXT_UNKNOWN 691 // UNKNOWN
#define TXT_OLD_GAME 692 // (old)
#define TXT_NO_SPACE 693 // Insufficient Disk Space to
#define TXT_MUST_HAVE_SPACE 694 // You must have %d megabytes
#define TXT_RUN_SETUP 695 // Run SETUP program first.
#define TXT_WAITING_FOR_OPPONENT 696 // Waiting for Opponent
#define TXT_SELECT_SETTINGS 697 // Please select 'Settings' to
#define TXT_PRISON 698 // Prison
#define TXT_GAME_WAS_SAVED 699 // Game Saved
#define TXT_SPACE_CANT_SAVE 700 // Insufficient disk space to
#define TXT_INVALID_PORT_ADDRESS 701 // Invalid Port/Address. COM
#define TXT_INVALID_SETTINGS 702 // Invalid Port and/or IRQ
#define TXT_IRQ_ALREADY_IN_USE 703 // IRQ already in use
#define TXT_ABORT 704 // Abort
#define TXT_RESTART 705 // Restart
#define TXT_RESTARTING 706 // Mission is
#define TXT_LOADING 707 // Mission is loading. Please
#define TXT_ERROR_IN_INITSTRING 708 // Error in the InitString
#define TXT_ORDER_INFO 709 // Order Info
#define TXT_SCENES 710 // Scenes
#define TXT_NEW_MISSIONS 711 // New Missions
#define TXT_THEME_CHRG 712 // Depth Charge
#define TXT_THEME_DRON 713 // Drone
#define TXT_THEME_FIST 714 // Iron Fist
#define TXT_THEME_CREP 715 // Creeping Upon
#define TXT_THEME_80MX 716 // C&C 80's Mix
#define TXT_THEME_DRIL 717 // Drill
#define TXT_CD_DIALOG_3 718 // Please insert the Covert
#define TXT_THEME_RECON 719 // Recon
#define TXT_THEME_VOICE 720 // Voice Rhythm
#define TXT_ERROR_NO_INIT 721 // Error - modem did not
#define TXT_NO_FLOW_CONTROL_RESPONSE 722 // Error - Modem failed to
#define TXT_NO_COMPRESSION_RESPONSE 723 // Error - Modem failed to
#define TXT_NO_ERROR_CORRECTION_RESPONSE 724 // Error - Modem failed to
#define TXT_ERROR_NO_DISABLE 725 // Error - unable to disable
#define TXT_ERROR_TOO_MANY 726 // Error - Too many errors
#define TXT_IGNORE 727 // Ignore
#define TXT_CONNECTING 728 // Connecting... Please Wait.
#define TXT_EXPLAIN_REGISTRATION 729 // To play Command & Conquer
#define TXT_REGISTER 730 // Register
#define TXT_ERROR_UNABLE_TO_RUN_WCHAT 731 // Wchat not installed. Please
#define TXT_INTERNET 732 // Internet Game
#define TXT_UNABLE_TO_SET_VIDEO_MODE 733 // Error - Unable to set the
#define TXT_UNABLE_TO_ALLOCATE_PRIMARY_VIDEO_BUFFER 734 // Error - Unable to allocate
#define TXT_NO_DIAL_TONE 735 // No dial tone. Ensure your
#define TXT_MODEM_INITIALISATION 736 // Modem Initialization
#define TXT_DATA_COMPRESSION 737 // Data Compression
#define TXT_ERROR_CORRECTION 738 // Error Correction
#define TXT_HARDWARE_FLOW_CONTROL 739 // Hardware Flow Control
#define TXT_ADVANCED 740 // Advanced
#define TXT_JUST_INTRO 741 // Intro
#define TXT_READING_IMAGE_DATA 742 // READING IMAGE DATA
#define TXT_ANALYZING 743 // ANALYZING
#define TXT_ENHANCING_IMAGE_DATA 744 // ENHANCING IMAGE DATA
#define TXT_ISOLATING_OPERATIONAL_THEATER 745 // ISOLATING OPERATIONAL
#define TXT_ESTABLISHING_TRADITIONAL_BOUNDARIES 746 // ESTABLISHING TRADITIONAL
#define TXT_FOR_VISUAL_REFERENCE 747 // FOR VISUAL REFERENCE
#define TXT_ENHANCING_IMAGE 748 // ENHANCING IMAGE
#define TXT_BONUS_MISSIONS 749 // Bonus Missions
#define TXT_BONUS_MISSION_1 750 // Bonus Mission 1
#define TXT_BONUS_MISSION_2 751 // Bonus Mission 2
#define TXT_BONUS_MISSION_3 752 // Bonus Mission 3
#define TXT_BONUS_MISSION_4 753 // Bonus Mission 4
#define TXT_BONUS_MISSION_5 754 // Bonus Mission 5
#define TXT_LOW_POWER 755
#define TXT_INSUFFICIENT_FUNDS 756

425
TIBERIANDAWN/CONST.CPP Normal file
View File

@@ -0,0 +1,425 @@
//
// 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&c\vcs\code\const.cpv 2.17 16 Oct 1995 16:52:24 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"
char const * SourceName[SOURCE_COUNT] =
{
"North",
"East",
"South",
"West",
"Shipping",
"Beach",
"Air",
"Visible",
"EnemyBase",
"HomeBase",
"Ocean",
};
/***************************************************************************
** 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
};
/***************************************************************************
** These are the various weapons and their characteristics.
**
** bullet type dmg, rof, range, sound
*/
WeaponTypeClass const Weapons[WEAPON_COUNT] = {
{BULLET_SNIPER, 125, 40, 0x0580, VOC_SNIPER, ANIM_NONE}, // WEAPON_RIFLE
{BULLET_SPREADFIRE, 25, 50, 0x0400, VOC_MINI, ANIM_GUN_N}, // WEAPON_CHAIN_GUN
{BULLET_BULLET, 1, 7, 0x01C0, VOC_RIFLE, ANIM_NONE}, // WEAPON_PISTOL
{BULLET_BULLET, 15, 20, 0x0200, VOC_MGUN2, ANIM_NONE}, // WEAPON_M16
{BULLET_TOW, 30, 60, 0x0400, VOC_BAZOOKA,ANIM_NONE}, // WEAPON_DRAGON
{BULLET_FLAME, 35, 50, 0x0200, VOC_FLAMER1,ANIM_FLAME_N}, // WEAPON_FLAMETHROWER
{BULLET_FLAME, 50, 50, 0x0200, VOC_FLAMER1,ANIM_FLAME_N}, // WEAPON_FLAME_TONGUE
{BULLET_CHEMSPRAY, 80, 70, 0x0200, VOC_FLAMER1,ANIM_CHEM_N}, // WEAPON_CHEMSPRAY
{BULLET_GRENADE, 50, 60, 0x0340, VOC_TOSS, ANIM_NONE}, // WEAPON_GRENADE
{BULLET_APDS, 25, 60, 0x0400, VOC_TANK2, ANIM_MUZZLE_FLASH}, // WEAPON_75MM
{BULLET_APDS, 30, 50, 0x04C0, VOC_TANK3, ANIM_MUZZLE_FLASH}, // WEAPON_105MM
{BULLET_APDS, 40, 80, 0x04C0, VOC_TANK4, ANIM_MUZZLE_FLASH}, // WEAPON_120MM
{BULLET_APDS, 40, 60, 0x0600, VOC_TANK4, ANIM_MUZZLE_FLASH}, // WEAPON_TURRET_GUN
{BULLET_SSM, 75, 80, 0x0500, VOC_ROCKET1,ANIM_NONE}, // WEAPON_MAMMOTH_TUSK
{BULLET_SSM2, 75, 80, 0x0600, VOC_ROCKET1,ANIM_NONE}, // WEAPON_MLRS
{BULLET_HE, 150, 65, 0x0600, VOC_TANK1, ANIM_MUZZLE_FLASH}, // WEAPON_155MM
{BULLET_BULLET, 15, 30, 0x0400, VOC_MGUN11, ANIM_GUN_N}, // WEAPON_M60MG
{BULLET_SSM, 60, 35, 0x0780, VOC_ROCKET2,ANIM_NONE}, // WEAPON_TOMAHAWK
{BULLET_SSM, 60, 40, 0x0680, VOC_ROCKET2,ANIM_NONE}, // WEAPON_TOW_TWO
{BULLET_NAPALM, 100, 20, 0x0480, VOC_NONE, ANIM_NONE}, // WEAPON_NAPALM
{BULLET_LASER, 200, 90, 0x0780, VOC_LASER, ANIM_NONE}, // WEAPON_OBELISK_LASER
{BULLET_SAM, 50, 50, 0x0780, VOC_ROCKET2,ANIM_NONE}, // WEAPON_NIKE
{BULLET_HONEST_JOHN, 100, 200, 0x0A00, VOC_ROCKET1,ANIM_NONE}, // WEAPON_HONEST_JOHN
{BULLET_HEADBUTT, 100, 30, 0x0180, VOC_DINOATK1,ANIM_NONE}, // WEAPON_STEG
{BULLET_TREXBITE, 155, 30, 0x0180, VOC_DINOATK1,ANIM_NONE}, // WEAPON_TREX
#ifdef PETROGLYPH_EXAMPLE_MOD
{BULLET_NUKE_LOB, 150, 130, 0x0B00, VOC_NUKE_LOB, ANIM_MUZZLE_FLASH}, // WEAPON_NUKE_LOB
#endif //PETROGLYPH_EXAMPLE_MOD
};
/***************************************************************************
** These are the various warheads.
**
** spread factor, destroys walls, destroys wood, destroys Tiberium, {armor defense table}
** -vs- {none, wood, aluminum, steel, concrete}
*/
WarheadTypeClass const Warheads[WARHEAD_COUNT] = {
{ 2,false,false,false,{0x100, 0x80, 0x90, 0x40, 0x40}}, // WARHEAD_SA Small arms -- good against infantry.
{ 6,true,true,true,{0xE0, 0xC0, 0x90, 0x40, 0x100}}, // WARHEAD_HE High explosive -- good against buildings & infantry.
{ 6,true,true,false,{0x40, 0xC0, 0xC0, 0x100, 0x80}}, // WARHEAD_AP Armor piercing -- good against armor.
{ 8,false,true,true,{0xE0, 0x100, 0xB0, 0x40, 0x80}}, // WARHEAD_FIRE Incendiary -- Good against flammables.
{ 4,false,false,false,{0x100, 0x100, 0x100, 0x100, 0x100}},// WARHEAD_LASER Light Amplification of Stimulated Emission by Radiation.
{ 7,true,true,true,{0x100, 0x100, 0xC0, 0xC0, 0xC0}}, // WARHEAD_PB Particle beam (neutron beam).
{ 4,false,false,false,{0x100, 0x20, 0x20, 0x10, 0x10}}, // WARHEAD_FIST Punching in hand-to-hand combat.
{ 4,false,false,false,{0x100, 0x20, 0x20, 0x10, 0x10}}, // WARHEAD_FOOT Kicking in hand-to-hand combat.
{ 4,false,false,false,{0x100, 0x08, 0x08, 0x08, 0x08}}, // WARHEAD_HOLLOW_POINT Sniper bullet type.
{255,false,false,false,{0x100, 0x01, 0x01, 0x01, 0x01}}, // WARHEAD_SPORE
{ 1, true,true,false,{0x100, 0xC0, 0x80, 0x20, 0x08}}, // WARHEAD_HEADBUTT
{ 1, true,true,false,{0x100, 0xC0, 0x80, 0x20, 0x08}}, // WARHEAD_FEEDME
};
/***************************************************************************
** 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 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
};
#ifdef NEVER
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
};
#endif
/*
** 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.
*/
#define S1 0x00
#define S2 0x40
#define S3 0x70
#define S4 0xA0
#define S5 0xC0
#define S6 0xFF
GroundType const Ground[LAND_COUNT] = {
// Foot
// | Tracked
// | | Harvester
// | | | Wheeled
// | | | | Winged
// | | | | | Hover
// | | | | | | float build
{66, {S3, S3, S3, S4, S6, S5, S1 }, true}, // LAND_CLEAR
{68, {S5, S4, S4, S4, S6, S5, S1 }, true}, // LAND_ROAD
{BLUE, {S1, S1, S1, S1, S6, S5, S6 }, false}, // LAND_WATER
{DKGREY, {S1, S1, S1, S1, S6, S1, S1 }, false}, // LAND_ROCK
{DKGREY, {S1, S1, S1, S1, S6, S1, S1 }, false}, // LAND_WALL
{143, {S3, S3, S3, S4, S6, S5, S1 }, false}, // LAND_TIBERIUM
{66, {S3, S3, S3, S4, S6, S5, S1 }, false}, // LAND_BEACH
};
/***************************************************************************
** These are the names of the theaters.
*/
TheaterDataType const Theaters[THEATER_COUNT] = {
{"DESERT","DESERT","DES"},
{"JUNGLE","JUNGLE","JUN"},
{"TEMPERATE","TEMPERAT","TEM"},
{"WINTER","WINTER","WIN"}
};
/***************************************************************************
** These are the remap tables that are used to convert the units/buildings
** into the other color schemes.
*/
unsigned char const RemapGold[256] = {
0,1,2,3,4,5,6,7,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,109,110,111, // 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,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 RemapRed[256] = {
0,1,2,3,4,5,6,7,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,109,110,111, // 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
127,126,125,124,122,46,120,47,125,124,123,122,42,121,120,120, // 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 RemapBlue[256] = {
0,1,2,3,4,5,6,7,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,109,110,111, // 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
2,119,118,135,136,138,112,12,118,135,136,137,138,139,114,112, // 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 RemapOrange[256] = {
0,1,2,3,4,5,6,7,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,109,110,111, // 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
24,25,26,27,29,31,46,47,26,27,28,29,30,31,43,47, // 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 RemapGreen[256] = {
0,1,2,3,4,5,6,7,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,109,110,111, // 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
5,165,166,167,159,142,140,199,166,167,157,3,159,143,142,141, // 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 RemapLtBlue[256] = {
0,1,2,3,4,5,6,7,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,109,110,111, // 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
161,200,201,202,204,205,206,12,201,202,203,204,205,115,198,114, // 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 RemapNone[256] = {
0,1,2,3,4,5,6,7,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,109,110,111, // 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,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
};

199
TIBERIANDAWN/CONTROL.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: F:\projects\c&c\vcs\code\control.cpv 2.18 16 Oct 1995 16:51:38 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 : January 19, 1995 [JLB] *
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* ControlClass::Action -- Normal action for control gaget objects. *
* ControlClass::ControlClass -- Constructor for control class objects. *
* 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::Action -- Normal action for control gaget 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 gaget'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 futher list processing be aborted? *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 01/15/1995 JLB : Created. *
*=============================================================================================*/
int ControlClass::Action(unsigned flags, KeyNumType & key)
{
/*
** If there is a peer link established, inform that gadget of this
** action call.
*/
if (Peer) {
Peer->Peer_To_Peer(flags, key, *this);
}
/*
** Only if the flags indicate that a recognized action has occured, 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;
}
}
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 heirarchy, 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));
}

86
TIBERIANDAWN/CONTROL.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
/* $Header: F:\projects\c&c\vcs\code\control.h_v 2.18 16 Oct 1995 16:46:08 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(unsigned id, int x, int y, int w, int h, unsigned flags=LEFTPRESS|RIGHTPRESS, int sticky=false);
// static ControlClass * Create_One_Of(unsigned id, int x, int y, int w, int h, unsigned flags=LEFTPRESS|RIGHTPRESS, int sticky=false);
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

599
TIBERIANDAWN/COORD.CPP Normal file
View File

@@ -0,0 +1,599 @@
//
// 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&c\vcs\code\coord.cpv 2.18 16 Oct 1995 16:51:24 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 : January 7, 1995 [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_Move -- Moves a coordinate an arbitrary direction for an arbitrary distance *
* Coord_Scatter -- Determines a random coordinate from an anchor point. *
* Coord_Spillage_List -- Determines the offset list for cell spillage/occupation. *
* Fixed_To_Cardinal -- Converts a fixed point number into a cardinal number. *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "function.h"
/***********************************************************************************************
* 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.
// {0, -MAP_CELL_W, -(MAP_CELL_W-1), 1, MAP_CELL_W+1, MAP_CELL_W, MAP_CELL_W-1, -1, -(MAP_CELL_W+1), REFRESH_EOL}
};
static short _manual[10];
//; 00 = on axis
//; 01 = below axis
//; 10 = above axis
//; 11 = undefined
static 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 = Fixed_To_Cardinal(ICON_PIXEL_W, Coord_XLepton(coord));
y = Fixed_To_Cardinal(ICON_PIXEL_H, Coord_YLepton(coord));
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_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)
{
short x = Coord_X(start);
short y = Coord_Y(start);
Move_Point(x, y, dir, distance);
return(XY_Coord(x,y));
#ifdef NEVER
static 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 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.
/*
** 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;
*((int*)&start) += _DX;
// asm add [word ptr start],ax
/*
** 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;
*(((int*)&start)+1) += _DX;
// asm add [word ptr start+2],ax
return(start);
#endif
}
#ifdef OBSOLETE
//BG: Note, this routine is replaced by assembly in COORDA.ASM
/***********************************************************************************************
* 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: *
* 05/27/1994 JLB : Created. *
*=============================================================================================*/
unsigned Cardinal_To_Fixed(unsigned base, unsigned cardinal)
{
long temp = 0;
if (base) {
*(unsigned*)(((char*)&temp)+1) = cardinal; // Shift up by 8 bits.
_DX = FP_SEG(temp);
_AX = FP_OFF(temp);
asm div word ptr base
return(_AX);
}
return(0xFFFF);
}
#endif
#ifdef OBSOLETE
//BG: Note, this routine is replaced by assembly in COORDA.ASM
/***********************************************************************************************
* 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: *
* 05/27/1994 JLB : Created. *
*=============================================================================================*/
unsigned Fixed_To_Cardinal(unsigned base, unsigned fixed)
{
unsigned long temp;
_AX = base;
asm mul word ptr fixed
_CX = _AX;
temp = ((unsigned long)MK_FP(_DX, _CX)) + 0x80;
if ( *((char*)&temp+3) ) {
return(0xFFFF);
}
return(*(unsigned*)(((char*)&temp)+1));
}
#endif
/***********************************************************************************************
* 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 & 0xC000C000L) 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 char const CosTable[256] = {
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 char const SinTable[256] = {
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.
//
// ST - 1/10/2019 11:20AM
//
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.
//
// ST - 1/10/2019 11:20AM
//
char *sin_table = (char*)&SinTable[0];
y += calcy(sin_table[dir], distance);
#endif
// asm add [word ptr start+2],ax
}

131
TIBERIANDAWN/COORDA.ASM Normal file
View File

@@ -0,0 +1,131 @@
;
; 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/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 Cardinal_To_Fixed(unsigned base, unsigned cardinal);
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
;***********************************************************************************************
;* 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,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

141
TIBERIANDAWN/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

183
TIBERIANDAWN/CREDITS.CPP Normal file
View File

@@ -0,0 +1,183 @@
//
// 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&c\vcs\code\credits.cpv 2.17 16 Oct 1995 16:51: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 ***
***********************************************************************************************
* *
* Project Name : Command & Conquer *
* *
* File Name : CREDITS.CPP *
* *
* Programmer : Joe L. Bostic *
* *
* Start Date : April 17, 1994 *
* *
* Last Update : March 13, 1995 [JLB] *
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* CreditClass::AI -- Handles updating the credit display. *
* CreditClass::Graphic_Logic -- Handles the credit redraw logic. *
* CreditClass::CreditClass -- Default constructor for the credit class object. *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "function.h"
/***********************************************************************************************
* CreditClass::CreditClass -- Default constructor for the credit class object. *
* *
* This is the constructor for the credit class object. It merely sets the credit display *
* state to null. *
* *
* INPUT: none *
* *
* OUTPUT: none *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 03/13/1995 JLB : Created. *
*=============================================================================================*/
CreditClass::CreditClass(void)
{
IsToRedraw = false;
IsUp = false;
IsAudible = false;
Credits = 0;
Current = 0;
Countdown = 0;
}
/***********************************************************************************************
* CreditClass::Graphic_Logic -- Handles the credit redraw logic. *
* *
* This routine should be called whenever the main game screen is to be updated. It will *
* check to see if the credit display should be redrawn. If so, it will redraw it. *
* *
* INPUT: forced -- Should the credit display be redrawn regardless of whether the redraw *
* flag is set? This is typically the case when the screen needs to be *
* redrawn from scratch. *
* *
* OUTPUT: none *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 03/13/1995 JLB : Created. *
*=============================================================================================*/
#define XX (320-120)
#define WW 50
void CreditClass::Graphic_Logic(bool forced)
{
int factor = Get_Resolution_Factor();
int xx = SeenBuff.Get_Width() - (120 << factor);
if (forced || IsToRedraw) {
/*
** Play a sound effect when the money display changes, but only if a sound
** effect was requested.
*/
if (IsAudible) {
if (IsUp) {
Sound_Effect(VOC_UP, VOL_1);
} else {
Sound_Effect(VOC_DOWN, VOL_1);
}
}
/*
** Display the new current value.
*/
//LogicPage->Fill_Rect(xx-(20 << factor), 1 << factor, xx+(20 << factor), 6 << factor, LTGREY);
TabClass::Draw_Credits_Tab();
Fancy_Text_Print("%ld", xx, 0, 11, TBLACK, TPF_GREEN12_GRAD|TPF_CENTER | TPF_USE_GRAD_PAL, Current);
IsToRedraw = false;
IsAudible = false;
}
}
/***********************************************************************************************
* CreditClass::AI -- Handles updating the credit display. *
* *
* This routine handles the logic that controls the rate of credit change in the credit *
* display. It doesn't actually redraw the credit display, but will flag it to be redrawn *
* if it detects that a change is to occur. *
* *
* INPUT: forced -- Should the credit display immediately reflect the current credit *
* total for the player? This is usually desired when initially loading *
* a scenario or saved game. *
* player_ptr -- Player to calculate visible credits for *
* logic_only -- If true, don't flag map for redraw *
* *
* OUTPUT: none *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 03/13/1995 JLB : Created. *
* 10/16/2019 ST : Added house and logic parameters so we can call this from HouseClass::AI *
*=============================================================================================*/
void CreditClass::AI(bool forced, HouseClass *player_ptr, bool logic_only)
{
if (player_ptr == NULL) {
return;
}
Credits = player_ptr->Available_Money();
/*
** Make sure that the credit counter doesn't drop below zero.
*/
Credits = MAX(Credits, 0L);
if (Current == Credits) return;
if (forced) {
IsAudible = false;
Current = Credits;
} else {
if (Countdown) Countdown--;
if (Countdown) return;
/*
** Determine the amount to change the display toward the
** desired value.
*/
long adder = Credits - Current;
adder = ABS(adder);
adder >>= 5;
adder = Bound(adder, 1L, 71+72);
if (Current > Credits) adder = -adder;
Current += adder;
Countdown = 1;
if (Current-adder != Current) {
IsAudible = true;
IsUp = (adder > 0);
}
}
IsToRedraw = true;
if (!logic_only) {
Map.Flag_To_Redraw(false);
}
}

71
TIBERIANDAWN/CREDITS.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
/* $Header: F:\projects\c&c\vcs\code\credits.h_v 2.18 16 Oct 1995 16:47:26 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 : CREDIT.H *
* *
* Programmer : Joe L. Bostic *
* *
* Start Date : April 19, 1994 *
* *
* Last Update : April 19, 1994 [JLB] *
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef CREDITS_H
#define CREDITS_H
class HouseClass;
extern HouseClass *PlayerPtr;
/****************************************************************************
** The animating credit counter display is controlled by this class.
*/
class CreditClass {
public:
long Credits; // Value of credits trying to update display to.
/*---------------------------------------------------------------------
** Constructors, Destructors, and overloaded operators.
*/
CreditClass(void);
/*---------------------------------------------------------------------
** Member function prototypes.
*/
void Update(bool forced=false, bool redraw=false);
void Graphic_Logic(bool forced=false);
void AI(bool forced=false, HouseClass *player_ptr = PlayerPtr, bool logic_only = false); // Added house and logic_only parameters. ST - 10/16/2019 2:26PM
long Current; // Credit value currently displayed.
unsigned IsToRedraw:1;
unsigned IsUp:1;
unsigned IsAudible:1;
private:
int Countdown; // Delay between ticks.
};
#endif

35
TIBERIANDAWN/CREW.CPP Normal file
View File

@@ -0,0 +1,35 @@
//
// 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&c\vcs\code\crew.cpv 2.18 16 Oct 1995 16:50:50 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 : CREW.CPP *
* *
* Programmer : Joe L. Bostic *
* *
* Start Date : April 23, 1994 *
* *
* Last Update : April 23, 1994 [JLB] *
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "function.h"

62
TIBERIANDAWN/CREW.H Normal file
View File

@@ -0,0 +1,62 @@
//
// 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&c\vcs\code\crew.h_v 2.18 16 Oct 1995 16:47:56 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 : CREW.H *
* *
* Programmer : Joe L. Bostic *
* *
* Start Date : April 23, 1994 *
* *
* Last Update : April 23, 1994 [JLB] *
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef CREW_H
#define CREW_H
/****************************************************************************
** This class handles the basic crew logic. This includes hero tracking,
** crew bail-out, and attached object logic.
*/
class CrewClass
{
public:
/*
** This keeps track of the number of "kills" the unit as accumulated.
** When it reaches a certain point, the unit improves.
*/
unsigned short Kills;
/*
** Constructors, Destructors, and overloaded operators.
*/
CrewClass(void) {Kills = 0;};
int Made_A_Kill(void) {Kills++;return(Kills);};
private:
};
#endif

465
TIBERIANDAWN/DDE.CPP Normal file
View File

@@ -0,0 +1,465 @@
//
// 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 : Dynamic Data Encapsulation *
* *
* File Name : DDE.CPP *
* *
* Programmer : Steve Wetherill *
* *
* Start Date : June 1, 1996 *
* *
* Last Update : June 8, 1996 [SW] *
* *
*-------------------------------------------------------------------------*
* Functions: *
* Instance_Class::InstanceClass -- class constructor *
* Instance_Class::InstanceClass -- class destructor *
* Instance_Class::Enable_Callback -- enables local processing of pokes *
* Instance_Class::Register_Servers -- registers a local DDE DNS service *
* Instance_Class::Cleanup_App -- currently does nothing *
* Instance_Class::Test_Server_Running -- does a trial connect to remote *
* Instance_Class::Open_Poke_Connection -- pokes some data to server *
* Instance_Class::Close_Poke_Connectionp -- closes connection to remote *
* Instance_Class::Poke_Server -- sends a chunk of data to remote *
* Instance_Class::dde_callback -- processes DDE transactions *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include <windows.h>
#include "dde.h"
/***************************************************************************
* These are static members of Instance_Class
*=========================================================================*/
DWORD Instance_Class::id_inst; // instance identifier set by DdeInitialize
BOOL Instance_Class::process_pokes; // controls response to pokes
char Instance_Class::ascii_name[32]; // name of server
//PG_TO_FIX ST - 12/20/2018 2:17PM
#if (0)
static BOOL CALLBACK (*Instance_Class::callback) (
LPBYTE pointer, // pointer to received data
long length // length of received data or advisory flag
) = NULL;
#endif
/***************************************************************************
* Instance_Class::InstanceClass -- class constructor *
* *
* INPUT: *
* name1 null terminated ASCII client name *
* name1 null terminated ASCII server name *
* *
* OUTPUT: *
* dde_error = TRUE if error occurs when initializing DDE *
* *
* WARNINGS: *
* none. *
* *
* HISTORY: *
* 6/1/1996 SW : Created. *
*=========================================================================*/
Instance_Class::Instance_Class( LPSTR name1, LPSTR name2 )
{
name1;
name2;
return;
#if (0) //ST - 1/2/2019 5:35PM
dde_error = FALSE; // no errors
process_pokes = FALSE; // disable pokes in callback
id_inst = 0; // set to 0 for first time through
conv_handle = 0; // conversation handle reset
lstrcpy( ascii_name, name1 ); // keep a record of ASCII name
if ( DdeInitialize(
(LPDWORD) &id_inst, // instance identifier
dde_callback,
APPCLASS_STANDARD | // filter server messages
CBF_FAIL_SELFCONNECTIONS, // prevent from connecting with self
0) != DMLERR_NO_ERROR) { // reserved
dde_error = TRUE; // flag an error
}
local_name = DdeCreateStringHandle(
id_inst, // instance identifier
name1, // string to register
CP_WINANSI); // Windows ANSI code page
remote_name = DdeCreateStringHandle(
id_inst, // instance identifier
name2, // string to register
CP_WINANSI); // Windows ANSI code page
poke_topic = DdeCreateStringHandle(
id_inst, // instance identifier
"POKE TOPIC", // System topic
CP_WINANSI); // Windows ANSI code page
poke_item = DdeCreateStringHandle(
id_inst, // instance identifier
"POKE ITEM", // System topic
CP_WINANSI); // Windows ANSI code page
system_topic = DdeCreateStringHandle(
id_inst, // instance identifier
SZDDESYS_TOPIC, // System topic
CP_WINANSI); // Windows ANSI code page
#endif
}
/***************************************************************************
* Instance_Class::~Instance_Class -- class destructor *
* *
* INPUT: *
* none. *
* *
* OUTPUT: *
* none. *
* *
* WARNINGS: *
* none. *
* *
* HISTORY: *
* 6/1/1996 SW : Created. *
*=========================================================================*/
Instance_Class::~Instance_Class()
{
DdeUninitialize( id_inst );
}
/***************************************************************************
* Instance_Class::Enable_Callback -- enables user callback *
* *
* INPUT: *
* TRUE = enable poke processing *
* FALSE = disable poke processing *
* *
* OUTPUT: *
* echos the input *
* *
* WARNINGS: *
* user callback must be explicitly enabled. Disbabled by default. *
* *
* HISTORY: *
* 6/1/1996 SW : Created. *
*=========================================================================*/
BOOL Instance_Class::Enable_Callback( BOOL flag ) // enable or disable callback
{
return (process_pokes = flag);
}
/***************************************************************************
* Instance_Class::Register_Server -- registers a local DDE DNS service *
* *
* INPUT: *
* BOOL CALLBACK ( *callback_fnc) ( LPBYTE, DWORD) = user poke callbacl *
* *
* OUTPUT: *
* TRUE == success *
* FALSE == failed *
* *
* WARNINGS: *
* none. *
* *
* HISTORY: *
* 6/1/1996 SW : Created. *
*=========================================================================*/
#if (0)
BOOL Instance_Class::Register_Server( BOOL (CALLBACK *)(LPBYTE, long));
//BOOL Instance_Class::Register_Server( BOOL CALLBACK ( *callback_fnc) (LPBYTE, long) )
{
if (DdeNameService( id_inst, local_name, 0L, DNS_REGISTER ) != 0L) {
callback = callback_fnc;
return ( TRUE );
} else {
return ( FALSE );
}
}
#endif
/***************************************************************************
* Instance_Class::Test_Server_Running -- does a trial connect to remote *
* *
* INPUT: *
* name = HSZ string handle of server name. *
* *
* OUTPUT: *
* TRUE == successfully connected to remote *
* FALSE == failed to connect *
* *
* WARNINGS: *
* - Can be called for local or remote server but of course will *
* fail if a called for local and local server is not "up". *
* - Disconects before exiting. *
* *
* HISTORY: *
* 6/1/1996 SW : Created. *
*=========================================================================*/
BOOL Instance_Class::Test_Server_Running( HSZ name )
{
if( Open_Poke_Connection( name ) == TRUE) {
Close_Poke_Connection();
return( TRUE );
} else {
return( FALSE );
}
}
/***************************************************************************
* Instance_Class::Open_Poke_Connection -- open a connection to server *
* *
* INPUT: *
* name = HSZ server name. *
* *
* OUTPUT: *
* TRUE == successfully opened connection *
* FALSE == failed to connect *
* *
* WARNINGS: *
* Can be called for local or remote server but of course will *
* fail if a called for local and local server is not "up". *
* *
* HISTORY: *
* 6/1/1996 SW : Created. *
*=========================================================================*/
BOOL Instance_Class::Open_Poke_Connection( HSZ name )
{
conv_handle = DdeConnect(
id_inst, // instance identifier
name, // service name string handle
poke_topic, // topic string handle
(PCONVCONTEXT) NULL);// use default context
if (conv_handle == NULL) {
return FALSE;
} else {
return TRUE;
}
}
/***************************************************************************
* Instance_Class::Close_Poke_Connection -- closes poke connection *
* *
* INPUT: *
* none. *
* *
* OUTPUT: *
* TRUE == successfully closed connection *
* FALSE == failed to close connection for some reason *
* *
* WARNINGS: *
* none. *
* *
* HISTORY: *
* 6/1/1996 SW : Created. *
*=========================================================================*/
BOOL Instance_Class::Close_Poke_Connection( void )
{
if( conv_handle ) {
HCONV temp_handle = conv_handle;
conv_handle = NULL;
return( DdeDisconnect( temp_handle ));
} else {
return( TRUE );
}
}
/***************************************************************************
* Instance_Class::Poke_Server -- pokes some data to server *
* *
* INPUT: *
* poke_data points to data to send to remote *
* poke_length length of buffer to send *
* *
* OUTPUT: *
* TRUE == successfully poked the data *
* FALSE == failed to connect *
* *
* WARNINGS: *
* has a 3 second timeout (change POKE_TIMEOUT, in milliseconds) *
* *
* HISTORY: *
* 6/1/1996 SW : Created. *
*=========================================================================*/
#define POKE_TIMEOUT 60*1000 // 60 sec timeout
BOOL Instance_Class::Poke_Server( LPBYTE poke_data, DWORD poke_length )
{
if( DdeClientTransaction(
poke_data, // address of data to pass to server
poke_length, // length of data
conv_handle, // handle of conversation
poke_topic, // handle of item name string
CF_TEXT, // no special clipboard data format
XTYP_POKE, // transaction type
POKE_TIMEOUT, // time-out duration (millisecs)
(LPDWORD) NULL // address of transaction result (don't check)
) == 0) {
return( FALSE);
} else {
return( TRUE );
}
}
/***************************************************************************
* Instance_Class::dde_callback -- callback dde event handler *
* *
* INPUT: *
* dde_event transaction type *
* uFmt clipboard data format *
* hconv handle of the conversation *
* hsz1 handle of a string *
* hsz2 handle of a string *
* hdata handle of a global memory object *
* dwData1 transaction-specific data *
* dwData2 transaction-specific data *
* *
* OUTPUT: *
* context specific HDDEDATA object *
* *
* WARNINGS: *
* NOTE: declared as HDDEDATA CALLBACK which means PASCAL parameters *
* *
* HISTORY: *
* 6/1/1996 SW : Created. *
*=========================================================================*/
HDDEDATA CALLBACK Instance_Class::dde_callback(
UINT dde_event, // transaction type
UINT uFmt, // clipboard data format
HCONV , // handle of the conversation
HSZ hsz1, // handle of a string
HSZ hsz2, // handle of a string
HDDEDATA hdata, // handle of a global memory object
DWORD , // transaction-specific data
DWORD // transaction-specific data
)
{
dde_event;
uFmt;
hsz1;
hsz2;
hdata;
return (HDDEDATA) NULL;
#if (0) //ST - 1/2/2019 5:38PM
if (!Instance_Class::callback){
return (HDDEDATA) NULL;
}
switch ( dde_event ) {
case XTYP_REGISTER:
case XTYP_UNREGISTER:
return (HDDEDATA) NULL;
case XTYP_ADVDATA:
return (HDDEDATA) DDE_FACK;
case XTYP_XACT_COMPLETE:
return (HDDEDATA) NULL;
case XTYP_DISCONNECT:
Instance_Class::callback( NULL, DDE_ADVISE_DISCONNECT);
return (HDDEDATA) NULL;
case XTYP_CONNECT: {
char buffer[32];
DdeQueryString (Instance_Class::id_inst, hsz2, buffer, sizeof (buffer), 0) ;
if (0 != strcmp (buffer, Instance_Class::ascii_name)) {
return (HDDEDATA) NULL;
}
DdeQueryString (Instance_Class::id_inst, hsz1, buffer, sizeof (buffer), 0) ;
if (0 != strcmp (buffer, "POKE TOPIC")) {
return (HDDEDATA) NULL;
}
Instance_Class::callback( NULL, DDE_ADVISE_CONNECT);
return (HDDEDATA) TRUE;
}
case XTYP_POKE:
if (Instance_Class::process_pokes == FALSE ) {
return (HDDEDATA) DDE_FNOTPROCESSED; // processing disabled
} else {
char buffer[32];
DdeQueryString (Instance_Class::id_inst, hsz1, buffer, sizeof (buffer), 0) ;
if (0 != strcmp (buffer, "POKE TOPIC")) {
return (HDDEDATA) DDE_FNOTPROCESSED;
} else if (uFmt == CF_TEXT) { // make sure it's CF_TEXT
BOOL processed;
BYTE FAR *pdata;
DWORD dw_length;
if ( (pdata = DdeAccessData( hdata, &dw_length)) == NULL ) {
return (HDDEDATA) DDE_FNOTPROCESSED;
}
processed = Instance_Class::callback((LPBYTE) pdata, dw_length);
DdeUnaccessData( hdata );
if (processed == TRUE) {
return (HDDEDATA) DDE_FACK;
} else {
return (HDDEDATA) NULL;
}
}
}
default:
return (HDDEDATA) NULL;
}
#endif
}

176
TIBERIANDAWN/DDE.H Normal file
View File

@@ -0,0 +1,176 @@
//
// 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 : Dynamic Data Encapsulation *
* *
* File Name : DDE.H *
* *
* Programmer : Steve Wetherill *
* *
* Start Date : June 1, 1996 *
* *
* Last Update : June 8, 1996 [SW] *
* *
*-------------------------------------------------------------------------*
* *
* This is the DDE (Instance_Class) which provides a simple CLIENT/SERVER *
* DDE model for data transactions between Windows applications. *
* This is a fairly naieve implementation allowing only one client/server *
* per Instance_Class object. *
* *
* Typical uses for this class are: *
* *
* i. Robust verification of whether an application is running *
* ii. Data transfer between applications *
* *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/*
***************************** Class defines *****************************
*/
#ifndef __DDE_H
#define __DDE_H
//#if (0)
#define DDE_ADVISE_CONNECT -1 // advisory "client has connected"
#define DDE_ADVISE_DISCONNECT -2 // advisory "client has disconnected"
/*
***************************** Class Declaration *****************************
*/
class Instance_Class {
/*
---------------------------- Public Interface ----------------------------
*/
public:
/*.....................................................................
Constructor:
- takes null terminated ASCII strings names for client and server
.....................................................................*/
Instance_Class( // constructor
LPSTR, // null terminated local sever name string
LPSTR // null terminated remote server name string
);
/*.....................................................................
Destructor:
.....................................................................*/
~Instance_Class(void); // the destructor
/*.....................................................................
Send data routine:
- sends an unsolicited packet of data to the remote server
.....................................................................*/
BOOL Poke_Server( LPBYTE, DWORD);
/*.....................................................................
Send data routine:
- sets up DNS for the server and registers a user callback to handle
incoming data
.....................................................................*/
BOOL Register_Server( BOOL (CALLBACK *)(LPBYTE, long));
//typedef void (CALLBACK *LPDXUTCALLBACKFRAMEMOVE)( double fTime, float fElapsedTime, void* pUserContext );
/*.....................................................................
Does a trial connect to the remote server.
- used to determine whether server is alive or not (and thus running)
.....................................................................*/
BOOL Test_Server_Running( HSZ );
/*.....................................................................
Enables user callback (disabled by default)
.....................................................................*/
BOOL Enable_Callback( BOOL ); // enable or disable callback
/*.....................................................................
Open a connection for sending data to remote server
.....................................................................*/
BOOL Open_Poke_Connection( HSZ );
/*.....................................................................
Close connection with remote server
.....................................................................*/
BOOL Close_Poke_Connection( void );
//
// static members
//
/*.....................................................................
User callback - called upon receipt of incoming data (static member!)
.....................................................................*/
static BOOL (CALLBACK *callback) (
LPBYTE pointer, // pointer to received data
long length // if >0 length of received data
// if <0
// -1 == client connect detected
// -2 == client disconnect detected
);
/*.....................................................................
DDE callback, called when DDEML has an event for us
.....................................................................*/
static HDDEDATA CALLBACK dde_callback(
UINT uType, // transaction type
UINT uFmt, // clipboard data format
HCONV hconv, // handle of the conversation
HSZ hsz1, // handle of a string
HSZ hsz2, // handle of a string
HDDEDATA hdata, // handle of a global memory object
DWORD dwData1, // transaction-specific data
DWORD dwData2 // transaction-specific data
);
HANDLE instance; // this application's instance
HWND hwnd; // valid window handle
/*.....................................................................
member variables
.....................................................................*/
static DWORD id_inst; // instance identifier set by DdeInitialize
static BOOL process_pokes; // controls response to pokes
static char ascii_name[32]; // name of server
//
// non-static member variables
//
HSZ remote_name; // string handle for remote server name
HSZ local_name; // string handle for local server name
HSZ system_topic; // string handle for the "system" topic
HSZ poke_topic; // string handle for poking data to server topic
HSZ poke_item; // string handle for poking data to server item
HCONV conv_handle; // conversation handle
BOOL dde_error; // error flag
};
#endif
//#endif

690
TIBERIANDAWN/DEBUG.CPP Normal file
View File

@@ -0,0 +1,690 @@
//
// 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&c\vcs\code\debug.cpv 2.17 16 Oct 1995 16:49:18 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 : DEBUG.CPP *
* *
* Programmer : Joe L. Bostic *
* *
* Start Date : September 10, 1993 *
* *
* Last Update : July 5, 1994 [JLB] *
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* Self_Regulate -- Regulates the logic timer to result in smooth animation. *
* Debug_Key -- Debug mode keyboard processing. *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "function.h"
#include <stdarg.h>
#include <filepcx.h>
#include <io.h>
#ifdef CHEAT_KEYS
extern bool ScreenRecording;
/***********************************************************************************************
* Debug_Key -- Debug mode keyboard processing. *
* *
* If debugging is enabled, then this routine will be called for every keystroke that the *
* game doesn't recognize. These extra keys usually perform some debugging function. *
* *
* INPUT: input -- The key code that was pressed. *
* *
* OUTPUT: none *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 10/07/1992 JLB : Created. *
*=============================================================================================*/
void Debug_Key(unsigned input)
{
static int map_x = -1;
static int map_y = -1;
static int map_width = -1;
static int map_height = -1;
if (!input || input & KN_BUTTON) return;
/*
** Processing of normal keystrokes.
*/
if (Debug_Flag) {
switch (input) {
case KN_L:
extern int NetMonoMode,NewMonoMode;
if (NetMonoMode)
NetMonoMode = 0;
else
NetMonoMode = 1;
NewMonoMode = 1;
break;
/*
** Start saving off screens
*/
case (int)KN_K|(int)KN_CTRL_BIT:
ScreenRecording = true;
break;
case KN_K:
//PG_TO_FIX
#if (0)
/*
** time to create a screen shot using the PCX code (if it works)
*/
{
GraphicBufferClass temp_page( SeenBuff.Get_Width(),
SeenBuff.Get_Height(),
NULL,
SeenBuff.Get_Width() * SeenBuff.Get_Height());
char filename[30];
SeenBuff.Blit(temp_page);
for (int lp = 0; lp < 99; lp ++) {
if (lp < 10) {
sprintf(filename, "scrsht0%d.pcx", lp);
} else {
sprintf(filename, "scrsht%d.pcx", lp);
}
if (access(filename, F_OK) == -1)
break;
}
Write_PCX_File(filename, temp_page, (unsigned char *)CurrentPalette);
//Map.Place_Random_Crate();
}
#endif
break;
case KN_P:
Keyboard::Clear();
while (!Keyboard::Check()) {
Self_Regulate();
Sound_Callback();
}
Keyboard::Clear();
break;
case KN_O:
{
AircraftClass * air = new AircraftClass(AIRCRAFT_ORCA, PlayerPtr->Class->House);
if (air) {
air->Altitude = 0;
air->Unlimbo(Map.Pixel_To_Coord(Get_Mouse_X(), Get_Mouse_Y()), DIR_N);
}
}
break;
case (int)KN_B|(int)KN_ALT_BIT:
{
Debug_Instant_Build ^= 1;
}
break;
case KN_B:
{
AircraftClass * air = new AircraftClass(AIRCRAFT_HELICOPTER, PlayerPtr->Class->House);
if (air) {
air->Altitude = 0;
air->Unlimbo(Map.Pixel_To_Coord(Get_Mouse_X(), Get_Mouse_Y()), DIR_N);
}
}
break;
case KN_T:
{
AircraftClass * air = new AircraftClass(AIRCRAFT_TRANSPORT, PlayerPtr->Class->House);
if (air) {
air->Altitude = 0;
air->Unlimbo(Map.Pixel_To_Coord(Get_Mouse_X(), Get_Mouse_Y()), DIR_N);
}
}
break;
case KN_GRAVE:
new AnimClass(ANIM_ART_EXP1, Map.Pixel_To_Coord(Get_Mouse_X(), Get_Mouse_Y()));
Explosion_Damage(Map.Pixel_To_Coord(Get_Mouse_X(), Get_Mouse_Y()), 250, NULL, WARHEAD_HE);
break;
case KN_Z:
// new AnimClass(ANIM_LZ_SMOKE, Map.Pixel_To_Coord(Get_Mouse_X(), Get_Mouse_Y()));
GDI_Ending();
break;
case KN_C:
Debug_Cheat = (Debug_Cheat == false);
PlayerPtr->IsRecalcNeeded = true;
PlayerPtr->Add_Nuke_Piece();
PlayerPtr->Add_Nuke_Piece();
PlayerPtr->Add_Nuke_Piece();
/*
** This placement might affect any prerequisite requirements for construction
** lists. Update the buildable options accordingly.
*/
if (!ScenarioInit) {
Map.Recalc();
for (int index = 0; index < Buildings.Count(); index++) {
Buildings.Ptr(index)->Update_Buildables();
}
}
break;
case (int)KN_Z|(int)KN_ALT_BIT:
if (map_x == -1) {
map_x = Map.MapCellX;
map_y = Map.MapCellY;
map_width = Map.MapCellWidth;
map_height = Map.MapCellHeight;
Map.MapCellX = 1;
Map.MapCellY = 1;
Map.MapCellWidth = 62;
Map.MapCellHeight = 62;
} else {
Map.MapCellX = map_x;
Map.MapCellY = map_y;
Map.MapCellWidth = map_width;
Map.MapCellHeight = map_height;
map_x = -1;
map_y = -1;
map_width = -1;
map_height = -1;
}
break;
#ifdef NEVER
case KN_G:
HouseClass::As_Pointer(HOUSE_GOOD)->Flag_Attach(Map.Click_Cell_Calc(Get_Mouse_X(), Get_Mouse_Y()));
break;
case KN_N:
HouseClass::As_Pointer(HOUSE_BAD)->Flag_Attach(Map.Click_Cell_Calc(Get_Mouse_X(), Get_Mouse_Y()));
break;
#endif
case KN_R:
if (CurrentObject.Count()) {
((TechnoClass *)CurrentObject[0])->IsCloakable = true;
}
break;
case KN_M:
if (Debug_Flag) {
if (MonoClass::Is_Enabled()) {
MonoClass::Disable();
} else {
MonoClass::Enable();
}
}
break;
case (int)KN_W|(int)KN_ALT_BIT:
PlayerPtr->Flag_To_Win();
break;
case (int)KN_L|(int)KN_ALT_BIT:
PlayerPtr->Flag_To_Lose();
break;
case KN_F:
Debug_Find_Path ^= 1;
break;
case KN_DELETE:
if (CurrentObject.Count()) {
Map.Recalc();
//CurrentObject[0]->Detach_All();
delete CurrentObject[0];
}
break;
case KN_D:
if (Teams.Ptr(0)) {
delete Teams.Ptr(0);
}
break;
case (int)KN_DELETE|(int)KN_SHIFT_BIT:
if (CurrentObject.Count()) {
Map.Recalc();
int damage = 50;
CurrentObject[0]->Take_Damage(damage, 0, WARHEAD_SA);
}
break;
case KN_INSERT:
if (CurrentObject.Count()) {
Map.PendingObject = &CurrentObject[0]->Class_Of();
if (Map.PendingObject) {
Map.PendingHouse = CurrentObject[0]->Owner();
Map.PendingObjectPtr = Map.PendingObject->Create_One_Of(HouseClass::As_Pointer(Map.PendingHouse));
if (Map.PendingObjectPtr) {
Map.Set_Cursor_Pos();
Map.Set_Cursor_Shape(Map.PendingObject->Occupy_List());
}
}
}
break;
#ifdef NEVER
case KN_1:
case KN_2:
case KN_3:
case KN_4:
case KN_5:
case KN_6:
case KN_7:
case KN_8:
case KN_9:
case KN_0:
MonoPage = (input & 0xFF) - KN_1;
MonoPage %= sizeof(MonoArray)/sizeof(MonoArray[0]);
MonoArray[MonoPage].View();
input = 0;
break;
#endif
#ifdef NEVER
case ((int)KN_F1 | (int)KN_SHIFT_BIT):
Special.IsBarOn = (Special.IsBarOn == false);
Map.Flag_To_Redraw(true);
break;
case ((int)KN_F1 | (int)KN_SHIFT_BIT): // quick load/save for debugging
if (!Save_Game(0,"Command & Conquer Save Game File")) {
CCMessageBox().Process("Error saving game!");
Prog_End();
exit(EXIT_SUCCESS);
}
break;
case ((int)KN_F2 | (int)KN_SHIFT_BIT): // quick load/save for debugging
if (!Load_Game(0)) {
CCMessageBox().Process("Error loading game!");
Prog_End();
exit(EXIT_SUCCESS);
}
break;
//#ifdef SCENARIO_EDITOR
case KN_F2: // enable/disable the map editor
Go_Editor(!Debug_Map);
break;
//#endif
#endif
#ifdef NEVER
case KN_F2: {
Debug_Map++;
Scenario_Editor();
Debug_Map--;
#ifdef NEVER
COORDINATE coord;
int index;
static COORDINATE _coords[] = {
0x00010001L,
0x00800080L,
0x00810081L,
0x00010081L,
0x00810001L,
0x00800081L,
0x00800001L,
0x00010080L,
0x00810080L,
0L
};
index = 0;
while (_coords[index]) {
coord = _coords[index++];
Mono_Printf("Spillage for %08lX = %d.\r", coord, Coord_Spillage_Number(coord));
}
Keyboard::Clear();
Keyboard::Get();
#endif
#ifdef NEVER
#define MAX_RADIUS 10
COORDINATE coord;
int x,y;
COORDINATE const *ptr;
int input;
int f1,f2;
TurnTrackType const *track;
#define XCENTER 160
#define YCENTER 100
for (;;) {
VisiblePage.Clear();
// Draw grid.
{
static int _gridx[] = {0,64,128,192,0,64,128,192,0,64,128,192};
static int _gridy[] = {0,0,0,0,64,64,64,64,128,128,128,128};
int index;
for (index = 0; index < 12; index++) {
LogicPage->Put_Pixel((_gridx[index]+XCENTER)-(32+64),(_gridy[index]+YCENTER)-(32+64), DKGRAY);
}
}
// Get facing #1.
LogicPage->Print("Facing #1 (0-7)?", 0, 0, WHITE, BLACK);
input = Keyboard::Get();
if (input == KA_ESC) break;
input -= KA_0;
input = Bound(input, 0, 7);
// input = MAX(input, 0);
// input = MIN(input, 7);
f1 = input;
Int_Print(f1, 100, 0, WHITE, BLACK);
// Get facing #2.
LogicPage->Print("Facing #2 (0-7)?", 0, 10, WHITE, BLACK);
input = Keyboard::Get();
if (input == KA_ESC) break;
input -= KA_0;
input = Bound(input, 0, 7);
// input = MAX(input, 0);
// input = MIN(input, 7);
f2 = input;
Int_Print(f2, 100, 10, WHITE, BLACK);
track = &TrackControl[f1][f2];
if (track->Track == 0) {
LogicPage->Print("Undefined track.", 0, 30, WHITE, BLACK);
} else {
int index; // Track index counter.
ptr = TrackPointers[track->Track-1];
index = 0;
while (ptr[index]) {
coord = Smooth_Turn(NULL, ptr[index], track->Flag);
x = (int)(coord & 0xFFFF);
y = (int)((coord >> 16) & 0xFFFF);
LogicPage->Put_Pixel(XCENTER + (x>>2), YCENTER + (y>>2), WHITE);
Delay(1);
index++;
}
}
input = Keyboard::Get();
if (input == KA_ESC) break;
}
Map.Flag_To_Redraw(true);
#endif
#ifdef NEVER
FILE *fh;
int index;
COORDINATE coord;
fh = fopen("diagonal.txt", "wt");
if (fh) {
fprintf(fh, "track 2\n");
coord = 0x0100FF00L;
for (index = 0; index <= 48; index++) {
fprintf(fh, "0x%08lXL\n", coord);
coord = Coord_Move(coord, 32, 11);
}
fprintf(fh, "\n\n");
fprintf(fh, "track 1\n");
coord = 0x01000000L;
for (index = 0; index <= 40; index++) {
fprintf(fh, "0x%08lXL\n", coord);
coord = Coord_Move(coord, 0, 11);
}
fprintf(fh, "\n\n");
fclose(fh);
}
#endif
#ifdef NEVER
FILE *fh;
int x,y,radius;
int radsize[MAX_RADIUS+2];
int count;
memset(radsize, 0, sizeof(radsize));
fh = fopen("Range.txt", "wt");
if (fh) {
fprintf(fh, "int const RadiusOffset[] = {\n");
for (radius = 0; radius <= MAX_RADIUS; radius++) {
fprintf(fh, "\t/* %-2d */\t", radius);
for (y = -MAX_RADIUS; y <= MAX_RADIUS; y++) {
for (x = -MAX_RADIUS; x <= MAX_RADIUS; x++) {
int xd,yd,dist;
xd = ABS(x);
yd = ABS(y);
if (xd > yd) {
dist = yd/2 + xd;
} else {
dist = xd/2 + yd;
}
if (dist == radius) {
dist = y*MAP_CELL_W + x;
if (y) {
if (y < 0) {
fprintf(fh, "(-MCW*%d)", ABS(y));
} else {
fprintf(fh, "(MCW*%d)", ABS(y));
}
fprintf(fh, "%c%d,", (x<0) ? '-' : '+', ABS(x));
} else {
fprintf(fh, "%d,", x);
}
radsize[radius]++;
}
}
}
fprintf(fh, "\n");
}
fprintf(fh, "};\n\n");
count = 0;
fprintf(fh, "int const RadiusCount[%d] = {", MAX_RADIUS+1);
for (radius = 0; radius <= MAX_RADIUS; radius++) {
count += radsize[radius];
fprintf(fh, "%d", count);
if (radius != MAX_RADIUS) {
fprintf(fh, ",");
}
}
fprintf(fh, "};\n");
fclose(fh);
}
#endif
}
break;
#endif
#ifdef NEVER
case ((int)KN_F3 | (int)KN_ALT_BIT): // quick load/save for debugging
Debug_Threat = (Debug_Threat == false);
Map.Flag_To_Redraw(true);
break;
#endif
case KN_F3:
Debug_Icon = (Debug_Icon == false);
Map.Flag_To_Redraw(true);
break;
/*
** Reveal entire map to player.
*/
case KN_F4:
if (GameToPlay == GAME_NORMAL) {
Debug_Unshroud = (Debug_Unshroud == false);
Map.Flag_To_Redraw(true);
}
break;
/*
** Shows sight and fire range in the form of circles emanating from the currently
** selected unit. The white circle is for sight range, the red circle is for
** fire range.
*/
case KN_F7:
if (CurrentObject.Count() && CurrentObject[0]->Is_Techno()) {
TechnoTypeClass const & ttype = (TechnoTypeClass const &)CurrentObject[0]->Class_Of();
int sight = ((int)ttype.SightRange)<<8;
int weapon = 0;
if (ttype.Primary != WEAPON_NONE) weapon = Weapons[ttype.Primary].Range;
Set_Logic_Page(SeenBuff);
COORDINATE center = CurrentObject[0]->Center_Coord();
COORDINATE center2 = CurrentObject[0]->Fire_Coord(0);
for (int r = 0; r < 255; r += 10) {
int x,y,x1,y1;
DirType r1 = (DirType)r;
DirType r2 = (DirType)((r+10) & 0xFF);
if (Map.Coord_To_Pixel(Coord_Move(center, r1, sight), x, y)) {
Map.Coord_To_Pixel(Coord_Move(center, r2, sight), x1, y1);
LogicPage->Draw_Line(x, y+8, x1, y1+8, WHITE);
}
if (Map.Coord_To_Pixel(Coord_Move(center2, r1, weapon), x, y)) {
Map.Coord_To_Pixel(Coord_Move(center2, r2, weapon), x1, y1);
LogicPage->Draw_Line(x, y+8, x1, y1+8, RED);
}
}
}
break;
case ((int)KN_F4 | (int)KN_CTRL_BIT):
Debug_Unshroud = (Debug_Unshroud == false);
Map.Flag_To_Redraw(true);
break;
#ifdef NEVER
case KN_F5:
Special.IsShowPath = (Special.IsShowPath == false);
//PlayerPtr->Credits += 1000;
break;
case KN_F6:
if (Map.In_Radar(XY_Cell(Map.MapCellX+5, Map.MapCellY - 1))) {
Mono_Printf("Arrrggggghhhhh!");
} else {
Mono_Printf("No Arrrggggghhhhh!");
}
break;
case ((int)KN_F9 | (int)KN_CTRL_BIT):
if (HouseClass::As_Pointer(HOUSE_GOOD))
(HouseClass::As_Pointer(HOUSE_GOOD))->Blowup_All();
break;
case ((int)KN_F10 | (int)KN_CTRL_BIT):
if (HouseClass::As_Pointer(HOUSE_BAD))
(HouseClass::As_Pointer(HOUSE_BAD))->Blowup_All();
break;
#endif
}
}
}
/***********************************************************************************************
* Self_Regulate -- Regulates the logic timer to result in smooth animation *
* *
* The self regulation process checks the number of frames displayed *
* per second and from this determines the amount of time to devote *
* to internal logic processing. By adjusting the time allotted to *
* internal processing, smooth animation can be maintained. *
* *
* INPUT: none *
* *
* OUTPUT: none *
* *
* WARNINGS: In order for this routine to work properly it MUST be *
* called every display loop. *
* *
* HISTORY: *
* 07/31/1991 JLB : Created. *
* 07/05/1994 JLB : Handles new monochrome system. *
*=============================================================================================*/
#define UPDATE_INTERVAL TIMER_SECOND
void Self_Regulate(void)
{
static CountDownTimerClass DebugTimer(BT_SYSTEM);
static ObjectClass * _lastobject = 0;
if (!DebugTimer.Time()) {
DebugTimer.Set(UPDATE_INTERVAL);
if (MonoClass::Is_Enabled()) {
MonoClass *mono = MonoClass::Get_Current();
mono->Set_Default_Attribute(2);
switch (MonoPage) {
case 0:
mono = &MonoArray[0];
mono->Clear();
/*
** Display the status of the currently selected object.
*/
if (CurrentObject.Count()) {
_lastobject = CurrentObject[0];
}
if (_lastobject && !_lastobject->IsActive) {
_lastobject = 0;
}
if (_lastobject) {
_lastobject->Debug_Dump(mono);
}
Logic.Debug_Dump(mono);
mono->Set_Cursor(0, 20);
mono->Printf(
"Heap size:%10ld \r"
"Largest: %10ld \r"
"Ttl Free: %10ld \r"
"Frag: %10ld \r",
Heap_Size(MEM_NORMAL),
Ram_Free(MEM_NORMAL),
Total_Ram_Free(MEM_NORMAL),
Total_Ram_Free(MEM_NORMAL)-Ram_Free(MEM_NORMAL)
);
*MonoClass::Get_Current() = *mono;
break;
}
MonoArray[MonoPage] = *mono;
}
}
}
#endif

39
TIBERIANDAWN/DEBUG.H Normal file
View File

@@ -0,0 +1,39 @@
//
// 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_DEBUG 0x3e8 //
#define TXTED_BLANK 0x3e9 // ____
#define TXTED_UNABLETOREAD 0x3ea // Unable to read scenario!
#define TXTED_FILEEXISTS 0x3eb // File exists. Replace?
#define TXTED_LOWMEM 0x3ec // Insufficient memory!
#define TXTED_EXIT 0x3ed // Exit Scenario Editor?
#define TXT_GENERIC_EXCEPTION 0x3ee // ERROR: Exception was
#define TXT_RADIO_1 0x3ef // hisssss
#define TXT_RADIO_2 0x3f0 // Roger.
#define TXT_RADIO_3 0x3f1 // Come in.
#define TXT_RADIO_4 0x3f2 // Over and out.
#define TXT_RADIO_5 0x3f3 // Requesting transport.
#define TXT_RADIO_6 0x3f4 // I've got a delivery for
#define TXT_RADIO_7 0x3f5 // I'm performing load/unload
#define TXT_RADIO_8 0x3f6 // I'm clear.
#define TXT_RADIO_9 0x3f7 // You are clear to unload.
#define TXT_RADIO_10 0x3f8 // Am unable to comply.
#define TXT_RADIO_11 0x3f9 // I'm starting construction
#define TXT_RADIO_12 0x3fa // I've finished construction.
#define TXT_RADIO_13 0x3fb // Oops, sorry. I might have
#define TXT_RADIO_14 0x3fc // I'm full. May I unload at
#define TXT_RADIO_15 0x3fd // Are you a refinery and are
#define TXT_RADIO_16 0x3fe // Take this kick! You...
#define TXT_RADIO_17 0x3ff // Take this punch! You...

2961
TIBERIANDAWN/DEFINES.H Normal file

File diff suppressed because it is too large Load Diff

181
TIBERIANDAWN/DESCDLG.CPP Normal file
View File

@@ -0,0 +1,181 @@
//
// 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&c\vcs\code\descdlg.cpv 2.17 16 Oct 1995 16:49:44 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 : DESCDLG.CPP *
* *
* Programmer : Maria del Mar McCready Legg *
* Joe L. Bostic *
* *
* Start Date : Jan 26, 1995 *
* *
* Last Update : Jan 26, 1995 [MML] *
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* DescriptionClass::Process -- Handles all the options graphic interface. *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "function.h"
#include "descdlg.h"
/***********************************************************************************************
* DescriptionClass::Process -- Handles all the options graphic interface. *
* *
* This dialog uses an edit box to "fill-out" a description. *
* *
* INPUT: char *string - return answer here. *
* OUTPUT: none *
* WARNINGS: none *
* HISTORY: 12/31/1994 MML : Created. *
*=============================================================================================*/
void DescriptionClass::Process(char *string)
{
/*
-----------------------------------------------------------------
Set up the window. Window x-coords are in bytes not pixels.
-----------------------------------------------------------------
*/
Set_Window(WINDOW_EDITOR, OPTION_X, OPTION_Y, OPTION_WIDTH, OPTION_HEIGHT);
Set_Logic_Page(SeenBuff);
/*
-----------------------------------------------------------------------
Create Buttons. Button coords are in pixels, but are window-relative.
-----------------------------------------------------------------------
*/
TextButtonClass optionsbtn(
BUTTON_OPTIONS,
TXT_OK,
TPF_6PT_GRAD,
0,
BUTTON_Y);
TextButtonClass cancelbtn(
BUTTON_CANCEL,
TXT_CANCEL,
TPF_6PT_GRAD,
0,
BUTTON_Y);
cancelbtn.X = OPTION_X + ((OPTION_WIDTH - optionsbtn.Width)/3)*2;
optionsbtn.X = OPTION_X + ((OPTION_WIDTH - optionsbtn.Width)/3);
optionsbtn.Add_Tail(cancelbtn);
EditClass edit(
BUTTON_EDIT,
string,
31,
TPF_6PT_GRAD,
0,
EDIT_Y
,EDIT_W);
edit.Set_Focus();
edit.X = OPTION_X + (OPTION_WIDTH - edit.Width)/2,
optionsbtn.Add_Tail(edit);
/*
** 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(OPTION_X, OPTION_Y, OPTION_WIDTH, OPTION_HEIGHT, GadgetClass::LEFTPRESS);
optionsbtn.Add_Tail(dialog);
/*
** 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_OPTIONS, 0, 0, SeenBuff.Get_Width(), SeenBuff.Get_Height(), GadgetClass::LEFTPRESS|GadgetClass::RIGHTPRESS);
optionsbtn.Add_Tail(background);
/*
------------------- Main Processing Loop --------------------
*/
bool display = true;
bool process = true;
while (process) {
/*
** 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=TRUE;
}
/*
-------------- Invoke game callback -------------
*/
Call_Back();
/*
-------------- Refresh display if needed --------------
*/
if (display) {
Window_Hide_Mouse(WINDOW_EDITOR);
/*
--------- Draw the background -----------
*/
Window_Box (WINDOW_EDITOR, BOXSTYLE_GREEN_BORDER); // has border, raised up
Draw_Caption(TXT_MISSION_DESCRIPTION, OPTION_X, OPTION_Y, OPTION_WIDTH);
/*
--------- Draw the titles -----------
*/
optionsbtn.Draw_All();
Window_Show_Mouse();
display = false;
}
/*
-------------- Get user input ---------------
*/
KeyNumType input = optionsbtn.Input();
/*
-------------- Process Input ----------------
*/
switch (input) {
case KN_RETURN:
case BUTTON_OPTIONS|KN_BUTTON:
strtrim(string);
process = false;
break;
case KN_ESC:
case BUTTON_CANCEL|KN_BUTTON:
string[0]= NULL;
strtrim(string);
process = false;
break;
case BUTTON_EDIT|KN_BUTTON:
break;
}
}
}

66
TIBERIANDAWN/DESCDLG.H Normal file
View File

@@ -0,0 +1,66 @@
//
// 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&c\vcs\code\descdlg.h_v 2.18 16 Oct 1995 16:47:26 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 : DESCDLG.H *
* *
* Programmer : Maria del Mar McCready Legg *
* Joe L. Bostic *
* *
* Start Date : Jan 26, 1995 *
* *
* Last Update : Jan 26, 1995 [MML] *
* *
*---------------------------------------------------------------------------------------------*/
#ifndef DESCDLG_H
#define DESCDLG_H
#include "gadget.h"
class DescriptionClass
{
private:
enum DescriptionClassEnum {
OPTION_WIDTH=216, // Width of dialog box.
OPTION_HEIGHT=122, // Height of dialog box.
OPTION_X=(((320 - OPTION_WIDTH) / 2) & ~7),
OPTION_Y=((200 - OPTION_HEIGHT) / 2),
TEXT_X=OPTION_X+32, // Title's x pos
TEXT_Y=OPTION_Y+32, // Add 11 for each following line
BUTTON_OPTIONS=1, // Button number for "Ok"
BUTTON_CANCEL,
BUTTON_EDIT,
BUTTON_X=OPTION_X+63, // Options button x pos
BUTTON_Y=OPTION_Y+102, // Options button y pos
EDIT_Y =OPTION_Y+50,
EDIT_W =180 //204,
};
public:
DescriptionClass(void) {};
void Process(char *string);
};
#endif

314
TIBERIANDAWN/DIAL8.CPP Normal file
View File

@@ -0,0 +1,314 @@
//
// 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&c\vcs\code\dial8.cpv 2.18 16 Oct 1995 16:51:32 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 : DIAL8.CPP *
* *
* Programmer : Bill Randolph *
* *
* Start Date : February 6, 1995 *
* *
* Last Update : February 6, 1995 [BR] *
* *
*-------------------------------------------------------------------------*
* Functions: *
* Dial8Class::Action -- action routine for Dial8Class *
* Dial8Class::Dial8Class -- constructor for the facing dial *
* Dial8Class::Draw_Me -- render routine for Dial8Class *
* Dial8Class::Get_Direction -- retrieves direction (0-255) of dial *
* Dial8Class::Set_Direction -- sets current direction (0-255) of dial *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "function.h"
/***************************************************************************
* Dial8Class::Dial8Class -- constructor for the facing dial *
* *
* INPUT: *
* id button ID *
* x,y,w,h dimensions in window-relative pixels *
* dir numerical initial facing value (0-255); this is the *
* value returned by WWLIB Desired_Facing8() *
* *
* OUTPUT: *
* none. *
* *
* WARNINGS: *
* none. *
* *
* HISTORY: *
* 11/16/1994 BR : Created. *
*=========================================================================*/
Dial8Class::Dial8Class(int id, int x, int y, int w, int h, DirType dir) :
ControlClass(id, x, y, w, h, LEFTPRESS | LEFTHELD | LEFTRELEASE, true)
{
/*
** Center coordinates.
*/
FaceX = X + (Width / 2);
FaceY = Y + (Height / 2);
/*
** Init directions.
*/
Direction = dir; // 0 - 255
Facing = Dir_Facing(Direction); // 0 - 7
OldFacing = Facing; // 0 - 7
/*
** Compute the drawing dimensions: a 45-degree angle intersects a unity-
** radius circle at (.707,.707). Make the decorations 8/10 of the radius,
** and the line extend to 6/10 of the radius. Use Width/2 for x-radius,
** Height/2 for y-radius.
*/
FacePoint[0][0] = FaceX;
FacePoint[0][1] = FaceY - (h * 8 / 2) / 10;
FacePoint[1][0] = FaceX + (w * 7 * 8 / 2) / 100;
FacePoint[1][1] = FaceY - (h * 7 * 8 / 2) / 100;
FacePoint[2][0] = FaceX + (w * 8 / 2) / 10;
FacePoint[2][1] = FaceY;
FacePoint[3][0] = FaceX + (w * 7 * 8 / 2) / 100;
FacePoint[3][1] = FaceY + (h * 7 * 8 / 2) / 100;
FacePoint[4][0] = FaceX;
FacePoint[4][1] = FaceY + (h * 8 / 2) / 10;
FacePoint[5][0] = FaceX - (w * 7 * 8 / 2) / 100;
FacePoint[5][1] = FaceY + (h * 7 * 8 / 2) / 100;
FacePoint[6][0] = FaceX - (w * 8 / 2) / 10;
FacePoint[6][1] = FaceY;
FacePoint[7][0] = FaceX - (w * 7 * 8 / 2) / 100;
FacePoint[7][1] = FaceY - (h * 7 * 8 / 2) / 100;
FaceLine[0][0] = FaceX;
FaceLine[0][1] = FaceY - (h * 6 / 2) / 10;
FaceLine[1][0] = FaceX + (w * 7 * 6 / 2) / 100;
FaceLine[1][1] = FaceY - (h * 7 * 6 / 2) / 100;
FaceLine[2][0] = FaceX + (w * 6 / 2) / 10;
FaceLine[2][1] = FaceY;
FaceLine[3][0] = FaceX + (w * 7 * 6 / 2) / 100;
FaceLine[3][1] = FaceY + (h * 7 * 6 / 2) / 100;
FaceLine[4][0] = FaceX;
FaceLine[4][1] = FaceY + (h * 6 / 2) / 10;
FaceLine[5][0] = FaceX - (w * 7 * 6 / 2) / 100;
FaceLine[5][1] = FaceY + (h * 7 * 6 / 2) / 100;
FaceLine[6][0] = FaceX - (w * 6 / 2) / 10;
FaceLine[6][1] = FaceY;
FaceLine[7][0] = FaceX - (w * 7 * 6 / 2) / 100;
FaceLine[7][1] = FaceY - (h * 7 * 6 / 2) / 100;
}
/***************************************************************************
* Dial8Class::Action -- activation function for Dial8Class *
* *
* 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/06/1995 BR : Created. *
*=========================================================================*/
int Dial8Class::Action(unsigned flags, KeyNumType &key)
{
static int is_sel = 0;
/*
** We might end up clearing the event bits. Make sure that the sticky
** process is properly updated anyway.
*/
Sticky_Process(flags);
if (flags & LEFTPRESS) {
is_sel = 1;
}
/*
** If left mouse is clicked or held, and the dial has changed its direction,
** invoke the parent Action routine:
** GadgetClass::Action handles Sticky processing, & sets IsToRepaint if any
** flag bits are set.
** ControlClass::Action handles Peer_To_Peer notification, and substitues
** 'key' with the button ID if any flags are set, or 0 if no flags are set
*/
if (flags & LEFTPRESS || ((flags & LEFTHELD) && is_sel)) {
/*
** Get new dial position (0-255)
*/
Direction = (DirType)Desired_Facing8(FaceX, FaceY, Get_Mouse_X(), Get_Mouse_Y());
/*
** Convert to Facing value (0-7).
*/
Facing = Dir_Facing(Direction);
/*
** If it's moved, redraw.
*/
if (Facing!=OldFacing) {
OldFacing = Facing;
ControlClass::Action(flags,key);
return(true);
} else {
/*
** Dial hasn't moved; kill the event & return
*/
key = KN_NONE;
ControlClass::Action(0,key);
return(true);
}
} else {
/*
** Otherwise, no events have occurred; kill the event if it's a LEFTRELEASE,
** and return
*/
if (flags & LEFTRELEASE) {
key = KN_NONE;
is_sel = 0;
}
return(ControlClass::Action(0,key));
}
}
/***************************************************************************
* Dial8Class::Draw_Me -- custom render routine for Dial8Class *
* *
* INPUT: *
* forced true = draw regardless of the current redraw flag state*
* *
* OUTPUT: *
* true = gadget was redrawn, false = wasn't *
* *
* WARNINGS: *
* none. *
* *
* HISTORY: *
* 02/06/1995 BR : Created. *
*=========================================================================*/
int Dial8Class::Draw_Me(int forced)
{
/*
** Redraw if parent indicates a redraw is needed
*/
if (ControlClass::Draw_Me(forced)) {
/*
** Hide the mouse.
*/
if (LogicPage == &SeenBuff) {
Hide_Mouse();
}
/*
** Draw background & decorations.
*/
Draw_Box(X, Y, Width, Height, BOXSTYLE_GREEN_DOWN, true);
for (int i=0; i<8; i++) {
Draw_Box(FacePoint[i][0] - 1, FacePoint[i][1] -1, 3, 3, BOXSTYLE_GREEN_RAISED, false);
}
/*
** Draw the hand & its shadow.
*/
LogicPage->Draw_Line(FaceX+1, FaceY+1, FaceLine[Facing][0]+1, FaceLine[Facing][1]+1,CC_GREEN_SHADOW);
LogicPage->Draw_Line(FaceX, FaceY, FaceLine[Facing][0], FaceLine[Facing][1],CC_LIGHT_GREEN);
/*
** Restore the mouse.
*/
if (LogicPage == &SeenBuff) {
Show_Mouse();
}
return(true);
}
return(false);
}
/***************************************************************************
* Dial8Class::Get_Direction -- retrieves direction (0-255) of dial *
* *
* INPUT: *
* none. *
* *
* OUTPUT: *
* DirType dial is pointing to *
* *
* WARNINGS: *
* none. *
* *
* HISTORY: *
* 11/17/1994 BR : Created. *
*=========================================================================*/
DirType Dial8Class::Get_Direction(void) const
{
return(Direction);
}
/***************************************************************************
* Dial8Class::Set_Direction -- sets current direction (0-255) of dial *
* *
* INPUT: *
* DirType to set dial to *
* *
* OUTPUT: *
* none. *
* *
* WARNINGS: *
* none. *
* *
* HISTORY: *
* 11/17/1994 BR : Created. *
*=========================================================================*/
void Dial8Class::Set_Direction(DirType dir)
{
Direction = dir;
Facing = Dir_Facing(Direction);
OldFacing = Facing;
Flag_To_Redraw();
}

73
TIBERIANDAWN/DIAL8.H Normal file
View File

@@ -0,0 +1,73 @@
//
// 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&c\vcs\code\dial8.h_v 2.18 16 Oct 1995 16:47: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 ***
***********************************************************************************************
* *
* Project Name : Command & Conquer *
* *
* File Name : DIAL8.H *
* *
* Programmer : Bill Randolph *
* *
* Start Date : 02/06/95 *
* *
* Last Update : February 6, 1995 [BR] *
* *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef DIAL8_H
#define DIAL8_H
class Dial8Class : public ControlClass
{
public:
/*
** Constructor/Destructor
*/
Dial8Class(int id, int x, int y, int w, int h, DirType dir);
/*
** Get/Set the direction the dial is currently pointing
*/
DirType Get_Direction(void) const;
void Set_Direction(DirType dir);
/*
** Overloaded draw routine
*/
virtual int Draw_Me(int forced = false);
protected:
/*
** Overloaded event processing routine
*/
virtual int Action(unsigned flags, KeyNumType &key);
private:
int FaceX; // x-coord of center of face
int FaceY; // y-coord of center of face
int FacePoint[8][2]; // coords of the little dial decorations
int FaceLine[8][2]; // coords for drawing the dial hand
DirType Direction; // 0-255 numerical direction of dial
FacingType Facing; // numerical facing direction of dial (0 - 7)
FacingType OldFacing; // previous Facing value
};
#endif

787
TIBERIANDAWN/DIALOG.CPP Normal file
View File

@@ -0,0 +1,787 @@
//
// 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&c\vcs\code\dialog.cpv 2.17 16 Oct 1995 16:51:50 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 : DIALOG.CPP *
* *
* Programmer : Joe L. Bostic *
* *
* Start Date : September 10, 1993 *
* *
* Last Update : May 18, 1995 [JLB] *
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* Clip_Text_Print -- Prints text with clipping and <TAB> support. *
* Dialog_Box -- draws a dialog background box *
* Display_Place_Building -- Displays the "place building" dialog box. *
* Display_Select_Target -- Displays the "choose target" prompt. *
* Display_Status -- Display the player scenario status box. *
* Draw_Box -- Displays a highlighted box. *
* Fancy_Text_Print -- Prints text with a drop shadow. *
* Redraw_Needed -- Determine if sidebar needs to be redrawn. *
* Render_Bar_Graph -- Renders a specified bargraph. *
* Simple_Text_Print -- Prints text with a drop shadow. *
* Window_Box -- Draws a fancy box over the specified window. *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "function.h"
/***********************************************************************************************
* Dialog_Box -- draws a dialog background box *
* *
* INPUT: *
* x,y,w,h the usual *
* *
* OUTPUT: *
* none. *
* *
* WARNINGS: *
* none. *
* *
* HISTORY: *
* 01/26/1995 BR : Created. *
*=============================================================================================*/
void Dialog_Box(int x, int y, int w, int h)
{
Draw_Box( x, y, w, h, BOXSTYLE_GREEN_BORDER, true);
}
/***********************************************************************************************
* Draw_Box -- Displays a highlighted box. *
* *
* This will draw a highlighted box to the logicpage. It can *
* optionally fill the box with a color as well. This is a low level *
* function and thus, it doesn't do any graphic mode color adjustments. *
* *
* INPUT: x,y -- Upper left corner of the box to be drawn (pixels). *
* *
* w,h -- Width and height of box (in pixels). *
* *
* up -- Is the box rendered in the "up" stated? *
* *
* filled-- Is the box to be filled. *
* *
* OUTPUT: none *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 05/28/1991 JLB : Created. *
* 05/30/1992 JLB : Embedded color codes. *
* 07/31/1992 JLB : Depressed option added. *
*=============================================================================================*/
extern void CC_Texture_Fill (void const *shapefile, int shapenum, int xpos, int ypos, int width, int height);
void Draw_Box(int x, int y, int w, int h, BoxStyleEnum up, bool filled)
{
static BoxStyleType const ButtonColors[BOXSTYLE_COUNT] = {
//Filler, Shadow, Hilite, Corner colors
{ LTGREY, WHITE, DKGREY, LTGREY}, // 0 Button is down.
{ LTGREY, DKGREY, WHITE, LTGREY}, // 1 Button is up w/border.
{ LTBLUE, BLUE, LTCYAN, LTBLUE}, // 2 Raised blue.
{ DKGREY, WHITE, BLACK, DKGREY}, // 3 Button is disabled down.
{ DKGREY, BLACK, WHITE, LTGREY}, // 4 Button is disabled up.
{ LTGREY, DKGREY, WHITE, LTGREY}, // 5 Button is up w/arrows.
//{ CC_GREEN_BKGD, CC_LIGHT_GREEN, CC_GREEN_SHADOW, CC_GREEN_CORNERS }, // 6 Button is down.
//{ CC_GREEN_BKGD, CC_GREEN_SHADOW, CC_LIGHT_GREEN, CC_GREEN_CORNERS }, // 7 Button is up w/border.
{ CC_GREEN_BKGD, 14, 12, 13 }, // 6 Button is down.
{ CC_GREEN_BKGD, 12, 14, 13 }, // 7 Button is up w/border.
{ DKGREY, WHITE, BLACK, DKGREY}, // 8 Button is disabled down.
{ DKGREY, BLACK, LTGREY, DKGREY}, // 9 Button is disabled up.
//{ BLACK, CC_GREEN_BOX, CC_GREEN_BOX, BLACK}, // 10 List box.
//{ BLACK, CC_GREEN_BOX, CC_GREEN_BOX, BLACK}, // 11 Menu box.
{ BLACK, 14, 14, BLACK}, // 10 List box.
{ BLACK, 14, 14, BLACK}, // 11 Menu box.
};
w--;
h--;
BoxStyleType const &style = ButtonColors[up];
if (filled) {
if (style.Filler == CC_GREEN_BKGD){
CC_Texture_Fill (MixFileClass::Retrieve("BTEXTURE.SHP"), InMainLoop, x, y, w, h);
}else{
LogicPage->Fill_Rect( x, y, x+w, y+h, style.Filler);
}
}
switch ( up ) {
case ( BOXSTYLE_GREEN_BOX ):
LogicPage->Draw_Rect(x, y, x+w, y+h, style.Highlight);
break;
case ( BOXSTYLE_GREEN_BORDER ):
LogicPage->Draw_Rect(x+1, y+1, x+w-1, y+h-1, style.Highlight);
break;
default:
LogicPage->Draw_Line(x, y+h, x+w, y+h, style.Shadow);
LogicPage->Draw_Line(x+w, y, x+w, y+h, style.Shadow);
LogicPage->Draw_Line(x, y, x+w, y, style.Highlight);
LogicPage->Draw_Line(x, y, x, y+h, style.Highlight);
LogicPage->Put_Pixel(x, y+h, style.Corner);
LogicPage->Put_Pixel(x+w, y, style.Corner);
break;
}
}
/***********************************************************************************************
* Format_Window_String -- Separates a String into Lines. *
* This function will take a long string and break it up into lines *
* which are not longer then the window width. Any character < ' ' is *
* considered a new line marker and will be replaced by a NULL. *
* *
* INPUT: char *String - string to be formated. *
* int maxlinelen - Max length of any line in pixels. *
* *
* OUTPUT: int - number of lines string is. *
* *
* WARNINGS: The string passed in will be modified - NULLs will be put *
* into each position that will be a new line. *
* *
* HISTORY: *
* 03/27/1992 SB : Created. *
* 05/18/1995 JLB : Greatly revised for new font system. *
*=============================================================================================*/
int Format_Window_String(char * string, int maxlinelen, int & width, int & height)
{
int linelen;
int lines = 0;
width = 0;
height = 0;
// In no string was passed in, then there are no lines.
if (!string) return(0);
// While there are more letters left divide the line up.
while (*string) {
linelen = 0;
height += FontHeight + FontYSpacing;
lines++;
// While the current line is less then the max length...
while (linelen < maxlinelen && *string != '\r' && *string != '\0') {
linelen += Char_Pixel_Width(*string++);
}
// if the line is to long...
if (linelen >= maxlinelen) {
/*
** Back up to an appropriate location to break.
*/
while (*string != ' ' && *string != '\r' && *string != '\0') {
linelen -= Char_Pixel_Width(*string--);
}
}
/*
** Record the largest width of the worst case string.
*/
if (linelen > width) {
width = linelen;
}
/*
** Force a break at the end of the line.
*/
if (*string) {
*string++ = '\r';
}
}
return(lines);
}
/***********************************************************************************************
* Window_Box -- Draws a fancy box over the specified window. *
* *
* This routine will draw a fancy (shaded) box over the specified *
* window. This is the effect used to give the polished look to *
* screen rectangles without having to use art. *
* *
* INPUT: window -- Specified window to fill and border. *
* *
* style -- The style to render the window. *
* *
* OUTPUT: none *
* *
* WARNINGS: The rendering is done to the LogicPage. *
* *
* HISTORY: *
* 03/03/1992 JLB : Created. *
* 07/31/1992 JLB : Cool raised border effect. *
* 06/08/1994 JLB : Takes appropriate enumeration parameters. *
*=============================================================================================*/
void Window_Box(WindowNumberType window, BoxStyleEnum style)
{
int x,y,w,h; // Window dimensions.
int border; // Width of border.
static int _border[BOXSTYLE_COUNT][2] = {
{0,0}, // 0 Simple beveled edge.
{2,4}, // 1 Wide raised border.
{1,1}, // 2 Thick beveled edge.
{2,1}, // 3 Thin raised border.
{0,0}, // 4 Simple beveled edge.
{20,0}, // 5 Simple beveled edge.
{0,0}, // 6 Simple beveled edge.
{2,4}, // 7 Wide raised border.
{0,0}, // 8 Simple beveled edge.
{20,0}, // 9 Simple beveled edge.
{0,1} // 10 Simple 1 pixel box.
};
x = WindowList[window][WINDOWX]<<3;
y = WindowList[window][WINDOWY];
w = WindowList[window][WINDOWWIDTH]<<3;
h = WindowList[window][WINDOWHEIGHT];
/*
** If it is to be rendered to the seenpage, then
** hide the mouse.
*/
if (LogicPage == (&SeenBuff)) Conditional_Hide_Mouse(x,y,x+w,y+h);
Draw_Box(x, y, w, h, style, true);
border = _border[style][1];
/*
** Draw the second border if requested.
*/
if (border) {
Draw_Box(x+border, y+border, w-(border<<1), h-(border<<1), style, false);
}
/*
** Restore the mouse if it has been hidden and return.
*/
if (LogicPage == &SeenBuff) Conditional_Show_Mouse();
}
/***********************************************************************************************
* Simple_Text_Print -- Prints text with a drop shadow. *
* *
* This routine functions like Text_Print, but will render a drop *
* shadow (in black). *
* *
* INPUT: text -- Pointer to text to render. *
* *
* x,y -- Pixel coordinate for to print text. *
* *
* fore -- Foreground color. *
* *
* back -- Background color. *
* *
* flag -- Text print control flags. *
* *
* OUTPUT: none *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 12/24/1991 JLB : Created. *
* 10/26/94 JLB : Handles font X spacing in a more friendly manner. *
*=============================================================================================*/
void Simple_Text_Print(char const *text, unsigned x, unsigned y, unsigned fore, unsigned back, TextPrintType flag)
{
static int yspace=0; // Y spacing adjustment for font.
static int xspace=0; // Spacing adjustment for font.
void const * font=0; // Font to use.
////////////////#if (0)
static unsigned char _textfontpal[16][16] = {
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27, 27, 26, 25, 24 },
{ 0,135, 0, 0, 0, 0, 0, 0, 0, 0, 0,136, 136,135,119, 2 },
{ 0,159, 0, 0, 0, 0, 0, 0, 0, 0, 0,142, 143,159,41 ,167 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0,157, 0, 0, 0, 0, 0, 0, 0, 0, 0,180, 180,157,158, 5 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0,179, 0, 0, 0, 0, 0, 0, 0, 0, 0,180, 180,179,178,176 },
{ 0,123, 0, 0, 0, 0, 0, 0, 0, 0, 0,122, 122,123,125,127 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0,203, 0, 0, 0, 0, 0, 0, 0, 0, 0,204, 204,203,202,201 },
{ 0, 1, 4,166, 41, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0,203, 0, 0, 0, 0, 0, 0, 0, 0, 0,204, 204,203,202,201 },
{ 0,203, 0, 0, 0, 0, 0, 0, 0, 0, 0,204, 204,203,202,201 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
};
static unsigned char _textpalmedium[16] = {
0, 25, 119,41, 0, 158,0, 178, 125,0, 202,0, 0, 0, 0, 0
};
static unsigned char _textpalbright[16] = {
0, 24, 2, 4, 0, 5, 0, 176, 127,0, 201,0, 0, 0, 0, 0
};
///////////////////////#endif //(0)
int point; // Requested font size.
int shadow; // Requested shadow value.
unsigned char fontpalette[16]; // Working font palette array.
memset(&fontpalette[0], back, 16);
if ((flag & 0xf) == TPF_VCR) {
fontpalette[3] = 12;
fontpalette[9] = 15;
fontpalette[10] = 200;
fontpalette[11] = 201;
fontpalette[12] = 202;
fontpalette[13] = 203;
fontpalette[14] = 204;
fontpalette[15] = 205;
}
char *tempstr = NULL;
if (text){
/*
** remove any 0xff characters from the string
*/
tempstr = new char [strlen (text)+1];
char *tempptr = tempstr;
for ( int i=0 ; i<(int)strlen(text)+1 ; i++ ) {
if (text[i] != -1){
*tempptr = text[i];
tempptr++;
}
}
}
/*
** A gradient font always requires special fixups for the palette.
*/
if ((flag & 0xf) == TPF_6PT_GRAD ||
(flag & 0xf) == TPF_GREEN12_GRAD ||
(flag & 0xf) == TPF_GREEN12) {
/*
** If a gradient palette was requested, then fill in the font palette array
** according to the color index specified.
*/
if (flag & TPF_USE_GRAD_PAL) {
memcpy(&fontpalette[0], _textfontpal[ (fore & 0x0f) ], 16);
} else {
/*
** Special adjustment for fonts that have gradient artwork. When there is
** no special gradient effect desired, then set the font color based on the
** forground color specified.
*/
memset(&fontpalette[4], fore, 12);
}
if (flag & TPF_MEDIUM_COLOR) {
fore = _textpalmedium[fore & 0x0F];
memset(&fontpalette[4], fore, 12);
}else{
if (flag & TPF_BRIGHT_COLOR) {
fore = _textpalbright[fore & 0x0F];
memset(&fontpalette[4], fore, 12);
}else{
fore = fontpalette[1];
}
}
}
/*
** Change the current font if it differs from the font desired.
*/
point = (flag & (TextPrintType)0x000F);
xspace = 1;
yspace = 0;
switch (point) {
case TPF_GREEN12:
font = Green12FontPtr;
break;
case TPF_GREEN12_GRAD:
font = Green12GradFontPtr;
break;
case TPF_MAP:
font = MapFontPtr;
xspace -= 1;
break;
case TPF_VCR:
font = VCRFontPtr;
break;
case TPF_6PT_GRAD:
font = GradFont6Ptr;
xspace -= 1;
//yspace -= 1;
break;
case TPF_3POINT:
xspace += 1;
font = Font3Ptr;
flag = flag & ~(TPF_DROPSHADOW|TPF_FULLSHADOW|TPF_NOSHADOW);
break;
case TPF_6POINT:
font = Font6Ptr;
xspace -= 1;
//yspace -= 1;
break;
case TPF_8POINT:
font = Font8Ptr;
xspace -= 2;
yspace -= 4;
break;
case TPF_LED:
xspace -= 4;
font = FontLEDPtr;
break;
default:
font = FontPtr;
break;
}
/*
** Change the current font palette according to the dropshadow flags.
*/
shadow = (flag & (TPF_NOSHADOW|TPF_DROPSHADOW|TPF_FULLSHADOW|TPF_LIGHTSHADOW));
switch (shadow) {
/*
** The text is rendered plain.
*/
case TPF_NOSHADOW:
fontpalette[2] = back;
fontpalette[3] = back;
xspace -= 1;
yspace -= 2;
break;
/*
** The text is rendered with a simple
** drop shadow.
*/
case TPF_DROPSHADOW:
fontpalette[2] = BLACK;
fontpalette[3] = back;
xspace -= 1;
break;
/*
** Special engraved text look for the options
** dialog system.
*/
case TPF_LIGHTSHADOW:
fontpalette[2] = ((14 * 16) + 7)+1;
fontpalette[3] = back;
xspace -= 1;
break;
/*
** Each letter is surrounded by black. This is used
** when the text will be over a non-plain background.
*/
case TPF_FULLSHADOW:
fontpalette[2] = BLACK;
fontpalette[3] = BLACK;
xspace -= 1;
break;
default:
break;
}
fontpalette[0] = back;
fontpalette[1] = fore;
/*
** Set the font and spacing according to the values they should be.
*/
FontXSpacing = xspace;
FontYSpacing = yspace;
Set_Font(font);
Set_Font_Palette(fontpalette);
/*
** Display the (centered) message if there is one.
*/
if (text && *text) {
switch (flag & (TPF_CENTER|TPF_RIGHT)) {
case TPF_CENTER:
x -= String_Pixel_Width(tempstr)>>1;
break;
case TPF_RIGHT:
x -= String_Pixel_Width(tempstr);
break;
default:
break;
}
if (x < (unsigned)SeenBuff.Get_Width() && y < (unsigned)SeenBuff.Get_Height()) {
LogicPage->Print(tempstr, x, y, fore, back);
}
}
if (tempstr){
delete [] tempstr;
}
}
/***********************************************************************************************
* Fancy_Text_Print -- Prints text with a drop shadow. *
* *
* This routine functions like Text_Print, but will render a drop *
* shadow (in black). *
* *
* INPUT: text -- Text number to print. *
* *
* x,y -- Pixel coordinate for to print text. *
* *
* fore -- Foreground color. *
* *
* back -- Background color. *
* *
* flag -- Text print control flags. *
* *
* OUTPUT: none *
* *
* WARNINGS: This routine is much slower than normal text print and *
* if rendered to the SEENPAGE, the intermediate rendering *
* steps could be visible. *
* *
* HISTORY: *
* 11/29/1994 JLB : Created *
*=============================================================================================*/
void Fancy_Text_Print(int text, unsigned x, unsigned y, unsigned fore, unsigned back, TextPrintType flag, ...)
{
char buffer[512]; // Working staging buffer.
va_list arg; // Argument list var.
/*
** If the text number is valid, then process it.
*/
if (text != TXT_NONE) {
va_start(arg, flag);
/*
** The text string must be locked since the vsprintf function doesn't know
** how to handle EMS pointers.
*/
char const * tptr = Text_String(text);
vsprintf(buffer, tptr, arg);
va_end(arg);
Simple_Text_Print(buffer, x, y, fore, back, flag);
} else {
/*
** Just the flags are to be changed, since the text number is TXT_NONE.
*/
Simple_Text_Print((char const *)0, x, y, fore, back, flag);
}
}
/***********************************************************************************************
* Fancy_Text_Print -- Prints text with a drop shadow. *
* *
* This routine functions like Text_Print, but will render a drop *
* shadow (in black). *
* *
* INPUT: text -- Pointer to text to render. *
* *
* x,y -- Pixel coordinate for to print text. *
* *
* fore -- Foreground color. *
* *
* back -- Background color. *
* *
* flag -- Text print control flags. *
* *
* OUTPUT: none *
* *
* WARNINGS: This routine is much slower than normal text print and *
* if rendered to the SEENPAGE, the intermediate rendering *
* steps could be visible. *
* *
* HISTORY: *
* 12/24/1991 JLB : Created. *
* 10/26/94 JLB : Handles font X spacing in a more friendly manner. *
* 11/29/1994 JLB : Separated actual draw action. *
*=============================================================================================*/
void Fancy_Text_Print(char const *text, unsigned x, unsigned y, unsigned fore, unsigned back, TextPrintType flag, ...)
{
char buffer[512]; // Working staging buffer.
va_list arg; // Argument list var.
/*
** If there is a valid text string pointer then build the final string into the
** working buffer before sending it to the simple string printing routine.
*/
if (text) {
/*
** Since vsprintf doesn't know about EMS pointers, be sure to surround this
** call with locking code.
*/
va_start(arg, flag);
vsprintf(buffer, text, arg);
va_end(arg);
Simple_Text_Print(buffer, x, y, fore, back, flag);
} else {
/*
** Just the flags are desired to be changed, so call the simple print routine with
** a NULL text pointer.
*/
Simple_Text_Print((char const *)0, x, y, fore, back, flag);
}
}
/***********************************************************************************************
* Clip_Text_Print -- Prints text with clipping and <TAB> support. *
* *
* Use this routine to print text that that should be clipped at an arbitrary right margin *
* as well as possibly recognizing <TAB> characters. Typical users of this routine would *
* be list boxes. *
* *
* INPUT: text -- Reference to the text to print. *
* *
* x,y -- Pixel coordinate of the upper left corner of the text position. *
* *
* fore -- The foreground color to use. *
* *
* back -- The background color to use. *
* *
* flag -- The text print flags to use. *
* *
* width -- The maximum pixel width to draw the text. Extra characters beyond this *
* point will not be printed. *
* *
* tabs -- Optional pointer to a series of pixel tabstop positions. *
* *
* OUTPUT: none *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 01/21/1995 JLB : Created. *
*=============================================================================================*/
void Conquer_Clip_Text_Print(char const *text, unsigned x, unsigned y, unsigned fore, unsigned back, TextPrintType flag, unsigned width, int const * tabs)
{
char buffer[512];
if (text) {
strcpy(buffer, text);
/*
** Set the font and spacing characteristics according to the flag
** value passed in.
*/
Simple_Text_Print(TXT_NONE, 0, 0, TBLACK, TBLACK, flag);
char * source = &buffer[0];
unsigned offset = 0;
int processing = true;
while (processing && offset < width) {
char * ptr = strchr(source, '\t');
/*
** Zap the tab character. It will be processed later.
*/
if (ptr) {
*ptr = '\0';
}
if (*source) {
/*
** Scan forward until the end of the string is reached or the
** maximum width, whichever comes first.
*/
int w = 0;
char * bptr = source;
do {
w += Char_Pixel_Width(*bptr++);
} while(*bptr && offset+w < width);
/*
** If the maximum width has been exceeded, then remove the last
** character and signal that further processing is not necessary.
*/
if (offset+w >= width) {
bptr--;
w -= Char_Pixel_Width(*bptr);
*bptr = '\0';
processing = 0;
}
/*
** Print this text block and advance the offset accordingly.
*/
Simple_Text_Print(source, x+offset, y, fore, back, flag);
offset += w;
}
/*
** If a <TAB> was the terminator for this text block, then advance
** to the next tabstop.
*/
if (ptr) {
if (tabs) {
while (offset > (unsigned) *tabs) {
tabs++;
}
offset = (unsigned) *tabs;
} else {
offset = ((offset+1 / 50) + 1) * 50;
}
source = ptr+1;
} else {
break;
}
}
}
}

4407
TIBERIANDAWN/DISPLAY.CPP Normal file

File diff suppressed because it is too large Load Diff

341
TIBERIANDAWN/DISPLAY.H Normal file
View File

@@ -0,0 +1,341 @@
//
// 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&c\vcs\code\display.h_v 2.15 16 Oct 1995 16:47:42 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 : DISPLAY.H *
* *
* Programmer : Joe L. Bostic *
* *
* Start Date : May 1, 1994 *
* *
* Last Update : May 1, 1994 [JLB] *
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef DISPLAY_H
#define DISPLAY_H
#include "map.h"
#include "layer.h"
#define ICON_PIXEL_W 24
#define ICON_PIXEL_H 24
#define ICON_LEPTON_W 256
#define ICON_LEPTON_H 256
#define CELL_PIXEL_W ICON_PIXEL_W
#define CELL_PIXEL_H ICON_PIXEL_H
#define CELL_LEPTON_W ICON_LEPTON_W
#define CELL_LEPTON_H ICON_LEPTON_H
// -----------------------------------------------------------
#define PIXEL_LEPTON_W (ICON_LEPTON_W/ICON_PIXEL_W)
#define PIXEL_LEPTON_H (ICON_LEPTON_H/ICON_PIXEL_H)
extern COORDINATE Coord_Add(COORDINATE coord1, COORDINATE coord2);
class DisplayClass: public MapClass
{
// Need access to shadow shapes
friend class DLLExportClass;
public:
/*
** This indicates the theater that the display is to represent.
*/
TheaterType Theater;
/*
** The tactical map display position is indicated by the cell of the
** upper left hand corner. These should not be altered directly. Use
** the Set_Tactical_Position function instead.
*/
COORDINATE TacticalCoord;
/*
** The dimensions (in cells) of the visible window onto the game map. This tactical
** map is how the player interacts and views the game world.
*/
int TacLeptonWidth;
int TacLeptonHeight;
/*
** These layer control elements are used to group the displayable objects
** so that proper overlap can be obtained.
*/
static LayerClass Layer[LAYER_COUNT];
/*
** This records the position and shape of a placement cursor to display
** over the map. This cursor is used when placing buildings and also used
** extensively by the scenario editor.
*/
CELL ZoneCell;
short ZoneOffset;
short const *CursorSize;
short CursorShapeSave[256]; // For save/load
bool ProximityCheck; // Is proximity check ok?
/*
** This holds the building type that is about to be placed upon the map.
** It is only valid during the building placement state. The PendingLegal
** flag is updated as the cursor moves and it reflects the legality of
** placing the building at the desired location.
*/
ObjectClass * PendingObjectPtr;
ObjectTypeClass const * PendingObject;
HousesType PendingHouse;
static unsigned char FadingBrighten[256];
static unsigned char FadingShade[256];
static unsigned char FadingLight[256];
static unsigned char RemapTables[HOUSE_COUNT][3][256];
static unsigned char FadingGreen[256];
static unsigned char FadingYellow[256];
static unsigned char FadingRed[256];
static unsigned char TranslucentTable[(MAGIC_COL_COUNT+1)*256];
static unsigned char WhiteTranslucentTable[(1+1)*256];
static unsigned char MouseTranslucentTable[(4+1)*256];
static void const *TransIconset;
static unsigned char UnitShadow[(USHADOW_COL_COUNT+1)*256];
static unsigned char SpecialGhost[2*256];
//-------------------------------------------------------------------------
DisplayClass(void);
virtual void Read_INI(char *buffer);
void Write_INI(char *buffer);
/*
** Initialization
*/
virtual void One_Time(void); // One-time inits
virtual void Init_Clear(void); // Clears all to known state
virtual void Init_IO(void); // Inits button list
virtual void Init_Theater(TheaterType theater); // Theater-specific inits
/*
** General display/map/interface support functionality.
*/
virtual void AI(KeyNumType &input, int x, int y);
virtual void Draw_It(bool complete=false);
/*
** Added functionality.
*/
COORDINATE Center_Map(void);
virtual bool Map_Cell(CELL cell, HouseClass *house, bool and_for_allies);
virtual CELL Click_Cell_Calc(int x, int y);
virtual void Help_Text(int , int =-1, int =-1, int =YELLOW, bool =false, int =0) {};
virtual MouseType Get_Mouse_Shape(void) const = 0;
virtual bool Scroll_Map(DirType facing, int & distance, bool really);
virtual void Refresh_Cells(CELL cell, short const *list);
virtual void Set_View_Dimensions(int x, int y, int width=-1, int height=-1);
/*
** Pending object placement control.
*/
virtual void Put_Place_Back(TechnoClass * ) {}; // Affects 'pending' system.
void Cursor_Mark(CELL pos, bool on);
void Set_Cursor_Shape(short const * list);
CELL Set_Cursor_Pos(CELL pos = -1);
void Get_Occupy_Dimensions(int & w, int & h, short const *list);
/*
** Tactical map only functionality.
*/
virtual void Set_Tactical_Position(COORDINATE coord);
void Refresh_Band(void);
void Select_These(COORDINATE coord1, COORDINATE coord2, bool additive = false);
COORDINATE Pixel_To_Coord(int x, int y);
bool Coord_To_Pixel(COORDINATE coord, int &x, int &y);
bool Push_Onto_TacMap(COORDINATE &source, COORDINATE &dest);
void Remove(ObjectClass const *object, LayerType layer);
void Submit(ObjectClass const *object, LayerType layer);
CELL Calculated_Cell(SourceType dir, HousesType house);
bool In_View(register CELL cell);
bool Passes_Proximity_Check(ObjectTypeClass const *object);
#ifdef USE_RA_AI
bool Passes_Proximity_Check(ObjectTypeClass const * object, HousesType house, short const * list, CELL trycell) const;
#endif
ObjectClass * Cell_Object(CELL cell, int x=0, int y=0);
ObjectClass * Next_Object(ObjectClass * object);
ObjectClass * Prev_Object(ObjectClass * object);
int Cell_Shadow(CELL cell, HouseClass *house);
short const * Text_Overlap_List(char const * text, int x, int y, int lines = 1);
bool Is_Spot_Free(COORDINATE coord) const;
COORDINATE Closest_Free_Spot(COORDINATE coord, bool any=false) const;
void Sell_Mode_Control(int control);
void Repair_Mode_Control(int control);
void Flag_Cell(CELL cell) {
Flag_To_Redraw(false);
IsToRedraw = true;
CellRedraw[cell] = true;
};
bool Is_Cell_Flagged(CELL cell) const {return CellRedraw.Is_True(cell);};
/*
** Computes starting position based on player's units' Coords.
*/
void Compute_Start_Pos(long& x, long& y);
/*
** File I/O.
*/
virtual void Code_Pointers(void);
virtual void Decode_Pointers(void);
protected:
virtual void Mouse_Right_Press(void);
virtual void Mouse_Left_Press(int x, int y);
virtual void Mouse_Left_Up(bool shadow, ObjectClass * object, ActionType action, bool wwsmall = false);
virtual void Mouse_Left_Held(int x, int y);
virtual void Mouse_Left_Release(CELL cell, int x, int y, ObjectClass * object, ActionType action, bool wwsmall = false);
public:
/*
** This is the pixel offset for the upper left corner of the tactical map.
*/
int TacPixelX;
int TacPixelY;
/*
** This is the coordinate that the tactical map should be in at next available opportunity.
*/
COORDINATE DesiredTacticalCoord;
/*
** If something in the tactical map is to be redrawn, this flag is set to true.
*/
unsigned IsToRedraw:1;
/*
** If the player is currently wielding a wrench (to select buildings for repair),
** then this flag is true. In such a state, normal movement and combat orders
** are preempted.
*/
unsigned IsRepairMode:1;
/*
** If the player is currently in "sell back" mode, then this flag will be
** true. While in this mode, anything clicked on will be sold back to the
** "factory".
*/
unsigned IsSellMode:1;
/*
** If the player is currently in ion cannon targetting mode, then this
** flag will be true. While in this mode, anything clicked on will be
** be destroyed by the ION cannon.
*/
unsigned IsTargettingMode:2;
protected:
/*
** If it is currently in rubber band mode (multi unit selection), then this
** flag will be true. While in such a mode, normal input is prempted while
** the extended selection is in progress.
*/
unsigned IsRubberBand:1;
/*
** The moment the mouse is held down, this flag gets set. If the mouse is dragged
** a sufficient distance while held down, then true rubber band mode selection
** can begin. Using a minimum distance prevents accidental rubber band selection
** mode from being initiated.
*/
unsigned IsTentative:1;
/*
** This gadget class is used for capturing input to the tactical map. All mouse input
** will be routed through this gadget.
*/
class TacticalClass : public GadgetClass {
public:
TacticalClass(void) : GadgetClass(0,0,0,0,LEFTPRESS|LEFTRELEASE|LEFTHELD|LEFTUP|RIGHTPRESS,true) {};
int Selection_At_Mouse(unsigned flags, KeyNumType & key);
int Command_Object(unsigned flags, KeyNumType & key);
protected:
virtual int Action(unsigned flags, KeyNumType & key);
};
friend class TacticalClass;
/*
** This is the "button" that tracks all input to the tactical map.
** It must be available to derived classes, for Save/Load purposes.
*/
public: //ST - 1/21/2019 11:59AM
static TacticalClass TacButton;
private:
/*
** This is a utility flag that is set during the icon draw process only if there
** was at least one shadow icon detected that should be redrawn. When the shadow
** drawing logic is to take place, but this flag is false, then the shadow drawing
** will be skipped since it would perform no function.
*/
unsigned IsShadowPresent:1;
/*
** Rubber band mode consists of stretching a box from the anchor point (specified
** here) to the current cursor position.
*/
int BandX,BandY;
int NewX,NewY;
static void const *ShadowShapes;
static unsigned char ShadowTrans[(SHADOW_COL_COUNT+1)*256];
void Redraw_Icons(int draw_flags=0);
void Redraw_Shadow(void);
void Redraw_Shadow_Rects(void);
/*
** This bit array is used to flag cells to be redrawn. If the icon needs to
** be redrawn for a cell, then the corresponding flag will be true.
*/
static BooleanVectorClass CellRedraw;
//
// We need a way to bypass visible view checks when we are running in the context of GlyphX without using the
// internal C&C renderer. We shouldn't know or care what the user is actually looking at
// ST - 4/17/2019 9:01AM
//
static bool IgnoreViewConstraints;
/*
** Some additional padding in case we need to add data to the class and maintain backwards compatibility for save/load
*/
unsigned char SaveLoadPadding[1024];
};
#endif

File diff suppressed because it is too large Load Diff

927
TIBERIANDAWN/DLLInterface.h Normal file
View File

@@ -0,0 +1,927 @@
//
// 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
#pragma once
#ifndef DLL_INTERFACE_H
#define DLL_INTERFACE_H
struct CarryoverObjectStruct;
/*
** DLL Interface version
**
**
**
*/
#define CNC_DLL_API_VERSION 0x100
#define MAX_EXPORT_CELLS (128 * 128)
#ifdef TIBERIAN_DAWN
#define MAP_MAX_CELL_WIDTH 64
#define MAP_MAX_CELL_HEIGHT 64
#else
#define MAP_MAX_CELL_WIDTH 128
#define MAP_MAX_CELL_HEIGHT 128
#endif
/*
** Interface structs require stricter packing
**
**
*/
#pragma pack(push)
#pragma pack(1)
/**************************************************************************************
**
** Game state request types
**
**
*/
enum GameStateRequestEnum {
GAME_STATE_NONE,
GAME_STATE_STATIC_MAP,
GAME_STATE_DYNAMIC_MAP,
GAME_STATE_LAYERS,
GAME_STATE_SIDEBAR,
GAME_STATE_PLACEMENT,
GAME_STATE_SHROUD,
GAME_STATE_OCCUPIER,
GAME_STATE_PLAYER_INFO
};
/**************************************************************************************
**
** Static map data (tiles)
**
**
*/
struct CNCStaticCellStruct {
char TemplateTypeName[32];
int IconNumber;
};
enum CnCTheaterType {
CNC_THEATER_NONE=-1,
CNC_THEATER_DESERT,
CNC_THEATER_JUNGLE,
CNC_THEATER_TEMPERATE,
CNC_THEATER_WINTER,
CNC_THEATER_COUNT,
CNC_THEATER_FIRST=0
};
struct CNCMapDataStruct {
int MapCellX;
int MapCellY;
int MapCellWidth;
int MapCellHeight;
int OriginalMapCellX;
int OriginalMapCellY;
int OriginalMapCellWidth;
int OriginalMapCellHeight;
CnCTheaterType Theater;
char ScenarioName[_MAX_FNAME+_MAX_EXT];
CNCStaticCellStruct StaticCells[MAX_EXPORT_CELLS];
};
/**************************************************************************************
**
** Object type enum
**
**
*/
#define DLL_LAYER_COUNT 3
enum DllObjectTypeEnum {
UNKNOWN,
INFANTRY,
UNIT,
AIRCRAFT,
BUILDING,
TERRAIN,
ANIM,
BULLET,
OVERLAY,
SMUDGE,
OBJECT,
SPECIAL,
INFANTRY_TYPE,
UNIT_TYPE,
AIRCRAFT_TYPE,
BUILDING_TYPE,
VESSEL,
VESSEL_TYPE
};
/**************************************************************************************
**
** Object action types
**
**
*/
enum DllActionTypeEnum : unsigned char {
DAT_NONE,
DAT_MOVE,
DAT_NOMOVE,
DAT_ENTER,
DAT_SELF,
DAT_ATTACK,
DAT_ATTACK_OUT_OF_RANGE,
DAT_GUARD,
DAT_SELECT,
DAT_CAPTURE,
DAT_SABOTAGE,
DAT_HEAL,
DAT_DAMAGE,
DAT_TOGGLE_PRIMARY,
DAT_CANT_DEPLOY,
DAT_REPAIR,
DAT_CANT_REPAIR
};
/**************************************************************************************
**
** Object state data
**
**
*/
#define MAX_OCCUPY_CELLS 36
#define MAX_OBJECT_PIPS 18
#define MAX_OBJECT_LINES 3
#define MAX_HOUSES 32
struct CNCObjectLineStruct {
int X;
int Y;
int X1;
int Y1;
int Frame;
unsigned char Color;
};
#define CNC_OBJECT_ASSET_NAME_LENGTH 16
struct CNCObjectStruct {
void *CNCInternalObjectPointer;
char TypeName[CNC_OBJECT_ASSET_NAME_LENGTH];
char AssetName[CNC_OBJECT_ASSET_NAME_LENGTH]; // CNC uses 8.3 filenames, so it shouldn't need to be bigger than 9
DllObjectTypeEnum Type;
int ID;
int BaseObjectID;
DllObjectTypeEnum BaseObjectType;
int PositionX;
int PositionY;
int Width;
int Height;
int Altitude;
int SortOrder;
int Scale;
int DrawFlags;
short MaxStrength;
short Strength;
unsigned short ShapeIndex;
unsigned short CellX;
unsigned short CellY;
unsigned short CenterCoordX;
unsigned short CenterCoordY;
short SimLeptonX;
short SimLeptonY;
unsigned char DimensionX;
unsigned char DimensionY;
unsigned char Rotation;
unsigned char MaxSpeed;
char Owner;
char RemapColor;
char SubObject;
bool IsSelectable;
unsigned int IsSelectedMask;
bool IsRepairing;
bool IsDumping;
bool IsTheaterSpecific;
unsigned int FlashingFlags;
unsigned char Cloak;
bool CanRepair;
bool CanDemolish;
bool CanDemolishUnit;
short OccupyList[MAX_OCCUPY_CELLS];
int OccupyListLength;
int Pips[MAX_OBJECT_PIPS];
int NumPips;
int MaxPips;
CNCObjectLineStruct Lines[MAX_OBJECT_LINES];
int NumLines;
bool RecentlyCreated;
bool IsALoaner;
bool IsFactory;
bool IsPrimaryFactory;
bool IsDeployable;
bool IsAntiGround;
bool IsAntiAircraft;
bool IsSubSurface;
bool IsNominal;
bool IsDog;
bool IsIronCurtain;
bool IsInFormation;
bool CanMove[MAX_HOUSES];
bool CanFire[MAX_HOUSES];
bool CanDeploy;
bool CanHarvest;
bool CanPlaceBombs;
bool IsFixedWingedAircraft;
bool IsFake;
unsigned char ControlGroup;
unsigned int VisibleFlags;
unsigned int SpiedByFlags;
char ProductionAssetName[CNC_OBJECT_ASSET_NAME_LENGTH];
const char* OverrideDisplayName;
DllActionTypeEnum ActionWithSelected[MAX_HOUSES];
static const unsigned int VISIBLE_FLAGS_ALL = 0xffffffff;
};
struct CNCObjectListStruct {
int Count;
CNCObjectStruct Objects[1]; // Variable length
};
/**************************************************************************************
**
** Placement validity data
**
** Used to pass back info about tructure placement validity
*/
struct CNCPlacementCellInfoStruct {
bool PassesProximityCheck; // If the structure was placed in this cell, does that satisfy the proximity check for the whole structure?
bool GenerallyClear; // Is this cell generally clear of obstructions that would prevent placement?
};
struct CNCPlacementInfoStruct {
int Count;
CNCPlacementCellInfoStruct CellInfo[1]; // Variable length
};
/**************************************************************************************
**
** Sidebar/construction state data
**
**
*/
enum DllSuperweaponTypeEnum {
SW_NONE,
SW_UNKNOWN,
//TD values
SW_NUKE,
SW_AIR_STRIKE,
SW_ION_CANNON,
//RA values
SW_SONAR_PULSE,
SW_CHRONOSPHERE,
SW_PARA_BOMB,
SW_PARA_INFANTRY,
SW_SPY_MISSION,
SW_IRON_CURTAIN,
SW_GPS,
SW_CHRONOSPHERE_DESTINATION
};
struct CNCSidebarEntryStruct {
char AssetName[16]; // CNC uses 8.3 filenames, so it shouldn't need to be bigger than 9
int BuildableType; // This is the original buildable type that should be passed back if we want to start/cancel construction
int BuildableID; // This is the original buildable id that should be passed back if we want to start/cancel construction
DllObjectTypeEnum Type; // Type converted to shared enum
DllSuperweaponTypeEnum SuperWeaponType;
int Cost; // Cost to construct
int PowerProvided; // Power cost to construct
int BuildTime; // Cost to construct
float Progress; // Construction progress (0.0 - 1.0)
short PlacementList[MAX_OCCUPY_CELLS]; // Which cells this structure occupies for placement (if structure)
int PlacementListLength; // How many cells
bool Completed; // Construction has completed
bool Constructing; // Is it currently constructing
bool ConstructionOnHold; // Is the current construction on hold
bool Busy; // Is the associated factory busy
bool BuildableViaCapture; // Is this buildable due to the capture of a structure of a different faction. This will be false for captured structures of the same faction (ActLike)
bool Fake; // Is this a fake structure?
};
struct CNCSidebarStruct {
int EntryCount[2]; // Counts for the left and right columns
int Credits; // Amount of currency available (excluding Tiberium)
int CreditsCounter; // Visible credits to display in the sidebar (includes count up/down logic)
int Tiberium; // Amount of Tiberium in reserve
int MaxTiberium; // Maximum amount of Tiberium storage available
int PowerProduced;
int PowerDrained;
int MissionTimer;
unsigned int UnitsKilled; // Total count of enemy units killed by this player; Includes Infantry, Vehicles, Aircraft
unsigned int BuildingsKilled; // Total count of enemy structures killed by this player
unsigned int UnitsLost; // Total count player-owned units killed/lost
unsigned int BuildingsLost; // Total count player-owned structures killed/lost
unsigned int TotalHarvestedCredits; // Complete total of gained credits over the match (does not include starting credits)
bool RepairBtnEnabled;
bool SellBtnEnabled;
bool RadarMapActive;
CNCSidebarEntryStruct Entries[1]; // Variable length column entries
};
enum SidebarRequestEnum {
SIDEBAR_REQUEST_START_CONSTRUCTION,
SIDEBAR_REQUEST_HOLD_CONSTRUCTION,
SIDEBAR_REQUEST_CANCEL_CONSTRUCTION,
SIDEBAR_REQUEST_START_PLACEMENT,
SIDEBAR_REQUEST_PLACE,
SIDEBAR_CANCEL_PLACE,
SIDEBAR_CLICK_REPAIR,
SIDEBAR_REQUEST_ENABLE_QUEUE,
SIDEBAR_REQUEST_DISABLE_QUEUE,
SIDEBAR_REQUEST_START_CONSTRUCTION_MULTI,
SIDEBAR_REQUEST_CANCEL_CONSTRUCTION_MULTI
};
enum SuperWeaponRequestEnum {
SUPERWEAPON_REQUEST_PLACE_SUPER_WEAPON
};
enum ControlGroupRequestEnum {
CONTROL_GROUP_REQUEST_CREATE,
CONTROL_GROUP_REQUEST_TOGGLE,
CONTROL_GROUP_REQUEST_ADDITIVE_SELECTION,
};
/**************************************************************************************
**
** Input events sent into the DLL
**
**
*/
enum InputRequestEnum {
INPUT_REQUEST_NONE,
INPUT_REQUEST_MOUSE_MOVE,
INPUT_REQUEST_MOUSE_LEFT_CLICK,
INPUT_REQUEST_MOUSE_RIGHT_DOWN,
INPUT_REQUEST_MOUSE_RIGHT_CLICK,
INPUT_REQUEST_MOUSE_AREA,
INPUT_REQUEST_MOUSE_AREA_ADDITIVE,
INPUT_REQUEST_SELL_AT_POSITION,
INPUT_REQUEST_SELECT_AT_POSITION,
INPUT_REQUEST_COMMAND_AT_POSITION,
INPUT_REQUEST_SPECIAL_KEYS
};
/**************************************************************************************
**
** Structure Requests Repair, Sell
**
**
*/
enum StructureRequestEnum {
INPUT_STRUCTURE_NONE,
INPUT_STRUCTURE_REPAIR_START,
INPUT_STRUCTURE_REPAIR,
INPUT_STRUCTURE_SELL_START,
INPUT_STRUCTURE_SELL,
INPUT_STRUCTURE_CANCEL,
};
/**************************************************************************************
**
** Unit Requests Scatter, Select Next, Select Previous, Guard Mode, Stop
**
**
*/
enum UnitRequestEnum {
INPUT_UNIT_NONE,
INPUT_UNIT_SCATTER,
INPUT_UNIT_SELECT_NEXT,
INPUT_UNIT_SELECT_PREVIOUS,
INPUT_UNIT_GUARD_MODE,
INPUT_UNIT_STOP,
INPUT_UNIT_FORMATION_TOGGLE, // RA Only
INPUT_UNIT_QUEUED_MOVEMENT_ON, // RA Only
INPUT_UNIT_QUEUED_MOVEMENT_OFF, // RA Only
};
/**************************************************************************************
**
** Game Action Requests
**
**
*/
enum GameRequestEnum {
INPUT_GAME_MOVIE_DONE,
INPUT_GAME_LOADING_DONE,
};
/**************************************************************************************
**
** Special Keys
**
**
*/
enum SpecialKeyRequestEnum {
INPUT_SPECIAL_KEY_CTRL = 0b00000001,
INPUT_SPECIAL_KEY_ALT = 0b00000010,
INPUT_SPECIAL_KEY_SHIFT = 0b00000100,
};
/**************************************************************************************
**
** Non-static map data.
**
** Per-cell smudges and overlays. Smudges are used for things like craters and structure bibs that draw under units.
** Overlays are things like walls and tiberium that can't move from the cell but aren't flat like smudges.
**
**
*/
struct CNCDynamicMapEntryStruct {
char AssetName[16];
int PositionX;
int PositionY;
int Width;
int Height;
short Type;
char Owner;
int DrawFlags;
unsigned char CellX;
unsigned char CellY;
unsigned char ShapeIndex;
bool IsSmudge;
bool IsOverlay;
bool IsResource;
bool IsSellable;
bool IsTheaterShape;
bool IsFlag;
};
struct CNCDynamicMapStruct {
bool VortexActive;
int VortexX;
int VortexY;
int VortexWidth;
int VortexHeight;
int Count;
CNCDynamicMapEntryStruct Entries[1]; // Variable length
};
/**************************************************************************************
**
** Event data
**
** Used to call back into the GlyphX engine for one-time events like sound effect triggers
**
**
*/
enum EventCallbackType {
CALLBACK_EVENT_INVALID = -1,
CALLBACK_EVENT_SOUND_EFFECT = 0,
CALLBACK_EVENT_SPEECH,
CALLBACK_EVENT_GAME_OVER,
CALLBACK_EVENT_DEBUG_PRINT,
CALLBACK_EVENT_MOVIE,
CALLBACK_EVENT_MESSAGE,
CALLBACK_EVENT_UPDATE_MAP_CELL,
CALLBACK_EVENT_ACHIEVEMENT,
CALLBACK_EVENT_STORE_CARRYOVER_OBJECTS,
CALLBACK_EVENT_SPECIAL_WEAPON_TARGETTING,
CALLBACK_EVENT_BRIEFING_SCREEN,
CALLBACK_EVENT_CENTER_CAMERA,
CALLBACK_EVENT_PING
};
struct GameOverMultiPlayerStatsStruct
{
GameOverMultiPlayerStatsStruct()
:
GlyphXPlayerID( 0 ),
IsHuman( false ),
WasHuman( false ),
IsWinner( false ),
ResourcesGathered( 0 ),
TotalUnitsKilled( 0 ),
TotalStructuresKilled( 0 ),
Efficiency( 0 ),
Score( 0 )
{
}
__int64 GlyphXPlayerID;
bool IsHuman;
bool WasHuman;
bool IsWinner;
int ResourcesGathered;
int TotalUnitsKilled;
int TotalStructuresKilled;
int Efficiency; // AKA Economy
int Score;
};
#define GAME_OVER_MULTIPLAYER_MAX_PLAYERS_TRACKED 8
enum EventCallbackMessageEnum {
MESSAGE_TYPE_DIRECT = 0,
MESSAGE_TYPE_PLAYER_DEFEATED,
MESSAGE_TYPE_COMPUTER_TAUNT,
MESSAGE_TYPE_PLAYER_DISCONNECTED
};
struct EventCallbackStruct {
EventCallbackStruct::EventCallbackStruct(void) : EventType(CALLBACK_EVENT_INVALID), GlyphXPlayerID(0) { }
EventCallbackType EventType;
__int64 GlyphXPlayerID;
union {
struct SoundEffectEvent {
int SFXIndex;
int Variation;
int PixelX;
int PixelY;
int PlayerID; //TO_FIX
char SoundEffectName[ 16 ];
int SoundEffectPriority;
int SoundEffectContext;
} SoundEffect;
struct SpeechEvent {
int SpeechIndex;
int PlayerID; //TO_FIX
char SpeechName[ 16 ];
} Speech;
struct GameOverEvent {
bool Multiplayer;
//
// Single-player data
//
bool PlayerWins;
const char* MovieName;
const char* MovieName2;
const char* MovieName3;
const char* MovieName4;
const char* AfterScoreMovieName;
int Score;
int Leadership;
int Efficiency;
int CategoryTotal;
int NODKilled;
int GDIKilled;
int CiviliansKilled;
int NODBuildingsDestroyed;
int GDIBuildingsDestroyed;
int CiviliansBuildingsDestroyed;
int RemainingCredits;
int SabotagedStructureType;
int TimerRemaining;
//
// Multi-player data
//
int MultiPlayerTotalPlayers;
GameOverMultiPlayerStatsStruct MultiPlayerPlayersData[ GAME_OVER_MULTIPLAYER_MAX_PLAYERS_TRACKED ];
} GameOver;
struct DebugPrintEvent {
const char *PrintString;
} DebugPrint;
struct MovieEvent {
const char* MovieName;
int Theme;
bool Immediate;
} Movie;
struct MessageEvent {
const char* Message;
float TimeoutSeconds;
EventCallbackMessageEnum MessageType;
__int64 MessageParam1;
} Message;
struct UpdateMapCellEvent {
int CellX;
int CellY;
char TemplateTypeName[32];
} UpdateMapCell;
struct AchievementEvent {
const char* AchievementType;
const char* AchievementReason;
} Achievement;
struct StoreCarryoverObjectsEvent {
CarryoverObjectStruct* CarryoverList;
} StoreCarryoverObjects;
struct SpecialWeaponTargettingEvent {
int Type;
int ID;
char Name[16];
DllSuperweaponTypeEnum WeaponType;
} SpecialWeaponTargetting;
struct CenterCameraEvent {
int CoordX;
int CoordY;
} CenterCamera;
struct PingEvent {
int CoordX;
int CoordY;
} Ping;
};
};
/**************************************************************************************
**
** Multiplayer setup data
**
** Used to pass multiplayer setup info into the C&C code from the GlyphX engine
**
**
*/
struct CNCMultiplayerOptionsStruct {
//int MPlayerPrefColor; // preferred color index for this player
//int MPlayerColorIdx; // actual color index of this player
//CnCHousesType MPlayerHouse; // House of this player (GDI/NOD)
//unsigned char MPlayerLocalID; // ID of this player
int MPlayerCount; // # of human players in this game
int MPlayerBases; // 1 = bases are on for this scenario
int MPlayerCredits; // # credits everyone gets
int MPlayerTiberium; // 1 = tiberium enabled for this scenario
int MPlayerGoodies; // 1 = goodies enabled for this scenario
int MPlayerGhosts; // 1 = houses with no players will still play
int MPlayerSolo; // 1 = allows a single-player net game
int MPlayerUnitCount; // # units for non-base multiplayer scenarios
bool IsMCVDeploy; // MCV undeploys instead of selling
bool SpawnVisceroids; // Do visceroids spawn
bool EnableSuperweapons; // Are superweapons available
bool MPlayerShadowRegrow;
bool MPlayerAftermathUnits;
bool CaptureTheFlag;
bool DestroyStructures; // New early win condition via destroying all a player's structures
};
struct CNCSpiedInfoStruct {
int Power;
int Drain;
int Money;
};
struct CNCPlayerInfoStruct {
char Name[64];
unsigned char House;
int ColorIndex;
unsigned __int64 GlyphxPlayerID;
int Team;
int StartLocationIndex;
unsigned char HomeCellX;
unsigned char HomeCellY;
bool IsAI;
unsigned int AllyFlags;
bool IsDefeated;
unsigned int SpiedPowerFlags;
unsigned int SpiedMoneyFlags;
CNCSpiedInfoStruct SpiedInfo[MAX_HOUSES];
int SelectedID;
DllObjectTypeEnum SelectedType;
DllActionTypeEnum ActionWithSelected[MAX_EXPORT_CELLS];
unsigned int ActionWithSelectedCount;
unsigned int ScreenShake;
bool IsRadarJammed;
};
//
enum GameRequestType {
GAME_REQUEST_MOVIE_DONE,
};
/**************************************************************************************
**
** Rules configuration data
**
**
*/
struct CNCDifficultyDataStruct
{
float FirepowerBias;
float GroundspeedBias;
float AirspeedBias;
float ArmorBias;
float ROFBias;
float CostBias;
float BuildSpeedBias;
float RepairDelay;
float BuildDelay;
bool IsBuildSlowdown;
bool IsWallDestroyer;
bool IsContentScan;
};
struct CNCRulesDataStruct
{
CNCDifficultyDataStruct Difficulties[3];
};
/**************************************************************************************
**
** Debug input interface
**
**
*/
enum DebugRequestEnum {
DEBUG_REQUEST_SPAWN_OBJECT,
DEBUG_REQUEST_END_GAME,
DEBUG_REQUEST_UNSHROUD,
DEBUG_REQUEST_SUPERWEAPON_RECHARGE,
DEBUG_REQUEST_KILL_OBJECT,
DEBUG_REQUEST_END_PRODUCTION,
DEBUG_REQUEST_ADD_RESOURCES,
DEBUG_REQUEST_UNLOCK_BUILDABLES,
DEBUG_REQUEST_FORCE_CRASH,
DEBUG_REQUEST_SET_GLOBAL_FLAG,
};
/**************************************************************************************
**
** Shroud data.
**
** Per-cell shroud info
**
**
*/
struct CNCShroudEntryStruct {
char ShadowIndex;
bool IsVisible;
bool IsMapped;
bool IsJamming;
};
struct CNCShroudStruct {
int Count;
CNCShroudEntryStruct Entries[1]; // Variable length
};
/**************************************************************************************
**
** Occupier data.
**
** Per-cell occupier info
**
**
*/
struct CNCOccupierObjectStruct {
DllObjectTypeEnum Type;
int ID;
};
struct CNCOccupierEntryHeaderStruct {
int Count;
};
struct CNCOccupierHeaderStruct {
int Count;
};
/**************************************************************************************
**
** Carryover object.
**
** Used to store object data that persists between missions
**
**
*/
struct CarryoverObjectStruct
{
CarryoverObjectStruct() : Next(0) {}
CarryoverObjectStruct* Next;
int RTTI;
int Type;
int Cell;
int Strength;
int House;
};
/*
** End of strict structure packing
**
**
*/
#pragma pack(pop)
#endif //DLL_INTERFACE_H

View File

@@ -0,0 +1,741 @@
//
// 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 <stdio.h>
//#include <iostream>
//#include <fstream>
#include "function.h"
#include "externs.h"
#include "DLLInterface.h"
#include "Gadget.h"
#include "defines.h" // VOC_COUNT, VOX_COUNT
#include "SidebarGlyphx.h"
#include "TEMPLATE.H"
extern "C" __declspec(dllexport) int __cdecl CNC_Editor_Startup();
extern "C" __declspec(dllexport) int __cdecl CNC_Editor_Cleanup();
extern "C" __declspec(dllexport) int __cdecl CNC_Editor_Load_Map(char* cncdata_directory, char* house_name, int scenario_index, char* east_west, char* variant);
extern "C" __declspec(dllexport) int __cdecl CNC_Editor_Load_Map_By_Scenario_Name(char* cncdata_directory, char* scenario_name);
extern "C" __declspec(dllexport) int __cdecl CNC_Editor_Clear_Map();
extern "C" __declspec(dllexport) int __cdecl CNC_Editor_Get_Map_Stats(int& map_width, int& map_height, int& theater);
extern "C" __declspec(dllexport) int __cdecl CNC_Editor_Get_Cell_Data_By_Index(int cell_index, char* cell_name, unsigned long cell_name_size, int& template_type, int& template_icon_index);
extern "C" __declspec(dllexport) int __cdecl CNC_Editor_Get_Cell_Data(int x, int y, char* cell_name, unsigned long cell_name_size, int& template_type, int& template_icon_index);
extern "C" __declspec(dllexport) int __cdecl CNC_Editor_Get_Cell_Texture_Buffer(int x, int y, int& out_width, int& out_height, SAFEARRAY*& out_texture_array);
extern "C" __declspec(dllexport) int __cdecl CNC_Editor_Get_Scenario_Names(char* cncdata_directory, int CD);
extern "C" __declspec(dllexport) int __cdecl CNC_Editor_Get_Template_Data(int template_type_index, SAFEARRAY*& template_points);
char EditorMapINIBuffer[SHAPE_BUFFER_SIZE];
bool EditorMapInitialized = false;
const static int EDITOR_COMMMAND_SUCCESS = 0;
const static int EDITOR_COMMMAND_FAILURE = 1;
const static char* MixFileNames[] =
{
"GENERAL.MIX",
"SC-000.MIX",
"SC-001.MIX",
"DESERT.MIX",
"TEMPERAT.MIX",
"WINTER.MIX"
};
extern MixFileClass *TheaterIcons;
extern bool Read_Movies_From_Scenario_Ini(char *root, bool fresh);
/**************************************************************************************************
* CNC_Editor_Startup
* Initializes the system to allow map loading for the editor
**************************************************************************************************/
extern "C" __declspec(dllexport) int __cdecl CNC_Editor_Startup()
{
BlackPalette = new(MEM_CLEAR | MEM_REAL) unsigned char[768];
GamePalette = new(MEM_CLEAR | MEM_REAL) unsigned char[768];
OriginalPalette = new(MEM_CLEAR | MEM_REAL) unsigned char[768];
WhitePalette = new(MEM_CLEAR | MEM_REAL) unsigned char[768];
memset(WhitePalette, 63, 768);
Set_Palette(GamePalette);
TheaterData = 0;
TheaterIcons = 0;
LowTheaterData = 0;
return EDITOR_COMMMAND_SUCCESS;
}
/**************************************************************************************************
* CNC_Editor_Cleanup
* Cleans up systems initialized by the editor
**************************************************************************************************/
extern "C" __declspec(dllexport) int __cdecl CNC_Editor_Cleanup()
{
if (BlackPalette)
{
delete[] BlackPalette;
}
if (GamePalette)
{
delete[] GamePalette;
}
if (OriginalPalette)
{
delete[] OriginalPalette;
}
if (WhitePalette)
{
delete[] WhitePalette;
}
return EDITOR_COMMMAND_SUCCESS;
}
/**************************************************************************************************
* CNC_Editor_Load_Mix_Files
* Loads all the Mix files for Tiberian Dawn
**************************************************************************************************/
void CNC_Editor_Load_Mix_Files()
{
int count = sizeof(MixFileNames) / sizeof(MixFileNames[0]);
for (int i = count - 1; i >= 0; --i)
{
MixFileClass::Free(MixFileNames[i]);
}
for (int i = 0; i < count; ++i)
{
new MixFileClass(MixFileNames[i]);
MixFileClass::Cache(MixFileNames[i]);
}
}
/**************************************************************************************************
* CNC_Editor_Setup_Content_Directory
* Sets up where the system should load map data from.
**************************************************************************************************/
void CNC_Editor_Setup_Content_Directory(char* cncdata_directory, char* cd_directory)
{
char content_directory[_MAX_PATH];
sprintf(content_directory, "%s\\TIBERIAN_DAWN\\%s\\", cncdata_directory, cd_directory);
if (strlen(content_directory) != 0) {
CCFileClass::Clear_Search_Drives();
CCFileClass::Reset_Raw_Path();
char *dll_dir = strdup(content_directory);
CCFileClass::Set_Search_Drives(dll_dir);
free(dll_dir);
}
}
void CNC_Editor_Setup_Content_Directory(char* cncdata_directory, int CD_index)
{
char cd_name[_MAX_PATH];
sprintf(cd_name, "CD%i", CD_index);
CNC_Editor_Setup_Content_Directory(cncdata_directory, cd_name);
}
/**************************************************************************************************
* CNC_Editor_Load_Map
* Loads the map with the given parameters.
*
* cncdata_directory: path of the base CNC data directory
* faction: the name of the faction we are loading the map for
* scenario_index: int scenario index
* east_west:
* variant:
*
* returns EDITOR_COMMMAND_SUCCESS on success, all other values are failure
**************************************************************************************************/
extern "C" __declspec(dllexport) int __cdecl CNC_Editor_Load_Map(
char* cncdata_directory,
char* house_name,
int scenario_index,
char* east_west,
char* variant)
{
CNC_Editor_Clear_Map();
int CD = 1;
if (stricmp(house_name, "GDI") == 0) {
ScenPlayer = SCEN_PLAYER_GDI;
GameToPlay = GAME_NORMAL;
if (scenario_index == 30 || scenario_index == 90) {
CD = 5;
}
else if (scenario_index >= 60 && scenario_index <= 72) {
CD = 4;
}
else if (scenario_index >= 20 && scenario_index < 60) {
CD = 3;
}
}
if (stricmp(house_name, "NOD") == 0) {
ScenPlayer = SCEN_PLAYER_NOD;
GameToPlay = GAME_NORMAL;
CD = 2;
// Hack a fix for scenario 21 since the same mission number is used in Covert Ops and N64
if (scenario_index == 81 || scenario_index == 22) {
CD = 5;
if (scenario_index == 81) {
scenario_index = 21;
}
}
else if (scenario_index >= 60 && scenario_index <= 61) {
CD = 4;
}
else if (scenario_index >= 20 && scenario_index < 60) {
CD = 3;
}
}
if (stricmp(house_name, "MULTI") == 0)
{
ScenPlayer = SCEN_PLAYER_MPLAYER;
GameToPlay = GAME_GLYPHX_MULTIPLAYER;
}
if (stricmp(house_name, "JUR") == 0)
{
ScenPlayer = SCEN_PLAYER_JP;
GameToPlay = GAME_NORMAL;
}
switch (CD)
{
case 4:
CNC_Editor_Setup_Content_Directory(cncdata_directory, "CONSOLE_1");
break;
case 5:
CNC_Editor_Setup_Content_Directory(cncdata_directory, "CONSOLE_2");
break;
default:
CNC_Editor_Setup_Content_Directory(cncdata_directory, CD);
break;
}
CNC_Editor_Load_Mix_Files();
Scenario = scenario_index;
BuildLevel = 7;
if (stricmp(east_west, "w") == 0)
{
ScenDir = SCEN_DIR_WEST;
}
else
{
ScenDir = SCEN_DIR_EAST;
}
ScenarioVarType variant_enum;
if (stricmp(variant, "b") == 0)
{
variant_enum = SCEN_VAR_B;
}
else if (stricmp(variant, "c") == 0)
{
variant_enum = SCEN_VAR_C;
}
else if (stricmp(variant, "d") == 0)
{
variant_enum = SCEN_VAR_D;
}
else
{
variant_enum = SCEN_VAR_A;
}
Set_Scenario_Name(ScenarioName, Scenario, ScenPlayer, ScenDir, variant_enum);
char fname[_MAX_FNAME + _MAX_EXT];
sprintf(fname, "%s.INI", ScenarioName);
CCFileClass file(fname);
if (!file.Is_Available())
{
return(EDITOR_COMMMAND_FAILURE);
}
else
{
memset(EditorMapINIBuffer, 0, SHAPE_BUFFER_SIZE);
file.Read(EditorMapINIBuffer, SHAPE_BUFFER_SIZE - 1);
}
Map.One_Time_Editor();
Map.Read_INI(EditorMapINIBuffer);
if (Map.Read_Binary(ScenarioName, &ScenarioCRC))
{
EditorMapInitialized = true;
return EDITOR_COMMMAND_SUCCESS;
}
else
{
return EDITOR_COMMMAND_FAILURE;
}
}
extern "C" __declspec(dllexport) int __cdecl CNC_Editor_Load_Map_By_Scenario_Name(char* cncdata_directory, char* scenario_name)
{
return EDITOR_COMMMAND_FAILURE;
}
/**************************************************************************************************
* CNC_Editor_Clear_Map
* Deletes the data for the currently loaded map.
*
* returns EDITOR_COMMMAND_SUCCESS on success, all other values are failure
**************************************************************************************************/
extern "C" __declspec(dllexport) int __cdecl CNC_Editor_Clear_Map()
{
if (EditorMapInitialized)
{
Map.Init_Clear();
int count = sizeof(MixFileNames) / sizeof(MixFileNames[0]);
for (int i = count - 1; i >= 0; --i)
{
MixFileClass::Free(MixFileNames[i]);
}
EditorMapInitialized = false;
TheaterData = nullptr;
TheaterIcons = nullptr;
return EDITOR_COMMMAND_SUCCESS;
}
else
{
return EDITOR_COMMMAND_FAILURE;
}
}
/**************************************************************************************************
* CNC_Editor_Get_Map_Stats
* Gets the stats for the currently loaded map
*
* map_width: out parameter storing the width of the map
* map_height: out parameter storing the height of the map
* theater: out paramter storing the theater of the map
*
* returns EDITOR_COMMMAND_SUCCESS on success, all other values are failure
**************************************************************************************************/
extern "C" __declspec(dllexport) int __cdecl CNC_Editor_Get_Map_Stats(int& map_width, int& map_height, int& theater)
{
if (EditorMapInitialized)
{
map_width = Map.MapCellWidth + 1;
map_height = Map.MapCellHeight + 1;
theater = Map.Theater;
return EDITOR_COMMMAND_SUCCESS;
}
map_width = -1;
map_height = -1;
theater = -1;
return EDITOR_COMMMAND_FAILURE;
}
/**************************************************************************************************
* CNC_Editor_Get_Cell_Data_By_Index
* Get the data from the given cell.
*
* cell_index: The index of the desired cell.
* cell_name: out buffer to be filled with the name of the given cell.
* cell_name_size: the size of the cell name buffer.
*
*
* returns EDITOR_COMMMAND_SUCCESS on success, all other values are failure
**************************************************************************************************/
extern "C" __declspec(dllexport) int __cdecl CNC_Editor_Get_Cell_Data_By_Index(int cell_index, char* cell_name, unsigned long cell_name_size, int& template_type, int& template_icon_index)
{
CellClass * cellptr = &Map[cell_index];
cell_name[0] = 0;
int icon = 0;
void *image_data = 0;
char template_name[10];
if (cellptr->Get_Template_Info(template_name, icon, image_data))
{
snprintf(cell_name, cell_name_size, "%s-%04d", template_name, icon);
template_type = cellptr->TType;
template_icon_index = icon;
return EDITOR_COMMMAND_SUCCESS;
}
return EDITOR_COMMMAND_FAILURE;
}
/**************************************************************************************************
* CNC_Editor_Get_Cell_Data
* Get the data from the given cell.
*
* x,y: The corrdinates of the desired cell.
* cell_name: out buffer to be filled with the name of the given cell.
* cell_name_size: the size of the cell name buffer.
*
* returns EDITOR_COMMMAND_SUCCESS on success, all other values are failure
**************************************************************************************************/
extern "C" __declspec(dllexport) int __cdecl CNC_Editor_Get_Cell_Data(int x, int y, char* cell_name, unsigned long cell_name_size, int& template_type, int& template_icon_index)
{
if (!EditorMapInitialized)
{
return EDITOR_COMMMAND_FAILURE;
}
int map_cell_x = Map.MapCellX;
int map_cell_y = Map.MapCellY;
int map_cell_width = Map.MapCellWidth;
int map_cell_height = Map.MapCellHeight;
if (map_cell_x > 0) {
map_cell_x--;
map_cell_width++;
}
if (map_cell_width < MAP_MAX_CELL_WIDTH) {
map_cell_width++;
}
if (map_cell_y > 0) {
map_cell_y--;
map_cell_height++;
}
if (map_cell_height < MAP_MAX_CELL_HEIGHT) {
map_cell_height++;
}
CELL cell = XY_Cell(map_cell_x + x, map_cell_y + y);
return CNC_Editor_Get_Cell_Data_By_Index((int)cell, cell_name, cell_name_size, template_type, template_icon_index);
}
/**************************************************************************************************
* CNC_Editor_Get_Cell_Texture_Buffer
*
* x,y:
* out_width, out_height: dimensions of the outputed texture array
* out_texture_array: output array of unsigned chars storing the color data for the requested object,
* every 3 chars is a set of RGB values
**************************************************************************************************/
extern "C" __declspec(dllexport) int __cdecl CNC_Editor_Get_Cell_Texture_Buffer(int x, int y, int& out_width, int& out_height, SAFEARRAY*& out_texture_array)
{
int map_cell_x = Map.MapCellX;
int map_cell_y = Map.MapCellY;
int map_cell_width = Map.MapCellWidth;
int map_cell_height = Map.MapCellHeight;
if (map_cell_x > 0) {
map_cell_x--;
map_cell_width++;
}
if (map_cell_width < MAP_MAX_CELL_WIDTH) {
map_cell_width++;
}
if (map_cell_y > 0) {
map_cell_y--;
map_cell_height++;
}
if (map_cell_height < MAP_MAX_CELL_HEIGHT) {
map_cell_height++;
}
CELL cell = XY_Cell(map_cell_x + x, map_cell_y + y);
CellClass * cellptr = &Map[cell];
char cell_name[_MAX_PATH];
int icon = 0;
void *image_data = 0;
if (cellptr->Get_Template_Info(cell_name, icon, image_data))
{
GraphicBufferClass temp_gbuffer(24, 24);
GraphicViewPortClass temp_viewport(&temp_gbuffer, 0, 0, 24, 24);
WindowList[WINDOW_CUSTOM][WINDOWX] = 0;
WindowList[WINDOW_CUSTOM][WINDOWY] = 0;
WindowList[WINDOW_CUSTOM][WINDOWWIDTH] = 24;
WindowList[WINDOW_CUSTOM][WINDOWHEIGHT] = 24;
temp_viewport.Draw_Stamp(image_data, icon, 0, 0, NULL, WINDOW_CUSTOM);
out_width = temp_viewport.Get_Width();
out_height = temp_viewport.Get_Height();
const int COLOR_SIZE = 3;
SAFEARRAYBOUND Bound;
Bound.lLbound = 0;
Bound.cElements = out_width * out_height * COLOR_SIZE;
out_texture_array = SafeArrayCreate(VT_UI1, 1, &Bound);
unsigned char* out_buffer;
HRESULT hr = SafeArrayAccessData(out_texture_array, (void **)&out_buffer);
if (SUCCEEDED(hr))
{
GraphicBufferClass* Graphic_Buffer = temp_viewport.Get_Graphic_Buffer();
int VP_Scan_Line = temp_viewport.Get_Width() + temp_viewport.Get_XAdd();
char * start_ptr;
start_ptr = (char *)Graphic_Buffer->Get_Buffer();
start_ptr += ((temp_viewport.Get_YPos() * VP_Scan_Line) + temp_viewport.Get_XPos());
for (int y = 0; y < out_height; ++y)
{
unsigned char* scanline_ptr = (unsigned char*)start_ptr + y * VP_Scan_Line;
unsigned char* out_buffer_y_ptr = out_buffer + (y * out_width * COLOR_SIZE);
for (int x = 0; x < out_width; ++x)
{
unsigned char* pallete_index_ptr = scanline_ptr + x;
unsigned char* out_buffer_ptr = out_buffer_y_ptr + (x * COLOR_SIZE);
int red_palette_index = (*pallete_index_ptr) * COLOR_SIZE;
out_buffer_ptr[0] = GamePalette[red_palette_index] << 2;
out_buffer_ptr[1] = GamePalette[red_palette_index + 1] << 2;
out_buffer_ptr[2] = GamePalette[red_palette_index + 2] << 2;
}
}
SafeArrayUnaccessData(out_texture_array);
return EDITOR_COMMMAND_SUCCESS;
}
}
return EDITOR_COMMMAND_FAILURE;
}
/**************************************************************************************************
* CNC_Editor_Get_Template_Data
* Get the data from the given tile template type.
*
* template_type_index: The index of the template type to use. should come from the Get_Cell_Data function.
* template_points: Out buffer to be filled with the list of positions of the tiles as offsets from the origin of the template.
* This data is store is an X, Y, X, Y, X, Y format.
*
* returns EDITOR_COMMMAND_SUCCESS on success, all other values are failure
**************************************************************************************************/
extern "C" __declspec(dllexport) int __cdecl CNC_Editor_Get_Template_Data(int template_type_index, SAFEARRAY*& template_points)
{
if (template_type_index >= TEMPLATE_COUNT || template_type_index == TEMPLATE_NONE)
{
return EDITOR_COMMMAND_FAILURE;
}
const TemplateTypeClass& template_type = TemplateTypeClass::As_Reference((TemplateType)template_type_index);
if (template_type.Get_Image_Data() == nullptr)
{
return EDITOR_COMMMAND_FAILURE;
}
short const * occupy_list = template_type.Occupy_List();
short const * counter = occupy_list;
while (counter && *counter != REFRESH_EOL)
{
counter++;
}
int occupy_list_size = counter - occupy_list;
SAFEARRAYBOUND bounds;
bounds.lLbound = 0;
bounds.cElements = occupy_list_size * 2;
template_points = SafeArrayCreate(VT_I4, 1, &bounds);
int *pData;
HRESULT hr = SafeArrayAccessData(template_points, (void **)&pData);
if (SUCCEEDED(hr))
{
for (int i = 0; i < occupy_list_size; i++)
{
CELL cell = occupy_list[i];
int x = Cell_X(cell);
int y = Cell_Y(cell);
pData[i * 2] = x;
pData[i * 2 + 1] = y;
}
SafeArrayUnaccessData(template_points);
return EDITOR_COMMMAND_SUCCESS;
}
return EDITOR_COMMMAND_FAILURE;
}
/**************************************************************************************************
* CNC_Editor_Get_Scenario_Names
*
**************************************************************************************************/
extern "C" __declspec(dllexport) int __cdecl CNC_Editor_Get_Scenario_Names(char* cncdata_directory, int CD)
{
unsigned char read_buffer[SHAPE_BUFFER_SIZE];
Set_Shape_Buffer(read_buffer, SHAPE_BUFFER_SIZE);
char team_ids[] =
{
'a',
'b',
'c',
'd',
'e',
'f',
'g',
'h',
'i',
'j',
'k',
'l',
'm',
'n',
'o',
'p',
'q',
'r',
's',
't',
'u',
'v',
'w',
'x',
'y',
'z',
};
/*
{
'g',
'b',
'm',
'j'
};
*/
const int team_count = sizeof(team_ids) / sizeof(char);
char direction_ids[] =
{
'e',
'w'
};
const int direction_count = sizeof(direction_ids) / sizeof(char);
char variant_ids[] =
{
'a',
'b',
'c',
'd'
};
const int variant_count = sizeof(variant_ids) / sizeof(char);
const int min_scenario_index = 1;
const int max_scenario_index = 99;
char scenario_name[_MAX_FNAME + _MAX_EXT];
char file_name[_MAX_FNAME + _MAX_EXT];
CNC_Editor_Setup_Content_Directory(cncdata_directory, CD);
CNC_Editor_Load_Mix_Files();
char output_file_name[256];
snprintf(output_file_name, 256, "d:\\TD_Disk%d_Names.txt", CD);
FILE * names_file = fopen(output_file_name, "w+");
for (int team_index = 0; team_index < team_count; team_index++)
{
for (int scenario_index = min_scenario_index; scenario_index <= max_scenario_index; ++scenario_index)
{
for (int direction_index = 0; direction_index < direction_count; direction_index++)
{
for (int variant_index = 0; variant_index < variant_count; variant_index++)
{
sprintf(scenario_name, "sc%c%.2d%c%c",
team_ids[team_index],
scenario_index,
direction_ids[direction_index],
variant_ids[variant_index]);
sprintf(file_name, "%s.INI", scenario_name);
CCFileClass file(file_name);
if (file.Is_Available())
{
if (Read_Movies_From_Scenario_Ini(scenario_name, false))
{
//fprintf(names_file, "%s - \t$Intro:%s \t\t$Brief:%s \t\t$Win:%s \t\t$Lose:%s \t\t$Action:%s \t\t$Theme:%s", scenario_name, IntroMovie, BriefMovie, WinMovie, LoseMovie, ActionMovie, MovieThemeName);
fprintf(names_file, "------------------%s-------------- %s \n", scenario_name, MovieThemeName);
if (stricmp("x", IntroMovie) != 0)
{
fprintf(names_file, "<IntroMovieName network=\"client\">%s</IntroMovieName>\n", IntroMovie);
}
if (stricmp("x", BriefMovie) != 0)
{
fprintf(names_file, "<BriefMovieName network=\"client\">%s</BriefMovieName>\n", BriefMovie);
}
if (stricmp("x", ActionMovie) != 0)
{
fprintf(names_file, "<ActionMovieName network=\"client\">%s</ActionMovieName>\n", ActionMovie);
}
if (stricmp("x", WinMovie) != 0)
{
fprintf(names_file, "<WinMovieName network=\"client\">%s</WinMovieName>\n", WinMovie);
}
}
fprintf(names_file, "\n");
}
}
}
}
}
fclose(names_file);
return EDITOR_COMMMAND_SUCCESS;
}

199
TIBERIANDAWN/DOOR.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: F:\projects\c&c\vcs\code\door.cpv 1.4 16 Oct 1995 16:49:16 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 : DOOR.CPP *
* *
* Programmer : Joe L. Bostic *
* *
* Start Date : 06/11/95 *
* *
* Last Update : June 14, 1995 [JLB] *
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* DoorClass::AI -- Handles the door processing logic. *
* DoorClass::Close_Door -- Try to close the unit's door. *
* DoorClass::DoorClass -- Constructor for the DoorClass object. *
* DoorClass::Door_Stage -- Fetches the current door animation frame. *
* DoorClass::Open_Door -- Opens the door for this unit. *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "function.h"
/***********************************************************************************************
* DoorClass::DoorClass -- Constructor for the DoorClass object. *
* *
* This constructor sets the door to an initial closed state. *
* *
* INPUT: none *
* *
* OUTPUT: none *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 06/14/1995 JLB : Created. *
*=============================================================================================*/
DoorClass::DoorClass(void)
{
State = IS_CLOSED;
IsToRedraw = false;
Stages = 0;
}
/***********************************************************************************************
* DoorClass::AI -- Handles the door processing logic. *
* *
* This routine should be called every game frame. It handles the door closing and opening *
* logic. *
* *
* INPUT: none *
* *
* OUTPUT: none *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 06/13/1995 JLB : Created. *
*=============================================================================================*/
void DoorClass::AI(void)
{
if (Control.Graphic_Logic()) {
if (Control.Fetch_Stage() >= Stages) {
Control.Set_Rate(0);
switch (State) {
case IS_OPENING:
State = IS_OPEN;
break;
case IS_CLOSING:
State = IS_CLOSED;
break;
}
}
IsToRedraw = true;
}
}
/***********************************************************************************************
* DoorClass::Open_Door -- Opens the door for this unit. *
* *
* This routine will perform the door open operation for this unit. It will control vehicle *
* rotation if necessary. *
* *
* INPUT: rate -- The animation rate (delay) to use for the door animation logic. *
* *
* stages -- The number of animations stages that this door must pass through. *
* *
* OUTPUT: Was action initiated to open the door? *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 05/08/1995 JLB : Created. *
*=============================================================================================*/
bool DoorClass::Open_Door(int rate, int stages)
{
switch (State) {
case IS_CLOSED:
case IS_CLOSING:
State = IS_OPENING;
Stages = stages-1;
Control.Set_Stage(0);
Control.Set_Rate(rate);
return(true);
}
return(false);
}
/***********************************************************************************************
* DoorClass::Close_Door -- Try to close the unit's door. *
* *
* This routine will attempt to close the unit's door. If the door is already closed or *
* in the process of closing, then no action is performed. *
* *
* INPUT: rate -- The animation rate (delay) to use for the door animation logic. *
* *
* stages -- The number of animations stages that this door must pass through. *
* *
* OUTPUT: Action was initiated to close the door? *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 05/08/1995 JLB : Created. *
*=============================================================================================*/
bool DoorClass::Close_Door(int rate, int stages)
{
switch (State) {
case IS_OPEN:
case IS_OPENING:
State = IS_CLOSING;
Stages = stages-1;
Control.Set_Stage(0);
Control.Set_Rate(rate);
return(true);
}
return(false);
}
/***********************************************************************************************
* DoorClass::Door_Stage -- Fetches the current door animation frame. *
* *
* Use this routine to fetch the current door animation frame number. Frame zero is the *
* closed frame and frame 'N' is the open frame. If the door is in the process of opening *
* or closing, the appropriate frame number is used. 'N' is defined as the number of *
* stages in the animation minus 1 (e.g., a four frame animation will return a door stage *
* number between 0 and 3, inclusive). *
* *
* INPUT: none *
* *
* OUTPUT: Returns with the door animation frame number. *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 06/14/1995 JLB : Created. *
*=============================================================================================*/
int DoorClass::Door_Stage(void) const
{
switch (State) {
case IS_CLOSING:
return((Stages-1) - Control.Fetch_Stage());
case IS_CLOSED:
return(0);
case IS_OPENING:
return(Control.Fetch_Stage());
case IS_OPEN:
return(Stages-1);
}
return(0);
}

91
TIBERIANDAWN/DOOR.H Normal file
View File

@@ -0,0 +1,91 @@
//
// 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&c\vcs\code\door.h_v 1.8 16 Oct 1995 16:47:54 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 : DOOR.H *
* *
* Programmer : Joe L. Bostic *
* *
* Start Date : 06/11/95 *
* *
* Last Update : June 11, 1995 [JLB] *
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef DOOR_H
#define DOOR_H
class DoorClass
{
private:
/*
** This is the animation control handler.
*/
StageClass Control;
/*
** This is the recorded number of stages of the current
** door animation process.
*/
unsigned char Stages;
/*
** This is the door state.
*/
enum {
IS_CLOSED, // Door is closed.
IS_OPENING, // Door is in the process of opening.
IS_OPEN, // Door is fully open.
IS_CLOSING // Door is in the process of closing.
} State;
/*
** If the animation for this door indicates that the object it is
** attached to should be redrawn, then this flag will be true.
*/
unsigned IsToRedraw:1;
public:
DoorClass(void);
bool Time_To_Redraw(void) {return(IsToRedraw);};
void Clear_Redraw_Flag(void) {IsToRedraw = false;};
void AI(void);
int Door_Stage(void) const;
bool Is_Door_Opening(void) {return(State == IS_OPENING);};
bool Is_Door_Closing(void) {return(State == IS_CLOSING);};
bool Open_Door(int rate, int stages);
bool Close_Door(int rate, int stages);
bool Is_Door_Open(void) {return(State == IS_OPEN);};
bool Is_Door_Closed(void) {return(State == IS_CLOSED);};
bool Is_Ready_To_Open(void);
/*
** File I/O.
*/
void Code_Pointers(void) { return; }
void Decode_Pointers(void) { return; }
};
#endif

172
TIBERIANDAWN/DPMI.CPP Normal file
View File

@@ -0,0 +1,172 @@
//
// 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&c\vcs\code\dpmi.cpv 2.17 16 Oct 1995 16:49: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 : DPMI.CPP *
* *
* Programmer : Joe L. Bostic *
* *
* Start Date : July 2, 1994 *
* *
* Last Update : July 2, 1994 [JLB] *
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
//PG_TO_FIX
#if (0)
#ifdef __FLAT__
#pragma inline
#endif
#include "function.h"
#include "dpmi.h"
#ifndef __FLAT__
void DOSSegmentClass::Swap(DOSSegmentClass &src, int soffset, DOSSegmentClass &dest, int doffset, int size)
{
if (!size) return;
unsigned short ssel = src.Selector;
unsigned short dsel = dest.Selector;
asm {
push es
push ds
mov si,soffset
mov di,doffset
mov cx,size
mov ax,ssel
mov dx,dsel
mov ds,ax
mov es,dx
}
again:
asm {
mov al,ds:[si]
mov ah,es:[di]
mov ds:[si],ah
mov es:[di],al
inc di
inc si
dec cx
jnz again
pop ds
pop es
}
}
#endif
void DOSSegmentClass::Swap(DOSSegmentClass &src, int soffset, DOSSegmentClass &dest, int doffset, int size)
{
extern void dss_swap(char *src, char *dest, int size);
#pragma aux dss_swap = \
"again: mov al,[esi]" \
"mov ah,[edi]" \
"mov [esi],ah" \
"stosb" \
"inc esi" \
"loop again" \
parm [esi] [edi] [ecx] \
modify [ax];
if (!size) return;
dss_swap((char *)(src.Selector + soffset), (char *)(dest.Selector + doffset), size);
}
#ifdef OBSOLETE
void DOSSegmentClass::Copy(DOSSegmentClass &src, int soffset, DOSSegmentClass &dest, int doffset, int size)
{
extern void dss_copy(char *src, char *dest, int size);
#pragma aux dss_copy = \
"mov ebx,ecx" \
"shr ecx,2" \
"jecxz copskip1" \
"rep movsd" \
"copskip1: mov ecx,ebx" \
"and ecx,3" \
"jecxz copskip2" \
"rep movsb" \
"copskip2:" \
parm [esi edi ecx] \
modify [ebx];
if (!size) return;
dss_copy((char *)(src.Selector + soffset), (char *)(dest.Selector + doffset), size);
}
#endif
#ifdef OBSOLETE
void DOSSegmentClass::Copy_To(void *source, int dest, int size)
{
extern void dss_copy_to(void *src, (void *)dest, int size);
#pragma aux dss_copy_to = \
"mov ebx,ecx" \
"shr ecx,2" \
"jecxz cop2skip1" \
"rep movsd" \
"cop2skip1: mov ecx,ebx" \
"and ecx,3" \
"jecxz cop2skip2" \
"rep movsb" \
"cop2skip2:" \
parm [esi edi ecx] \
modify [ebx];
if (!size) return;
dss_copy_to(src, (void *)(Selector + dest), size);
}
#endif
#ifdef OBSOLETE
void DOSSegmentClass::Copy_From(void *dest, int source, int size)
{
extern void dss_copy_from(void *dest, (void *)source, int size);
#pragma aux dss_copy_from = \
"mov ebx,ecx" \
"shr ecx,2" \
"jecxz copfskip1" \
"rep movsd" \
"copfskip1: mov ecx,ebx" \
"and ecx,3" \
"jecxz copfskip2" \
"rep movsb" \
"copfskip2:" \
parm [edi esi ecx] \
modify [ebx];
if (!size) return;
dss_copy_from(dest, (void *)(Selector + source), size);
}
#endif
#endif //PG_TO_FIX

172
TIBERIANDAWN/DPMI.H Normal file
View File

@@ -0,0 +1,172 @@
//
// 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&c\vcs\code\dpmi.h_v 2.17 16 Oct 1995 16:44: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 : DPMI.H *
* *
* Programmer : Joe L. Bostic *
* *
* Start Date : July 2, 1994 *
* *
* Last Update : July 2, 1994 [JLB] *
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef DPMI_H
#define DPMI_H
#include <dos.h>
#include <stdlib.h>
#include <stdio.h>
#include <mem.h>
extern void output(short port, short data);
class DOSSegmentClass {
/*
** This is the selector/segment value. In real mode it is the segment, in protected
** mode it is the selector (also 16 bits). This value is moved into DS or ES when
** accessing memory.
** Note: in Watcom flat addressing, Selector == Segment<<4 (ex: 0A0000h)
*/
unsigned int Selector;
/*
** These are C equivalents for pushing and popping the DS segment register. By using
** these, it is possible to create very small code that uses a segment and
** offset without damaging the DS register. These are especially useful in protected
** mode, but they are legal in real mode as well.
*/
void Push_DS(void) {/*__emit__(0x1E);*/};
void Pop_DS(void) {/*__emit__(0x1F);*/};
public:
DOSSegmentClass(void);
~DOSSegmentClass(void);
DOSSegmentClass(unsigned short segment, long size=(1024L*64L));
unsigned int Get_Selector(void);
/*
** This routine is used to assign where the descriptor actually points to in
** low DOS memory. In real mode, this is a simple segment assignment and the size
** is always 64K regardless of what is specified. In protected mode, the segment
** is used to update the selector and the size can be any length.
** In Watcom flat mode, it sets Selector == segment<<4
*/
void Assign(unsigned short segment, long size=(1024L*64L));
/*
** These routines will move the data to/from regular memory and the segment/descriptor
** memory.
*/
void Copy_To(void *source, int dest, int size);
void Copy_From(void *dest, int source, int size);
void Copy_Word_To(short data, int dest);
void Copy_Byte_To(char data, int dest);
void Copy_DWord_To(long data, int dest);
short Copy_Word_From(int source);
char Copy_Byte_From(int source);
long Copy_DWord_From(int source);
/*
** These routines move data around between sections of segmented (descriptor) memory.
** Typically, this is used when accessing DOS memory in protected mode or when dealing
** with hard memory areas such as the screen.
*/
static void Copy(DOSSegmentClass &src, int soffset, DOSSegmentClass &dest, int doffset, int size);
static void Swap(DOSSegmentClass &src, int soffset, DOSSegmentClass &dest, int doffset, int size);
};
inline DOSSegmentClass::DOSSegmentClass(void)
{
Selector = 0xB0000;
}
inline DOSSegmentClass::~DOSSegmentClass(void)
{
}
inline void DOSSegmentClass::Copy_Word_To(short data, int dest)
{
*(short *)(Selector+dest) = data;
}
inline void DOSSegmentClass::Copy_Byte_To(char data, int dest)
{
*(char *)(Selector+dest) = data;
}
inline void DOSSegmentClass::Copy_DWord_To(long data, int dest)
{
*(long *)(Selector+dest) = data;
}
inline DOSSegmentClass::DOSSegmentClass(unsigned short segment, long)
{
Assign(segment);
}
inline void DOSSegmentClass::Assign(unsigned short segment, long)
{
Selector = (long)(segment)<<4L;
}
inline void DOSSegmentClass::Copy_To(void *source, int dest, int size)
{
memmove((void*)(Selector+dest), source, size);
}
inline void DOSSegmentClass::Copy_From(void *dest, int source, int size)
{
memmove(dest, (void*)(Selector+source), size);
}
inline void DOSSegmentClass::Copy(DOSSegmentClass &src, int soffset, DOSSegmentClass &dest, int doffset, int size) {
memmove((void*)(dest.Selector+doffset), (void*)(src.Selector+soffset), size);
}
inline short DOSSegmentClass::Copy_Word_From(int source)
{
return *(short*)(Selector+source);
}
inline char DOSSegmentClass::Copy_Byte_From(int source)
{
return *(char*)(Selector+source);
}
inline long DOSSegmentClass::Copy_DWord_From(int source)
{
return *(long*)(Selector+source);
}
inline unsigned int DOSSegmentClass::Get_Selector(void)
{
return Selector;
}
#endif

2284
TIBERIANDAWN/DRIVE.CPP Normal file

File diff suppressed because it is too large Load Diff

223
TIBERIANDAWN/DRIVE.H 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: F:\projects\c&c\vcs\code\drive.h_v 2.19 16 Oct 1995 16:47:44 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 : DRIVE.H *
* *
* Programmer : Joe L. Bostic *
* *
* Start Date : April 14, 1994 *
* *
* Last Update : April 14, 1994 [JLB] *
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef DRIVE_H
#define DRIVE_H
#include "foot.h"
/****************************************************************************
** Movable objects are handled by this class definition. Moveable objects
** cover everything except buildings.
*/
class DriveClass : public FootClass
{
public:
/*
** This points to the static control data that gives 'this' unit its characteristics.
*/
UnitTypeClass const * const Class;
/*
** Simulated sub-pixel offset to find out where the object would be if it could make a sub-pixel move. Only used by
** GlyphX client for more accurate positioning.
**
** ST - 4/30/2019 8:05AM
*/
short SimLeptonX;
short SimLeptonY;
/*
** This records the number of "loads" of Tiberium the unit is carrying. Only
** harvesters use this field.
*/
unsigned char Tiberium;
/*
** If this unit performing harvesting action, then this flag is true. The flag
** is located here because the other bit flags here give it a free place to
** reside.
*/
unsigned IsHarvesting:1;
/*
** This flags when a transport vehicle could not unload at its designated location
** and is heading off the map to try again later. When this flag is true, the
** transport unit is allowed to disappear when it reaches the edge of the map.
*/
unsigned IsReturning:1;
/*
** Some units must have their turret locked down to face their body direction.
** When this flag is set, this condition is in effect. This flag is a more
** accurate check than examining the TrackNumber since the turret may be
** rotating into position so that a pending track may start. During this process
** the track number does not indicate anything.
*/
unsigned IsTurretLockedDown:1;
/*
** This vehicle could be processing a "short track". A short track is one that
** doesn't actually go anywhere. Kind of like turning in place.
*/
unsigned IsOnShortTrack:1;
/*---------------------------------------------------------------------
** Constructors, Destructors, and overloaded operators.
*/
DriveClass(void);
DriveClass(UnitType classid, HousesType house);
virtual ~DriveClass(void) {};
operator UnitType(void) const {return Class->Type;};
/*---------------------------------------------------------------------
** Member function prototypes.
*/
virtual int Offload_Tiberium_Bail(void);
void Do_Turn(DirType dir);
virtual void Approach_Target(void);
virtual ObjectTypeClass const & Class_Of(void) const;
virtual void Overrun_Square(CELL cell, bool threaten=true);
virtual void Assign_Destination(TARGET target);
virtual void Per_Cell_Process(bool center);
virtual bool Ok_To_Move(DirType ) const;
virtual void AI(void);
#ifdef CHEAT_KEYS
virtual void Debug_Dump(MonoClass *mono) const;
#endif
void Force_Track(int track, COORDINATE coord);
virtual int Tiberium_Load(void) const;
void Exit_Map(void);
void Mark_Track(COORDINATE headto, MarkType type);
/*
** File I/O.
*/
virtual void Code_Pointers(void);
virtual void Decode_Pointers(void);
/**********************************************************************
** These enumerations are used as working constants that exist only
** in the DriveClass namespace.
*/
enum DriveClassEnum {
BACKUP_INTO_REFINERY=64, // Track to backup into refinery.
OUT_OF_REFINERY, // Track to leave refinery.
OUT_OF_WEAPON_FACTORY // Track to leave weapons factory.
};
private:
/****************************************************************************
** Smooth turning tracks are controlled by this structure and these
** processing bits.
*/
typedef enum TrackControlType : unsigned char {
F_=0x00, // No translation necessary?
F_T=0x01, // Transpose X and Y components?
F_X=0x02, // Reverse X component sign?
F_Y=0x04, // Reverse Y component sign?
F_D=0x08 // Two cell consumption?
} TrackControlType;
//#define F_S 0x10 // Is this a 90 degree turn?
typedef struct {
char Track; // Which track to use.
char StartTrack; // Track when starting from stand-still.
DirType Facing; // Facing when track has been completed.
DriveClass::TrackControlType Flag; // List processing flag bits.
} TurnTrackType;
typedef struct {
COORDINATE Offset; // Offset to origin coordinate.
DirType Facing; // Facing (primary track).
} TrackType;
typedef struct {
DriveClass::TrackType const * Track; // Pointer to track list.
int Jump; // Index where track jumping is allowed.
int Entry; // Entry point if jumping to this track.
int Cell; // Per cell process should occur at this index.
} RawTrackType;
/*
** These speed values are used to accumulate movement and then
** convert them into pixel "steps" that are then translated through
** the currently running track so that the unit will move.
*/
unsigned char SpeedAccum;
/*
** This the track control logic (used for ground vehicles only). The 'Track'
** variable holds the track being followed (0 == not following track). The
** 'TrackIndex' variable holds the current index into the specified track
** (starts at 0).
*/
char TrackNumber;
char TrackIndex;
/*---------------------------------------------------------------------
** Member function prototypes.
*/
virtual void Fixup_Path(PathType *path);
bool While_Moving(void);
bool Start_Of_Move(void);
void Lay_Track(void);
COORDINATE Smooth_Turn(COORDINATE adj, DirType *dir);
static TurnTrackType const TrackControl[67];
static RawTrackType const RawTracks[13];
static TrackType const Track13[];
static TrackType const Track12[];
static TrackType const Track11[];
static TrackType const Track10[];
static TrackType const Track9[];
static TrackType const Track8[];
static TrackType const Track7[];
static TrackType const Track6[];
static TrackType const Track5[];
static TrackType const Track4[];
static TrackType const Track3[];
static TrackType const Track2[];
static TrackType const Track1[24];
};
//PG_TO_FIX
//inline DriveClass::TrackControlType operator |(DriveClass::TrackControlType, DriveClass::TrackControlType);
//inline DriveClass::TrackControlType operator &(DriveClass::TrackControlType, DriveClass::TrackControlType);
//inline DriveClass::TrackControlType operator ~(DriveClass::TrackControlType);
#endif

468
TIBERIANDAWN/EDIT.CPP Normal file
View File

@@ -0,0 +1,468 @@
//
// 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&c\vcs\code\edit.cpv 2.18 16 Oct 1995 16:48:16 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 : EDIT.CPP *
* *
* Programmer : Joe L. Bostic, Maria del Mar McCready Legg *
* *
* Start Date : 01/15/95 *
* *
* Last Update : June 25, 1995 [JLB] *
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* EditClass::Action -- Handles input events. *
* EditClass::Draw_Background -- Draw the background to the edit gadget. *
* EditClass::Draw_Me -- Draws the edit box and embedded text. *
* EditClass::Draw_Text -- Draws the edit gadget text. *
* EditClass::EditClass -- Normal constructor for edit class object. *
* EditClass::Handle_Key -- Handles keyboard input to edit gadget. *
* EditClass::Set_Text -- Sets the text to the edit gadget. *
* EditClass::~EditClass -- Default destructor for the edit gadget. *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "function.h"
/***********************************************************************************************
* EditClass::EditClass -- Normal constructor for edit class object. *
* *
* This is the normal constructor used to create an edit object. *
* *
* INPUT: id -- The ID number for this edit object. This is the ID number that will be *
* returned by the Input() function when the <RETURN> key is pressed if this *
* gadget has the keyboard input focus. *
* *
* text -- Referenct to the text buffer that the edit gadget will modify as keyboard *
* input is processed. The value that this buffer contains is the default *
* text displayed. *
* *
* maxlen-- The maximum size of the text buffer specified. This length INCLUDES the *
* trailing null character so a simple sizeof() function call can be used. *
* *
* flags -- These are the text print control flags. It is used to control how the *
* text looks in the edit box. Use the normal TPF_??? flags. *
* *
* x,y -- The pixel coordinates of the upper left corner of the edit gadget area. *
* *
* w,h -- The pixel dimensions of the edit box. If either of these are no provided, *
* or set to -1, then the dimension is determined from the string itself. *
* *
* sytle -- This style flag parameter control what kind of characters are allowed in *
* the edit box. The initial string in the text buffer may contain illegal *
* characters, but they are NOT removed regardless of this parameter. *
* *
* OUTPUT: none *
* WARNINGS: none *
* HISTORY: *
* 01/05/1995 MML : Created. *
* 01/21/1995 JLB : Modified. *
*=============================================================================================*/
EditClass::EditClass(int id, char * text, int max_len, TextPrintType flags, int x, int y, int w, int h, EditStyle style) :
ControlClass (id, x, y, w, h, LEFTPRESS), String(text)
{
TextFlags = flags;
EditFlags = style;
Color = CC_GREEN;
Set_Text(text, max_len);
if (w == -1 || h == -1) {
Fancy_Text_Print(TXT_NONE, 0, 0, TBLACK, TBLACK, TextFlags);
if (h == -1) {
Height = FontHeight+2;
}
if (w == -1) {
if (strlen(String) > 0) {
Width = String_Pixel_Width(String) + 6;
} else {
Width = ((Char_Pixel_Width('X')+FontXSpacing) * (MaxLength+1)) + 2;
}
}
}
IsReadOnly = 0;
}
/***********************************************************************************************
* EditClass::~EditClass -- Default destructor for the edit gadget. *
* *
* This default destructor removes the focus setting if it currently has it. *
* *
* INPUT: none *
* *
* OUTPUT: none *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 01/24/1995 JLB : Created. *
*=============================================================================================*/
EditClass::~EditClass(void)
{
if (Has_Focus()) {
Clear_Focus();
}
}
/***********************************************************************************************
* EditClass::Set_Text -- Sets the text to the edit gadget. *
* *
* Use this routine to change the text that this edit gadget refers to. *
* *
* INPUT: text -- Reference to the character array that this edit gadget will be *
* modifying. *
* max_len -- The maximum size of the buffer that will be modified. *
* *
* OUTPUT: none *
* WARNINGS: none *
* HISTORY: *
* 01/21/1995 JLB : Created. *
*=============================================================================================*/
void EditClass::Set_Text(char * text, int max_len)
{
String = text;
MaxLength = max_len-1;
Length = strlen(String);
Flag_To_Redraw();
}
/***********************************************************************************************
* EditClass::Draw_Me -- Draws the edit box and embedded text. *
* *
* This routine will render the edit box. This will show the box outline as well as any *
* text it may contain. *
* *
* INPUT: forced -- Should the edit box be drawn even if it thinks it doesn't have to? *
* *
* OUTPUT: Was the edit box drawn? *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 06/25/1995 JLB : Created. *
*=============================================================================================*/
int EditClass::Draw_Me(int forced)
{
if (ControlClass::Draw_Me(forced)) {
/*
** Hide the mouse.
*/
if (LogicPage == &SeenBuff) {
Conditional_Hide_Mouse(X, Y, X+Width, Y+Height);
}
/*
** Draw the body & set text color.
*/
Draw_Background();
/*
** Display the text.
*/
Draw_Text(String);
/*
** Display the mouse.
*/
if (LogicPage == &SeenBuff) {
Conditional_Show_Mouse();
}
return(true);
}
return(false);
}
/***********************************************************************************************
* EditClass::Action -- Handles input events. *
* *
* This routine will handle all mouse and keyboard events directed at this edit box *
* gadget. For keyboard events, this will insert the characters into the edit box. *
* *
* INPUT: flags -- The event flag that triggered this function call. *
* *
* key -- Reference to the keyboard/mouse event that triggered this function call. *
* *
* OUTPUT: Should the list be processed further? *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 06/25/1995 JLB : Created. *
*=============================================================================================*/
int EditClass::Action(unsigned flags, KeyNumType & key)
{
/*
** If this is a read-only edit box, it's a display-only device
*/
if (IsReadOnly) {
return(false);
}
/*
** If the left mouse button is pressed over this gadget, then set the focus to
** this gadget. The event flag is cleared so that no button ID number is returned.
*/
if ((flags & LEFTPRESS)) {
flags &= ~LEFTPRESS;
Set_Focus();
Flag_To_Redraw(); // force to draw cursor
}
/*
** Handle keyboard events here. Normally, the key is added to the string, but if the
** RETURN key is pressed, then the button ID number is returned from the Input()
** function.
*/
if ((flags & KEYBOARD) && Has_Focus()) {
/*
** Process the keyboard character. If indicated, consume this keyboard event
** so that the edit gadget ID number is not returned.
*/
if (key == KN_ESC) {
Clear_Focus();
flags = 0;
} else {
KeyASCIIType ascii = (KeyASCIIType)(Keyboard::To_ASCII(key) & 0x00ff);
/*
** Allow numeric keypad presses to map to ascii numbers
*/
if ((key & WWKEY_VK_BIT) && ascii >='0' && ascii <= '9'){
key &= ~WWKEY_VK_BIT;
if ( (!(flags & LEFTRELEASE)) && (!(flags & RIGHTRELEASE))){
if (Handle_Key (ascii) ) {
flags &= ~KEYBOARD;
key = KN_NONE;
}
}
}else{
/*
** Filter out all special keys except return and backspace
*/
if ((!(key & WWKEY_VK_BIT) && ascii >= ' ' && ascii <= 127)
|| key == KN_RETURN || key == KN_BACKSPACE){
if ( (!(flags & LEFTRELEASE)) && (!(flags & RIGHTRELEASE))){
if (Handle_Key(Keyboard::To_ASCII(key))) {
flags &= ~KEYBOARD;
key = KN_NONE;
}
}
}else{
//if (key & WWKEY_RLS_BIT){
// if ( (!(flags & LEFTRELEASE)) && (!(flags & RIGHTRELEASE))){
flags &= ~KEYBOARD;
key = KN_NONE;
// }
//}
}
}
}
}
return(ControlClass::Action(flags, key));
}
/***********************************************************************************************
* EditClass::Draw_Background -- Draw the background to the edit gadget. *
* *
* This routine will redraw the edit gadget background. The overlaying text is handled by *
* a different routine. The mouse is guaranteed to be hidden when this routine is called. *
* *
* INPUT: none *
* *
* OUTPUT: none *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 01/21/1995 JLB : Created. *
*=============================================================================================*/
void EditClass::Draw_Background(void)
{
Draw_Box (X, Y, Width, Height, BOXSTYLE_GREEN_BOX, true);
}
/***********************************************************************************************
* EditClass::Draw_Text -- Draws the edit gadget text. *
* *
* This routine is called when the edit gadget text needs to be drawn. The background has *
* already been drawn by the time this function is called. The mouse is guaranteed to be *
* hidden as well. *
* *
* INPUT: text -- The text to draw in the edit gadget. *
* *
* OUTPUT: none *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 01/21/1995 JLB : Created. *
*=============================================================================================*/
void EditClass::Draw_Text(char const * text)
{
if (FontPtr == GradFont6Ptr) {
TextPrintType flags;
if (Has_Focus()) {
flags = TPF_BRIGHT_COLOR;
} else {
flags = (TextPrintType)0;
}
Conquer_Clip_Text_Print(text, X+1, Y+1, Color, TBLACK, TextFlags | flags, Width-2);
if (Has_Focus() && (int)strlen(text) < MaxLength &&
((int)String_Pixel_Width(text) + (int)String_Pixel_Width ("_") < Width-2) ) {
Conquer_Clip_Text_Print( "_", X+1+String_Pixel_Width(text), Y+1, Color, TBLACK, TextFlags | flags);
}
} else {
Conquer_Clip_Text_Print(text, X+1, Y+1, Has_Focus() ? BLUE : WHITE, TBLACK, TextFlags, Width-2);
if (Has_Focus() && (int)strlen(text) < MaxLength &&
((int)String_Pixel_Width(text) + (int)String_Pixel_Width ("_") < Width-2) ) {
Conquer_Clip_Text_Print("_",X+1+String_Pixel_Width(text),Y+1,BLUE,TBLACK, TextFlags);
}
}
}
/***********************************************************************************************
* EditClass::Handle_Key -- Handles keyboard input to edit gadget. *
* *
* This is the gruntwork routine that processes keyboard input to the edit gadget. This *
* routine will be called when keyboard input has been detected and this gadget has the *
* current focus. *
* *
* INPUT: ascii -- The ASCII key code that was fetched from the keyboard buffer. *
* *
* OUTPUT: bool; Should this keyboard input NOT cause the gadget ID number to be returned *
* from the controlling Input() routine? Typically, the return value would be *
* true unless the focus is lost due to the <RETURN> key being pressed. *
* *
* WARNINGS: none *
* HISTORY: *
* 01/21/1995 JLB : Created. *
*=============================================================================================*/
bool EditClass::Handle_Key(KeyASCIIType ascii)
{
switch (ascii) {
/*
** Handle the special case of a non-keyboard event. It is possible that this
** key code might be passed to this routine if this routine has been overridden
** and the key event was consumed.
*/
case 0:
break;
/*
** If the return key is pressed, then remove the focus from this edit
** gadget but otherwise let the normal gadget processing proceed. This
** causes the gadget ID number to be returned from the Input() function
** so that the controlling program will know that the text can be
** processed.
*/
case KA_RETURN:
Clear_Focus();
return(false);
/*
** When the BACKSPACE key is pressed, remove the last character in the edit string.
*/
case KA_BACKSPACE:
if (Length) {
Length--;
String[Length] = '\0';
Flag_To_Redraw();
}
break;
/*
** If the keyboard event was not a recognized special key, then examine to see
** if it can legally be added to the edit string and do so if possible.
*/
default:
/*
** Don't add a character if the length is greater than edit width.
*/
if (((int)String_Pixel_Width(String) + (int)Char_Pixel_Width(ascii) ) >= (Width-2)) {
break;
}
/*
** Don't add a character if the length is already at maximum.
*/
if (Length >= MaxLength) break;
/*
** Invisible characters are never added to the string. This is
** especially true for spaces at the beginning of the string.
*/
if (!isgraph(ascii) && ascii != ' ') break;
if (ascii == ' ' && Length == 0) break;
/*
** If this is an upper case only edit gadget, then force the alphabetic
** character to upper case.
*/
if ((EditFlags & UPPERCASE) && isalpha(ascii)) {
ascii = (KeyASCIIType)toupper(ascii);
}
if ((!(EditFlags & NUMERIC) || !isdigit(ascii)) &&
(!(EditFlags & ALPHA) || !isalpha(ascii)) &&
(!(EditFlags & MISC) || isalnum(ascii)) &&
ascii != ' ') {
break;
}
/*
** The character passed all legality checks, so add it to the edit string
** and flag this gadget to be redrawn. The manual flag to redraw is needed
** because the event flag has been cleared. This prevents the gadget's ID
** number from being returned just because the gadget has been edited.
*/
String[Length++] = ascii;
String[Length] = '\0';
Flag_To_Redraw();
break;
}
return(true);
}

113
TIBERIANDAWN/EDIT.H Normal file
View File

@@ -0,0 +1,113 @@
//
// 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&c\vcs\code\edit.h_v 2.17 16 Oct 1995 16:46:32 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 : EDIT.H *
* *
* Programmer : Joe L. Bostic *
* *
* Start Date : 01/15/95 *
* *
* Last Update : January 15, 1995 [JLB] *
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef EDIT_H
#define EDIT_H
class EditClass : public ControlClass
{
public:
typedef enum EditStyle {
ALPHA =0x0001, // Edit accepts alphabetic characters.
NUMERIC =0x0002, // Edit accepts numbers.
MISC =0x0004, // Edit accepts misc graphic characters.
UPPERCASE =0x0008, // Force to upper case.
ALPHANUMERIC=(int)ALPHA|(int)NUMERIC|(int)MISC,
} EditStyle;
EditClass (int id, char * text, int max_len, TextPrintType flags, int x, int y, int w=-1, int h=-1, EditStyle style=ALPHANUMERIC);
virtual ~EditClass(void);
virtual int Draw_Me(int forced);
virtual void Set_Text(char * text, int max_len);
void Set_Color (int color) { Color = color; }
void Set_Read_Only(int rdonly) {IsReadOnly = rdonly;}
protected:
/*
** These are the text size and style flags to be used when displaying the text
** of the edit gadget.
*/
TextPrintType TextFlags;
/*
** Input flags that control what characters are allowed in the string.
*/
EditStyle EditFlags;
/*
** Pointer to text staging buffer and the maximum length of the string it
** can contain.
*/
char *String;
int MaxLength;
/*
** This is the current length of the string. This length will never exceed the
** MaxLength allowed.
*/
int Length;
/*
** This is the desired color of the edit control.
*/
int Color;
virtual int Action (unsigned flags, KeyNumType &key);
virtual void Draw_Background(void);
virtual void Draw_Text(char const * text);
virtual bool Handle_Key(KeyASCIIType ascii);
private:
int IsReadOnly;
};
//inline EditClass::EditStyle operator |(EditClass::EditStyle, EditClass::EditStyle);
//inline EditClass::EditStyle operator &(EditClass::EditStyle, EditClass::EditStyle);
//inline EditClass::EditStyle operator ~(EditClass::EditStyle);
inline EditClass::EditStyle operator|(EditClass::EditStyle a, EditClass::EditStyle b)
{return static_cast<EditClass::EditStyle>(static_cast<int>(a) | static_cast<int>(b));}
inline EditClass::EditStyle operator&(EditClass::EditStyle a, EditClass::EditStyle b)
{return static_cast<EditClass::EditStyle>(static_cast<int>(a) & static_cast<int>(b));}
inline EditClass::EditStyle operator~(EditClass::EditStyle a)
{return static_cast<EditClass::EditStyle>(~static_cast<int>(a));}
#endif

258
TIBERIANDAWN/ENDING.CPP Normal file
View File

@@ -0,0 +1,258 @@
//
// 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&c\vcs\code\ending.cpv 1.5 16 Oct 1995 16:50:30 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 : ENDING.H *
* *
* Programmer : Barry W. Green *
* *
* Start Date : July 10, 1995 *
* *
* Last Update : July 10, 1995 [BWG] *
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "function.h"
#include "textblit.h"
void GDI_Ending(void)
{
#ifdef DEMO
Fade_Palette_To(BlackPalette, FADE_PALETTE_MEDIUM, Call_Back);
Load_Title_Screen("DEMOPIC.PCX", &HidPage, Palette);
Blit_Hid_Page_To_Seen_Buff();
Fade_Palette_To(Palette, FADE_PALETTE_MEDIUM, Call_Back);
Clear_KeyBuffer();
Get_Key_Num();
Fade_Palette_To(BlackPalette, FADE_PALETTE_MEDIUM, Call_Back);
VisiblePage.Clear();
#else
if (TempleIoned) {
Play_Movie("GDIFINB");
} else {
Play_Movie("GDIFINA");
}
Score.Presentation();
if (TempleIoned) {
Play_Movie("GDIEND2");
} else {
Play_Movie("GDIEND1");
}
CountDownTimerClass count;
if (CCFileClass("TRAILER.VQA").Is_Available()) {
Fade_Palette_To(BlackPalette, FADE_PALETTE_MEDIUM, Call_Back);
Load_Uncompress(CCFileClass("ATTRACT2.CPS"), SysMemPage, SysMemPage, Palette);
SysMemPage.Scale(SeenBuff, 0, 0, 0, 0, 320, 199, 640, 398);
Fade_Palette_To(Palette, FADE_PALETTE_MEDIUM, Call_Back);
Clear_KeyBuffer();
count.Set(TIMER_SECOND*3);
while (count.Time()) {
Call_Back();
}
Fade_Palette_To(BlackPalette, FADE_PALETTE_MEDIUM, Call_Back);
Play_Movie("TRAILER"); // Red Alert teaser.
}
Fade_Palette_To(BlackPalette, FADE_PALETTE_MEDIUM, Call_Back);
Load_Uncompress(CCFileClass("ATTRACT2.CPS"), SysMemPage, SysMemPage, Palette);
SysMemPage.Scale(SeenBuff, 0, 0, 0, 0, 320, 199, 640, 398);
Fade_Palette_To(Palette, FADE_PALETTE_MEDIUM, Call_Back);
Clear_KeyBuffer();
// CountDownTimerClass count;
count.Set(TIMER_SECOND*3);
while (count.Time()) {
Call_Back();
}
Fade_Palette_To(BlackPalette, FADE_PALETTE_MEDIUM, Call_Back);
Play_Movie("CC2TEASE");
#endif
}
#ifndef DEMO
/***********************************************************************************************
* Nod_Ending -- play ending movies for Nod players *
* *
* INPUT: none *
* *
* OUTPUT: none *
* *
* WARNINGS: *
* *
* HISTORY: *
* 7/10/1995 BWG : Created. *
*=============================================================================================*/
void Nod_Ending(void)
{
static unsigned char const _tanpal[]={0x0,0xED,0xED,0x2C,0x2C,0xFB,0xFB,0xFD,0xFD,0x0,0x0,0x0,0x0,0x0,0x52,0x0};
char fname[12];
#ifdef NOT_FOR_WIN95
char *satpic = new char[64000];
#endif //NOT_FOR_WIN95
int oldfontxspacing = FontXSpacing;
void const *oldfont;
Score.Presentation();
oldfont = Set_Font(ScoreFontPtr);
PseudoSeenBuff = new GraphicBufferClass(320,200,(void*)NULL);
TextPrintBuffer = new GraphicBufferClass(SeenBuff.Get_Width(), SeenBuff.Get_Height(), (void*)NULL);
TextPrintBuffer->Clear();
BlitList.Clear();
SeenBuff.Clear();
HidPage.Clear();
PseudoSeenBuff->Clear();
void * localpal = Load_Alloc_Data(CCFileClass("SATSEL.PAL"));
Load_Uncompress(CCFileClass("SATSEL.CPS"), SysMemPage, SysMemPage);
#ifdef NOT_FOR_WIN95
memcpy(satpic, HidPage.Get_Buffer(), 64000);
#else
SysMemPage.Blit(*PseudoSeenBuff);
#endif //NOT_FOR_WIN95
void *kanefinl = Load_Sample("KANEFINL.AUD");
void *loopie6m = Load_Sample("LOOPIE6M.AUD");
Play_Movie("NODFINAL", THEME_NONE, false);
Hide_Mouse();
Wait_Vert_Blank();
Set_Palette(localpal);
#ifdef NOT_FOR_WIN95
memcpy(SeenBuff.Get_Buffer(), satpic, 64000);
#endif //NOT_FOR_WIN95
Show_Mouse();
InterpolationPaletteChanged = TRUE;
InterpolationPalette = (unsigned char*)localpal;
Increase_Palette_Luminance(InterpolationPalette , 30,30,30,63);
Read_Interpolation_Palette("SATSELIN.PAL");
Interpolate_2X_Scale(PseudoSeenBuff, &SeenBuff,"SATSELIN.PAL");
Keyboard::Clear();
Play_Sample(kanefinl,255,128);
Play_Sample(loopie6m,255,128);
bool mouseshown = false;
bool done = false;
int selection = 1;
bool printedtext = false;
while (!done) {
if (!printedtext && !Is_Sample_Playing(kanefinl)) {
printedtext++;
Alloc_Object(new ScorePrintClass(Text_String(TXT_SEL_TARGET), 0, 180,_tanpal));
mouseshown = true;
Show_Mouse();
}
Call_Back_Delay(1);
if (!Keyboard::Check()) {
if (!Is_Sample_Playing(loopie6m)) Play_Sample(loopie6m,255,128);
} else {
if (Is_Sample_Playing(kanefinl)) {
Clear_KeyBuffer();
} else {
int key = Keyboard::Get();
if ((key & 0x10FF) == KN_LMOUSE && !(key & KN_RLSE_BIT)) {
int mousex = _Kbd->MouseQX;
int mousey = _Kbd->MouseQY;
if (mousey >= 22*2 && mousey <= 177*2) {
done++;
if (mousex < 160*2 && mousey < 100*2) selection = 2;
if (mousex < 160*2 && mousey >= 100*2) selection = 3;
if (mousex >= 160*2 && mousey >= 100*2) selection = 4;
}
}
}
}
}
if (mouseshown) Hide_Mouse();
#ifdef NOT_FOR_WIN95
delete satpic;
#else
delete PseudoSeenBuff;
#endif //NOT_FOR_WIN95
/* get rid of all the animating objects */
for (int i = 0; i < MAXSCOREOBJS; i++) if (ScoreObjs[i]) {
delete ScoreObjs[i];
ScoreObjs[i] = 0;
}
// erase the "choose a target" text
SeenBuff.Fill_Rect(0,180*2,319*2,199*2,0);
TextPrintBuffer->Fill_Rect(0,180*2,319*2,199*2,0);
Hide_Mouse();
Keyboard::Clear();
Set_Font(oldfont);
FontXSpacing = oldfontxspacing;
Free_Sample(kanefinl);
Free_Sample(loopie6m);
sprintf(fname,"NODEND%d",selection);
PreserveVQAScreen = 1;
Play_Movie(fname);
CountDownTimerClass count;
if (CCFileClass("TRAILER.VQA").Is_Available()) {
Fade_Palette_To(BlackPalette, FADE_PALETTE_MEDIUM, Call_Back);
Load_Uncompress(CCFileClass("ATTRACT2.CPS"), SysMemPage, SysMemPage, Palette);
SysMemPage.Scale(SeenBuff, 0, 0, 0, 0, 320, 199, 640, 398);
Fade_Palette_To(Palette, FADE_PALETTE_MEDIUM, Call_Back);
Clear_KeyBuffer();
count.Set(TIMER_SECOND*3);
while (count.Time()) {
Call_Back();
}
Fade_Palette_To(BlackPalette, FADE_PALETTE_MEDIUM, Call_Back);
Play_Movie("TRAILER"); // Red Alert teaser.
}
Fade_Palette_To(BlackPalette, FADE_PALETTE_MEDIUM, Call_Back);
Load_Uncompress(CCFileClass("ATTRACT2.CPS"), SysMemPage, SysMemPage, Palette);
SysMemPage.Scale(SeenBuff, 0, 0, 0, 0, 320, 199, 640, 398);
Fade_Palette_To(Palette, FADE_PALETTE_MEDIUM, Call_Back);
Clear_KeyBuffer();
// CountDownTimerClass count;
count.Set(TIMER_SECOND*3);
while (count.Time()) {
Call_Back();
}
Fade_Palette_To(BlackPalette, FADE_PALETTE_MEDIUM, Call_Back);
Play_Movie("CC2TEASE");
delete [] localpal;
delete TextPrintBuffer;
BlitList.Clear();
}
#endif

39
TIBERIANDAWN/ENDING.H Normal file
View File

@@ -0,0 +1,39 @@
//
// 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 *
* *
* File Name : ENDING.H *
* *
* Programmer : Barry W. Green *
* *
* Start Date : July 10, 1995 *
* *
* Last Update : July 10, 1995 [BWG] *
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef ENDING_H
#define ENDING_H
void Nod_Ending(void);
#endif

779
TIBERIANDAWN/EVENT.CPP Normal file
View File

@@ -0,0 +1,779 @@
//
// 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&c\vcs\code\event.cpv 2.17 16 Oct 1995 16:50: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 ***
***********************************************************************************************
* *
* Project Name : Command & Conquer *
* *
* File Name : EVENT.CPP *
* *
* Programmer : Joe L. Bostic *
* *
* Start Date : 12/09/94 *
* *
* Last Update : June 25, 1995 [JLB] *
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* EventClass::EventClass -- Construct an id and cell based event. *
* EventClass::EventClass -- Construct simple target type event. *
* EventClass::EventClass -- Constructor for mission change events. *
* EventClass::EventClass -- Constructor for navigation computer events. *
* EventClass::EventClass -- Constructor for object types affecting cells event. *
* EventClass::EventClass -- Constructor for sidebar build events. *
* EventClass::EventClass -- Constructs event to transfer special flags. *
* EventClass::EventClass -- Default constructor for event objects. *
* EventClass::EventClass -- Event for sequencing animations. *
* EventClass::EventClass -- Megamission assigned to unit. *
* EventClass::Execute -- Execute a queued command. *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "function.h"
#include "ccdde.h"
/***************************************************************************
** Table of what data is really used in the EventClass struct for different
** events. This table must be kept current with the EventType enum.
*/
unsigned char EventClass::EventLength[EventClass::LAST_EVENT] = {
0, // EMPTY
size_of(EventClass, Data.General ), // ALLY
size_of(EventClass, Data.MegaMission ), // MEGAMISSION
size_of(EventClass, Data.Target ), // IDLE
size_of(EventClass, Data.Target ), // SCATTER
0, // DESTRUCT
0, // DEPLOY
size_of(EventClass, Data.Place ), // PLACE
0, // OPTIONS
size_of(EventClass, Data.General ), // GAMESPEED
size_of(EventClass, Data.Specific ), // PRODUCE
size_of(EventClass, Data.Specific.Type ), // SUSPEND
size_of(EventClass, Data.Specific.Type ), // ABANDON
size_of(EventClass, Data.Target ), // PRIMARY
size_of(EventClass, Data.Special ), // SPECIAL_PLACE
0, // EXIT
size_of(EventClass, Data.Anim ), // ANIMATION
size_of(EventClass, Data.Target ), // REPAIR
size_of(EventClass, Data.Target ), // SELL
size_of(EventClass, Data.Options ), // SPECIAL
0, // FRAMESYNC
0, // MESSAGE
size_of(EventClass, Data.FrameInfo.Delay ), // RESPONSE_TIME
size_of(EventClass, Data.FrameInfo ), // FRAMEINFO
size_of(EventClass, Data.NavCom ), // ARCHIVE
size_of(EventClass, Data.Timing ), // TIMING
size_of(EventClass, Data.ProcessTime ), // PROCESS_TIME
};
char * EventClass::EventNames[EventClass::LAST_EVENT] = {
"EMPTY",
"ALLY",
"MEGAMISSION",
"IDLE",
"SCATTER",
"DESTRUCT",
"DEPLOY",
"PLACE",
"OPTIONS",
"GAMESPEED",
"PRODUCE",
"SUSPEND",
"ABANDON",
"PRIMARY",
"SPECIAL_PLACE",
"EXIT",
"ANIMATION",
"REPAIR",
"SELL",
"SPECIAL",
"FRAMESYNC",
"MESSAGE",
"RESPONSE_TIME",
"FRAMEINFO",
"ARCHIVE",
"TIMING",
"PROCESS_TIME",
};
/***********************************************************************************************
* EventClass::EventClass -- Constructs event to transfer special flags. *
* *
* This constructs an event that will transfer the special flags. *
* *
* INPUT: data -- The special flags to be transported to all linked computers. *
* *
* OUTPUT: none *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 06/25/1995 JLB : Created. *
*=============================================================================================*/
EventClass::EventClass(SpecialClass data)
{
ID = Houses.ID(PlayerPtr);
Type = SPECIAL;
Frame = ::Frame;
Data.Options.Data = data;
}
/***********************************************************************************************
* EventClass::EventClass -- Construct simple target type event. *
* *
* This will construct a generic event that needs only a target parameter. The actual *
* event and target values are specified as parameters. *
* *
* INPUT: type -- The event type to construct. *
* *
* target-- The target value that this event is to apply to. *
* *
* OUTPUT: none *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 06/25/1995 JLB : Created. *
*=============================================================================================*/
EventClass::EventClass(EventType type, TARGET target)
{
ID = Houses.ID(PlayerPtr);
Type = type;
Frame = ::Frame;
Data.Target.Whom = target;
}
/***********************************************************************************************
* EventClass::EventClass -- Default constructor for event objects. *
* *
* This constructs a simple event object that requires no parameters other than the *
* type of event it is. *
* *
* INPUT: type -- The type of event to construct. *
* *
* OUTPUT: none *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 12/27/1994 JLB : Created. *
*=============================================================================================*/
EventClass::EventClass(EventType type)
{
ID = Houses.ID(PlayerPtr);
Type = type;
Frame = ::Frame;
}
/***********************************************************************************************
* EventClass::EventClass -- Constructor for general-purpose-data events. *
* *
* INPUT: type -- The type of event to construct. *
* val -- data value *
* *
* OUTPUT: none *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 12/27/1994 JLB : Created. *
*=============================================================================================*/
EventClass::EventClass(EventType type, int val)
{
ID = Houses.ID(PlayerPtr);
Type = type;
Data.General.Value = val;
Frame = ::Frame;
}
/***********************************************************************************************
* EventClass::EventClass -- Constructor for navigation computer events. *
* *
* Constructor for events that are used to assign the navigation computer. *
* *
* INPUT: type -- The type of event (this constructor can be used by other navigation *
* type events). *
* *
* src -- The object that the event should apply to. *
* *
* dest -- The destination (or target) that the event needs to complete. *
* *
* OUTPUT: none *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 12/27/1994 JLB : Created. *
*=============================================================================================*/
EventClass::EventClass(EventType type, TARGET src, TARGET dest)
{
ID = Houses.ID(PlayerPtr);
Type = type;
Frame = ::Frame;
Data.NavCom.Whom = src;
Data.NavCom.Where = dest;
}
/***********************************************************************************************
* EventClass::EventClass -- Event for sequencing animations. *
* *
* This constructor is used for animations that must be created through the event system. *
* *
* INPUT: anim -- The animation that will be created. *
* *
* coord -- The location where the animation is to be created. *
* *
* OUTPUT: none *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 05/19/1995 JLB : Created. *
*=============================================================================================*/
EventClass::EventClass(AnimType anim, HousesType owner, COORDINATE coord)
{
ID = Houses.ID(PlayerPtr);
Type = ANIMATION;
Frame = ::Frame;
Data.Anim.What = anim;
Data.Anim.Owner = owner;
Data.Anim.Where = coord;
}
/***********************************************************************************************
* EventClass::EventClass -- Megamission assigned to unit. *
* *
* This is the event that is used to assign most missions to units. It combines both the *
* mission and the target (navcom and tarcom). *
* *
* INPUT: src -- The object that this mission is to apply to. *
* *
* mission -- The mission to assign to this object. *
* *
* target -- The target to assign to this object's TarCom. *
* *
* destination -- The destination to assign to this object's NavCom. *
* *
* OUTPUT: none *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 05/18/1995 JLB : Created. *
*=============================================================================================*/
EventClass::EventClass(TARGET src, MissionType mission, TARGET target, TARGET destination)
{
ID = Houses.ID(PlayerPtr);
Type = MEGAMISSION;
Frame = ::Frame;
Data.MegaMission.Whom = src;
Data.MegaMission.Mission = mission;
Data.MegaMission.Target = target;
Data.MegaMission.Destination = destination;
}
/***********************************************************************************************
* EventClass::EventClass -- Constructor for sidebar build events. *
* *
* This constructor is used for events that deal with an object type and an object ID. *
* Typically, this is used exclusively by the sidebar. *
* *
* INPUT: type -- The event type of this object. *
* *
* object -- The object type number. *
* *
* id -- The object sub-type number. *
* *
* OUTPUT: none *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 05/18/1995 JLB : Created. *
*=============================================================================================*/
EventClass::EventClass(EventType type, RTTIType object, int id)
{
ID = Houses.ID(PlayerPtr);
Type = type;
Frame = ::Frame;
Data.Specific.Type = object;
Data.Specific.ID = id;
}
/***********************************************************************************************
* EventClass::EventClass -- Constructor for object types affecting cells event. *
* *
* This constructor is used for those events that have an object type and associated cell. *
* Typically, this is for building placement after construction has completed. *
* *
* INPUT: type -- The event type for this object. *
* *
* object -- The object type number (actual object is probably inferred from the *
* sidebar data). *
* *
* cell -- The cell location where this event is to occur. *
* *
* OUTPUT: none *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 05/18/1995 JLB : Created. *
*=============================================================================================*/
EventClass::EventClass(EventType type, RTTIType object, CELL cell)
{
ID = Houses.ID(PlayerPtr);
Type = type;
Frame = ::Frame;
Data.Place.Type = object;
Data.Place.Cell = cell;
}
/***********************************************************************************************
* EventClass::EventClass -- Construct an id and cell based event. *
* *
* This constructor is used for those events that require an ID number and a cell location. *
* *
* INPUT: type -- The event type this will be. *
* *
* id -- The arbitrary id number to assign. *
* *
* cell -- The location for this event. *
* *
* OUTPUT: none *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 05/18/1995 JLB : Created. *
*=============================================================================================*/
EventClass::EventClass(EventType type, int id, CELL cell)
{
ID = Houses.ID(PlayerPtr);
Type = type;
Frame = ::Frame;
Data.Special.ID = id;
Data.Special.Cell = cell;
}
/***********************************************************************************************
* EventClass::Execute -- Execute a queued command. *
* *
* This routine executes an event. The even must already have been confirmed by any *
* remote machine before calling this routine. *
* *
* INPUT: none *
* *
* OUTPUT: none *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 12/27/1994 JLB : Created. *
*=============================================================================================*/
void EventClass::Execute(void)
{
TechnoClass * techno;
AnimClass * anim = 0;
HouseClass * house = 0;
char txt[80];
int i;
//#if (0)
if (Type < 0 || Type > PROCESS_TIME){
char tempbuf[128];
sprintf (tempbuf, "Packet type %d received\n", Type);
CCDebugString (tempbuf);
sprintf (tempbuf, " ID = %d\n", ID);
CCDebugString (tempbuf);
sprintf (tempbuf, " Frame = %d\n", Frame);
CCDebugString (tempbuf);
sprintf (tempbuf, " MPlayer ID = %d\n", MPlayerID);
CCDebugString (tempbuf);
}
//#endif //(0)
switch (Type) {
/*
** Update the archive target for this building.
*/
case ARCHIVE:
techno = As_Techno(Data.NavCom.Whom);
if (techno && techno->IsActive) {
techno->ArchiveTarget = Data.NavCom.Where;
}
break;
/*
** Make or break alliance.
*/
case ALLY:
house = Houses.Raw_Ptr(Data.General.Value);
if (Houses.Raw_Ptr(ID)->Is_Ally(house)) {
Houses.Raw_Ptr(ID)->Make_Enemy((HousesType)Data.General.Value);
} else {
Houses.Raw_Ptr(ID)->Make_Ally((HousesType)Data.General.Value);
}
break;
/*
** Special self destruct action requested. This is active in the multiplayer mode.
*/
case DESTRUCT:
CCDebugString ("C&C95 - Resignation packet received\n");
Houses.Raw_Ptr(ID)->Flag_To_Die();
Houses.Raw_Ptr(ID)->Resigned = true;
break;
/*
** Update the special control flags. This is necessary so that in a multiplay
** game, all machines will agree on the rules. If these options change during
** game play, then all players are informed that options have changed.
*/
case SPECIAL:
{
Special = Data.Options.Data;
HouseClass * house = Houses.Raw_Ptr(ID);
sprintf(txt, Text_String(TXT_SPECIAL_WARNING), house->Name);
Messages.Add_Message(txt, MPlayerTColors[house->RemapColor],
TPF_6PT_GRAD|TPF_USE_GRAD_PAL|TPF_FULLSHADOW, 1200, 0, 0);
Map.Flag_To_Redraw(false);
}
break;
/*
** Starts or stops repair on the specified object. This event is triggered by the
** player clicking the repair wrench on a building.
*/
case REPAIR:
CCDebugString ("C&C95 - Repair packet received\n");
techno = As_Techno(Data.Target.Whom);
if (techno && techno->IsActive) {
techno->Repair(-1);
}
break;
/*
** Tells a building/unit to sell. This event is triggered by the player clicking the
** sell animating cursor over the building or unit.
*/
case SELL:
CCDebugString ("C&C95 - Sell packet received\n");
techno = As_Techno(Data.Target.Whom);
if (techno && techno->IsActive && techno->House == Houses.Raw_Ptr(ID)) {
techno->Sell_Back(-1);
} else {
if (Is_Target_Cell(Data.Target.Whom)) {
Houses.Raw_Ptr(ID)->Sell_Wall(As_Cell(Data.Target.Whom));
}
}
break;
/*
** This even is used to trigger an animation that is generated as a direct
** result of player intervention.
*/
case ANIMATION:
anim = new AnimClass(Data.Anim.What, Data.Anim.Where);
if (anim) {
//2019/09/19 JAS - Visibility needs to be determined per player
if (Data.Anim.What != ANIM_MOVE_FLASH || Data.Anim.Owner == HOUSE_NONE || Special.IsVisibleTarget)
{
anim->Set_Visible_Flags(0xffff);
}
else
{
anim->Set_Visible_Flags(1 << Data.Anim.Owner);
}
}
break;
/*
** This event will place the specified object at the specified location.
** The event is used to place newly constructed buildings down on the map. The
** object type is specified. From this object type, the house can determine the
** exact factory and real object pointer to use.
*/
case PLACE:
CCDebugString ("C&C95 - Place packet received\n");
Houses.Raw_Ptr(ID)->Place_Object(Data.Place.Type, Data.Place.Cell);
break;
/*
** This event starts production of the speicified object type. The house can
** determine from the type and ID value, what object to begin production on and
** what factory to use.
*/
case PRODUCE:
CCDebugString ("C&C95 - Produce packet received\n");
Houses.Raw_Ptr(ID)->Begin_Production(Data.Specific.Type, Data.Specific.ID);
break;
/*
** This event is generated when the player puts production on hold. From the
** object type, the factory can be inferred.
*/
case SUSPEND:
CCDebugString ("C&C95 - Suspend packet received\n");
Houses.Raw_Ptr(ID)->Suspend_Production(Data.Specific.Type);
break;
/*
** This event is generated when the player cancels production of the specified
** object type. From the object type, the exact factory can be inferred.
*/
case ABANDON:
CCDebugString ("C&C95 - Abandon packet received\n");
Houses.Raw_Ptr(ID)->Abandon_Production(Data.Specific.Type);
break;
/*
** Toggles the primary factory state of the specified building.
*/
case PRIMARY:{
CCDebugString ("C&C95 - Primary building packet received\n");
BuildingClass * building = As_Building(Data.Target.Whom);
if (building && building->IsActive) {
building->Toggle_Primary();
}
}
break;
/*
** This is the general purpose mission control event. Most player
** action routes through this event. It sets a unit's mission, TarCom,
** and NavCom to the values specified.
*/
case MEGAMISSION:
techno = As_Techno(Data.MegaMission.Whom);
if (techno && techno->IsActive) {
/*
** Fetch a pointer to the object of the mission.
*/
ObjectClass * object;
if (Target_Legal(Data.MegaMission.Target)) {
object = As_Object(Data.MegaMission.Target);
} else {
object = As_Object(Data.MegaMission.Destination);
}
/*
** Break any existing team contact, since it is now invalid.
*/
if (!techno->IsTethered) {
techno->Transmit_Message(RADIO_OVER_OUT);
}
switch (techno->What_Am_I()) {
case RTTI_INFANTRY:
case RTTI_UNIT:
if (((FootClass *)techno)->Team) {
((FootClass *)techno)->Team->Remove((FootClass *)techno);
}
break;
}
if (object) {
// 2019/09/20 JAS - Added record of who clicked on the object
HouseClass* house = Houses.Raw_Ptr(ID);
bool is_allied = house != nullptr && house->Is_Ally(techno);
if (is_allied || Special.IsVisibleTarget) {
object->Clicked_As_Target((HousesType)ID);
}
}
techno->Assign_Mission(Data.MegaMission.Mission);
/*
** Guard area mode is handled with care. The specified target is actually
** assigned as the location that should be guarded. In addition, the
** movement destination is immediately set to this new location.
*/
if (Data.MegaMission.Mission == MISSION_GUARD_AREA &&
// Target_Legal(Data.MegaMission.Target) &&
(techno->What_Am_I() == RTTI_INFANTRY || techno->What_Am_I() == RTTI_UNIT || techno->What_Am_I() == RTTI_AIRCRAFT)) {
techno->ArchiveTarget = Data.MegaMission.Target;
techno->Assign_Target(TARGET_NONE);
techno->Assign_Destination(Data.MegaMission.Target);
} else {
techno->Assign_Target(Data.MegaMission.Target);
techno->Assign_Destination(Data.MegaMission.Destination);
}
#ifdef NEVER
if ((techno->What_Am_I() == RTTI_UNIT || techno->What_Am_I() == RTTI_INFANTRY) &&
Data.MegaMission.Mission == MISSION_GUARD_AREA) {
techno->ArchiveTarget = Data.MegaMission.Destination;
}
#endif
}
break;
/*
** Request that the unit/infantry/aircraft go into idle mode.
*/
case IDLE:
techno = As_Techno(Data.Target.Whom);
if (techno && techno->IsActive && !techno->IsInLimbo && !techno->IsTethered) {
techno->Assign_Destination(TARGET_NONE);
techno->Assign_Target(TARGET_NONE);
techno->Enter_Idle_Mode();
}
break;
/*
** Request that the unit/infantry/aircraft scatter from its current location.
*/
case SCATTER:
techno = As_Techno(Data.Target.Whom);
if (techno && techno->IsActive && !techno->IsInLimbo && !techno->IsTethered) {
techno->Scatter(0, true);
}
break;
/*
** If we are placing down the ion cannon blast then lets take
** care of it.
*/
case SPECIAL_PLACE:
CCDebugString ("C&C95 - Special blast packet received\n");
Houses.Raw_Ptr(ID)->Place_Special_Blast((SpecialWeaponType)Data.Special.ID, Data.Special.Cell);
break;
/*
** Exit the game.
** Give parting message while palette is fading to black.
*/
case EXIT:
CCDebugString ("C&C95 - Exit game packet received\n");
Theme.Queue_Song(THEME_NONE);
Stop_Speaking();
Speak(VOX_CONTROL_EXIT);
while (Is_Speaking()) {
Call_Back();
}
GameActive = false;
break;
/*
** Process the options menu.
*/
case OPTIONS:
SpecialDialog = SDLG_OPTIONS;
break;
/*
** Process the options Game Speed
*/
case GAMESPEED:
CCDebugString ("C&C95 - Game speed packet received\n");
Options.GameSpeed = Data.General.Value;
break;
/*
** Adjust connection timing for multiplayer games
*/
case RESPONSE_TIME:
char flip[128];
sprintf (flip, "C&C95 - Changing MaxAhead to %d frames\n", Data.FrameInfo.Delay);
CCDebugString (flip);
MPlayerMaxAhead = Data.FrameInfo.Delay;
break;
//
// This event tells all systems to use new timing values. It's like
// RESPONSE_TIME, only it works. It's only used with the
// COMM_MULTI_E_COMP protocol.
//
case TIMING:
CCDebugString ("C&C95 - Timing packet received\n");
//#if(TIMING_FIX)
//
// If MaxAhead is about to increase, we're vulnerable to a Packet-
// Received-Too-Late error, if any system generates an event after
// this TIMING event, but before it executes. So, record the
// period of vulnerability's frame start & end values, so we
// can reschedule these events to execute after it's over.
//
if (Data.Timing.MaxAhead > MPlayerMaxAhead) {
NewMaxAheadFrame1 = Frame;
NewMaxAheadFrame2 = Frame + Data.Timing.MaxAhead;
}
//#endif
DesiredFrameRate = Data.Timing.DesiredFrameRate;
MPlayerMaxAhead = Data.Timing.MaxAhead;
sprintf (flip, "C&C95 - Timing packet: DesiredFrameRate = %d\n", Data.Timing.DesiredFrameRate);
CCDebugString (flip);
sprintf (flip, "C&C95 - Timing packet: MaxAhead = %d\n", Data.Timing.MaxAhead);
CCDebugString (flip);
/*
** If spawned from WChat then we should be getting poked every minute. If not then
** deliberately break the max ahead value
*/
if (Special.IsFromWChat){
MPlayerMaxAhead += DDEServer.Time_Since_Heartbeat()/(70*60);
//if (DDEServer.Time_Since_Heartbeat() >= 70*60) CCDebugString ("C&C95 - Missed a heartbeat\n");
}
break;
//
// This event tells all systems what the other systems' process
// timing requirements are; it's used to compute a desired frame rate
// for the game.
//
case PROCESS_TIME:
for (i = 0; i < MPlayerCount; i++) {
if (MPlayerID == ::MPlayerID[i]) {
TheirProcessTime[i] = Data.ProcessTime.AverageTicks;
char flip[128];
sprintf (flip, "C&C95 - Received PROCESS_TIME packet of %04x ticks\n", Data.ProcessTime.AverageTicks);
CCDebugString (flip);
break;
}
}
break;
/*
** Default: do nothing.
*/
default:
break;
}
}

224
TIBERIANDAWN/EVENT.H Normal file
View File

@@ -0,0 +1,224 @@
//
// 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&c\vcs\code\event.h_v 2.19 16 Oct 1995 16:46:14 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 : EVENT.H *
* *
* Programmer : Joe L. Bostic *
* *
* Start Date : 12/09/94 *
* *
* Last Update : December 9, 1994 [JLB] *
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef EVENT_H
#define EVENT_H
/*
** This event class is used to contain all external game events (things that the player can
** do at any time) so that these events can be transported between linked computers. This
** encapsulation is required in order to ensure that each event affects all computers at the
** same time (same game frame).
*/
class EventClass
{
public:
/*
** All external events are identified by these labels.
*/
typedef enum EventType : unsigned char {
EMPTY,
ALLY, // Make allie of specified house.
MEGAMISSION, // Full change of mission with target and destination.
IDLE, // Request to enter idle mode.
SCATTER, // Request to scatter from current location.
DESTRUCT, // Self destruct request (surrender action).
DEPLOY, // MCV is to deploy at current location.
PLACE, // Place building at location specified.
OPTIONS, // Bring up options screen.
GAMESPEED, // Set game speed
PRODUCE, // Start or Resume production.
SUSPEND, // Suspend production.
ABANDON, // Abandon production.
PRIMARY, // Primary factory selected.
SPECIAL_PLACE, // Special target location selected
EXIT, // Exit game.
ANIMATION, // Flash ground as movement feedback.
REPAIR, // Repair specified object.
SELL, // Sell specified object.
SPECIAL, // Special options control.
// Private events.
FRAMESYNC, // Game-connection packet; includes Scenario CRC & sender's frame #
// Used to initiate game connection phase & to reconnect;
// When one of these is received, the receiver knows there are
// no associated commands in this packet.
MESSAGE, // Message to another player (The message is the 40 bytes
// after the event class).
RESPONSE_TIME, // use a new propogation delay value
FRAMEINFO, // Game-heartbeat packet; includes Game CRC & command count
// All packets sent for a frame are prefixed with one of these
ARCHIVE, // Updates archive target on specified object.
TIMING, // new timing values for all systems to use
PROCESS_TIME, // a system's average processing time, in ticks per frame
LAST_EVENT, // one past the last event
} EventType;
EventType Type; // Type of queue command object.
/*
** 'Frame' is the frame that the command should execute on.
** 27 bits gives over 25 days of playing time without wrapping,
** at 30 frames per second, so it should be plenty!
*/
unsigned Frame : 27;
/*
** House index of the player originating this event
*/
unsigned ID : 4;
/*
** This bit tells us if we've already executed this event.
*/
unsigned IsExecuted: 1;
/*
** Multiplayer ID of the player originating this event.
** High nybble: the color index of this player.
** Low nybble: the HousesType this player is "acting like" (GDI/NOD)
*/
unsigned char MPlayerID;
/*
** This union contains the specific data that the event requires.
*/
union {
struct {
SpecialClass Data; // The special option flags.
} Options;
struct {
TARGET Whom; // The object to apply the event to.
} Target;
struct {
AnimType What; // The animation to create.
HousesType Owner; // The owner of the animation (when it matters).
COORDINATE Where; // The location to place the animation.
} Anim;
struct {
int Value; // general-purpose data
} General;
struct {
TARGET Whom; // Whom to apply mission to.
MissionType Mission; // What mission to apply.
TARGET Target; // Target to assign.
TARGET Destination;// Destination to assign.
} MegaMission;
struct {
TARGET Whom; // Whom to apply mission to.
MissionType Mission; // What mission to apply.
} Mission;
struct {
TARGET Whom; // Whom to apply movement change to.
TARGET Where; // Where to set NavCom to.
} NavCom;
struct {
TARGET Whom; // Whom to apply attack change to.
TARGET Target; // What to set TarCom to.
} TarCom;
struct {
RTTIType Type;
int ID;
} Specific;
struct {
RTTIType Type;
CELL Cell;
} Place;
struct {
int ID;
CELL Cell;
} Special;
/*
** This structure is used for FRAMEINFO, FRAMESYNC, and RESPONSE_TIME
** events; exactly one of these will be sent each frame, whether there's
** data that frame or not.
** CRC: the game CRC when this packet was generated; used to detect sync errors
** CommandCount: # of commands the sender has sent; used to detect missed packets
** Delay: sender's propogation delay value for this frame
*/
struct {
unsigned long CRC;
unsigned short CommandCount; // # commands sent so far
unsigned char Delay; // propogation delay used this frame
// (Frame - Delay = sender's current frame #)
} FrameInfo;
//
// This structure sets new timing values for all systems in a multiplayer
// game. This structure replaces the RESPONSE_TIME event for
// the COMM_MULTI_E_COMP protocol.
//
struct {
unsigned short DesiredFrameRate;
unsigned short MaxAhead;
} Timing;
//
// This structure is transmitted by all systems, and is used to compute
// the "desired" frame rate for the game.
//
struct {
unsigned short AverageTicks;
} ProcessTime;
} Data;
//-------------- Functions ---------------------
EventClass(void) {Type = EMPTY;};
EventClass(SpecialClass data);
EventClass(EventType type, TARGET target);
EventClass(EventType type);
EventClass(EventType type, int val);
EventClass(EventType type, TARGET src, TARGET dest);
// EventClass(TARGET src, MissionType mission);
EventClass(TARGET src, MissionType mission, TARGET target=TARGET_NONE, TARGET destination=TARGET_NONE);
EventClass(EventType type, RTTIType object, int id);
EventClass(EventType type, RTTIType object, CELL cell);
EventClass(EventType type, int id, CELL cell);
EventClass(AnimType anim, HousesType owner, COORDINATE coord);
// Process the event.
void Execute(void);
int operator == (EventClass & q) {
return memcmp(this, &q, sizeof(q)) == 0;
};
static unsigned char EventLength[LAST_EVENT];
static char * EventNames[LAST_EVENT];
};
#endif

420
TIBERIANDAWN/EXPAND.CPP Normal file
View File

@@ -0,0 +1,420 @@
//
// 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$ */
/***********************************************************************************************
*** 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 : EXPAND.CPP *
* *
* Programmer : Joe L. Bostic *
* *
* Start Date : 11/03/95 *
* *
* Last Update : November 3, 1995 [JLB] *
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "function.h"
#ifdef NEWMENU
bool Expansion_Present(void)
{
CCFileClass file("EXPAND.DAT");
return(file.Is_Available());
}
class EListClass : public ListClass
{
public:
EListClass(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) {};
protected:
virtual void Draw_Entry(int index, int x, int y, int width, int selected);
};
void EListClass::Draw_Entry(int index, int x, int y, int width, int selected)
{
if (TextFlags & TPF_6PT_GRAD) {
TextPrintType flags = TextFlags;
if (selected) {
flags = flags | TPF_BRIGHT_COLOR;
LogicPage->Fill_Rect (x, y, x + width - 1, y + LineHeight - 1, CC_GREEN_SHADOW);
} else {
if (!(flags & TPF_USE_GRAD_PAL)) {
flags = flags | TPF_MEDIUM_COLOR;
}
}
Conquer_Clip_Text_Print(List[index]+sizeof(int), x, y, CC_GREEN, TBLACK, flags, width, Tabs);
} else {
Conquer_Clip_Text_Print(List[index]+sizeof(int), x, y, (selected ? BLUE : WHITE), TBLACK, TextFlags, width, Tabs);
}
}
bool Expansion_Dialog(void)
{
int factor = (SeenBuff.Get_Width() == 320) ? 1 : 2;
int option_width = 236 * factor;
int option_height = 162 * factor;
int option_x = (320*factor - option_width) /2;
int option_y = (200*factor - option_height) /2;
GadgetClass * buttons = NULL;
void const *up_button;
void const *down_button;
if (InMainLoop){
up_button = Hires_Retrieve("BTN-UP.SHP");
down_button = Hires_Retrieve("BTN-DN.SHP");
}else{
up_button = Hires_Retrieve("BTN-UP2.SHP");
down_button = Hires_Retrieve("BTN-DN2.SHP");
}
TextButtonClass ok(200, TXT_OK, TPF_6PT_GRAD|TPF_NOSHADOW, option_x+25*factor, option_y+option_height-15*factor);
TextButtonClass cancel(201, TXT_CANCEL, TPF_6PT_GRAD|TPF_NOSHADOW, option_x+option_width-50*factor, option_y+option_height-15*factor);
EListClass list(202, option_x+10*factor, option_y+20*factor, option_width-20*factor, option_height-40*factor, TPF_6PT_GRAD|TPF_NOSHADOW, up_button, down_button);
buttons = &ok;
cancel.Add(*buttons);
list.Add(*buttons);
/*
** Add in all the expansion scenarios.
*/
char * sbuffer = (char*)_ShapeBuffer;
int index;
for (index = 20; index < 60; index++) {
char buffer[128];
CCFileClass file;
Set_Scenario_Name(buffer, index, SCEN_PLAYER_GDI, SCEN_DIR_EAST, SCEN_VAR_A);
strcat(buffer, ".INI");
file.Set_Name(buffer);
if (file.Is_Available()) {
file.Read(sbuffer, 1000);
sbuffer[1000] = '\r';
sbuffer[1000+1] = '\n';
sbuffer[1000+2] = '\0';
WWGetPrivateProfileString("Basic", "Name", "x", buffer, sizeof(buffer), sbuffer);
char * data = new char [strlen(buffer)+1+sizeof(int)+25];
*((int*)&data[0]) = index;
strcpy(&data[sizeof(int)], "GDI: ");
strcat(&data[sizeof(int)], buffer);
list.Add_Item(data);
}
}
for (index = 20; index < 60; index++) {
char buffer[128];
CCFileClass file;
Set_Scenario_Name(buffer, index, SCEN_PLAYER_NOD, SCEN_DIR_EAST, SCEN_VAR_A);
strcat(buffer, ".INI");
file.Set_Name(buffer);
if (file.Is_Available()) {
file.Read(sbuffer, 1000);
sbuffer[1000] = '\r';
sbuffer[1000+1] = '\n';
sbuffer[1000+2] = '\0';
WWGetPrivateProfileString("Basic", "Name", "x", buffer, sizeof(buffer), sbuffer);
char * data = new char [strlen(buffer)+1+sizeof(int)+25];
*((int*)&data[0]) = index;
strcpy(&data[sizeof(int)], "NOD: ");
strcat(&data[sizeof(int)], buffer);
list.Add_Item(data);
}
}
Set_Logic_Page(SeenBuff);
bool recalc = true;
bool display = true;
bool process = true;
bool okval = true;
while (process) {
Call_Back();
/*
** 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=TRUE;
}
if (display) {
display = false;
Hide_Mouse();
/*
** Load the background picture.
*/
Load_Title_Screen("HTITLE.PCX", &HidPage, Palette);
Blit_Hid_Page_To_Seen_Buff();
Dialog_Box(option_x, option_y, option_width, option_height);
Draw_Caption(TXT_MISSION_DESCRIPTION, option_x, option_y, option_width);
buttons->Draw_All();
Show_Mouse();
}
KeyNumType input = buttons->Input();
switch (input) {
case KN_RETURN:
case 200|KN_BUTTON:
if (list.Current_Item()[sizeof(int)] == 'G') {
ScenPlayer = SCEN_PLAYER_GDI;
} else {
ScenPlayer = SCEN_PLAYER_NOD;
}
ScenDir = SCEN_DIR_EAST;
Whom = HOUSE_GOOD;
Scenario = *(int *)list.Current_Item();
process = false;
okval = true;
break;
case KN_ESC:
case 201|KN_BUTTON:
ScenPlayer = SCEN_PLAYER_GDI;
ScenDir = SCEN_DIR_EAST;
Whom = HOUSE_GOOD;
Scenario = *(int *)list.Current_Item();
process = false;
okval = false;
break;
default:
break;
}
}
/*
** Free up the allocations for the text lines in the list box.
*/
for (index = 0; index < list.Count(); index++) {
delete [] (char *)list.Get_Item(index);
}
return(okval);
}
/***********************************************************************************************
* Bonus_Dialog -- Asks the user which bonus mission he wants to play *
* *
* *
* *
* INPUT: Nothing *
* *
* OUTPUT: Nothing *
* *
* WARNINGS: None *
* *
* HISTORY: *
* 3/26/97 11:07AM ST : Created *
*=============================================================================================*/
bool Bonus_Dialog(void)
{
int factor = (SeenBuff.Get_Width() == 320) ? 1 : 2;
int option_width = 236 * factor;
int option_height = 162 * factor;
int option_x = (320*factor - option_width) /2;
int option_y = (200*factor - option_height) /2;
GadgetClass * buttons = NULL;
void const *up_button;
void const *down_button;
if (InMainLoop){
up_button = Hires_Retrieve("BTN-UP.SHP");
down_button = Hires_Retrieve("BTN-DN.SHP");
}else{
up_button = Hires_Retrieve("BTN-UP2.SHP");
down_button = Hires_Retrieve("BTN-DN2.SHP");
}
TextButtonClass ok(200, TXT_OK, TPF_6PT_GRAD|TPF_NOSHADOW, option_x+25*factor, option_y+option_height-15*factor);
TextButtonClass cancel(201, TXT_CANCEL, TPF_6PT_GRAD|TPF_NOSHADOW, option_x+option_width-50*factor, option_y+option_height-15*factor);
EListClass list(202, option_x+10*factor, option_y+20*factor, option_width-20*factor, option_height-40*factor, TPF_6PT_GRAD|TPF_NOSHADOW, up_button, down_button);
buttons = &ok;
cancel.Add(*buttons);
list.Add(*buttons);
/*
** Add in all the expansion scenarios.
*/
char * sbuffer = (char*)_ShapeBuffer;
int gdi_scen_names[3]={
TXT_BONUS_MISSION_1,
TXT_BONUS_MISSION_2,
TXT_BONUS_MISSION_3
};
int nod_scen_names[2]={
TXT_BONUS_MISSION_4,
TXT_BONUS_MISSION_5
};
int index;
for (index = 60; index < 63; index++) {
char buffer[128];
CCFileClass file;
Set_Scenario_Name(buffer, index, SCEN_PLAYER_GDI, SCEN_DIR_EAST, SCEN_VAR_A);
strcat(buffer, ".INI");
file.Set_Name(buffer);
if (file.Is_Available()) {
memcpy (buffer, Text_String (gdi_scen_names[index-60]), 1+strlen(Text_String (gdi_scen_names[index-60])));
char * data = new char [strlen(buffer)+1+sizeof(int)+25];
*((int*)&data[0]) = index;
strcpy(&data[sizeof(int)], "GDI: ");
strcat(&data[sizeof(int)], buffer);
list.Add_Item(data);
}
}
for (index = 60; index < 62; index++) {
char buffer[128];
CCFileClass file;
Set_Scenario_Name(buffer, index, SCEN_PLAYER_NOD, SCEN_DIR_EAST, SCEN_VAR_A);
strcat(buffer, ".INI");
file.Set_Name(buffer);
if (file.Is_Available()) {
memcpy (buffer, Text_String (nod_scen_names[index-60]), 1+strlen(Text_String (nod_scen_names[index-60])));
char * data = new char [strlen(buffer)+1+sizeof(int)+25];
*((int*)&data[0]) = index;
strcpy(&data[sizeof(int)], "NOD: ");
strcat(&data[sizeof(int)], buffer);
list.Add_Item(data);
}
}
Set_Logic_Page(SeenBuff);
bool recalc = true;
bool display = true;
bool process = true;
bool okval = true;
while (process) {
Call_Back();
/*
** 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=TRUE;
}
if (display) {
display = false;
Hide_Mouse();
/*
** Load the background picture.
*/
Load_Title_Screen("HTITLE.PCX", &HidPage, Palette);
Blit_Hid_Page_To_Seen_Buff();
Dialog_Box(option_x, option_y, option_width, option_height);
Draw_Caption(TXT_BONUS_MISSIONS, option_x, option_y, option_width);
buttons->Draw_All();
Show_Mouse();
}
KeyNumType input = buttons->Input();
switch (input) {
case KN_RETURN:
case 200|KN_BUTTON:
if (list.Current_Item()[sizeof(int)] == 'G') {
ScenPlayer = SCEN_PLAYER_GDI;
} else {
ScenPlayer = SCEN_PLAYER_NOD;
}
ScenDir = SCEN_DIR_EAST;
Whom = HOUSE_GOOD;
Scenario = *(int *)list.Current_Item();
process = false;
okval = true;
break;
case KN_ESC:
case 201|KN_BUTTON:
ScenPlayer = SCEN_PLAYER_GDI;
ScenDir = SCEN_DIR_EAST;
Whom = HOUSE_GOOD;
Scenario = *(int *)list.Current_Item();
process = false;
okval = false;
break;
default:
break;
}
}
/*
** Free up the allocations for the text lines in the list box.
*/
for (index = 0; index < list.Count(); index++) {
delete [] (char *)list.Get_Item(index);
}
return(okval);
}
#endif

407
TIBERIANDAWN/EXTERNS.H Normal file
View File

@@ -0,0 +1,407 @@
//
// 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&c\vcs\code\externs.h_v 2.15 16 Oct 1995 16:45:34 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 : EXTERNS.H *
* *
* Programmer : Joe L. Bostic *
* *
* Start Date : May 27, 1994 *
* *
* Last Update : May 27, 1994 [JLB] *
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef EXTERNS_H
#define EXTERNS_H
#include "cell.h"
#ifdef SCENARIO_EDITOR
#include "mapedit.h"
#endif
#include "techno.h"
#include "type.h"
#include "building.h"
#include "unit.h"
#include "credits.h"
#include "goptions.h"
#include "options.h"
#include "infantry.H"
#ifdef JAPANESE
extern bool ForceEnglish;
#endif
extern bool Debug_Quiet;
extern bool Debug_Cheat;
extern bool Debug_Remap;
extern bool Debug_Flag;
extern bool Debug_Lose;
extern bool Debug_Map;
extern bool Debug_Win;
extern bool Debug_Icon;
extern bool Debug_Passable;
extern bool Debug_Unshroud;
extern bool Debug_Threat;
extern bool Debug_Find_Path;
extern bool Debug_Check_Map;
extern bool Debug_Playtest;
extern bool Debug_Heap_Dump;
extern bool Debug_Smart_Print;
extern bool Debug_Trap_Check_Heap;
extern bool Debug_Instant_Build;
extern bool Debug_Force_Crash;
extern void const *WarFactoryOverlay;
/*
** Dynamic global variables (these change or are initialized at run time).
*/
#ifdef PATCH
extern bool IsV107;
extern char OverridePath[128];
#endif
extern bool SlowPalette;
extern char VersionText[16];
extern bool ScoresPresent;
extern int CrateCount;
extern TCountDownTimerClass CrateTimer;
extern bool CrateMaker;
extern ThemeType TransitTheme;
extern bool AllowVoice;
extern NewConfigType NewConfig;
extern char BriefingText[512];
extern char IntroMovie[_MAX_FNAME+_MAX_EXT];
extern char ActionMovie[_MAX_FNAME+_MAX_EXT];
extern char BriefMovie[_MAX_FNAME+_MAX_EXT];
extern char WinMovie[_MAX_FNAME+_MAX_EXT];
extern char WinMovie2[_MAX_FNAME + _MAX_EXT];
extern char WinMovie3[_MAX_FNAME + _MAX_EXT];
extern char WinMovie4[_MAX_FNAME + _MAX_EXT];
extern char LoseMovie[_MAX_FNAME+_MAX_EXT];
extern char MovieThemeName[_MAX_FNAME + _MAX_EXT];
extern VoxType SpeakQueue;
extern bool PlayerWins;
extern bool PlayerLoses;
extern bool PlayerRestarts;
extern StructType SabotagedType;
extern bool TempleIoned;
extern long Frame;
extern void * SpeechBuffer;
extern int PreserveVQAScreen;
extern bool BreakoutAllowed;
extern bool Brokeout;
extern CELL Views[4];
extern GameOptionsClass Options;
extern LogicClass Logic;
#ifdef SCENARIO_EDITOR
extern MapEditClass Map;
#else
extern MouseClass Map;
#endif
extern ScoreClass Score;
extern MonoClass MonoArray[MonoClass::MAX_MONO_PAGES];
extern MixFileClass * ScoreMix;
extern MixFileClass * TheaterData;
extern MixFileClass * LowTheaterData;
extern MixFileClass * MoviesMix;
extern MixFileClass * GeneralMix;
extern ThemeClass Theme;
extern SpecialClass Special;
extern RulesClass Rule;
/*
** Game object allocation and tracking classes.
*/
extern TFixedIHeapClass<UnitClass> Units;
extern TFixedIHeapClass<FactoryClass> Factories;
extern TFixedIHeapClass<TerrainClass> Terrains;
extern TFixedIHeapClass<TemplateClass> Templates;
extern TFixedIHeapClass<SmudgeClass> Smudges;
extern TFixedIHeapClass<OverlayClass> Overlays;
extern TFixedIHeapClass<InfantryClass> Infantry;
extern TFixedIHeapClass<BulletClass> Bullets;
extern TFixedIHeapClass<BuildingClass> Buildings;
extern TFixedIHeapClass<AnimClass> Anims;
extern TFixedIHeapClass<AircraftClass> Aircraft;
extern TFixedIHeapClass<TriggerClass> Triggers;
extern TFixedIHeapClass<TeamTypeClass> TeamTypes;
extern TFixedIHeapClass<TeamClass> Teams;
extern TFixedIHeapClass<HouseClass> Houses;
extern QueueClass<EventClass, MAX_EVENTS> OutList;
extern QueueClass<EventClass, (MAX_EVENTS * 8)> DoList;
typedef DynamicVectorArrayClass<ObjectClass *, HOUSE_COUNT, HOUSE_FIRST> SelectedObjectsType;
extern SelectedObjectsType CurrentObject;
extern DynamicVectorClass<TriggerClass *> CellTriggers;
extern DynamicVectorClass<TriggerClass *> HouseTriggers[HOUSE_COUNT];
extern CELL Waypoint[WAYPT_COUNT];
extern BaseClass Base;
/*
** Loaded data file pointers.
*/
extern void const * Green12FontPtr;
extern void const * Green12GradFontPtr;
extern void const * MapFontPtr;
extern void const * VCRFontPtr;
extern void const * Font3Ptr;
extern void const * Font6Ptr;
extern void const * Font8Ptr;
extern void const * FontLEDPtr;
extern void const * ScoreFontPtr;
extern void const * GradFont6Ptr;
extern char const * SystemStrings;
/*
** Miscellaneous globals.
*/
extern HousesType Whom;
//extern _VQAConfig AnimControl;
extern long SpareTicks;
extern int MonoPage;
extern unsigned char * OriginalPalette;
extern int EndCountDown;
extern bool GameActive;
extern bool SpecialFlag;
extern int ScenarioInit;
extern long TutorFlags[2];
extern HouseClass * PlayerPtr;
extern unsigned char * BlackPalette;
extern unsigned char * WhitePalette;
extern unsigned char * GamePalette;
extern unsigned Scenario;
extern ScenarioPlayerType ScenPlayer;
extern ScenarioDirType ScenDir;
extern ScenarioVarType ScenVar;
extern int CarryOverMoney;
extern int CarryOverCap;
extern int CarryOverPercent;
extern char ScenarioName[_MAX_FNAME+_MAX_EXT];
extern unsigned BuildLevel;
extern unsigned long ScenarioCRC;
#ifdef SCENARIO_EDITOR
extern CELL CurrentCell;
#endif
extern GameType GameToPlay;
extern CommProtocolType CommProtocol;
extern CCFileClass RecordFile;
extern int RecordGame;
extern int SuperRecord;
extern int PlaybackGame;
extern int AllowAttract;
extern GetCDClass CDList;
/*
** Modem globals
*/
extern bool ModemService;
//extern NullModemClass NullModem;
//extern DynamicVectorClass<PhoneEntryClass *> PhoneBook;
extern int CurPhoneIdx;
extern DynamicVectorClass <char *> InitStrings;
extern SerialSettingsType SerialDefaults;
extern ModemGameType ModemGameToPlay;
extern char * DialMethodCheck[ DIAL_METHODS ];
extern char * CallWaitStrings[ CALL_WAIT_STRINGS_NUM ];
/*
** Network/Modem globals
*/
extern int ScenarioIdx;
extern int ColorUsed[];
extern char MPlayerName[MPLAYER_NAME_MAX];
extern int MPlayerGColors[];
extern int MPlayerTColors[];
extern char MPlayerDescriptions[100][40];
extern DynamicVectorClass <char *> MPlayerScenarios;
extern DynamicVectorClass <int> MPlayerFilenum;
extern int MPlayerMax;
extern int MPlayerPrefColor;
extern int MPlayerColorIdx;
extern HousesType MPlayerHouse;
extern unsigned char MPlayerLocalID;
extern int MPlayerCount;
extern int MPlayerBases;
extern int MPlayerCredits;
extern int MPlayerTiberium;
extern int MPlayerGoodies;
extern int MPlayerGhosts;
extern int MPlayerSolo;
extern int MPlayerUnitCount;
extern int MPlayerCountMin[2];
extern int MPlayerCountMax[2];
extern unsigned long MPlayerMaxAhead;
extern unsigned long FrameSendRate;
extern unsigned char MPlayerID[MAX_PLAYERS];
extern HousesType MPlayerHouses[MAX_PLAYERS];
extern char MPlayerNames [MAX_PLAYERS][MPLAYER_NAME_MAX];
extern MessageListClass Messages;
extern IPXAddressClass MessageAddress;
extern char LastMessage[MAX_MESSAGE_LENGTH];
extern int MPlayerBlitz;
extern int MPlayerObiWan;
extern MPlayerScoreType MPlayerScore[MAX_MULTI_NAMES];
extern int MPlayerGamesPlayed;
extern int MPlayerNumScores;
extern int MPlayerWinner;
extern int MPlayerCurGame;
extern int TheirProcessTime[MAX_PLAYERS - 1];
extern int DesiredFrameRate;
extern char * GlobalPacketNames[];
extern char * SerialPacketNames[];
typedef struct {
union {
AircraftClass *Aircraft;
AnimClass *Anim;
BuildingClass *Building;
BulletClass *Bullet;
InfantryClass *Infantry;
UnitClass *Unit;
void *All;
} Ptr;
} TrapObjectType;
extern long TrapFrame;
extern RTTIType TrapObjType;
extern TrapObjectType TrapObject;
extern COORDINATE TrapCoord;
extern void * TrapThis;
extern CellClass * TrapCell;
extern int TrapCheckHeap;
/*
** Network (IPX) globals
*/
extern IPXManagerClass Ipx;
extern int IsBridge;
extern IPXAddressClass BridgeNet;
extern bool NetMaster;
extern bool NetStealth;
extern bool NetProtect;
extern bool NetOpen;
extern char MPlayerGameName[MPLAYER_NAME_MAX];
extern GlobalPacketType GPacket;
extern int GPacketlen;
extern IPXAddressClass GAddress;
extern unsigned short GProductID;
extern char * MetaPacket;
extern int MetaSize;
extern DynamicVectorClass <NodeNameType *> Games;
extern DynamicVectorClass <NodeNameType *> Players;
extern int Seed;
extern long * RandSeedPtr;
extern int CustomSeed;
extern int NewMaxAheadFrame1;
extern int NewMaxAheadFrame2;
/*
** Constant externs (data is not modified during game play).
*/
extern unsigned char const RemapGreen[256];
extern unsigned char const RemapBlue[256];
extern unsigned char const RemapOrange[256];
extern unsigned char const RemapNone[256];
extern unsigned char const RemapGold[256];
extern unsigned char const RemapRed[256];
extern unsigned char const RemapLtBlue[256];
extern WeaponTypeClass const Weapons[WEAPON_COUNT];
extern WarheadTypeClass const Warheads[WARHEAD_COUNT];
extern char const * SourceName[SOURCE_COUNT];
extern GroundType const Ground[LAND_COUNT];
extern TheaterDataType const Theaters[THEATER_COUNT];
extern unsigned char const Facing32[256];
extern unsigned char const Facing8[256];
extern unsigned char const Pixel2Lepton[24];
extern COORDINATE const StoppingCoordAbs[5];
extern CELL const AdjacentCell[FACING_COUNT];
extern COORDINATE const AdjacentCoord[FACING_COUNT];
extern int SoundOn;
//extern GraphicBufferClass SeenPage;
extern GraphicBufferClass VisiblePage;
extern GraphicBufferClass HiddenPage;
extern GraphicViewPortClass SeenBuff;
extern GraphicBufferClass ModeXBuff;
extern GraphicViewPortClass HidPage;
extern GraphicBufferClass LoResHidPage;
extern GraphicBufferClass SysMemPage;
extern int MenuList[][8];
extern CountDownTimerClass FrameTimer;
extern CountDownTimerClass CountDownTimer;
extern TimerClass ProcessTimer;
extern int ProcessTicks;
extern int ProcessFrames;
extern SpecialDialogType SpecialDialog;
//extern bool IsFindPath;
extern char *DebugFname; // for stoopid debugging purposes
extern int DebugLine; // for stoopid debugging purposes
extern int RequiredCD;
extern int MouseInstalled;
extern int AreThingiesEnabled;
extern WWKeyboardClass Kbd;
extern int In_Debugger;
extern WWMouseClass *WWMouse;
extern HANDLE hInstance;
extern int AllDone;
extern "C" bool MMXAvailable;
extern int Get_CD_Index (int cd_drive, int timeout);
void Memory_Error_Handler(void);
extern bool GameStatisticsPacketSent;
extern bool ConnectionLost;
extern bool InMainLoop; // True if in game state rather than menu state
void CCDebugString (char *string);
extern void *PacketLater;
void Load_Title_Screen(char *name, GraphicViewPortClass *video_page, unsigned char *palette);
extern "C"{
extern bool IsTheaterShape;
}
extern void Reset_Theater_Shapes(void);
extern TheaterType LastTheater;
extern bool ShareAllyVisibility;
#endif

180
TIBERIANDAWN/FACING.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: F:\projects\c&c\vcs\code\facing.cpv 1.9 16 Oct 1995 16:49:40 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 : FACING.CPP *
* *
* Programmer : Joe L. Bostic *
* *
* Start Date : 03/21/95 *
* *
* Last Update : March 21, 1995 [JLB] *
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* FacingClass::Rotation_Adjust -- Perform a rotation adjustment to current facing. *
* FacingClass::Set_Current -- Sets the current rotation value. *
* FacingClass::Set_Desired -- Sets the desired facing value. *
* FacingClass::FacingClass -- Default constructor for the facing class. *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "function.h"
#include "facing.h"
/***********************************************************************************************
* FacingClass::FacingClass -- Default constructor for the facing class. *
* *
* This default constructor merely sets the desired and current facing values to be the *
* same (North). *
* *
* INPUT: none *
* *
* OUTPUT: none *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 03/21/1995 JLB : Created. *
*=============================================================================================*/
FacingClass::FacingClass(void)
{
CurrentFacing = DIR_N;
DesiredFacing = DIR_N;
}
/***********************************************************************************************
* FacingClass::Set_Desired -- Sets the desired facing value. *
* *
* This routine is used to set the desired facing value without altering the current *
* facing setting. Typicall use of this routine is when a vehicle needs to face a *
* direction, but currently isn't facing the correct direction. After this routine is *
* called, it is presumed that subsequent calls to Rotation_Adjust() will result in the *
* eventual alignment of the current facing. *
* *
* INPUT: facing -- The new facing to assign to the desired value. *
* *
* OUTPUT: bool; Did the desired facing value actually change by this routine call? *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 03/21/1995 JLB : Created. *
*=============================================================================================*/
int FacingClass::Set_Desired(DirType facing)
{
if (DesiredFacing != facing) {
DesiredFacing = facing;
return(true);
}
return(false);
}
/***********************************************************************************************
* FacingClass::Set_Current -- Sets the current rotation value. *
* *
* This routine will set the current rotation value. It is used to override the facing *
* value without adjusting the desired setting. *
* *
* INPUT: facing -- The new facing to assign to the current facing value. *
* *
* OUTPUT: bool; Was the current setting changed by this routine. Failure means that the *
* current setting was already at the value specified. *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 03/21/1995 JLB : Created. *
*=============================================================================================*/
int FacingClass::Set_Current(DirType facing)
{
if (CurrentFacing != facing) {
CurrentFacing = facing;
return(true);
}
return(false);
}
/***********************************************************************************************
* FacingClass::Rotation_Adjust -- Perform a rotation adjustment to current facing. *
* *
* This routine is used when the current and desired facings differ but the current *
* facing should be adjusted toward the desired facing. The amount of rotation to adjust *
* is provided as a rotation rate parameter. Typical use of this routine is for turrets *
* and other vehicle related rotating. *
* *
* INPUT: rate -- The rotation rate to use when adjusting the current facing toward the *
* desired facing. A value of 127 means instantaneous rotation. *
* *
* OUTPUT: bool; Did the rotation result in the current facing transitioning from one *
* 1/32 zone to another? If true, then the owning object most likely will *
* need to be redrawn to reflect the change. *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 03/21/1995 JLB : Created. *
*=============================================================================================*/
int FacingClass::Rotation_Adjust(int rate)
{
/*
** Only perform the rotation adjustment if the desired facing is not the
** same as the current facing.
*/
if (Is_Rotating()) {
rate = MIN(rate, 127);
DirType oldfacing = CurrentFacing;
int diff = Difference();
/*
** If the allowed facing change is greater than the difference between
** the current facing and the desired facing, then just snap the
** facing to the new value.
*/
if (ABS(diff) < rate) {
CurrentFacing = DesiredFacing;
} else {
/*
** Adjust the current facing clockwise or counterclockwise depending
** on the shortest distance to the desired facing from the current
** facing.
*/
if (diff < 0) {
CurrentFacing = (DirType)(CurrentFacing - (DirType)rate);
} else {
CurrentFacing = (DirType)(CurrentFacing + (DirType)rate);
}
}
/*
** If this facing adjustment caused the current facing to rotate into a
** new 1/32 rotation zone (likely to cause a redraw), then return
** this fact with a true value.
*/
return(Facing_To_32(CurrentFacing) != Facing_To_32(oldfacing));
}
return(false);
}

76
TIBERIANDAWN/FACING.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: F:\projects\c&c\vcs\code\facing.h_v 1.14 16 Oct 1995 16:46: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 : FACING.H *
* *
* Programmer : Joe L. Bostic *
* *
* Start Date : 03/21/95 *
* *
* Last Update : March 21, 1995 [JLB] *
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef FACING_H
#define FACING_H
/*
** This is a general facing handler class. It is used in those cases where facing needs to be
** kept track of, but there could also be an associated desired facing. The current facing
** is supposed to transition to the desired state over time. Using this class facilitates this
** processing as well as isolating the rest of the code from the internals.
*/
class FacingClass
{
public:
FacingClass(void);
FacingClass(DirType dir) {CurrentFacing = DesiredFacing = dir;};
operator DirType(void) const {return CurrentFacing;};
DirType Current(void) const {return CurrentFacing;};
DirType Desired(void) const {return DesiredFacing;};
int Set_Desired(DirType facing);
int Set_Current(DirType facing);
void Set(DirType facing) {
Set_Current(facing);
Set_Desired(facing);
};
DirType Get(void) const { return CurrentFacing; }
int Is_Rotating(void) const {return (DesiredFacing != CurrentFacing);};
int Difference(void) const {return (signed char)(*((unsigned char*)&DesiredFacing) - *((unsigned char*)&CurrentFacing));};
int Difference(DirType facing) const {return (signed char)(*((signed char*)&facing) - *((signed char*)&CurrentFacing));};
int Rotation_Adjust(int rate);
private:
DirType CurrentFacing;
DirType DesiredFacing;
};
#endif

785
TIBERIANDAWN/FACTORY.CPP Normal file
View File

@@ -0,0 +1,785 @@
//
// 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&c\vcs\code\factory.cpv 2.18 16 Oct 1995 16:51:26 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 : FACTORY.CPP *
* *
* Programmer : Joe L. Bostic *
* *
* Start Date : 12/26/94 *
* *
* Last Update : May 22, 1995 [JLB] *
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* FactoryClass::AI -- Process factory production logic. *
* FactoryClass::Abandon -- Abandons current construction with money refunded. *
* FactoryClass::Completed -- Clears factory object after a completed production process. *
* FactoryClass::Completion -- Fetchs the completion step for this factory. *
* FactoryClass::Cost_Per_Tick -- Breaks entire production cost into managable chunks. *
* FactoryClass::FactoryClass -- Default constructor for factory objects. *
* FactoryClass::Get_Object -- Fetches pointer to object being constructed. *
* FactoryClass::Get_Special_Item -- gets factorys spc prod item *
* FactoryClass::Has_Changed -- Checks to see if a production step has occurred? *
* FactoryClass::Has_Completed -- Checks to see if object has completed production. *
* FactoryClass::Set -- Assigns a factory to produce an object. *
* FactoryClass::Set -- Fills a factory with an already completed object. *
* FactoryClass::Set -- Force factory to "produce" special object. *
* FactoryClass::Start -- Resumes production after suspension or creation. *
* FactoryClass::Suspend -- Temporarily stop production. *
* FactoryClass::operator delete -- Returns a factory to the free factory pool. *
* FactoryClass::operator new -- Allocates a factory object from the free factory pool. *
* FactoryClass::~FactoryClass -- Default destructor for factory objects. *
* FactoryClass::Validate -- validates factory pointer *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "function.h"
/***********************************************************************************************
* FactoryClass::Validate -- validates factory pointer *
* *
* INPUT: *
* none. *
* *
* OUTPUT: *
* 1 = ok, 0 = error *
* *
* WARNINGS: *
* none. *
* *
* HISTORY: *
* 08/09/1995 BRR : Created. *
*=============================================================================================*/
#ifdef CHEAT_KEYS
int FactoryClass::Validate(void) const
{
int num;
num = Factories.ID(this);
if (num < 0 || num >= FACTORY_MAX) {
Validate_Error("FACTORY");
return (0);
}
else
return (1);
}
#else
#define Validate()
#endif
/***********************************************************************************************
* FactoryClass::FactoryClass -- Default constructor for factory objects. *
* *
* This brings the factory into a null state. It is called when a factory object is *
* created. *
* *
* INPUT: none *
* *
* OUTPUT: none *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 12/26/1994 JLB : Created. *
*=============================================================================================*/
FactoryClass::FactoryClass(void)
{
IsSuspended = false;
IsDifferent = false;
IsBlocked = false;
Balance = 0;
SpecialItem = SPC_NONE;
Object = NULL;
House = NULL;
Set_Rate(0);
Set_Stage(0);
}
/***********************************************************************************************
* FactoryClass::~FactoryClass -- Default destructor for factory objects. *
* *
* This cleans up a factory object in preparation for deletion. If there is currently *
* an object in production, it is abandoned and money is refunded. *
* *
* INPUT: none *
* *
* OUTPUT: none *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 12/26/1994 JLB : Created. *
*=============================================================================================*/
FactoryClass::~FactoryClass(void)
{
if (GameActive) {
Abandon();
}
}
/***********************************************************************************************
* FactoryClass::Init -- Clears all units for scenario preparation. *
* *
* This routine will zero out the factory list and objects. This routine is typically *
* used in preparation for a new scenario load. All factorys are guaranteed to be eliminated*
* by this routine. *
* *
* INPUT: none *
* *
* OUTPUT: none *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 08/15/1994 JLB : Created. *
*=============================================================================================*/
void FactoryClass::Init(void)
{
Factories.Free_All();
}
/***********************************************************************************************
* FactoryClass::operator new -- Allocates a factory object from the free factory pool. *
* *
* This routine allocates a factory from the free factory pool. If there is no more room *
* to allocate a factory, then NULL is returned. *
* *
* INPUT: none *
* *
* OUTPUT: Returns with pointer to the newly allocated factory object. *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 12/26/1994 JLB : Created. *
*=============================================================================================*/
void * FactoryClass::operator new(size_t)
{
void * ptr = Factories.Allocate();
if (ptr) {
((FactoryClass *)ptr)->IsActive = true;
}
return(ptr);
}
/***********************************************************************************************
* FactoryClass::operator delete -- Returns a factory to the free factory pool. *
* *
* This returns the factory object back to the factory allocation pool. The factory is then *
* available to be allocated. *
* *
* INPUT: ptr -- Pointer to the factory object to delete. *
* *
* OUTPUT: none *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 12/26/1994 JLB : Created. *
*=============================================================================================*/
void FactoryClass::operator delete(void *ptr)
{
if (ptr) {
((FactoryClass *)ptr)->IsActive = false;
}
Factories.Free((FactoryClass *)ptr);
}
/***********************************************************************************************
* FactoryClass::AI -- Process factory production logic. *
* *
* This routine should be called once per game tick. It handles the production process. *
* As production proceeds, money is deducted from the owner object's house. When production *
* completes, the factory stop processing. A call to Abandon, Delete, or Completed is *
* required after that point. *
* *
* INPUT: none *
* *
* OUTPUT: none *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 12/26/1994 JLB : Created. *
* 01/04/1995 JLB : Uses exact installment payment method. *
*=============================================================================================*/
void FactoryClass::AI(void)
{
Validate();
if (!IsSuspended && (Object != NULL || SpecialItem)) {
int stages = 1;
/*
** Determine the acceleration factor for factory production.
** This applies only to human players. The computer builds
** units on a building by building basis -- quantity of building
** factory types doesn't affect individual factories.
*/
if (Object && House->IsHuman) {
switch (Object->What_Am_I()) {
case RTTI_AIRCRAFT:
stages = House->AircraftFactories;
break;
case RTTI_INFANTRY:
stages = House->InfantryFactories;
break;
case RTTI_UNIT:
stages = House->UnitFactories;
break;
case RTTI_BUILDING:
stages = House->BuildingFactories;
break;
}
stages = MAX(stages, 1);
}
for (int index = 0; index < stages; index++) {
if (!Has_Completed() && Graphic_Logic()) {
IsDifferent = true;
int cost = Cost_Per_Tick();
cost = MIN(cost, Balance);
/*
** Enough time has expired so that another production step can occur.
** If there is insufficient funds, then go back one production step and
** continue the countdown. The idea being that by the time the next
** production step occurs, there may be sufficient funds available.
*/
if (cost > House->Available_Money()) {
Set_Stage(Fetch_Stage()-1);
} else {
House->Spend_Money(cost);
Balance -= cost;
}
if ( Debug_Instant_Build ) {
Set_Stage(STEP_COUNT);
}
/*
** If the production has completed, then suspend further production.
*/
if (Fetch_Stage() == STEP_COUNT) {
IsSuspended = true;
Set_Rate(0);
House->Spend_Money(Balance);
Balance = 0;
}
}
}
}
}
/***********************************************************************************************
* FactoryClass::Force_Complete -- Force the factory to finish what it's building *
* *
* For debugging/testing support *
* *
* *
* INPUT: none *
* *
* OUTPUT: none *
* *
* WARNINGS: *
* *
* HISTORY: *
* 8/23/2019 3:54PM ST : Created. *
*=============================================================================================*/
void FactoryClass::Force_Complete(void)
{
Validate();
if (!IsSuspended && (Object != NULL || SpecialItem)) {
Set_Stage(STEP_COUNT);
IsSuspended = true;
Set_Rate(0);
Balance = 0;
IsDifferent = true;
}
}
/***********************************************************************************************
* FactoryClass::Has_Changed -- Checks to see if a production step has occurred? *
* *
* Use this routine to determine if production has advanced at least one step. By using *
* this function, intelligent rendering may be performed. *
* *
* INPUT: none *
* *
* OUTPUT: bool; Has the production process advanced one step since the last time this *
* function was called? *
* *
* WARNINGS: This function clears the changed status flag as a side effect. *
* *
* HISTORY: *
* 12/26/1994 JLB : Created. *
*=============================================================================================*/
bool FactoryClass::Has_Changed(void)
{
Validate();
bool changed = IsDifferent;
IsDifferent = false;
return(changed);
}
/***********************************************************************************************
* FactoryClass::Set -- Assigns a factory to produce an object. *
* *
* This routine initializes a factory to produce the object specified. The desired object *
* type is created and placed in suspended animation (limbo) until such time as production *
* completes. Production is not actually started by this routine. An explicit call to *
* Start() is required to begin production. *
* *
* INPUT: object -- Reference to the object type class that is to be produced. *
* *
* house -- Reference to the owner of the object to be produced. *
* *
* OUTPUT: bool; Was production successfully prepared for this factory object. Failure means *
* that the object could not be created. This is catastrophic and in such *
* cases, the factory object should be deleted. *
* *
* WARNINGS: Be sure to examine the return value from this function. Failure to initialize *
* the factory means that the factory is useless and should be deleted. *
* *
* HISTORY: *
* 12/26/1994 JLB : Created. *
*=============================================================================================*/
bool FactoryClass::Set(TechnoTypeClass const & object, HouseClass & house)
{
Validate();
/*
** If there is any production currently in progress, abandon it.
*/
Abandon();
/*
** Set up the factory for the new production process.
*/
IsDifferent = true;
IsSuspended = true;
Set_Rate(0);
Set_Stage(0);
/*
** Create an object of the type requested.
*/
Object = (TechnoClass *)object.Create_One_Of(&house);
if (Object) {
House = Object->House;
Balance = object.Cost_Of() * house.CostBias;
Object->PurchasePrice = Balance;
}
/*
** If all was set up successfully, then return true.
*/
return(Object != NULL);
}
/***********************************************************************************************
* FactoryClass::Set -- Force factory to "produce" special object. *
* *
* Use this routine to force the factory into special production mode. Such production is *
* used for the ion cannon and other timed special weapon events. *
* *
* INPUT: type -- The special weapon type to begin "production" of. *
* *
* house -- The owner of this production object. *
* *
* OUTPUT: Was the assignment successful? *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 05/22/1995 JLB : Created. *
*=============================================================================================*/
bool FactoryClass::Set(int const & type, HouseClass & house)
{
Validate();
/*
** If there is any production currently in progress, abandon it.
*/
Abandon();
/*
** Set up the factory for the new production process.
*/
IsDifferent = true;
IsSuspended = true;
Set_Rate(0);
Set_Stage(0);
/*
** Create an object of the type requested.
*/
SpecialItem = type;
House = &house;
Balance = 0;
/*
** If all was set up successfully, then return true.
*/
return(SpecialItem != SPC_NONE);
}
/***********************************************************************************************
* FactoryClass::Set -- Fills a factory with an already completed object. *
* *
* This routine is called when a produced object is in placement mode but then placement *
* is suspended. The object must then return to the factory as if it were newly completed *
* and awaiting removal. *
* *
* INPUT: object -- The object to return to the factory. *
* *
* OUTPUT: none *
* *
* WARNINGS: This will abandon any current object being produced at the factory in order *
* to set the new object into it. *
* *
* HISTORY: *
* 12/26/1994 JLB : Created. *
*=============================================================================================*/
void FactoryClass::Set(TechnoClass & object)
{
Validate();
Abandon();
Object = &object;
House = Object->House;
Balance = 0;
Set_Rate(0);
Set_Stage(STEP_COUNT);
IsDifferent = true;
IsSuspended = true;
}
/***********************************************************************************************
* FactoryClass::Suspend -- Temporarily stop production. *
* *
* This routine will suspend production until a subsiquent call to Start() or Abandon(). *
* Typical use of this function is when the player puts production on hold or when there *
* is insufficient funds. *
* *
* INPUT: none *
* *
* OUTPUT: bool; Was production actually stopped? A false return value indicates that the *
* factory was empty or production was already stopped (or never started). *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 12/26/1994 JLB : Created. *
*=============================================================================================*/
bool FactoryClass::Suspend(void)
{
Validate();
if (!IsSuspended) {
IsSuspended = true;
Set_Rate(0);
return(true);
}
return(false);
}
/***********************************************************************************************
* FactoryClass::Start -- Resumes production after suspension or creation. *
* *
* This function will start the production process. It works for newly created factory *
* objects, as well as if production had been suspended previously. *
* *
* INPUT: none *
* *
* OUTPUT: bool; Was production started? A false return value means that the factory is *
* empty or there is unsufficient credits to begin production. *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 12/26/1994 JLB : Created. *
*=============================================================================================*/
bool FactoryClass::Start(void)
{
Validate();
if ((Object || SpecialItem) && IsSuspended && !Has_Completed()) {
if (House->IsHuman || House->Available_Money() >= Cost_Per_Tick()) {
int time;
if (Object) {
time = Object->Class_Of().Time_To_Build(House->Class->House);
} else {
time = TICKS_PER_MINUTE * 5;
}
/*
** Adjust time according to IQ setting of computer controlled house. The
** build time will range from double normal time at the slowest to
** just normal time at the fastest.
*/
if (!House->IsHuman && Rule.Diff[House->Difficulty].IsBuildSlowdown) {
time = (int)((time*Rule.MaxIQ*2.0f) / (House->IQ+Rule.MaxIQ));
}
int frac = House->Power_Fraction();
frac = Bound(frac, 0x0010, 0x0100);
int rate = (time*256) / frac;
rate /= STEP_COUNT;
rate = Bound(rate, 1, 255);
Set_Rate(rate);
IsSuspended = false;
return(true);
}
}
return(false);
}
/***********************************************************************************************
* FactoryClass::Abandon -- Abandons current construction with money refunded. *
* *
* This routine is used when construction is to be abandoned and current money spend is *
* to be refunded. This function effectively clears out this factory of all record of the *
* producing object so that it may either be deleted or started anew with the Set() *
* function. *
* *
* INPUT: none *
* *
* OUTPUT: bool; Was an object actually abandoned? A false return value indicates that the *
* factory was not producing any object. *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 12/26/1994 JLB : Created. *
*=============================================================================================*/
bool FactoryClass::Abandon(void)
{
Validate();
if (Object) {
if (Object) {
/*
** Refund all money expended so far, back to the owner of the object under construction.
*/
int money = Object->Class_Of().Cost_Of() * Object->House->CostBias;
House->Refund_Money(money - Balance);
Balance = 0;
/*
** Delete the object under construction.
*/
ScenarioInit++;
delete Object;
Object = NULL;
ScenarioInit--;
}
if (SpecialItem) {
SpecialItem = SPC_NONE;
}
/*
** Set the factory back to the idle and empty state.
*/
Set_Rate(0);
Set_Stage(0);
IsSuspended = true;
IsDifferent = true;
return(true);
}
return(false);
}
/***********************************************************************************************
* FactoryClass::Completion -- Fetchs the completion step for this factory. *
* *
* Use this routine to determine what animation (or completion step) the factory is *
* currently on. *
* *
* INPUT: none *
* *
* OUTPUT: Returns a completion step number beteen 0 (uncompleted), to STEP_COUNT (completed) *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 12/26/1994 JLB : Created. *
*=============================================================================================*/
int FactoryClass::Completion(void)
{
Validate();
return(Fetch_Stage());
}
/***********************************************************************************************
* FactoryClass::Has_Completed -- Checks to see if object has completed production. *
* *
* Use this routine to examine the factory object in order to determine if the associated *
* object has completed production and is awaiting placement. *
* *
* INPUT: none *
* *
* OUTPUT: bool; Is the associated object to the factory completed and ready for placement? *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 12/26/1994 JLB : Created. *
*=============================================================================================*/
bool FactoryClass::Has_Completed(void)
{
Validate();
if (Object && Fetch_Stage() == STEP_COUNT) {
return(true);
}
if (SpecialItem && Fetch_Stage() == STEP_COUNT) {
return(true);
}
return(false);
}
/***********************************************************************************************
* FactoryClass::Get_Object -- Fetches pointer to object being constructed. *
* *
* This routine gets the pointer to the currently constructing object. *
* *
* INPUT: none *
* *
* OUTPUT: Returns with a pointer to the object undergoing construction. *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 12/26/1994 JLB : Created. *
*=============================================================================================*/
TechnoClass * FactoryClass::Get_Object(void) const
{
Validate();
return(Object);
}
/***************************************************************************
* FactoryClass::Get_Special_Item -- gets factorys spc prod item *
* *
* INPUT: none *
* *
* OUTPUT: int the item the factory is currently working on *
* *
* HISTORY: *
* 05/05/1995 PWG : Created. *
*=========================================================================*/
int FactoryClass::Get_Special_Item(void) const
{
Validate();
return(SpecialItem);
}
/***********************************************************************************************
* FactoryClass::Cost_Per_Tick -- Breaks entire production cost into managable chunks. *
* *
* Use this routine to determine the cost per game "tick" to produce the object. *
* *
* INPUT: none *
* *
* OUTPUT: Returns the number of credits necessary to advance production one game tick. *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 12/26/1994 JLB : Created. *
*=============================================================================================*/
int FactoryClass::Cost_Per_Tick(void)
{
Validate();
if (Object) {
int steps = STEP_COUNT - Fetch_Stage();
if (steps) {
return(Balance / steps);
}
return(Balance);
}
return(0);
}
/***********************************************************************************************
* FactoryClass::Completed -- Clears factory object after a completed production process. *
* *
* This routine is called after production completes, and the object produced has been *
* placed into the game. It resets the factory for deletion or starting of new production. *
* *
* INPUT: none *
* *
* OUTPUT: bool; Did any resetting occur? Failure is the result of the factory not having *
* any completed object. An immediate second call to this routine will also *
* yield false. *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 12/26/1994 JLB : Created. *
*=============================================================================================*/
bool FactoryClass::Completed(void)
{
Validate();
if (Object && Fetch_Stage() == STEP_COUNT) {
Object = NULL;
IsSuspended = true;
IsDifferent = true;
Set_Stage(0);
Set_Rate(0);
return(true);
}
if (SpecialItem && Fetch_Stage() == STEP_COUNT) {
SpecialItem = SPC_NONE;
IsSuspended = true;
IsDifferent = true;
Set_Stage(0);
Set_Rate(0);
return(true);
}
return(false);
}

161
TIBERIANDAWN/FACTORY.H Normal file
View File

@@ -0,0 +1,161 @@
//
// 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&c\vcs\code\factory.h_v 2.17 16 Oct 1995 16:45:44 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 : FACTORY.H *
* *
* Programmer : Joe L. Bostic *
* *
* Start Date : 12/26/94 *
* *
* Last Update : December 26, 1994 [JLB] *
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef FACTORY_H
#define FACTORY_H
#include "stage.h"
class FactoryClass : private StageClass
{
friend class DLLExportClass; // ST - 1/29/2019 11:04AM
public:
FactoryClass(void);
~FactoryClass(void);
static void * operator new(size_t size);
static void operator delete(void *ptr);
static void Init(void);
/*
** File I/O.
*/
bool Load(FileClass & file);
bool Save(FileClass & file);
void Code_Pointers(void);
void Decode_Pointers(void);
bool Abandon(void);
bool Completed(void);
bool Has_Changed(void);
bool Has_Completed(void);
bool Is_Building(void) const {return(Fetch_Rate() != 0);};
bool Set(TechnoTypeClass const & object, HouseClass & house);
bool Set(int const & type, HouseClass & house);
bool Start(void);
bool Suspend(void);
int Completion(void);
TechnoClass * Get_Object(void) const;
int Get_Special_Item(void) const;
void AI(void);
void Set(TechnoClass & object);
HouseClass * Get_House(void) {return(House);};
bool Is_Blocked(void) {return IsBlocked;}
void Set_Is_Blocked(bool set) {IsBlocked = set;}
/*
** Dee-buggin' support.
*/
int Validate(void) const;
/*
** Added for debugging / testing. ST - 8/23/2019 3:52PM
*/
void Force_Complete(void);
/*
** This flag is used to maintain the pool of factory class objects. If the object has
** been allocated, then this flag is true. Otherwise, the object is free to be
** allocated.
*/
unsigned IsActive:1;
protected:
enum StepCountEnum {
STEP_COUNT=108 // Number of steps to break production down into.
};
int Cost_Per_Tick(void);
private:
/*
** If production is temporarily suspended, then this flag will be true. A factory
** is suspended when it is first created, when production has completed, and when
** explicitly instructed to Suspend() production. Suspended production is not
** abandoned. It may be resumed with a call to Start().
*/
unsigned IsSuspended:1;
/*
** If the AI process detected that the production process has advanced far enough
** that a change in the building animation would occur, this flag will be true.
** Examination of this flag (through the Has_Chaged function) allows intelligent
** updating of any production graphic.
*/
unsigned IsDifferent:1;
/*
** The exit from the factory is blocked by something, which means a unit is prevented from exiting after construction
** has completed. ST - 2/25/2020 11:29AM
*/
unsigned IsBlocked:1;
/*
** This records the balance due on the current production item. This value will
** be reduced as production proceeds. It will reach zero the moment production has
** finished. Using this method ensures that the total production cost will be EXACT
** regardless of the number of installment payments that are made.
*/
int Balance;
int OriginalBalance;
/*
** This is the object that is being produced. It is held in a state of limbo while
** undergoing production. Since the object is created at the time production is
** started, it is always available when production completes.
*/
TechnoClass * Object;
/*
** If the factory is not producing an object and is instead producing
** a special item, then special item will be set.
*/
int SpecialItem;
/*
** The factory has to be doing production for one house or another.
** The house pointer will point to whichever house it is being done
** for.
*/
HouseClass * House;
/*
** 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

213
TIBERIANDAWN/FIELD.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
/***************************************************************************
* *
* Project Name : Westwood Auto Registration App *
* *
* File Name : FIELD.CPP *
* *
* Programmer : Philip W. Gorrow *
* *
* Start Date : 04/22/96 *
* *
* Last Update : April 22, 1996 [PWG] *
* *
* Actual member function for the field class. *
*-------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include <string.h>
#include "field.h"
// ST - 12/18/2018 10:14AM
#pragma warning(disable:4996)
FieldClass::FieldClass(char *id, char data)
{
strncpy(ID, id, sizeof(ID));
DataType = TYPE_CHAR;
Size = sizeof(data);
Data = new char[Size];
memcpy(Data, &data, Size);
Next = NULL;
}
FieldClass::FieldClass(char *id, unsigned char data)
{
strncpy(ID, id, sizeof(ID));
DataType = TYPE_UNSIGNED_CHAR;
Size = sizeof(data);
Data = new char[Size];
memcpy(Data, &data, Size);
Next = NULL;
}
FieldClass::FieldClass(char *id, short data)
{
strncpy(ID, id, sizeof(ID));
DataType = TYPE_SHORT;
Size = sizeof(data);
Data = new char[Size];
memcpy(Data, &data, Size);
Next = NULL;
}
FieldClass::FieldClass(char *id, unsigned short data)
{
strncpy(ID, id, sizeof(ID));
DataType = TYPE_UNSIGNED_SHORT;
Size = sizeof(data);
Data = new char[Size];
memcpy(Data, &data, Size);
Next = NULL;
}
FieldClass::FieldClass(char *id, long data)
{
strncpy(ID, id, sizeof(ID));
DataType = TYPE_LONG;
Size = sizeof(data);
Data = new char[Size];
memcpy(Data, &data, Size);
Next = NULL;
}
FieldClass::FieldClass(char *id, unsigned long data)
{
strncpy(ID, id, sizeof(ID));
DataType = TYPE_UNSIGNED_LONG;
Size = sizeof(data);
Data = new char[Size];
memcpy(Data, &data, Size);
Next = NULL;
}
FieldClass::FieldClass(char *id, char *data)
{
strncpy(ID, id, sizeof(ID));
DataType = TYPE_STRING;
Size = (unsigned short)(strlen(data)+1);
Data = new char[Size];
memcpy(Data, data, Size);
Next = NULL;
}
FieldClass::FieldClass(char *id, void *data, int length)
{
strncpy(ID, id, sizeof(ID));
DataType = TYPE_CHUNK;
Size = (unsigned short)length;
Data = new char[Size];
memcpy(Data, data, Size);
Next = NULL;
}
/**************************************************************************
* PACKETCLASS::HOST_TO_NET_FIELD -- Converts host field to net format *
* *
* INPUT: FIELD * to the data field we need to convert *
* *
* OUTPUT: none *
* *
* HISTORY: *
* 04/22/1996 PWG : Created. *
*========================================================================*/
void FieldClass::Host_To_Net(void)
{
//
// Before we convert the data type, we should convert the actual data
// sent.
//
switch (DataType) {
case TYPE_CHAR:
case TYPE_UNSIGNED_CHAR:
case TYPE_STRING:
case TYPE_CHUNK:
break;
case TYPE_SHORT:
case TYPE_UNSIGNED_SHORT:
*((unsigned short *)Data) = htons(*((unsigned short *)Data));
break;
case TYPE_LONG:
case TYPE_UNSIGNED_LONG:
*((unsigned long *)Data) = htonl(*((unsigned long *)Data));
break;
//
// Might be good to insert some type of error message here for unknown
// datatypes -- but will leave that for later.
//
default:
break;
}
//
// Finally convert over the data type and the size of the packet.
//
DataType = htons(DataType);
Size = htons(Size);
}
/**************************************************************************
* PACKETCLASS::NET_TO_HOST_FIELD -- Converts net field to host format *
* *
* INPUT: FIELD * to the data field we need to convert *
* *
* OUTPUT: none *
* *
* HISTORY: *
* 04/22/1996 PWG : Created. *
*========================================================================*/
void FieldClass::Net_To_Host(void)
{
//
// Convert the variables to host order. This needs to be converted so
// the switch statement does compares on the data that follows.
//
Size = ntohs(Size);
DataType = ntohs(DataType);
//
// Before we convert the data type, we should convert the actual data
// sent.
//
switch (DataType) {
case TYPE_CHAR:
case TYPE_UNSIGNED_CHAR:
case TYPE_STRING:
case TYPE_CHUNK:
break;
case TYPE_SHORT:
case TYPE_UNSIGNED_SHORT:
*((unsigned short *)Data) = ntohs(*((unsigned short *)Data));
break;
case TYPE_LONG:
case TYPE_UNSIGNED_LONG:
*((unsigned long *)Data) = ntohl(*((unsigned long *)Data));
break;
//
// Might be good to insert some type of error message here for unknown
// datatypes -- but will leave that for later.
//
default:
break;
}
}

82
TIBERIANDAWN/FIELD.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
/***************************************************************************
* *
* Project Name : Westwood Auto Registration App *
* *
* File Name : FIELD.H *
* *
* Programmer : Philip W. Gorrow *
* *
* Start Date : 04/22/96 *
* *
* Last Update : April 22, 1996 [PWG] *
* *
* This module takes care of maintaining the field list used to process *
* packets. *
* *
*-------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef __FIELD_H
#define __FIELD_H
#include <windows.h>
#include <winsock.h>
#define FIELD_HEADER_SIZE (sizeof(FieldClass) - (sizeof(void *) * 2))
#define TYPE_CHAR 1
#define TYPE_UNSIGNED_CHAR 2
#define TYPE_SHORT 3
#define TYPE_UNSIGNED_SHORT 4
#define TYPE_LONG 5
#define TYPE_UNSIGNED_LONG 6
#define TYPE_STRING 7
#define TYPE_CHUNK 20
class PacketClass;
class FieldClass {
public:
friend class PacketClass;
//
// Define constructors to be able to create all the different kinds
// of fields.
//
FieldClass(void) {};
FieldClass(char *id, char data);
FieldClass(char *id, unsigned char data);
FieldClass(char *id, short data);
FieldClass(char *id, unsigned short data);
FieldClass(char *id, long data);
FieldClass(char *id, unsigned long data);
FieldClass(char *id, char *data);
FieldClass(char *id, void *data, int length);
void Host_To_Net(void);
void Net_To_Host(void);
private:
char ID[4]; // id value of this field
unsigned short DataType; // id of the data type we are using
unsigned short Size; // size of the data portion of this field
void *Data; // pointer to the data portion of this field
FieldClass *Next; // pointer to the next field in the field list
};
#endif

1543
TIBERIANDAWN/FINDPATH.CPP Normal file

File diff suppressed because it is too large Load Diff

129
TIBERIANDAWN/FLASHER.CPP Normal file
View File

@@ -0,0 +1,129 @@
//
// 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&c\vcs\code\flasher.cpv 2.18 16 Oct 1995 16:49:24 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 : FLASHER.CPP *
* *
* Programmer : Joe L. Bostic *
* *
* Start Date : May 28, 1994 *
* *
* Last Update : October 17, 1994 [JLB] *
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* FlasherClass::Process -- Performs the logic processing for the flashing ability. *
* FlasherClass::Debug_Dump -- Displays current status to the monochrome screen. *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "function.h"
#ifdef CHEAT_KEYS
/***********************************************************************************************
* FlasherClass::Debug_Dump -- Displays current status to the monochrome screen. *
* *
* This utility function will output the current status of the FlasherClass to the mono *
* screen. It is through this display that bugs may be fixed or detected. *
* *
* INPUT: none *
* *
* OUTPUT: none *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 05/31/1994 JLB : Created. *
*=============================================================================================*/
void FlasherClass::Debug_Dump(MonoClass *mono) const
{
mono->Set_Cursor(50, 7);
mono->Printf("%2d", FlashCount);
}
#endif
/***********************************************************************************************
* FlasherClass::Process -- Performs the logic processing for the flashing ability. *
* *
* The ability for an object to flash is controlled by this logic processing routine. It *
* should be called once per game tick per unit. *
* *
* INPUT: none *
* *
* OUTPUT: bool; Should the associated object be redrawn? *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 05/28/1994 JLB : Created. *
* 06/20/1994 JLB : Is now independent of object it represents. *
*=============================================================================================*/
bool FlasherClass::Process(void)
{
// 2019/09/20 JAS - Flashing info needs to exist per player
for (int i = 0; i < HOUSE_COUNT; i++)
{
if (FlashCountPerPlayer[i])
{
FlashCountPerPlayer[i]--;
}
}
if (FlashCount) {
FlashCount--;
IsBlushing = false;
if (FlashCount & 0x01) {
IsBlushing = true;
}
return(true);
}
return(false);
}
/***********************************************************************************************
* FlasherClass::Get_Flashing_Flags -- *
* *
* Gets the flags tell which players this object should flash for. *
* *
* INPUT: none *
* *
* OUTPUT: unsigned int; Flag representing the players to flash for *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 2019/09/20 JAS : Created. *
*=============================================================================================*/
unsigned int FlasherClass::Get_Flashing_Flags() const
{
unsigned flags = 0;
for (int i = 0; i < HOUSE_COUNT; ++i)
{
if (FlashCountPerPlayer[i] > 0)
{
flags |= (1 << i);
}
}
return flags;
}

81
TIBERIANDAWN/FLASHER.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: F:\projects\c&c\vcs\code\flasher.h_v 2.17 16 Oct 1995 16:45:12 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 : FLASHER.H *
* *
* Programmer : Joe L. Bostic *
* *
* Start Date : May 28, 1994 *
* *
* Last Update : May 28, 1994 [JLB] *
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef FLASHER_H
#define FLASHER_H
class FlasherClass {
public:
/*
** When this object is targeted, it will flash a number of times. This is the
** flash control number. It counts down to zero and then stops. Odd values
** cause the object to be rendered in a lighter color.
*/
unsigned FlashCount:7;
/*
** When an object is targeted, it flashes several times to give visual feedback
** to the player. Every other game "frame", this flag is true until the flashing
** is determined to be completed.
*/
unsigned IsBlushing:1;
// 2019/09/20 JAS - Flashing info needs to exist per player
FlasherClass(void) {
FlashCount = 0;
IsBlushing = false;
for (int i = 0; i < HOUSE_COUNT; ++i)
{
FlashCountPerPlayer[i] = 0;
}
}
#ifdef CHEAT_KEYS
void Debug_Dump(MonoClass *mono) const;
#endif
bool Process(void);
/*
** File I/O.
*/
void Code_Pointers(void);
void Decode_Pointers(void);
// 2019/09/20 JAS - Flashing info needs to exist per player
unsigned int Get_Flashing_Flags() const;
unsigned int FlashCountPerPlayer[HOUSE_COUNT];
};
#endif

130
TIBERIANDAWN/FLY.CPP Normal file
View File

@@ -0,0 +1,130 @@
//
// 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&c\vcs\code\fly.cpv 2.18 16 Oct 1995 16:50:40 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 : FLY.CPP *
* *
* Programmer : Joe L. Bostic *
* *
* Start Date : April 24, 1994 *
* *
* Last Update : June 5, 1995 [JLB] *
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* FlyClass::Physics -- Performs vector physics (movement). *
* FlyClass::Fly_Speed -- Sets the flying object to the speed specified. *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "function.h"
/***********************************************************************************************
* FlyClass::Physics -- Performs vector physics (movement). *
* *
* This routine performs movement (vector) physics. It takes the *
* specified location and moves it according to the facing and speed *
* of the vector. It returns the status of the move. *
* *
* INPUT: coord -- Reference to the coordinate that the vector will *
* be applied to. *
* *
* OUTPUT: Returns with the status of the vector physics. This could *
* range from no effect, to exiting the edge of the world. *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 04/24/1994 JLB : Created. *
* 06/05/1995 JLB : Simplified to just do movement. *
*=============================================================================================*/
ImpactType FlyClass::Physics(COORDINATE & coord, DirType facing)
{
if (SpeedAdd != MPH_IMMOBILE) {
int actual = (int)SpeedAdd + SpeedAccum;
div_t result = div(actual, PIXEL_LEPTON_W);
SpeedAccum = result.rem;
actual -= result.rem;
COORDINATE old = coord;
/*
** If movement occurred that is at least one
** pixel, then check update the coordinate and
** check for edge of world collision.
*/
if (result.quot) {
COORDINATE newcoord; // New working coordinate.
newcoord = Coord_Move(coord, facing, actual);
/*
** If no movement occurred, then presume it hasn't moved at all
** and return immediately with this indication.
*/
if (newcoord == coord) {
return(IMPACT_NONE);
}
/*
** Remember the new position.
*/
coord = newcoord;
/*
** If the new coordinate is off the edge of the world, then report
** this.
*/
if (newcoord & 0xC000C000L /*|| !Map.In_Radar(Coord_Cell(newcoord))*/) {
coord = old;
return(IMPACT_EDGE);
}
return(IMPACT_NORMAL);
}
}
return(IMPACT_NONE);
}
/***********************************************************************************************
* FlyClass::Fly_Speed -- Sets the flying object to the speed specified. *
* *
* This sets the speed of the projectile. It basically functions like a throttle value *
* where 0 equals stop and 255 equals maximum speed (whatever that is for the particular *
* object). *
* *
* INPUT: speed -- Speed setting from 0 to 255. *
* *
* maximum -- The maximum speed of the object. *
* *
* OUTPUT: none *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 07/26/1994 JLB : Created. *
* 07/26/1994 JLB : Added maximum speed as guiding value. *
*=============================================================================================*/
void FlyClass::Fly_Speed(int speed, MPHType maximum)
{
SpeedAdd = (MPHType)Fixed_To_Cardinal((int)maximum, speed);
}

80
TIBERIANDAWN/FLY.H 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
/* $Header: F:\projects\c&c\vcs\code\fly.h_v 2.19 16 Oct 1995 16:45:18 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 : FLY.H *
* *
* Programmer : Joe L. Bostic *
* *
* Start Date : April 24, 1994 *
* *
* Last Update : April 24, 1994 [JLB] *
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef FLY_H
#define FLY_H
typedef enum ImpactType : unsigned char {
IMPACT_NONE, // No movement (of significance) occurred.
IMPACT_NORMAL, // Some (non eventful) movement occurred.
IMPACT_EDGE // The edge of the world was reached.
} ImpactType;
/****************************************************************************
** Flying objects are handled by this class definition.
*/
class FlyClass {
public:
/*---------------------------------------------------------------------
** Constructors, Destructors, and overloaded operators.
*/
FlyClass(void) {
SpeedAdd = MPH_IMMOBILE;
SpeedAccum = 0;
};
/*---------------------------------------------------------------------
** Member function prototypes.
*/
void Fly_Speed(int speed, MPHType maximum);
ImpactType Physics(COORDINATE &coord, DirType facing);
MPHType Get_Speed(void) const {return(SpeedAdd);};
/*
** File I/O.
*/
void Code_Pointers(void);
void Decode_Pointers(void);
private:
/*
** Object movement consists of incrementing the accumulator until enough "distance"
** has accumulated so that moving the object becomes reasonable.
*/
unsigned SpeedAccum; // Lepton accumulator.
MPHType SpeedAdd; // Lepton add (per frame).
};
#endif

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