=0) {
+ /*
+ ** We found a C&C cd - lets see if it was the one we were looking for
+ */
+ if (cd == cd_index || cd == -1 || cd == -2) {
+ /*
+ ** Woohoo! The disk was in a different cd drive. Refresh the search path list
+ * and return.
+ */
+ new_cd_drive = cd_drive;
+ break;
+ }
+ }
+ }
+
+ /*
+ ** A new disc has become available so break
+ */
+ if (new_cd_drive) break;
+
+ /*
+ ** Increase the timeout for subsequent drive searches.
+ */
+ drive_search_timeout = 5*60;
+
+ /*
+ ** Prompt to insert the CD into the drive.
+ */
+ if (cd == -1) {
+ sprintf(buffer, Text_String(TXT_CD_DIALOG_1), cd+1, _cd_name[cd]);
+ } else {
+ sprintf(buffer, Text_String(TXT_CD_DIALOG_2), cd+1, _cd_name[cd]);
+ }
+#ifdef WIN32
+ GraphicViewPortClass * oldpage = Set_Logic_Page(SeenBuff);
+#else
+ GraphicBufferClass * oldpage = Set_Logic_Page(SeenBuff);
+#endif
+ theme_playing = Theme.What_Is_Playing();
+ Theme.Stop();
+ int hidden = Get_Mouse_State();
+ font = (void *)FontPtr;
+
+ /*
+ ** Only set the palette if necessary.
+ */
+ if (PaletteClass::CurrentPalette[1].Red_Component() +
+ PaletteClass::CurrentPalette[1].Blue_Component() +
+ PaletteClass::CurrentPalette[1].Green_Component() == 0) {
+
+ GamePalette.Set();
+ }
+
+ Keyboard->Clear();
+
+ while (Get_Mouse_State()) Show_Mouse();
+
+ if (WWMessageBox().Process(buffer, TXT_OK, TXT_CANCEL, TXT_NONE, TRUE) == 1) {
+ Set_Logic_Page(oldpage);
+ Hide_Mouse();
+ return(false);
+ }
+ while (hidden--) Hide_Mouse();
+ Set_Font(font);
+ Set_Logic_Page(oldpage);
+ }
+ }
+
+ CurrentCD = cd_index;
+
+#ifndef DEMO
+
+ CCFileClass::Set_CD_Drive(new_cd_drive);
+ CCFileClass::Refresh_Search_Drives();
+
+ /*
+ ** If it broke out of the query for CD-ROM loop, then this means that the
+ ** CD-ROM has been inserted.
+ */
+// if (cd > -3 && _last != cd) {
+ if (cd > -1 && _last != cd) {
+ _last = cd;
+
+ Theme.Stop();
+
+// if (ConquerMix) delete ConquerMix;
+ if (MoviesMix) delete MoviesMix;
+ if (GeneralMix) delete GeneralMix;
+ if (ScoreMix) delete ScoreMix;
+ if (MainMix) delete MainMix;
+
+ MainMix = new MFCD("MAIN.MIX", &FastKey);
+ assert(MainMix != NULL);
+// ConquerMix = new MFCD("CONQUER.MIX", &FastKey);
+ if (CCFileClass("MOVIES1.MIX").Is_Available()) {
+ MoviesMix = new MFCD("MOVIES1.MIX", &FastKey);
+ } else {
+ MoviesMix = new MFCD("MOVIES2.MIX", &FastKey);
+ }
+ assert(MoviesMix != NULL);
+ GeneralMix = new MFCD("GENERAL.MIX", &FastKey);
+ ScoreMix = new MFCD("SCORES.MIX", &FastKey);
+ ThemeClass::Scan();
+ }
+#endif
+
+ if (theme_playing != THEME_NONE) {
+ Theme.Queue_Song(theme_playing);
+ }
+
+ return(true);
+}
+
+
+/***************************************************************************
+ * DISK_SPACE_AVAILABLE -- returns bytes of free disk space *
+ * *
+ * INPUT: none *
+ * *
+ * OUTPUT: returns amount of free disk space *
+ * *
+ * HISTORY: *
+ * 08/11/1995 PWG : Created. *
+ *=========================================================================*/
+unsigned long Disk_Space_Available(void)
+{
+ struct diskfree_t diskdata;
+ unsigned drive;
+
+ _dos_getdrive(&drive);
+ _dos_getdiskfree(drive, &diskdata);
+
+ return(diskdata.avail_clusters * diskdata.sectors_per_cluster * diskdata.bytes_per_sector);
+}
+
+
+/***********************************************************************************************
+ * Do_Record_Playback -- handles saving/loading map pos & current object *
+ * *
+ * INPUT: *
+ * none. *
+ * *
+ * OUTPUT: *
+ * none. *
+ * *
+ * WARNINGS: *
+ * none. *
+ * *
+ * HISTORY: *
+ * 08/15/1995 BRR : Created. *
+ *=============================================================================================*/
+static void Do_Record_Playback(void)
+{
+ int count;
+ TARGET tgt;
+ int i;
+ COORDINATE coord;
+ ObjectClass * obj;
+ unsigned long sum;
+ unsigned long sum2;
+ unsigned long ltgt;
+
+ /*
+ ** Record a game
+ */
+ if (Session.Record) {
+
+ /*
+ ** Save the map's location
+ */
+ Session.RecordFile.Write(&Map.DesiredTacticalCoord,
+ sizeof (Map.DesiredTacticalCoord));
+
+ /*
+ ** Save the current object list count
+ */
+ count = CurrentObject.Count();
+ Session.RecordFile.Write(&count, sizeof(count));
+
+ /*
+ ** Save a CRC of the selected-object list.
+ */
+ sum = 0;
+ for (i = 0; i < count; i++) {
+ ltgt = (unsigned long)(CurrentObject[i]->As_Target());
+ sum += ltgt;
+ }
+ Session.RecordFile.Write (&sum, sizeof(sum));
+
+ /*
+ ** Save all selected objects.
+ */
+ for (i = 0; i < count; i++) {
+ tgt = CurrentObject[i]->As_Target();
+ Session.RecordFile.Write (&tgt, sizeof(tgt));
+ }
+
+ //
+ // Save team-selection and formation events
+ //
+ Session.RecordFile.Write (&TeamEvent, sizeof(TeamEvent));
+ Session.RecordFile.Write (&TeamNumber, sizeof(TeamNumber));
+ Session.RecordFile.Write (&FormationEvent, sizeof(FormationEvent));
+Session.RecordFile.Write (TeamMaxSpeed, sizeof(TeamMaxSpeed));
+Session.RecordFile.Write (TeamSpeed, sizeof(TeamSpeed));
+Session.RecordFile.Write (&FormMove, sizeof(FormMove));
+Session.RecordFile.Write (&FormSpeed, sizeof(FormSpeed));
+Session.RecordFile.Write (&FormMaxSpeed, sizeof(FormMaxSpeed));
+ TeamEvent = 0;
+ TeamNumber = 0;
+ FormationEvent = 0;
+ }
+
+ /*
+ ** Play back a game ("attract" mode)
+ */
+ if (Session.Play) {
+
+ /*
+ ** Read & set the map's location.
+ */
+ if (Session.RecordFile.Read(&coord, sizeof(coord))==sizeof(coord)) {
+ if (coord != Map.DesiredTacticalCoord) {
+ Map.Set_Tactical_Position(coord);
+ }
+ }
+
+ if (Session.RecordFile.Read(&count, sizeof(count))==sizeof(count)) {
+ /*
+ ** Compute a CRC of the current object-selection list.
+ */
+ sum = 0;
+ for (i = 0; i < CurrentObject.Count(); i++) {
+ ltgt = (unsigned long)(CurrentObject[i]->As_Target());
+ sum += ltgt;
+ }
+
+ /*
+ ** Load the CRC of the objects on disk; if it doesn't match, select
+ ** all objects as they're loaded.
+ */
+ Session.RecordFile.Read (&sum2, sizeof(sum2));
+ if (sum2 != sum) {
+ Unselect_All();
+ }
+
+ AllowVoice = true;
+
+ for (i = 0; i < count; i++) {
+ if (Session.RecordFile.Read (&tgt, sizeof(tgt))==sizeof(tgt)) {
+ obj = As_Object(tgt);
+ if (obj && (sum2 != sum)) {
+ obj->Select();
+ AllowVoice = false;
+ }
+ }
+ }
+
+ AllowVoice = true;
+
+ }
+
+ //
+ // Save team-selection and formation events
+ //
+ Session.RecordFile.Read (&TeamEvent, sizeof(TeamEvent));
+ Session.RecordFile.Read (&TeamNumber, sizeof(TeamNumber));
+ Session.RecordFile.Read (&FormationEvent, sizeof(FormationEvent));
+ if (TeamEvent) {
+ Handle_Team(TeamNumber, TeamEvent - 1);
+ }
+ if (FormationEvent) {
+ Toggle_Formation();
+ }
+
+Session.RecordFile.Read (TeamMaxSpeed, sizeof(TeamMaxSpeed));
+Session.RecordFile.Read (TeamSpeed, sizeof(TeamSpeed));
+Session.RecordFile.Read (&FormMove, sizeof(FormMove));
+Session.RecordFile.Read (&FormSpeed, sizeof(FormSpeed));
+Session.RecordFile.Read (&FormMaxSpeed, sizeof(FormMaxSpeed));
+ /*
+ ** The map isn't drawn in playback mode, so draw it here.
+ */
+ Map.Render();
+ }
+}
+
+
+/***********************************************************************************************
+ * Hires_Load -- Allocates memory for, and loads, a resolution dependant file. *
+ * *
+ * *
+ * *
+ * INPUT: Name of file to load *
+ * *
+ * OUTPUT: Ptr to loaded file *
+ * *
+ * WARNINGS: Caller is responsible for releasing the memory allocated *
+ * *
+ * *
+ * HISTORY: *
+ * 5/13/96 3:20PM ST : Created *
+ *=============================================================================================*/
+void * Hires_Load(char * name)
+{
+ char filename[30];
+ int length;
+ void * return_ptr;
+
+#ifdef WIN32
+ sprintf(filename, "H%s", name);
+#else
+ strcpy(filename, name);
+#endif
+ CCFileClass file (filename);
+
+ if (file.Is_Available()) {
+
+ length = file.Size();
+ return_ptr = new char[length];
+ file.Read(return_ptr, length);
+ return (return_ptr);
+
+ } else {
+ return (NULL);
+ }
+}
+
+
+/***********************************************************************************************
+ * Crate_From_Name -- Given a crate name convert it to a crate type. *
+ * *
+ * Use this routine to convert an ASCII crate name into a crate type. If no match could *
+ * be found, then CRATE_MONEY is assumed. *
+ * *
+ * INPUT: name -- Pointer to the crate name text to convert into a crate type. *
+ * *
+ * OUTPUT: Returns with the crate name converted into a crate type. *
+ * *
+ * WARNINGS: none *
+ * *
+ * HISTORY: *
+ * 08/12/1996 JLB : Created. *
+ *=============================================================================================*/
+CrateType Crate_From_Name(char const * name)
+{
+ if (name != NULL) {
+ for (CrateType crate = CRATE_FIRST; crate < CRATE_COUNT; crate++) {
+ if (stricmp(name, CrateNames[crate]) == 0) return(crate);
+ }
+ }
+ return(CRATE_MONEY);
+}
+
+
+/***********************************************************************************************
+ * Owner_From_Name -- Convert an owner name into a bitfield. *
+ * *
+ * This will take an owner specification and convert it into a bitfield that represents *
+ * it. Sometimes this will be just a single house bit, but other times it could be *
+ * all the allies or soviet house bits combined. *
+ * *
+ * INPUT: text -- Pointer to the text to convert into a house bitfield. *
+ * *
+ * OUTPUT: Returns with the houses specified. The value is in the form of a bit field with *
+ * one bit per house type. *
+ * *
+ * WARNINGS: none *
+ * *
+ * HISTORY: *
+ * 08/12/1996 JLB : Created. *
+ *=============================================================================================*/
+int Owner_From_Name(char const * text)
+{
+ int ownable = 0;
+ if (stricmp(text, "soviet") == 0) {
+ ownable |= HOUSEF_SOVIET;
+ } else {
+ if (stricmp(text, "allies") == 0 || stricmp(text, "allied") == 0) {
+ ownable |= HOUSEF_ALLIES;
+ } else {
+ HousesType h = HouseTypeClass::From_Name(text);
+ if (h != HOUSE_NONE && (h < HOUSE_MULTI1 || h > HOUSE_MULTI8)) {
+ ownable |= (1 << h);
+ }
+ }
+ }
+ return(ownable);
+}
+
+
+/***********************************************************************************************
+ * Shake_The_Screen -- Dispatcher that shakes the screen. *
+ * *
+ * This routine will shake the game screen the number of shakes requested. *
+ * *
+ * INPUT: shakes -- The number of shakes to shake the screen. *
+ * *
+ * OUTPUT: none *
+ * *
+ * WARNINGS: none *
+ * *
+ * HISTORY: *
+ * 09/04/1996 BWG : Created. *
+ *=============================================================================================*/
+void Shake_The_Screen(int shakes)
+{
+#ifdef WIN32
+ shakes += shakes;
+
+ Hide_Mouse();
+ SeenPage.Blit(HidPage);
+ int oldyoff = 0;
+ int newyoff = 0;
+ while(shakes--) {
+ int x = TickCount;
+// CountDownTimer = 1;
+ do {
+ newyoff = Sim_Random_Pick(0,2) - 1;
+ } while (newyoff == oldyoff);
+ switch (newyoff) {
+ case -1:
+ HidPage.Blit(SeenPage, 0,2, 0,0, 640,398);
+ break;
+ case 0:
+ HidPage.Blit(SeenPage);
+ break;
+ case 1:
+ HidPage.Blit(SeenPage, 0,0, 0,2, 640,398);
+ break;
+ } while (x == TickCount);
+// } while (CountDownTimer != 0) ;
+ }
+ HidPage.Blit(SeenPage);
+ Show_Mouse();
+#else
+ Shake_Screen(shakes);
+#endif
+}
+
+
+/***********************************************************************************************
+ * List_Copy -- Makes a copy of a cell offset list. *
+ * *
+ * This routine will make a copy of a cell offset list. It will only copy the significant *
+ * elements of the list limited by the maximum length specified. *
+ * *
+ * INPUT: source -- Pointer to a cell offset list. *
+ * *
+ * len -- The maximum number of cell offset elements to store in to the *
+ * destination list pointer. *
+ * *
+ * dest -- Pointer to the destination list to store the copy into. *
+ * *
+ * OUTPUT: none *
+ * *
+ * WARNINGS: Ensure that the destination list is large enough to hold the list copy. *
+ * *
+ * HISTORY: *
+ * 09/04/1996 JLB : Created. *
+ *=============================================================================================*/
+void List_Copy(short const * source, int len, short * dest)
+{
+ if (dest == NULL || dest == NULL) {
+ return;
+ }
+
+ while (len > 0) {
+ *dest = *source;
+ if (*dest == REFRESH_EOL) break;
+ dest++;
+ source++;
+ len--;
+ }
+}
+
+
+
+#if 0
+//
+// Boy, this function sure is crummy
+//
+void Crummy(int crumb1, int crumb2)
+{
+ if (Debug_Check_Map && Debug_Heap_Dump) {
+ Mono_Printf("Hi, I'm Crummy. And so are these: %d, %d\n",crumb1,crumb2);
+ }
+}
+#endif
diff --git a/CODE/CONQUER.H b/CODE/CONQUER.H
new file mode 100644
index 0000000..ab194da
--- /dev/null
+++ b/CODE/CONQUER.H
@@ -0,0 +1,573 @@
+/*
+** Command & Conquer Red Alert(tm)
+** Copyright 2025 Electronic Arts Inc.
+**
+** This program is free software: you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation, either version 3 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program. If not, see .
+*/
+
+#define TXT_NONE 0 //
+#define TXT_CREDIT_FORMAT 1 // %3d.%02d
+#define TXT_TIME_FORMAT_HOURS 2 // Temps:%02d:%02d:%02d
+#define TXT_TIME_FORMAT_NO_HOURS 3 // Temps:%02d:%02d
+#define TXT_BUTTON_SELL 4 // Vente
+#define TXT_SELL 5 // Vente structure
+#define TXT_BUTTON_REPAIR 6 // R‚paration
+#define TXT_YOU 7 // Vous :
+#define TXT_ENEMY 8 // Ennemi :
+#define TXT_BUILD_DEST 9 // Bƒtiments d‚truits par
+#define TXT_UNIT_DEST 10 // Unit‚s d‚truites par
+#define TXT_TIB_HARV 11 // Minerai r‚colt‚ par
+#define TXT_SCORE_1 12 // Score: %d
+#define TXT_YES 13 // Oui
+#define TXT_NO 14 // Non
+#define TXT_SCENARIO_WON 15 // Mission Accomplie
+#define TXT_SCENARIO_LOST 16 // Mission Echou‚e
+#define TXT_START_NEW_GAME 17 // Nouvelle partie
+#define TXT_INTRO 18 // Intro/Preview
+#define TXT_CANCEL 19 // Annuler
+#define TXT_ROCK 20 // Rocher
+#define TXT_CIVILIAN 21 // Civil
+#define TXT_JP 22 // Equipe de confinement
+#define TXT_OK 23 // OK
+#define TXT_TREE 24 // Arbre
+#define TXT_LEFT 25 //
+#define TXT_RIGHT 26 //
+#define TXT_UP 27 //
+#define TXT_DOWN 28 //
+#define TXT_CLEAR 29 // Effacer
+#define TXT_WATER 30 // Eau
+#define TXT_ROAD 31 // Route
+#define TXT_SLOPE 32 // Pente
+#define TXT_PATCH 33 // Patch
+#define TXT_RIVER 34 // RiviŠre
+#define TXT_LOAD_MISSION 35 // Charger Mission
+#define TXT_SAVE_MISSION 36 // Sauvegarder Mission
+#define TXT_DELETE_MISSION 37 // Effacer Mission
+#define TXT_LOAD_BUTTON 38 // Charger
+#define TXT_SAVE_BUTTON 39 // Sauvegarder
+#define TXT_DELETE_BUTTON 40 // Effacer
+#define TXT_GAME_CONTROLS 41 // Contr“les
+#define TXT_SOUND_CONTROLS 42 // Son
+#define TXT_RESUME_MISSION 43 // Reprendre Mission
+#define TXT_VISUAL_CONTROLS 44 // Affichage
+#define TXT_QUIT_MISSION 45 // Abandonner Mission
+#define TXT_EXIT_GAME 46 // Quitter le jeu
+#define TXT_OPTIONS 47 // Options
+#define TXT_SQUISH 48 // D‚bris humains
+#define TXT_CRATER 49 // CratŠre
+#define TXT_SCORCH 50 // Marque de br–lure
+#define TXT_BRIGHTNESS 51 // Luminosit‚ :
+#define TXT_MUSIC 52 // Musique
+#define TXT_VOLUME 53 // Effets sonores
+#define TXT_TINT 54 // Teintes :
+#define TXT_CONTRAST 55 // Contraste :
+#define TXT_SPEED 56 // Vitesse du jeu :
+#define TXT_SCROLLRATE 57 // Vitesse d‚filement :
+#define TXT_COLOR 58 // Couleur :
+#define TXT_RETURN_TO_GAME 59 // Revenir au jeu
+#define TXT_ENEMY_SOLDIER 60 // Soldat ennemi
+#define TXT_ENEMY_VEHICLE 61 // V‚hicule ennemi
+#define TXT_ENEMY_STRUCTURE 62 // Structure ennemie
+#define TXT_LTANK 63 // Tank l‚ger
+#define TXT_MTANK 64 // Tank lourd
+#define TXT_MTANK2 65 // Tank moyen
+#define TXT_HTANK 66 // Tank Mammouth
+#define TXT_SAM 67 // Missiles SAM
+#define TXT_JEEP 68 // Ranger
+#define TXT_TRANS 69 // H‚licoptŠre Chinook
+#define TXT_HARVESTER 70 // Collecteur minerai
+#define TXT_ARTY 71 // Artillerie
+#define TXT_E1 72 // Mitrailleurs
+#define TXT_E2 73 // Grenadiers
+#define TXT_E3 74 // Bazookas
+#define TXT_E4 75 // Lance-flammes
+#define TXT_HELI 76 // H‚licoptŠre d'assaut
+#define TXT_ORCA 77 // Hind
+#define TXT_APC 78 // VBT
+#define TXT_GUARD_TOWER 79 // Tour de garde
+#define TXT_COMMAND 80 // D“me radar
+#define TXT_HELIPAD 81 // H‚liport
+#define TXT_AIRSTRIP 82 // Piste d'atterrissage
+#define TXT_STORAGE 83 // Silo minerai
+#define TXT_CONST_YARD 84 // Chantier de construction
+#define TXT_REFINERY 85 // Raffinerie de minerai
+#define TXT_CIV1 86 // Eglise
+#define TXT_CIV2 87 // Chez Hans et Gretel
+#define TXT_CIV3 88 // Manoir d'Hewitt
+#define TXT_CIV4 89 // Maison de Ricktor
+#define TXT_CIV5 90 // Maison de Gretchin
+#define TXT_CIV6 91 // La grange
+#define TXT_CIV7 92 // Pub Damon
+#define TXT_CIV8 93 // Maison de Fran
+#define TXT_CIV9 94 // Usine d'instruments
+#define TXT_CIV10 95 // Fabricant de jouets
+#define TXT_CIV11 96 // Maison de Ludwig
+#define TXT_CIV12 97 // Meules de foin
+#define TXT_CIV13 98 // Meule de foin
+#define TXT_CIV14 99 // Champ de bl‚
+#define TXT_CIV15 100 // Champ en friche
+#define TXT_CIV16 101 // Champ de ma‹s
+#define TXT_CIV17 102 // Champ de c‚leri
+#define TXT_CIV18 103 // Champ de pommes de terre
+#define TXT_CIV20 104 // Maison de Sala
+#define TXT_CIV21 105 // Maison d'Abdul
+#define TXT_CIV22 106 // Le Pub Barjo de Pablo
+#define TXT_CIV23 107 // Puits du village
+#define TXT_CIV24 108 // Marchand de chameaux
+#define TXT_CIV25 109 // Eglise
+#define TXT_CIV26 110 // Maison d'Ali
+#define TXT_CIV27 111 // Ted le Marchand
+#define TXT_CIV28 112 // Maison de Menelik
+#define TXT_CIV29 113 // Maison du pasteur John
+#define TXT_CIV30 114 // Puits du village
+#define TXT_CIV31 115 // Hutte du gu‚risseur
+#define TXT_CIV32 116 // Hutte de Rikitikitembo
+#define TXT_CIV33 117 // Hutte de Roarke
+#define TXT_CIV34 118 // Hutte de Moubasa'
+#define TXT_CIV35 119 // Hutte d'Aksoum
+#define TXT_CIV36 120 // Hutte de Mambo
+#define TXT_CIV37 121 // Le studio
+#define TXT_CIVMISS 122 // Centre technologique
+#define TXT_TURRET 123 // Tourelle
+#define TXT_GUNBOAT 124 // Aviso-torpilleur
+#define TXT_MCV 125 // V‚hicule de construction
+#define TXT_POWER 126 // Centrale ‚lectrique
+#define TXT_ADVANCED_POWER 127 // Centrale ‚lectrique avanc‚e
+#define TXT_HOSPITAL 128 // H“pital
+#define TXT_BARRACKS 129 // Caserne
+#define TXT_PUMP 130 // Pompe
+#define TXT_TANKER 131 // P‚trolier
+#define TXT_SANDBAG_WALL 132 // Sacs de sable
+#define TXT_CYCLONE_WALL 133 // Cl“ture grillag‚e
+#define TXT_BRICK_WALL 134 // Mur de b‚ton
+#define TXT_BARBWIRE_WALL 135 // Cl“ture barbel‚e
+#define TXT_WOOD_WALL 136 // BarriŠre de bois
+#define TXT_WEAPON_FACTORY 137 // Usine d'armement
+#define TXT_AGUARD_TOWER 138 // Tour de garde avanc‚e
+#define TXT_BIO_LAB 139 // Laboratoire biologique
+#define TXT_FIX_IT 140 // Centre de service
+#define TXT_TAB_SIDEBAR 141 // Contr“les
+#define TXT_TAB_BUTTON_CONTROLS 142 // Options
+#define TXT_TAB_BUTTON_DATABASE 143 // Base de donn‚es
+#define TXT_SHADOW 144 // Terrain inconnu
+#define TXT_OPTIONS_MENU 145 // Menu des options
+#define TXT_STOP 146 // Stop
+#define TXT_PLAY 147 // Lect
+#define TXT_SHUFFLE 148 // Al‚at.
+#define TXT_REPEAT 149 // R‚p‚ter
+#define TXT_MUSIC_VOLUME 150 // Musique :
+#define TXT_SOUND_VOLUME 151 // Effets sonores :
+#define TXT_ON 152 // Oui
+#define TXT_OFF 153 // Non
+#define TXT_MULTIPLAYER_GAME 154 // Jeu Multijoueurs
+#define TXT_NO_FILES 155 // Pas de fichiers disponibles
+#define TXT_DELETE_SINGLE_FILE 156 // Voulez-vous effacer ce
+#define TXT_DELETE_MULTIPLE_FILES 157 // Voulez-vous effacer %d
+#define TXT_RESET_MENU 158 // D‚faut
+#define TXT_CONFIRM_EXIT 159 // Voulez-vous abandonner la
+#define TXT_MISSION_DESCRIPTION 160 // Description de la mission
+#define TXT_C1 161 // Joe
+#define TXT_C2 162 // Barry
+#define TXT_C3 163 // Shelly
+#define TXT_C4 164 // Maria
+#define TXT_C5 165 // Karen
+#define TXT_C6 166 // Steve
+#define TXT_C7 167 // Phil
+#define TXT_C8 168 // Dwight
+#define TXT_C9 169 // Erik
+#define TXT_EINSTEIN 170 // Prof. Einstein
+#define TXT_BIB 171 // Cour
+#define TXT_FASTER 172 // Rapide
+#define TXT_SLOWER 173 // Lent
+#define TXT_AIR_STRIKE 174 // Attaque a‚rienne
+#define TXT_STEEL_CRATE 175 // Caisse d'acier
+#define TXT_WOOD_CRATE 176 // Caisse de bois
+#define TXT_WATER_CRATE 177 // Caisse flottante
+#define TXT_FLAG_SPOT 178 // Emplacement du drapeau
+#define TXT_UNABLE_READ_SCENARIO 179 // Lecture sc‚nario impossible
+#define TXT_ERROR_LOADING_GAME 180 // Erreur de chargement !
+#define TXT_OBSOLETE_SAVEGAME 181 // Sauvegarde obsolŠte
+#define TXT_MUSTENTER_DESCRIPTION 182 // Vous devez entrer une
+#define TXT_ERROR_SAVING_GAME 183 // Erreur de sauvegarde !
+#define TXT_DELETE_FILE_QUERY 184 // Effacer ce fichier ?
+#define TXT_EMPTY_SLOT 185 // [EMPLACEMENT VIDE]
+#define TXT_SELECT_MPLAYER_GAME 186 // Choix du jeu Multijoueurs
+#define TXT_MODEM_SERIAL 187 // Modem/S‚rie
+#define TXT_NETWORK 188 // R‚seau
+#define TXT_INIT_NET_ERROR 189 // Initialisation r‚seau
+#define TXT_JOIN_NETWORK_GAME 190 // Rejoindre jeu en r‚seau
+#define TXT_NEW 191 // Nouveau
+#define TXT_JOIN 192 // Joindre
+#define TXT_SEND_MESSAGE 193 // Envoi Message
+#define TXT_YOUR_NAME 194 // Votre nom :
+#define TXT_SIDE_COLON 195 // Camp :
+#define TXT_COLOR_COLON 196 // Couleur :
+#define TXT_GAMES 197 // Parties
+#define TXT_PLAYERS 198 // Joueurs
+#define TXT_SCENARIO_COLON 199 // Sc‚nario :
+#define TXT_NOT_FOUND 200 // >> NON TROUVE <<
+#define TXT_START_CREDITS_COLON 201 // Cr‚dits :
+#define TXT_BASES_COLON 202 // Bases :
+#define TXT_TIBERIUM_COLON 203 // Minerai :
+#define TXT_CRATES_COLON 204 // Caisses :
+#define TXT_AI_PLAYERS_COLON 205 // Joueurs IA :
+#define TXT_REQUEST_DENIED 206 // Demande refus‚e.
+#define TXT_UNABLE_PLAY_WAAUGH 207 // Impossible de jouer,
+#define TXT_NOTHING_TO_JOIN 208 // Aucune partie disponible !
+#define TXT_NAME_ERROR 209 // Vous devez entrer un nom !
+#define TXT_DUPENAMES_NOTALLOWED 210 // Les noms identiques ne sont
+#define TXT_YOURGAME_OUTDATED 211 // La version de votre jeu est
+#define TXT_DESTGAME_OUTDATED 212 // Version du jeu de
+#define TXT_THATGUYS_GAME 213 // Partie de %s
+#define TXT_THATGUYS_GAME_BRACKET 214 // [Partie de %s]
+#define TXT_NETGAME_SETUP 215 // Configuration du jeu en
+#define TXT_REJECT 216 // Rejeter
+#define TXT_CANT_REJECT_SELF 217 // Vous ne pouvez pas vous
+#define TXT_SELECT_PLAYER_REJECT 218 // Vous devez s‚lectionner un
+#define TXT_BASES 219 // Bases
+#define TXT_CRATES 220 // Caisses
+#define TXT_AI_PLAYERS 221 // Joueur IA
+#define TXT_SCENARIOS 222 // Sc‚narios
+#define TXT_CREDITS_COLON 223 // Cr‚dits :
+#define TXT_ONLY_ONE 224 // Un seul joueur ?
+#define TXT_OOPS 225 // Oops !
+#define TXT_TO 226 // Pour %s :
+#define TXT_TO_ALL 227 // Pour tous
+#define TXT_MESSAGE 228 // Message :
+#define TXT_CONNECTION_LOST 229 // Perte de connexion avec %s
+#define TXT_LEFT_GAME 230 // %s a quitt‚ le jeu.
+#define TXT_PLAYER_DEFEATED 231 // %s a ‚t‚ vaincu !
+#define TXT_WAITING_CONNECT 232 // Attente de connexion...
+#define TXT_NULL_CONNERR_CHECK_CABLES 233 // Erreur de connexion !
+#define TXT_MODEM_CONNERR_REDIALING 234 // Erreur de connexion !
+#define TXT_MODEM_CONNERR_WAITING 235 // Erreur de connexion !
+#define TXT_SELECT_SERIAL_GAME 236 // Choix du jeu en s‚rie
+#define TXT_DIAL_MODEM 237 // Appel
+#define TXT_ANSWER_MODEM 238 // Attente appel
+#define TXT_NULL_MODEM 239 // Null Modem
+#define TXT_SETTINGS 240 // ParamŠtres
+#define TXT_PORT_COLON 241 // Port :
+#define TXT_IRQ_COLON 242 // IRQ :
+#define TXT_BAUD_COLON 243 // Bauds :
+#define TXT_INIT_STRING 244 // ChaŒne d'initialisation
+#define TXT_CWAIT_STRING 245 // ChaŒne d'attente d'appel
+#define TXT_TONE_BUTTON 246 // Tonalit‚
+#define TXT_PULSE_BUTTON 247 // Impulsions
+#define TXT_HOST_SERIAL_GAME 248 // H“te du jeu en s‚rie
+#define TXT_OPPONENT_COLON 249 // Adversaire :
+#define TXT_USER_SIGNED_OFF 250 // Utilisateur reparti !
+#define TXT_JOIN_SERIAL_GAME 251 // Rejoindre jeu en s‚rie
+#define TXT_PHONE_LIST 252 // R‚pertoire
+#define TXT_ADD 253 // Ajouter
+#define TXT_EDIT 254 // Editer
+#define TXT_DIAL 255 // Appel
+#define TXT_DEFAULT 256 // D‚faut
+#define TXT_DEFAULT_SETTINGS 257 // D‚faut
+#define TXT_CUSTOM_SETTINGS 258 // Autres paramŠtres
+#define TXT_PHONE_LISTING 259 // R‚pertoire
+#define TXT_NAME_COLON 260 // Nom :
+#define TXT_NUMBER_COLON 261 // Num‚ro :
+#define TXT_UNABLE_FIND_MODEM 262 // Modem non d‚tect‚. V‚rifiez
+#define TXT_NO_CARRIER 263 // Pas de porteuse.
+#define TXT_LINE_BUSY 264 // Ligne occup‚e.
+#define TXT_NUMBER_INVALID 265 // Num‚ro incorrect.
+#define TXT_SYSTEM_NOT_RESPONDING 266 // L'autre systŠme ne r‚pond
+#define TXT_OUT_OF_SYNC 267 // Mauvaise synchronisation !
+#define TXT_PACKET_TOO_LATE 268 // Paquet re‡u trop tard !
+#define TXT_PLAYER_LEFT_GAME 269 // L'autre joueur a quitt‚ le
+#define TXT_FROM 270 // De %s:%s
+#define TXT_SCORE_TIME 271 // TEMPS :
+#define TXT_SCORE_LEAD 272 // COMMANDEMENT :
+#define TXT_SCORE_EFFI 273 // EFFICACITE :
+#define TXT_SCORE_TOTA 274 // SCORE TOTAL :
+#define TXT_SCORE_CASU 275 // PERTES :
+#define TXT_SCORE_NEUT 276 // NEUTRE :
+#define TXT_SCORE_BUIL 277 // BATIMENTS PERDUS
+#define TXT_SCORE_BUIL1 278 // BATIMENTS
+#define TXT_SCORE_BUIL2 279 // PERDUS :
+#define TXT_SCORE_TOP 280 // MEILLEURS SCORES
+#define TXT_SCORE_ENDCRED 281 // CREDITS DE FIN :
+#define TXT_SCORE_TIMEFORMAT1 282 // %dh %dm
+#define TXT_SCORE_TIMEFORMAT2 283 // %dm
+#define TXT_DIALING 284 // Appel...
+#define TXT_DIALING_CANCELED 285 // Appel annul‚
+#define TXT_WAITING_FOR_CALL 286 // Attente d'appel...
+#define TXT_ANSWERING_CANCELED 287 // Attente d'appel annul‚e
+#define TXT_E6 288 // Ing‚nieurs
+#define TXT_E8 289 // Espion
+#define TXT_MODEM_OR_LOOPBACK 290 // Pas de cƒble Null Modem
+#define TXT_MAP 291 // Carte
+#define TXT_BLOSSOM_TREE 292 // Arbre en fleurs
+#define TXT_RESTATE_MISSION 293 // Briefing
+#define TXT_COMPUTER 294 // Joueur IA
+#define TXT_COUNT 295 // Nombre :
+#define TXT_LEVEL 296 // Niveau :
+#define TXT_OPPONENT 297 // Adversaire
+#define TXT_KILLS_COLON 298 // Vict.:
+#define TXT_VIDEO 299 // Vid‚o
+#define TXT_C10 300 // Scientifique
+#define TXT_CAPTURE_THE_FLAG 301 // Capture drapeau
+#define TXT_OBJECTIVE 302 // Objectifs de mission
+#define TXT_MISSION 303 // Mission
+#define TXT_NO_SAVES 304 // Pas de sauvegardes
+#define TXT_CIVILIAN_BUILDING 305 // Bƒtiment civil
+#define TXT_TECHNICIAN 306 // Technicien
+#define TXT_NO_SAVELOAD 307 // Sauvegarde interdite en
+#define TXT_DELPHI 308 // Agent Sp‚cial 1
+#define TXT_TO_REPLAY 309 // Voulez-vous recommencer
+#define TXT_RECONN_TO 310 // Reconnexion vers %s.
+#define TXT_PLEASE_WAIT 311 // Attendez %02d secondes.
+#define TXT_SURRENDER 312 // Voulez-vous vous rendre ?
+#define TXT_SEL_TRANS 313 // CHOIX DE LA TRANSMISSION
+#define TXT_GAMENAME_MUSTBE_UNIQUE 314 // Les sauvegardes ne peuvent
+#define TXT_GAME_IS_CLOSED 315 // Partie ferm‚e.
+#define TXT_NAME_MUSTBE_UNIQUE 316 // Les noms doivent ˆtre tous
+#define TXT_RECONNECTING_TO 317 // Reconnexion vers %s
+#define TXT_WAITING_FOR_CONNECTIONS 318 // Attente de connexions...
+#define TXT_TIME_ALLOWED 319 // Temps autoris‚ : %02d
+#define TXT_PRESS_ESC 320 // Appuyez sur Echap pour
+#define TXT_JUST_YOU_AND_ME 321 // De l'ordinateur : Il ne
+#define TXT_CAPTURE_THE_FLAG_COLON 322 // Capture du drapeau :
+#define TXT_CHAN 323 // Agent Sp‚cial 2
+#define TXT_HAS_ALLIED 324 // %s s'est alli‚(e) avec %s
+#define TXT_AT_WAR 325 // %s d‚clare la guerre … %s
+#define TXT_SEL_TARGET 326 // Choisissez un cible
+#define TXT_RESIGN 327 // Abandonner
+#define TXT_TIBERIUM_FAST 328 // Le minerai pousse trŠs
+#define TXT_ANSWERING 329 // R‚ponse en cours...
+#define TXT_INITIALIZING_MODEM 330 // Initialisation Modem...
+#define TXT_SCENARIOS_DO_NOT_MATCH 331 // Les sc‚narios ne
+#define TXT_POWER_OUTPUT 332 // Production d'‚nergie
+#define TXT_POWER_OUTPUT_LOW 333 // Production d'‚nergie
+#define TXT_CONTINUE 334 // Continuer
+#define TXT_QUEUE_FULL 335 // Saturation des donn‚es …
+#define TXT_SPECIAL_WARNING 336 // %s a modifi‚ les options de
+#define TXT_CD_DIALOG_1 337 // Placez un CD d'Alerte Rouge
+#define TXT_CD_DIALOG_2 338 // Placez le CD %d (%s) dans
+#define TXT_CD_ERROR1 339 // Alerte Rouge n'a pas
+#define TXT_NO_SOUND_CARD 340 // Pas de carte sonore
+#define TXT_UNKNOWN 341 // INCONNU
+#define TXT_OLD_GAME 342 // (ancien)
+#define TXT_NO_SPACE 343 // Espace disque insuffisant
+#define TXT_MUST_HAVE_SPACE 344 // Vous devez disposer de %d
+#define TXT_RUN_SETUP 345 // Lancez d'abord le programme
+#define TXT_WAITING_FOR_OPPONENT 346 // Attente adversaire
+#define TXT_SELECT_SETTINGS 347 // Choisissez l'option
+#define TXT_PRISON 348 // Prison
+#define TXT_GAME_WAS_SAVED 349 // Mission sauvegard‚e
+#define TXT_SPACE_CANT_SAVE 350 // Espace disque insuffisant
+#define TXT_INVALID_PORT_ADDRESS 351 // Port/Adresse invalide. COM
+#define TXT_INVALID_SETTINGS 352 // paramŠtres Port et/ou IRQ
+#define TXT_IRQ_ALREADY_IN_USE 353 // IRQ d‚j… utilis‚
+#define TXT_ABORT 354 // Oui
+#define TXT_RESTART 355 // Recommencer
+#define TXT_RESTARTING 356 // Mission relanc‚e. Attendez
+#define TXT_LOADING 357 // Chargement de la mission.
+#define TXT_ERROR_IN_INITSTRING 358 // Erreur chaŒne
+#define TXT_SHADOW_COLON 359 // Ombre
+#define TXT_AVMINE 360 // Mine Anti-V‚hicule
+#define TXT_APMINE 361 // Mine Anti-Personnel
+#define TXT_NEW_MISSIONS 362 // Nouvelles missions
+#define TXT_THIEF 363 // Voleur
+#define TXT_MRJ 364 // Brouilleur de radar
+#define TXT_GAP_GENERATOR 365 // G‚n‚rateur d'ombre
+#define TXT_PILLBOX 366 // Bunker
+#define TXT_CAMOPILLBOX 367 // Bunker camoufl‚
+#define TXT_CHRONOSPHERE 368 // ChronosphŠre
+#define TXT_ENGLAND 369 // Roy. Uni
+#define TXT_GERMANY 370 // Allemagne
+#define TXT_SPAIN 371 // Espagne
+#define TXT_USSR 372 // URSS
+#define TXT_UKRAINE 373 // Ukraine
+#define TXT_GREECE 374 // GrŠce
+#define TXT_FRANCE 375 // France
+#define TXT_TURKEY 376 // Turquie
+#define TXT_SHORE 377 // Rivage
+#define TXT_PLACE_OBJECT 378 // Choisir objet
+#define TXT_SS 379 // Sous-marin
+#define TXT_DD 380 // Contre-torpilleur
+#define TXT_CA 381 // Croiseur
+#define TXT_TRANSPORT 382 // Transport
+#define TXT_PT 383 // Aviso-torpilleur
+#define TXT_LOBBY 384 // Hall
+#define TXT_CHANNEL_GAMES 385 // Parties
+#define TXT_SAVING_GAME 386 // Sauvegarder partie...
+#define TXT_GAME_FULL 387 // La partie est au complet.
+#define TXT_MUST_SELECT_GAME 388 // Vous devez s‚lectionner une
+#define TXT_S_PLAYING_S 389 // %s joue contre %s
+#define TXT_ONLY_HOST_CAN_MODIFY 390 // Seul l'h“te peut modifier
+#define TXT_GAME_CANCELLED 391 // La partie a ‚t‚ annul‚e.
+#define TXT_S_FORMED_NEW_GAME 392 // %s a initi‚ une nouvelle
+#define TXT_GAME_NOW_IN_PROGRESS 393 // La partie de %s est
+#define TXT_TESLA 394 // Bobine de Tesla
+#define TXT_MGG 395 // G‚n‚rateur d'ombre mobile
+#define TXT_FLAME_TURRET 396 // Tour lance-flammes
+#define TXT_AAGUN 397 // Canon Anti-Avion
+#define TXT_KENNEL 398 // Niche
+#define TXT_SOVIET_TECH 399 // Centre Technique
+#define TXT_BADGER 400 // Bombardier
+#define TXT_MIG 401 // Mig
+#define TXT_YAK 402 // Yak
+#define TXT_FENCE 403 // Barbel‚s
+#define TXT_MEDIC 404 // M‚decin
+#define TXT_SABOTEUR 405 // Saboteur
+#define TXT_GENERAL 406 // G‚n‚ral
+#define TXT_E7 407 // Tanya
+#define TXT_PARA_BOMB 408 // Parabombes
+#define TXT_PARA_INFANTRY 409 // Parachutistes
+#define TXT_PARA_SABOTEUR 410 // Saboteur parachutiste
+#define TXT_SHIP_YARD 411 // Chantier naval
+#define TXT_SUB_PEN 412 // Port sous-marin
+#define TXT_SCENARIO_OPTIONS 413 // Options Sc‚nario
+#define TXT_SPY_MISSION 414 // Avion espion
+#define TXT_U2 415 // Avion espion
+#define TXT_GUARD_DOG 416 // Chien d'attaque
+#define TXT_SPY_INFO 417 // Info Espion
+#define TXT_BUILDNGS 418 // Bƒtiments
+#define TXT_UNITS 419 // Unit‚s
+#define TXT_INFANTRY 420 // Infanterie
+#define TXT_AIRCRAFT 421 // Avion
+#define TXT_TRUCK 422 // Camion d'approvisionnement
+#define TXT_INVUL 423 // Module d'invuln‚rabilit‚
+#define TXT_IRON_CURTAIN 424 // Rideau de Fer
+#define TXT_ADVANCED_TECH 425 // Centre technique avanc‚
+#define TXT_V2_LAUNCHER 426 // Lance-roquettes V2
+#define TXT_FORWARD_COM 427 // Poste de commandement
+#define TXT_DEMOLITIONER 428 // Bombardeur
+#define TXT_MINE_LAYER 429 // Poseur de mines
+#define TXT_FAKE_CONST 430 // Chantier de construction
+#define TXT_FAKE_WEAP 431 // Usine d'armement leurre
+#define TXT_FAKE_YARD 432 // Chantier naval leurre
+#define TXT_FAKE_PEN 433 // Port sous-marin leurre
+#define TXT_FAKE_RADAR 434 // D“me radar leurre
+#define TXT_THEME_BIGF 435 // Bigfoot
+#define TXT_THEME_CRUS 436 // La r‚volte
+#define TXT_THEME_FAC1 437 // A l'attaque 1
+#define TXT_THEME_FAC2 438 // A l'attaque 2
+#define TXT_THEME_HELL 439 // Marche de l'enfer
+#define TXT_THEME_RUN1 440 // Sauve-qui-peut
+#define TXT_THEME_SMSH 441 // La d‚bƒcle
+#define TXT_THEME_TREN 442 // Tranch‚es
+#define TXT_THEME_WORK 443 // Les professionnels
+#define TXT_THEME_AWAIT 444 // Attente
+#define TXT_THEME_DENSE_R 445 // Dense
+#define TXT_THEME_MAP 446 // S‚lection carte
+#define TXT_THEME_FOGGER1A 447 // Fogger
+#define TXT_THEME_MUD1A 448 // Boue
+#define TXT_THEME_RADIO2 449 // Radio 2
+#define TXT_THEME_ROLLOUT 450 // Laminage
+#define TXT_THEME_SNAKE 451 // Serpent
+#define TXT_THEME_TERMINAT 452 // Extermination
+#define TXT_THEME_TWIN 453 // Jumeau
+#define TXT_THEME_VECTOR1A 454 // Vecteur
+#define TXT_TEAM_MEMBERS 455 // Equipiers
+#define TXT_BRIDGE 456 // Pont
+#define TXT_BARREL 457 // Baril
+#define TXT_GOODGUY 458 // Amical
+#define TXT_BADGUY 459 // Ennemi
+#define TXT_GOLD 460 // Or
+#define TXT_GEMS 461 // Gemmes
+#define TXT_TEASER 462 // Film titre
+#define TXT_MOVIES 463 // Films
+#define TXT_INTERIOR 464 // Int‚rieur
+#define TXT_SONAR_PULSE 465 // Signal sonar
+#define TXT_MSLO 466 // Silo de missiles
+#define TXT_GPS_SATELLITE 467 // Satellite GPS
+#define TXT_NUCLEAR_BOMB 468 // Bombe atomique
+#define TXT_EASY 469 // Facile
+#define TXT_HARD 470 // Difficile
+#define TXT_NORMAL 471 // Normal
+#define TXT_DIFFICULTY 472 // S‚lectionnez un niveau de
+#define TXT_ALLIES 473 // Alli‚s
+#define TXT_SOVIET 474 // Soviets
+#define TXT_THEME_INTRO 475 // ThŠme Intro
+#define TXT_SHADOW_REGROWS 476 // Progr. ombre
+#define TXT_ORE_SPREADS 477 // Progr. minerai
+#define TXT_THEME_SCORE 478 // Musiques
+#define TXT_INTERNET 479 // Internet
+#define TXT_ICE 480 // Glace
+#define TXT_CRATE 481 // Caisses
+#define TXT_SKIRMISH 482 // Escarmouche
+#define TXT_CHOOSE 483 // Choisissez votre camp.
+#define TXT_MINERALS 484 // Min‚raux pr‚cieux
+#define TXT_IGNORE 485 // Ignorer
+#define TXT_ERROR_NO_RESP 486 // Erreur - le modem ne r‚pond
+#define TXT_ERROR_NO_RESCODE 487 // Erreur - Le modem n'a pas
+#define TXT_ERROR_NO_INIT 488 // Erreur - Le modem n'a pas
+#define TXT_ERROR_NO_VERB 489 // Erreur - Le modem n'a pas
+#define TXT_ERROR_NO_ECHO 490 // Erreur - Le modem n'a pas
+#define TXT_ERROR_NO_DISABLE 491 // Erreur - Impossible de
+#define TXT_ERROR_TOO_MANY 492 // Erreur - Trop d'erreurs
+#define TXT_ERROR_ERROR 493 // Erreur - Le modem a
+#define TXT_ERROR_TIMEOUT 494 // Erreur - Temps d'attente de
+#define TXT_ACCOMPLISHED 495 // Accompli
+#define TXT_CLICK_CONTINUE 496 // Cliquez pour continuer
+#define TXT_RECEIVING_SCENARIO 497 // R‚ception du sc‚nario de
+#define TXT_SENDING_SCENARIO 498 // Envoi du sc‚nario aux
+#define TXT_NO_FLOW_CONTROL_RESPONSE 499 // Erreur - Le modem n'a pas
+#define TXT_NO_COMPRESSION_RESPONSE 500 // Erreur - Le modem n'a pas
+#define TXT_NO_ERROR_CORRECTION_RESPONSE 501 // Erreur - Le modem n'a pas
+#define TXT_EXPLAIN_REGISTRATION 502 // Pour jouer … Alerte Rouge
+#define TXT_ERROR_UNABLE_TO_RUN_WCHAT 503 // Erreur - Impossible
+#define TXT_REGISTER 504 // Enregistrer
+#define TXT_ORE_MINE 505 // Gisement Minerai
+#define TXT_NO_REGISTERED_MODEM 506 // Aucun modem configur‚
+#define TXT_CHRONOSHIFT 507 // D‚placement chronoporte
+#define TXT_UNABLE_TO_OPEN_PORT 508 // Adresse invalide ou en
+#define TXT_NO_DIAL_TONE 509 // Pas de tonalit‚.
+#define TXT_NO_EXPANSION_SCENARIO 510 // Erreur - L'autre joueur n'a
+#define TXT_STAND_BY 511 // Patientez SVP...
+#define TXT_THEME_CREDITS 512 // Musique du g‚n‚rique de fin
+#define TXT_POWER_AAGUN 513 // Puissance faible: Canon(s)
+#define TXT_POWER_TESLA 514 // Puissance faible: Bobine(s)
+#define TXT_LOW_POWER 515 // Puissance Faible
+#define TXT_COMMANDER 516 // Commandant:
+#define TXT_BATTLES_WON 517 // Parties gagn‚es:
+#define TXT_MISMATCH 518 // Fichier de donn‚es du jeu
+#define TXT_SCENARIO_ERROR 519 // Votre version de jeu
+#define TXT_CONNECTING 520 // Connecting
+#define TXT_MODEM_INITIALISATION 521 // Initialisation du Modem
+#define TXT_DATA_COMPRESSION 522 // Compression des Donn‚es
+#define TXT_ERROR_CORRECTION 523 // Correction d'Erreur
+#define TXT_HARDWARE_FLOW_CONTROL 524 // Contr“le Mat‚riel du Flux
+#define TXT_ADVANCED 525 // Avanc‚
+#define TXT_THEME_2ND_HAND 526 // Seconde main
+#define TXT_THEME_ARAZOID 527 // Arazo‹de
+#define TXT_THEME_BACKSTAB 528 // Retour … l'envoyeur
+#define TXT_THEME_CHAOS2 529 // Chaos2
+#define TXT_THEME_SHUT_IT 530 // Fermez-la !
+#define TXT_THEME_TWINMIX1 531 // Visite de courtoisie
+#define TXT_THEME_UNDER3 532 // A couvert
+#define TXT_THEME_VR2 533 // VR2
+#define TXT_ASK_EMERGENCY_SAVE_NOT_RESPONDING 534 // L'autre systŠme ne r‚pond
+#define TXT_ASK_EMERGENCY_SAVE_HUNG_UP 535 // L'autre systŠme a
+#define TXT_NO_REG_APP 536 // Alerte Rouge n'a pu
+#define TXT_NO_CS_SCENARIOS 537 // Un joueur de la partie n'a
+#define TXT_MISSILESUB 538 // Sous-marin MS
+#define TXT_SHOCKTROOPER 539 // Electrocuteur
+#define TXT_MECHANIC 540 // M‚canicien
+#define TXT_CHRONOTANK 541 // Chrono Tank
+#define TXT_TESLATANK 542 // Tank Tesla
+#define TXT_MAD 543 // Tank M.A.D.
+#define TXT_DEMOTRUCK 544 // Camion de d‚molition
+#define TXT_PHASETRANSPORT 545 // Transport Cam‚l‚on
+#define TXT_THEME_BOG 546 // Mar‚cages
+#define TXT_THEME_FLOAT_V2 547 // Volutes
+#define TXT_THEME_GLOOM 548 // T‚nŠbres
+#define TXT_THEME_GRNDWIRE 549 // Terrain min‚
+#define TXT_THEME_RPT 550 // M‚caniciens 2
+#define TXT_THEME_SEARCH 551 // Battue
+#define TXT_THEME_TRACTION 552 // Traction
+#define TXT_THEME_WASTELND 553 // Chaos
+#define TXT_CARRIER 554 // H‚liport Mobile
diff --git a/CODE/CONQUER.IDE b/CODE/CONQUER.IDE
new file mode 100644
index 0000000000000000000000000000000000000000..66bf576c8a877a8ed8b59d1c7af8204a1838ff65
GIT binary patch
literal 42942
zcmeHwdwf>aneIxyT)y0|ga9A#i4h}01VlhCO6~+h5|eOI5e-Qo!H~oxAS&JwDI(rc
zE49{IODUz+T5BCD9;f3l4s|*`9cz{GIF840JRHYytm9Z}&-1)%zu(?jd`Zvz+2614
z_j~u+Yp?ft-nG}>d+oK?T6=#LeFHshy&ciYv(Jt;4fJj7Y#)l&boX?ooAD;mJY!yX
z@r&19`Gzr{CmU0|F4dG86HYK)r|p{bcA|lNmiX&=8_nc-Tvy5Zn&3Ox-v1$sKP1bPN^D)dZfDfBGpH0asT>ChR_GUz$bnb29#+0b*LbD-xz
z=R)U0&xbC6E`%Ah
zhBiZ6psmmq(3Q|t(ACgOpqD}~gRX&I4qXeq0(vF14Z0564()(;Lf1n#K)ayb(2dY}
z(5s+5&`r=@DCL7a#zf`p(CaG6q?-1=-m5ov4w#uh=_qWXd{#5==y{R87NqW6B1GVrjgBRWeaSlyw=i!^82)RuNp+K)Z7C
zidRWQKFbEW%vKM_nm|Qx-Muj!YX}udYa8rVPSzYMVdk@M-9}AgjiQpyw4UyDwoD^Z
z(`Z_f>|f`g;#dQzSbzOnZCa_+OnzFfX&D;m?l0dw)K}Hn-`U&YaZH!m%eN~q&7GV2
zwsc0P22Jj(NaMcX9e9Y@xXDl51z?fw0_
zFRVFL!cyk#rpGID)~G5{KAl@T6~~%ZC6$~VJw2Mn8dxQZ$G_c}gy^@sbCk$-N8?vVoDksTUM1fMN2BNSl&`wy0r4#S+lWnRvklckd4fVsRJ}VlV>*=$ss=ofL=-DOBEls5}>PqSw
zDx)*1W-TnKs;-I7=qqVl(aH=VXADZc{GC-&y}C6P(PP8Ao(k%HQ`T+FDsMk{H&jVv
z`IR@wW`4?QgJpel0hUbPN)Zq_dmxwHCda;|L9{P2#eB4szUb;zbg
zeF(?93I}I(HA^AN%uC)&=nyujvn8Y=
z$8l5dX2r3Eq#|j9Lj#(|mXnID4>rfr*rHMq-1@#=#j&NO!nC@|#s-@fl@^$vmSQUE
zT9=nM8PhKN7?svpFukg-yuPv4n9IB}V9QN~+{>#QR#@&5Y0>#<8K$MRxvrtMwY;Lf
z+SGgeZ1Jg}EoCZKG`BQ18&fIiCDI!7(=$wYWo31Jb#r+uj23!%U~5r@by-bgL+b+X
zT4XCyh5Ytd8gsVipDj!kwBd|a5L!NLeX1lPeZxR!e_4B?B38d
zdZI};eb@A~Z?Su6ZV`@BY1yj{>#WMY
zUNSVUs-M-;w|StwQ@HA-_3zuAYi#9T0=vqUt*Gg>ko_B!?lW%#a;(fa@mViV5kA)(
z^{KU4&$ZFP&K^9}b#?@s5O5Wp6&>n}a%Hxj|9lEj!LxuVZ>ecm;59gBdFLmeSX6i)
z8S316-h30qCR@kw2}XtYp!OdB+T)Xr3a`D*z1^|<0iSqOc;0XB>D$nawndqDeE2k^
z!fR%8N83;vHq7|^#!@a0;V4$tL*Hn1i
zeDYG^H8<3`slTUf$ZIb}<*Ce1hwskzuHHUwv1P(1HWlW5Nb+ud^GQxc@-25CV;=K-
z^C?foOXt<>-6x~+1n8%ynnB#YhBo&b+rEs-)8Vl6zRkTI-F>k(JD(g?n76_9z5#ol
zM&*gpPYWZhv$t&kV98rVo;LmTWHZp&-Mik~XFi3hkawVsUhO{1)2Wxp_FDfy-+FX8
zcx{!aJh}SVRMXc#)ZN!Rh)ovHr&<-337Y*l!@0$#^NCl5{F}N52SMPaN91YPPfs?R
zI(s({dRRUstB`vW+U^6_atpa5@&xUthnViA;aP1M7Jl3MJ3DZSE0#~)DtuN$dMu4k
z<0>pKd-_|Sd`ef5w6<%}va$Qhr*{?RcjI7JCtB-x>bL29vR7exH=EXQ`-OK5`P8q%
z>!Le$O-7_Qz)uS?4Lub$PwXX75gh6XJuldMpu+ri^=%%s=Tt;`6^5k+t_AissPMRL
z=;>S6)-!1C@O-i-LWMrplh#XP4~2@P_4T3PZC=@Pp~7-s-*YW`J8b!|M?-}^*Y~uc
z1P5@OZ9029RCw*L@9ypBZyV~eexuS8;->?T6M693LDUJ>H+xA`SQZ@v-COkfV(*Cx
zeRp&ZqF%W+cI~rgMTN(%qq_~Kg2>kb!OcdmcV4hJMuk|kZU_4YOsp)~Q=`K2
zY9HvlM)!$5I4aB+(r_9NnqF_8*t?^`eQNLP8|d)Ln!P?MHm!Hi-b16(8|0@UPkoy<
z_2IHy?eVgwNJX$+eQldOUiKiVNPc;idpPzisR%B1PDP~0X;>QSS6dH7q$g^4T6>os
z8}?ACu>96-9vWg^ZxWwT>Af1B-qVBo4SK%pdBdJ96`nWiHh1@QboXvBUOIcdR9MFA
zY(Fe|-YlLyVk+X_yC0@XdPI85{B%5L#P&HVy=Z|CPXjKHANJs>a9`Tm+dBtQo$r?Xlt}NMpPnvl
z=9ZSS$|khy?eklS^!}+$GTL7?D;g?W>lz!%mKt-t@XVCnLEmPqxoE+fipn`_@JL<1
zqN;k0ZO#KQ;Mub$Q6%~4QJ#}i&Hez{Id26|3ljS;7dL=bI*~IZ*
zgYUq_Xvr
zChj77(`}ivr&lFTnU}Y;R5!N*@TS;DrB~RuPcwM5ym&=5GievhBM+$zK`ZCuepe3zHb9&nXp
zT$ft5S9gucTG*6qe
zJpb(BSMl;!*%-SfqSE_6EPX|Db1?rL8Bk&QRyEhHWclWL{2VndK`JtP#9)jzp+1y|H3hb!DJ@IZB~I{+8DATITQXJv>J+
zR9OBs_2n%~1J?paH&n=9v7)}--~Wh=eE8|;$Eeq17nKnaKMnhCPd)T^+jEDbB`VBY
zCC&}*+5s<}BPl8@yA=&}vS+q0t3*aw{Pc9wT8%#6@>cF%MtvrIl*lNIZ0+A?j?$<|K9)9?^Au?G^1%@t6}bk=o2siMD;Ceu9TleI3TQ5`<88^NbL2;b
z`%&IdM|zZzc_!tfl=Rf8
zsb5WfF7=nGpQL7or-f_6>%)7(&xJn;PfA;m)|+-;+6!r~r+t!^ojxtSCVgG{jp>i2
zznK1J`j_dGGAc6GX55(ZSjLMP*_pF5S7yGD`FiGOnd7r6vi4-Xne}DXr0fORE3>y`
z@6CQL`bKlPWGIxC5g1nV^
z19^M$4&}X;_hDX2{*?R+@-NN5E`M+SGx@LOf0UnHP*$+4U}M3qf~N{zDR{Rav2ar1
zg2GD+w-nx2c&PBz!uJbP#!MYkGiLpm9b=vt^YWOt$9yrSsAzUkbJ3QfuNJ*p^hMG5
zvCGC@H}=5T*T*Inmldxq-c$Ty@!Q2;7Ec|wY~03iyT%VreVN&m;ql-frxi#TL^Yo;jO*|n7mGdl)P6^|#n1JoZ94TkI%IgU>
zEm5{zvxsvvieY1IZCXguQfo~(gt3St<+QB{*|a1{`|$!3PBu+QqwNxNWfw;6O)}Ow
zM*&X*;Uw!Y95!1L=2b9m@hO6@Z8G6hbh#ZV7rw;k2gXb{sYtV9+Pu;~MQT{AHSacT
z+>4nZNlbY(=_L9MF}EOr`}cMZ*OO)a57=%@NY;Ok^+Yon>zI)sTe4+6DoZ2F1X-Se
zr7=^n{KHM(0h=*NvZYW`3uJwatVd*7EL(momj5QpAIkDMS!POVjx3+W7L<^z|5Vn;
z%KA%UISK0_b4bP#smG$q-@}MlgC(9qn@^ryw$ubSg*=B~UpDW8US)L=yDOe_&
zk8@C-zZK|La=BY`uz8v}PnL6KIZu}JWqH0V7szsRva2A0M=A{iQ
zpRDubNH9D(Fw+Z`9fl_dX6nh3b)zvnEx3PnpR?fgRl1jL46{ebN0p?^9WfvFWVAV8
zo-ns8j=vnR|1I6b{N;||FN!CwM3e9Nv$?kWt$EKw`mteL`6F^7Y
zZ_AbGz;n+n-x%1uHjJ-m1iq+YN`4@JoMjn2PGgb&cf+`fN8p-n
zm@?6vn=sB?f!?l)6}5|JFTCQ4*5>lcYJ{uGn;S@E^EeK+zZk|l-sKJB`2hFvOk-2n
zewc11z{<8C3eaA7BeV*wj2_dFG_Qhjl?~gI(YA@e){ZbH@Wg{m#1?WE%UUK%3_XYm
zxpE={
zr@yfKeHymgkx^a~&!!zIpMou}kYl@H$`-@+3-*k=z`6`mHW|GcgP93a*b%g_YFNkQ
z!r}dts29cutxz|p1*?gggfXUa!5WOp^I^YbP36?eHI*2WHwlw$d7O?sa8@8jaJ78H
zeWnQI!ML?4felA$F!;xESlTc);OnAVt
zITJPK5RHD9JJZ)*qjd=jtmEFZg*@Jz$WC_>=DVlR4M&oL
zHoG00a@cT0IcRg2V^aYejw%Oj_Bb|`u;IvZ(B^K(rV2J$j?F!eO*L#d(j4Tu*RiRA
z4M&`VHupI;wXorQ_MpxEj?Gfoa0EJN^MGSh2OEw;2W=j7Y?i@>qtQW|y^hUAu;Hk5
z(B>h>rXDsNoetVO?AR=a4M(VhHjg+q4Y1*S{h-ZP9h*kjaHKkD^QdFf1RIW62W|E_
zHW$N&qt-#2uQ@i&u;KdxL7T@Mn-
zh9lZRn(Y@Ts!
zHo%4>>%si|(6Q-)4c~bQ+C1ynbi-zrWAh`&W+QAk;vVFAE@orf*;m1)5;nGx%6nE1
zwy+KRQUceWO;}>)%DDXRLcfX3f#v5nz7?rL*nQXW$ax5tL|=_?{G8!@FXVVO;|siy
zZ{{%0w{sYB+?e47UdXXt#yN(|upD6`{BR8RufF+agyW-|A9*XnanKV(+qfj!5VauMfP674u5X&iTZZ2M0+wpYiFE!XU^<#^pboLhfBwtq^;cHop_I~Y5*
zT(ifPW35XrKK|!pi*oo=sITpHJ9Nsi-5fi%T(ifP{XBYaQzaQJBW({OHDXenbX*N|D0`%ca_X?<|K+L<Z^9Xf
zN%#L!7gMY1WAOKVg13c%r0+8(2nbe38NDV*8htR0baDN^d7R|zhDc}|zKV0q?%bJ>WT7a^q{x^WcF839gvZsdY<
zd5m*P0nd$doO2@&HjObGk3M#8G$G|;Xd4m|a2#h~$i@n}MZ#s?76$g*$VXc9h@34*
zX@#zX{YacMh0~74*nKGgCn`(`ububvxi6d(608FYVY4b`BNSNZdA=Gcmq0IOf}E2r
zo(Z`{!m}jEk@Ls;9fPzhVw?xW?;OW(5p3FGHXdor?>eNkQ<1>^JttO%{E}NFyjX(q0l$-xcC&E)9_RDhxh&@;
z&UqDu&8;yTOJ&bze!t*0q-=-Y!vq{(J-@KW3u@?iZKtW5O&=J)V|YOK!9f=bLbyZboQ1OOf_qT+Y8m8KS$=JOmZa
z02Z_TgcF;>7X`N4eK`wh563vC%Dya@uRw95^*aqVkHl=0Lci_sRir!$mGd8oyq{Vj
zw@A3&+rq$do{hA9aXEjEeIee}q#eV|culb2>P`9+#8n7&*W3M>rb;`LyLT1DsF9
zIDa{r=k^uy9SUx=e#>C<&6tf+=ohq}M9R0IO-#VK?F+d@!jk4CSk7~h_EcO>eiPx_
zNZAjSGLL#db2KBh)^c8hTwbZ05!!v33C{1tIQPoFtTP9&g&VEkS+MzT%tk3_!*4Ad
zMEE_Z)^(bWD>t?;ZT?2j?`)(U0?HWHb(f0Y4(B>OcbJV*X#Ma5pr3)>%!FZONN$mE
zyA5S&_jeA`ekguV!tW&U+bLfp<3{f9YI7cJo{iZkg?_c{M@V@NI=q~>XQkGXJHA-o
zbCLez81K82c;2j+??Z5-E$ex(c|K;NZ119+DL+B*0(7`i
zPuib!GN~zf2t6Dpl9!}(q&%N;JY{BTYwG^gW2w<_RrulX3G{1ppikp?nn`a>-=BUg
zJ(@9;aWvyZ#*)kjGM~@P%$k|CJ!^lK$u7y>n!PXkIR$>sdc;EU)_NHS;RmxwR~O@eY}dI~fZ8iuAp)1evAOeoubY>Tno%jZ?@
zXFim(!3v>cphZwVSF!Ch4$8L71ZV_05jqJv85)J22Au*u9a;iC13DFYCbSfK7IYf)
zY^Xh!XvM4zqlbvOmIGzWJ-7@PVa`HoE!z|w
zO!hD$AH$;>{1#onESxvYk6&&)3xeOM3u5vEkziT#tOQ!=lAc1m)pt=p4X?FDzw4*9I`(twbs9WSStj-ix>1$GRzPA
z0<0g_BEj$F1u>9w`4J_b%Ni~3u4X;M1mOBQvUb#Sfj-Z!*hrE;q$Zg!&>dd
z_{TH`_E#*1wcwHXnDD}3e)!yKF|0L%-=*_8c?YuTTT;HPq!AKqUrhP5)k@)}3N
zRl|-CEi8t$_$wn|s)zaUF|752-%$(r3tv2fAKoQ`-&YG_nn%F!t`hw2S`cGJpzVz-8V+STrvWNcj@4F;evUyEsj&mjdyi^0XU9?FB`!RTLHoE#|5zA
zH6viyYB)ZEpUX$Uu$AF|V~#D7n5XdC5io3(@GHeu*z$>C;;ux@n|KGIB4JCyfrPgc
z@)K(kuS-0X_-Y{vuqKwl1xy8!aZBN6BVA`b(31f|!PAZh|sN_KNpasw|P`(ercNaL1-%6>;?Z8|#c)|CQ64od9
zUS3c9>(ZU@!FL{W(e9y_3lb7wcM*Qv%C{N##sO#9a~Ay>P|kwqEO*Xg=PY&3Lgy@V
z&LZb5an1ri2g+I8v!I-XeJ+%WR5NYd$+334j>ogq)HWqxt1-2WJPut4@%;oG&s0%-R~*kafa~>1ENi3F@k0^^I-(mPn!WMdYP^|FoR`^IckEt)Uczd?jB;9LdUQ{O9
z-OQ!sOU63Y<}Wj$wkZWM&08AQOYwdP&kt9UZc#oWlrI(QRDXZNh$$aE%}+m4&U4L`
zgcu(Y%Euf~eZF+Wl#d*1z{m5}6`zj?<;%c2)$*Oh{$>XFnDd*#$7{e9e}9QkzAUU$
zEnj_NZBsU4nm>Aa5`4U#T=DscP`(_jQ!U><@Z}<=eDrh_e7rVY@%e~QzC5f`E#C?7
zp?qVoPPKfy!B>Qs
z^3l^A@Ui}J#pfeJ`Nm?MYWa?XuNX1qqo>v2V_oKo&qsvvjl(+C@=Z^wZ5of5^3l^a
z@UdQW#pfeJ`6ghUYWcQ-FM^oz(bMDLV;$>?&qsvvO~g9Y@*M-;B*c`Do_+>C*4M81
zd_*YUWUNyyUnIGcXD?T3)%6BH#
zsg`dI_(~B|K6=^;KHe)`@%e~QzO%4SwR{J`Hw`i6qo;k~<9*i^pN|OTI~(g%%Xbod
z(-BiXdU^?byobBu^AVwZGq6szeD$fdO=XBFA3ePXKDGy3@%e~QzH_inwS4=)Hxn`C
zqo;7zk#e>zT=DscP`+7Mr&_)f;G2z@^3l_D@UflZiqA)c@|}xys^wc0u5FrwnDWt6
z6ZqKXamD8&Lix_aI@R*+2H#x7l#iZd~A!k
z;`0%qeCK1GYWb$8)iy0aO!?^PCGfFb=Zeoqgz_!KI@R)R1K%RVl#ia?10UOnuK0XJ
zDBohNQ!U>y@LhnI^3hW``$#$4o38kLL@3{dSf^UPNP2D462z2`o~DD3ZC6)(J|dK_
z9P3oe*8{!^#FUSon!v|)uq!?v5z1GIb*kk%48AJFl#iZc%12L!!N<0~D?T3)%2$VVs^vQfzGa9h
zA3ePTK0Y_N;`0%qd>3JzYWYrruO2bwqo<^tBjtPsamD8&Liv_sooe~&Gi#d~5K}&S
zDg_^(XI%05h)}*ptWz!DKJYamrhN2N4?aE{x#IH?p?nu(ooe|`fUg-b<)f#5@bNjz
z6`zj?gTO!?^P0r2se%@v=I2<2OWb*kmt4Zf9#DIYyO4?aHsx#IH?
zp?s^bPPKf;!M7SQ<)f$L;N!ETD?T3)%6AFYsg`egc5Tz8h$)|V$~{uf=TcXEJ|dLw
zGOSZA-!|~A3GmTV3HbPo>x$1ugz{aEb*kk%2EMh3Y5wSGDfsxj?26Avgz{a1b*kly
zr~5k7p?sZKr&_+u+}ft~h$$aEy#YSI@R(W1m8x)l#iaGc}L3G@8OEiM}+cSg>|asI|;rX#FUSos=&uS
z6jyvcB9w0v)~S}SKCiZ^7cu3dr!MfZKgJcGj|k=K!#dUS?E_ywV#-HPyTQl49anrl
zB9!lHtWz!D3GfXdrhN4DH2Bz0Zr&_+l;M=y`w&wf^!_n?us_@t-v<%&@dSJ<5ufwLXr+$6mzL2ffdS55GU(
z_vHH^fHT*^!=MDdr|`HHR^7lbKMQuqL4^;b6k^2`3Z6iS>!A6Za+VPdt(M
zdE%nb($MbE!V|Z
z(+lPoY%AD_H>Tbwh!mC<_TY`F!-Yo+GshH_<%)v3wk2yIeTvT7wQ}lGvFNzAs
z&KbLP?89S^kNpD<5NA4t@#g*Pz{uCj7?a{SR1wB4!iH~2CCCwD5l76^?ffPvKK_Ey
zu(<&gQ;8Z6>om-Cuw!ClV`qzxOn3Zk3Hkog#a~(gb@;Iq@t0xtm|X#XkD0I6(qAw9
zW#HTQV-bch78AmFL?XM-BNn_*_VGlR3)X^It0YWez(VjOD^|TeaQJE6Xy=Oif@v
zn9BW_hWuyYD`P3R8bTOJ51}75gps`v`UCN98q|uezSF~U;vDqR$|`@9vdWjTq6ar$1*0700y)Y=(Z7o<
z9K~PZi2lZmf*La-s%Vs47RAk_9>KBZ0$}~oXzm4%;3Sm$SbUC>~2Nt{!SRBq$YSJW#@7#QqR!HDEo>p
zB;&^`#YIhYP!}ZhRkD0}g-$#LrMaBspvbBy92xvLAJg?U*)*GmILC4}d`-qT2E%e4
zbAB1;n(-YKUNd}$g6}-&{7u$Wnvdux*Ejxq3O{!iE9d%g4w{>{)12#jeX^~)d3~QI
z*Ef$huW$F-=6gYIJ;=Gnu7@e3?EMtkdwSrEJeSQqSM-RV?l9iy<(cJqdW>Oannby2fMLCq2r
zXYMLWb2-~V{W8JUOst`CrQ^psLs6Q;a~%}ZwT3=dQ1-n`ZjTuCHOE2S7w|PlP{BK%
z`Z~`+1$~_-DElt9^`&*qT+{;e5mJW~nd^z$werz8rQcLK3$KS01f9H!o){2VK65?}6@cD)5dNeR&4?oT$
zR+N^|LZ^076x+cIrFP+*V)t$_E8t&qy~y$ZY9QB(#6OwTzvg=JD5bR6yFP~BP1WB8
zj=%Jfe^f3If2`eIe;1D8??UmXSFhFKZ@b89=g2W#&s2O*89(||l$L*ugIXIn-niR4C@sO-QEGr%sR4MrwFF11
z#qr;6!>+AqN&dOERD81qp*dFHbxsMb^xC~VW9s4_ciq=z4)VjmxwcG@+G2HmUgRK|
zuIJiCaeZoT>qlvq)l0i9c&_n0GyeDJjzkN
zSdQ{Y?d9fCkjSlMXrH(*Lv$HsMZltD@MuXicxd9auk0nNA$O96x6B_
zQL9HmtsW6|$tb8xMnqjY3hL4kQJ0N^x@<($no&?|Mnqjc3hMF^QENv*tvv;$waXRG
z`H}9`F05Ivh4r*h-*HwZF_TcC!M2~Z3AM!>acxLy=naxq6$$^mp
zMQ(EZ;hmaTFWV;ZmmFvOqSryC1V$k+rhwmRaeVbTsJ+Jb)hDRbfG^Eqzk@muK=lhM
zEe`5x2lZkAb+w=};-Cf`)PV#)hXaDjih~+-P#XhfI4G!`IH(~P74m%z2`VoRYO{ly
zlH{W{3#uRvYKwzvNb*OGwg_rW9Mm-q>Xj59b&a6L#zAd$P|u|LsI7t;7YB8%gK9|g
zQP&D;LLAg}4r*Eeb)BFl#z9^0po%hlU)Kw2avan)2UQk8Z4=aKaZoons9OWa>jpuc
z9tU-!gUZkJb9kem&WMA$$w5s^nmkWyx0?iYW*pSb4(jay>SjTm6$f>TgPN4$`?^I?
zXU9R^>Yz5J`lwq4H6sq{HV3sJ%}3oPsB_|=wmYb|(|y!-LCuPTy4^u7Gqv*N3ifH;
zE~s6HSGJkQ&1PiLG5->A7=Zg-GVBQgSyK>H7E4V)pPzXK~=^<
z?Qu|L#z*ZDRCOHG-41Ge0Cl&ZYU7~paZoQO`o8WFR9zg@y$rT@(j(pM&ZR
zpzagY@;Ipb9n|_9zvS;1RAU^}0}g6|`IiPQ`3D4baU9fx4(ieX>On!Z#6j(KP&Em@
zuf2j=5eM~cQ)Wd?hBo68k2lZ~q_w|UNE{lWus)K4awXw7J
ztAe^b4(d?{^;!V+sGzQhgWBhyCMEj5_6e#j4(e+T>a|oK^)*4Y$3Z>jpl%GH9urh&
z9Msnx)cXO{*9Em94(f3S^<0*p!^Z{H9S8Ld2lZ68kNSq7u8Mc%sBa3YFAnNS2elyEenW|Oq9+A)bsW^U98^Q5kNTFN2IHWfa!}dnKI$n!
zZH|Nbwu5>t)kl3>P@F@nPdM71-|wLIB>SlSg5peB7xf(n)e!Pg-w_n&!@8&g4k|mr
zM;#CpXT7?p?>eYS#z%cuP@LQ9q7FK!ngHscpl*qS`ksS&Es(?S3F@{us6!5FL870-
zLxQ?J4(j_3YD=IDzb~je;-H>(Q1>PIzMdA;SK^?4;Gh};NBIYWx-$;y8Rt3n%M|O2
z}+QbL?F}4aIr3{Go$A_^tJFhHSq9zs$g|C_EkFzsEco;#kwU`~(=p
zF7ahWFRovZ;=ch=G|qno3dZ?wG8D!0--0M=&wmXH#`*6-!8rd#C>ZCz2?gW)SD|2>
z|1K1a^IwL7asJy-FwTD+3dZ^GL%}%z^(YwUzY+!G{CA>Yoc~f3jPu`$f^q(9Q83Pb
zFAB!_FGj&Q|IH{E=f4^SrpVye?JPw`7cPpIR6bP80Wtt
z1>^j8q+p!?k`#>d-;#oH{%cY&&VNq|#`!Nw!8rd-DH!L!Dh1>GccoyQ|FRT}^WT<&
zasKO4FwTEp3dZ>_Ou;z+jVT!CzcK~m{CB2cod41kjPu``f^q(9Q!vhdZwkiw4?PsS
z#MhmjIR6PGn9hHin14G)bubIqn9q|xP4=(l`9(*{H{qJU=Ww$5RdNE-eU$q2Z2gx<&aeSKf<21~7$ET0h!{#%D8{zUwe4=O?J`uNTGrq@(?Jpr*
zfba`1J`)qm_aOcvLT>*Y;WC63*I4_l2pNCb3p2OcFQWG%B;S(=iF@0N7hY?(FGI-f
z+Yw$sytn;xFFyA=yL|{D?G7O%-+Nv-{(2j4LfDM$PatGIP9R)|uwk3s{KL@<<123F|lI|zv%f3ue#FWljUhrRF<
zFD$*q+O0)cV^BU`{7r=9DZJIDFZ05i5pus?_2T9>YqtO)%cI|mAMnEWyl~QXTMjoP
zB<~Ae_$fl-rrmDCD-kjuPkHg<2x(um!-h>>xCRM7)^3d#-sgo!z3@vfob#}?+vtUld*SO|nE8lJukgaHUUx
z4}0M!URe65wOi|j4|w6LUTF5&^toQx>)
+
+// The following functions exhibit variable return modes.
+// That is, they may equally-usefully be called for a value
+// as called just for their effects. Accordingly we inhibit
+// Warning 534 for these functions.
+// Feel free to add to or subtract from this list.
+
+-esym(534,close,creat,fclose,fflush,fprintf,fputc)
+-esym(534,fputs,fscanf,fseek,fwrite,lseek,memcpy,memmove,memset)
+-esym(534,printf,puts,scanf,sprintf,sscanf,strcat,strcpy)
+-esym(534,strncat,strncpy,unlink,write)
+
+//------------------------------------------------------------------
+
+-width(0,0) // don't break up message lines
+
+// 32 bit integer and pointer size is four bytes.
+-si4 -sp4
+
+// Include directories
+-ic:\projects\c&czero\code\watcom\h;..\vq\include;..\gcl510\h
diff --git a/CODE/CONST.CPP b/CODE/CONST.CPP
new file mode 100644
index 0000000..52adc51
--- /dev/null
+++ b/CODE/CONST.CPP
@@ -0,0 +1,820 @@
+/*
+** Command & Conquer Red Alert(tm)
+** Copyright 2025 Electronic Arts Inc.
+**
+** This program is free software: you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation, either version 3 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program. If not, see .
+*/
+
+/* $Header: /CounterStrike/CONST.CPP 1 3/03/97 10:24a Joe_bostic $ */
+/***********************************************************************************************
+ *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
+ ***********************************************************************************************
+ * *
+ * Project Name : Command & Conquer *
+ * *
+ * File Name : CONST.CPP *
+ * *
+ * Programmer : Joe L. Bostic *
+ * *
+ * Start Date : September 20, 1993 *
+ * *
+ * Last Update : September 20, 1993 [JLB] *
+ * *
+ *---------------------------------------------------------------------------------------------*
+ * Functions: *
+ * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+
+#include "function.h"
+
+
+/***************************************************************************
+** These are the access passwords used to activate cheat mode, editor mode,
+** and special game options.
+*/
+long const PlayCodes[] = {
+ 0xE0792D6D, // Dwight Okahara
+ 0x90046ECF, // Paul S. Mudra
+ 0xC3EE9A26, // Frank Klepaki
+ 0xED382178, // Ed Del Castillo
+ 0L
+};
+
+long const CheatCodes[] = {
+ 0xA0E2AB53, // Joseph Hewitt
+ 0x00532693, // Mike Lightner
+ 0x7DDFF824, // Joe Bostic
+ 0x2CB5CF01, // Phil Gorrow
+ 0xB5B63531, // Bill Randolph
+ 0xDFABC23A, // Adam Isgreen
+ 0x52B19A22, // Erik Yeo
+ 0xBE79088C, // David Dettmer
+ 0xB216AE7E, // Barry Green
+ 0x0E07B213, // Steve Tall
+ 0L
+};
+
+
+long const EditorCodes[] = {
+ 0xA2C09326, // Erik Yeo
+ 0x1F944BB3, // Mike Lightner
+ 0xDE07154D, // Adam Isgreen
+ 0x0E07B213, // Steve Tall
+ 0x16B170B1, // Joe Bostic
+ 0L
+};
+
+
+/***********************************************************************************************
+** Unit order names. These names correspond to the player selectable orders
+** a unit can have. The system initiated orders have no use for the ASCII name
+** associated, but they are listed here for completeness sake.
+*/
+char const * Missions[MISSION_COUNT] = {
+ "Sleep",
+ "Attack",
+ "Move",
+ "QMove",
+ "Retreat",
+ "Guard",
+ "Sticky",
+ "Enter",
+ "Capture",
+ "Harvest",
+ "Area Guard",
+ "Return",
+ "Stop",
+ "Ambush",
+ "Hunt",
+ "Unload",
+ "Sabotage",
+ "Construction",
+ "Selling",
+ "Repair",
+ "Rescue",
+ "Missile",
+ "Harmless"
+};
+
+
+/***************************************************************************
+** Special weapon names.
+*/
+#ifdef SCENARIO_EDITOR
+char const * const SpecialWeaponName[SPC_COUNT] = {
+ "Sonar Pulse",
+ "Nuclear Missile",
+ "Chronosphere",
+ "Parachute Bomb",
+ "Paratroopers",
+ "Recon Plane",
+ "Iron Curtain",
+ "GPS Satellite"
+};
+#endif
+int const SpecialWeaponHelp[SPC_COUNT] = {
+ TXT_SONAR_PULSE,
+ TXT_NUCLEAR_BOMB,
+ TXT_CHRONOSHIFT,
+ TXT_PARA_BOMB,
+ TXT_PARA_INFANTRY,
+ TXT_SPY_MISSION,
+ TXT_INVUL,
+ TXT_GPS_SATELLITE
+};
+char const * const SpecialWeaponFile[SPC_COUNT] = {
+ "SONR",
+ "ATOM",
+ "WARP",
+ "PBMB",
+ "PINF",
+ "CAM",
+ "INFX",
+ "GPSS"
+};
+
+
+/***************************************************************************
+** Type of quarry to search out and attack. These values are used for team
+** attack missions.
+*/
+char const * const QuarryName[QUARRY_COUNT] = {
+ "N/A",
+ "Anything",
+ "Buildings - any",
+ "Harvesters",
+ "Infantry",
+ "Vehicles - any",
+ "Ships - any",
+ "Factories",
+ "Base Defenses",
+ "Base Threats",
+ "Power Facilities",
+ "Fake Buildings"
+};
+
+
+/***************************************************************************
+** These are the text names for the formation types.
+*/
+char const * const FormationName[FORMATION_COUNT] = {
+ "None",
+
+ "Tight",
+ "Loose",
+ "Wedge North",
+ "Wedge East",
+ "Wedge South",
+ "Wedge West",
+ "Line N/S",
+ "Line E/W"
+};
+
+
+/***************************************************************************
+** These are the ASCII names for the reinforcement sources.
+*/
+char const * const SourceName[SOURCE_COUNT] =
+{
+ "North",
+ "East",
+ "South",
+ "West",
+ "Air"
+};
+
+
+/***************************************************************************
+** These are the text names for the various armor types a unit may possess.
+*/
+char const * const ArmorName[ARMOR_COUNT] = {
+ "none",
+ "wood",
+ "light",
+ "heavy",
+ "concrete"
+};
+
+
+// HACK ALERT! This unused text string is here to stop Watcom from crashing. There is some
+// magic text heap length that causes a crash before the code executes. This dummy string
+// changes the text heap length enough to stop the crash. Who knows why, but it works.
+char * __test__ = "alskdfjlasdfjkajsdfkja;sldjfklasj9awutreqjfnfdkvnldzlknvadsjgflkasdjfkajsdfas";
+
+
+/***************************************************************************
+** The list of VQ filenames.
+*/
+char const * const VQName[VQ_COUNT] = {
+ "AAGUN",
+ "MIG",
+ "SFROZEN",
+ "AIRFIELD",
+ "BATTLE",
+ "BMAP",
+ "BOMBRUN",
+ "DPTHCHRG",
+ "GRVESTNE",
+ "MONTPASS",
+ "MTNKFACT",
+ "CRONTEST",
+ "OILDRUM",
+ "ALLYEND",
+ "RADRRAID",
+ "SHIPYARD",
+ "SHORBOMB",
+ "SITDUCK",
+ "SLNTSRVC",
+ "SNOWBASE",
+ "EXECUTE",
+ "REDINTRO", // low res.
+ "NUKESTOK",
+ "V2ROCKET",
+ "SEARCH",
+ "BINOC",
+ "ELEVATOR",
+ "FROZEN",
+ "MCV",
+ "SHIPSINK",
+ "SOVMCV",
+ "TRINITY",
+ "ALLYMORF",
+ "APCESCPE",
+ "BRDGTILT",
+ "CRONFAIL",
+ "STRAFE",
+ "DESTROYR",
+ "DOUBLE",
+ "FLARE",
+ "SNSTRAFE",
+ "LANDING",
+ "ONTHPRWL",
+ "OVERRUN",
+ "SNOWBOMB",
+ "SOVCEMET",
+ "TAKE_OFF",
+ "TESLA",
+ "SOVIET8",
+ "SPOTTER",
+ "ALLY1",
+ "ALLY2",
+ "ALLY4",
+ "SOVFINAL",
+ "ASSESS",
+ "SOVIET10",
+ "DUD",
+ "MCV_LAND",
+ "MCVBRDGE",
+ "PERISCOP",
+ "SHORBOM1",
+ "SHORBOM2",
+ "SOVBATL",
+ "SOVTSTAR",
+ "AFTRMATH",
+ "SOVIET11",
+ "MASASSLT",
+ "ENGLISH", // High res.
+ "SOVIET1",
+ "SOVIET2",
+ "SOVIET3",
+ "SOVIET4",
+ "SOVIET5",
+ "SOVIET6",
+ "SOVIET7",
+ "PROLOG",
+ "AVERTED",
+ "COUNTDWN",
+ "MOVINGIN",
+ "ALLY10",
+ "ALLY12",
+ "ALLY5",
+ "ALLY6",
+ "ALLY8",
+ "TANYA1",
+ "TANYA2",
+ "ALLY10B",
+ "ALLY11",
+ "ALLY14",
+ "ALLY9",
+ "SPY",
+ "TOOFAR",
+ "SOVIET12",
+ "SOVIET13",
+ "SOVIET9",
+ "BEACHEAD",
+ "SOVIET14",
+ "SIZZLE",
+ "SIZZLE2",
+ "ANTEND",
+ "ANTINTRO"
+};
+
+
+/***************************************************************************
+** Relative coordinate offsets from the center of a cell for each
+** of the legal positions that an object in a cell may stop at. Only infantry
+** are allowed to stop at other than the center of the cell.
+*/
+COORDINATE const StoppingCoordAbs[5] = {
+ 0x00800080L, // center
+ 0x00400040L, // upper left
+ 0x004000C0L, // upper right
+ 0x00C00040L, // lower left
+ 0x00C000C0L // lower right
+};
+
+
+/***************************************************************************
+** Converts pixel values (cell relative) into the appropriate lepton (sub cell)
+** value. This is used to convert pixel (screen) coordinates into the underlying
+** coordinate system.
+*/
+unsigned char const Pixel2Lepton[24] = {
+ 0x00,0x0B,0x15,0x20,0x2B,0x35,0x40,0x4B,
+ 0x55,0x60,0x6B,0x75,0x80,0x8B,0x95,0xA0,
+ 0xAB,0xB5,0xC0,0xCB,0xD5,0xE0,0xEB,0xF5
+};
+
+
+/***************************************************************************
+** This array is used to index a facing in order to retrieve a cell
+** offset that, when added to another cell, will achieve the adjacent cell
+** in the indexed direction.
+*/
+CELL const AdjacentCell[FACING_COUNT] = {
+ -(MAP_CELL_W), // North
+ -(MAP_CELL_W-1), // North East
+ 1, // East
+ MAP_CELL_W+1, // South East
+ MAP_CELL_W, // South
+ MAP_CELL_W-1, // South West
+ -1, // West
+ -(MAP_CELL_W+1) // North West
+};
+
+COORDINATE const AdjacentCoord[FACING_COUNT] = {
+ 0xFF000000L,
+ 0xFF000100L,
+ 0x00000100L,
+ 0x01000100L,
+ 0x01000000L,
+ 0x0100FF00L,
+ 0x0000FF00L,
+ 0xFF00FF00L
+};
+
+
+/***************************************************************************
+** This specifies the odds of receiving the various random crate power
+** ups. The odds are expressed as "shares" of 100 percent.
+*/
+int CrateShares[CRATE_COUNT] = {
+ 50, // CRATE_MONEY
+ 20, // CRATE_UNIT
+ 3, // CRATE_PARA_BOMB
+ 1, // CRATE_HEAL_BASE
+ 3, // CRATE_CLOAK
+ 5, // CRATE_EXPLOSION
+ 5, // CRATE_NAPALM
+ 20, // CRATE_SQUAD
+ 1, // CRATE_DARKNESS
+ 1, // CRATE_REVEAL
+ 3, // CRATE_SONAR
+ 10, // CRATE_ARMOR
+ 10, // CRATE_SPEED
+ 10, // CRATE_FIREPOWER
+ 1, // CRATE_ICBM
+ 1, // CRATE_TIMEQUAKE
+ 3, // CRATE_INVULN
+ 5 // CRATE_VORTEX
+};
+
+AnimType CrateAnims[CRATE_COUNT] = {
+ ANIM_NONE, // CRATE_MONEY
+ ANIM_NONE, // CRATE_UNIT
+ ANIM_NONE, // CRATE_PARA_BOMB
+ ANIM_NONE, // CRATE_HEAL_BASE
+ ANIM_NONE, // CRATE_CLOAK
+ ANIM_NONE, // CRATE_EXPLOSION
+ ANIM_NONE, // CRATE_NAPALM
+ ANIM_NONE, // CRATE_SQUAD
+ ANIM_NONE, // CRATE_DARKNESS
+ ANIM_NONE, // CRATE_REVEAL
+ ANIM_NONE, // CRATE_SONAR
+ ANIM_NONE, // CRATE_ARMOR
+ ANIM_NONE, // CRATE_SPEED
+ ANIM_NONE, // CRATE_FIREPOWER
+ ANIM_NONE, // CRATE_ICBM
+ ANIM_NONE, // CRATE_TIMEQUAKE
+ ANIM_NONE, // CRATE_INVULN
+ ANIM_NONE // CRATE_VORTEX
+};
+
+int CrateData[CRATE_COUNT] = {
+ 0, // CRATE_MONEY
+ 0, // CRATE_UNIT
+ 0, // CRATE_PARA_BOMB
+ 0, // CRATE_HEAL_BASE
+ 0, // CRATE_CLOAK
+ 0, // CRATE_EXPLOSION
+ 0, // CRATE_NAPALM
+ 0, // CRATE_SQUAD
+ 0, // CRATE_DARKNESS
+ 0, // CRATE_REVEAL
+ 0, // CRATE_SONAR
+ 0, // CRATE_ARMOR
+ 0, // CRATE_SPEED
+ 0, // CRATE_FIREPOWER
+ 0, // CRATE_ICBM
+ 0, // CRATE_TIMEQUAKE
+ 0, // CRATE_INVULN
+ 0 // CRATE_VORTEX
+};
+
+char const * const CrateNames[CRATE_COUNT] = {
+ "Money",
+ "Unit",
+ "ParaBomb",
+ "HealBase",
+ "Cloak",
+ "Explosion",
+ "Napalm",
+ "Squad",
+ "Darkness",
+ "Reveal",
+ "Sonar",
+ "Armor",
+ "Speed",
+ "Firepower",
+ "ICBM",
+ "TimeQuake",
+ "Invulnerability",
+ "ChronalVortex"
+};
+
+
+/***************************************************************************
+** This converts 0..255 facing values into either 8, 16, or 32 facing values.
+** Note: a simple shift won't suffice because 0..255 facing values should
+** be converted to the CLOSEST appropriate facing, NOT rounded down to the
+** nearest facing.
+*/
+unsigned char const Facing8[256] = {
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+ 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
+ 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
+ 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+ 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
+ 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+ 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+};
+
+
+unsigned char const Facing16[256] = {
+ 0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,
+ 2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,
+ 4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,
+ 6,6,6,6,6,6,6,6,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,8,8,8,8,8,8,8,8,
+ 8,8,8,8,8,8,8,8,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,12,12,12,12,12,12,12,
+ 12,12,12,12,12,12,12,12,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,14,14,14,14,14,14,14,14,
+ 14,14,14,14,14,14,14,14,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,0,0,0,0,0,0,0,0
+};
+
+
+signed char const Rotation16[256] = {
+ 0,1,2,3,4,5,6,7,-8,-7,-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6,7,-8,-7,-6,-5,-4,-3,-2,-1,
+ 0,1,2,3,4,5,6,7,-8,-7,-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6,7,-8,-7,-6,-5,-4,-3,-2,-1,
+ 0,1,2,3,4,5,6,7,-8,-7,-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6,7,-8,-7,-6,-5,-4,-3,-2,-1,
+ 0,1,2,3,4,5,6,7,-8,-7,-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6,7,-8,-7,-6,-5,-4,-3,-2,-1,
+ 0,1,2,3,4,5,6,7,-8,-7,-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6,7,-8,-7,-6,-5,-4,-3,-2,-1,
+ 0,1,2,3,4,5,6,7,-8,-7,-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6,7,-8,-7,-6,-5,-4,-3,-2,-1,
+ 0,1,2,3,4,5,6,7,-8,-7,-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6,7,-8,-7,-6,-5,-4,-3,-2,-1,
+ 0,1,2,3,4,5,6,7,-8,-7,-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6,7,-8,-7,-6,-5,-4,-3,-2,-1
+};
+
+
+/*
+** This table incorporates a compensating factor for the distortion caused
+** by 3D-Studio when it tries to render 45% angles.
+*/
+unsigned char const Facing32[256] = {
+ 0,0,0,0,0,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,
+ 3,4,4,4,4,4,4,5,5,5,5,5,5,5,6,6,6,6,6,6,6,7,7,7,7,7,7,7,8,8,8,8,
+ 8,8,8,9,9,9,9,9,9,9,10,10,10,10,10,10,10,11,11,11,11,11,11,11,12,12,12,12,12,12,12,12,
+ 13,13,13,13,13,13,13,13,14,14,14,14,14,14,14,14,14,15,15,15,15,15,15,15,15,15,16,16,16,16,16,16,
+ 16,16,16,16,16,17,17,17,17,17,17,17,17,17,18,18,18,18,18,18,18,18,18,19,19,19,19,19,19,19,19,19,
+ 19,20,20,20,20,20,20,21,21,21,21,21,21,21,22,22,22,22,22,22,22,23,23,23,23,23,23,23,24,24,24,24,
+ 24,24,24,25,25,25,25,25,25,25,26,26,26,26,26,26,26,27,27,27,27,27,27,27,28,28,28,28,28,28,28,28,
+ 29,29,29,29,29,29,29,29,30,30,30,30,30,30,30,30,30,31,31,31,31,31,31,31,31,31,0,0,0,0,0,0
+};
+
+
+#ifdef OBSOLETE
+unsigned char const Facing32[256] = {
+ 0,0,0,0,
+ 1,1,1,1,1,1,1,1,
+ 2,2,2,2,2,2,2,2,
+ 3,3,3,3,3,3,3,3,
+ 4,4,4,4,4,4,4,4,
+ 5,5,5,5,5,5,5,5,
+ 6,6,6,6,6,6,6,6,
+ 7,7,7,7,7,7,7,7,
+ 8,8,8,8,8,8,8,8,
+ 9,9,9,9,9,9,9,9,
+ 10,10,10,10,10,10,10,10,
+ 11,11,11,11,11,11,11,11,
+ 12,12,12,12,12,12,12,12,
+ 13,13,13,13,13,13,13,13,
+ 14,14,14,14,14,14,14,14,
+ 15,15,15,15,15,15,15,15,
+ 16,16,16,16,16,16,16,16,
+ 17,17,17,17,17,17,17,17,
+ 18,18,18,18,18,18,18,18,
+ 19,19,19,19,19,19,19,19,
+ 20,20,20,20,20,20,20,20,
+ 21,21,21,21,21,21,21,21,
+ 22,22,22,22,22,22,22,22,
+ 23,23,23,23,23,23,23,23,
+ 24,24,24,24,24,24,24,24,
+ 25,25,25,25,25,25,25,25,
+ 26,26,26,26,26,26,26,26,
+ 27,27,27,27,27,27,27,27,
+ 28,28,28,28,28,28,28,28,
+ 29,29,29,29,29,29,29,29,
+ 30,30,30,30,30,30,30,30,
+ 31,31,31,31,31,31,31,31,
+ 0,0,0,0
+};
+#endif
+
+
+/***************************************************************************
+** These are the movement costs (in ticks at fastest speed) to enter each
+** of the given terrain cells.
+*/
+
+int const GroundColor[LAND_COUNT] = {
+ 141, // "Clear" terrain.
+ 141, // Road terrain.
+ 172, // Water.
+ 21, // Impassable rock.
+ 21, // Wall (blocks movement).
+ 158, // Tiberium field.
+ 141, // Beach terrain.
+ 141, // Rocky terrain.
+ 174 // Rocky riverbed.
+};
+
+int const SnowColor[LAND_COUNT] = {
+ 141, // "Clear" terrain.
+ 141, // Road terrain.
+ 172, // Water.
+ 21, // Impassable rock.
+ 21, // Wall (blocks movement).
+ 158, // Tiberium field.
+ 141, // Beach terrain.
+ 141, // Rocky terrain.
+ 174 // Rocky riverbed.
+};
+
+#ifdef NEVER
+int const GroundColor[LAND_COUNT] = {
+ 46, // "Clear" terrain.
+ 44, // Road terrain.
+ BLUE, // Water.
+ DKGREY, // Impassable rock.
+ DKGREY, // Wall (blocks movement).
+ 158, // Tiberium field.
+ 64, // Beach terrain.
+ DKGREY, // Rocky terrain.
+ DKGREY // Rocky riverbed.
+};
+
+int const SnowColor[LAND_COUNT] = {
+ WHITE, // "Clear" terrain.
+ LTGRAY, // Road terrain.
+ BLUE, // Water.
+ DKGREY, // Impassable rock.
+ DKGREY, // Wall (blocks movement).
+ 158, // Tiberium field.
+ LTGRAY, // Beach terrain.
+ DKGREY, // Rocky terrain.
+ DKGREY // Rocky riverbed.
+};
+#endif
+
+GroundType Ground[LAND_COUNT];
+
+
+/***************************************************************************
+** These are the names of the theaters.
+*/
+TheaterDataType const Theaters[THEATER_COUNT] = {
+ {"TEMPERATE","TEMPERAT","TEM"},
+ {"SNOW","SNOW","SNO"},
+ {"INTERIOR","INTERIOR","INT"},
+};
+
+
+unsigned char const RemapCiv2[256] = {
+ 0,1,2,3,4,5,6,209,8,9,10,11,12,13,12,15, // 0..15
+ 16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31, // 16..31
+ 32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47, // 32..47
+ 48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63, // 48..63
+ 64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79, // 64..79
+ 80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95, // 80..95
+ 96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111, // 96..111
+ 112,113,114,115,116,117,187,188,120,121,122,123,124,125,126,127, // 112..127
+ 128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143, // 128..143
+ 144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,209, // 144..159
+ 160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175, // 160..175
+ 176,177,178,179,180,181,182,183,184,185,186,167, 13,189,190,191, // 176..191
+ 192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207, // 192..207
+ 208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223, // 208..223
+ 224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239, // 224..239
+ 240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255 // 240..255
+};
+
+unsigned char const RemapCiv4[256] = {
+ 0,1,2,3,4,5,6,187,8,9,10,11,12,13,14,15, // 0..15
+ 16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31, // 16..31
+ 32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47, // 32..47
+ 48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63, // 48..63
+ 64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79, // 64..79
+ 80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95, // 80..95
+ 96,97,98,99,100,101,102,103,104,105,106,107,108,118,110,119, // 96..111
+ 112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127, // 112..127
+ 128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143, // 128..143
+ 144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159, // 144..159
+ 160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175, // 160..175
+ 176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191, // 176..191
+ 192,193,194,195,196,197,198,199,200,201,202,203,204,205,188,207, // 192..207
+ 208,209,182,211,212,213,214,215,216,217,218,219,220,221,222,223, // 208..223
+ 224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239, // 224..239
+ 240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255 // 240..255
+};
+
+unsigned char const RemapCiv5[256] = {
+ 0,1,2,3,4,5,6,109,8,9,10,11,131,13,14,15, // 0..15
+ 16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31, // 16..31
+ 32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47, // 32..47
+ 48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63, // 48..63
+ 64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79, // 64..79
+ 80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95, // 80..95
+ 96,97,98,99,100,101,102,103,104,105,106,107,108,177,110,178, // 96..111
+ 112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127, // 112..127
+ 128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143, // 128..143
+ 144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159, // 144..159
+ 160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175, // 160..175
+ 176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191, // 176..191
+ 192,193,194,195,196,197,198,199,111,201,202,203,204,205,111,207, // 192..207
+ 208,209,182,211,212,213,214,215,216,217,218,219,220,221,222,223, // 208..223
+ 224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239, // 224..239
+ 240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255 // 240..255
+};
+
+unsigned char const RemapCiv6[256] = {
+ 0,1,2,3,4,5,6,120,8,9,10,11,12,13,238,15, // 0..15
+ 16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31, // 16..31
+ 32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47, // 32..47
+ 48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63, // 48..63
+ 64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79, // 64..79
+ 80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95, // 80..95
+ 96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111, // 96..111
+ 112,113,114,115,116,117,236,206,120,121,122,123,124,125,126,127, // 112..127
+ 128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143, // 128..143
+ 144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,111, // 144..159
+ 160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175, // 160..175
+ 176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191, // 176..191
+ 192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207, // 192..207
+ 208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223, // 208..223
+ 224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239, // 224..239
+ 240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255 // 240..255
+};
+
+unsigned char const RemapCiv7[256] = {
+ 0,1,2,3,4,5,6,7,8,9,10,11,12,13,131,15, // 0..15
+ 16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31, // 16..31
+ 32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47, // 32..47
+ 48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63, // 48..63
+ 64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79, // 64..79
+ 80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95, // 80..95
+ 96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111, // 96..111
+ 112,113,114,115,116,117,157,212,120,121,122,123,124,125,126,127, // 112..127
+ 128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143, // 128..143
+ 144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,7, // 144..159
+ 160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175, // 160..175
+ 176,177,178,179,180,181,182,183,184,185,186,118,119,189,190,191, // 176..191
+ 192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207, // 192..207
+ 208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223, // 208..223
+ 224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239, // 224..239
+ 240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255 // 240..255
+};
+
+unsigned char const RemapCiv8[256] = {
+ 0,1,2,3,4,5,6,182,8,9,10,11,12,13,131,15, // 0..15
+ 16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31, // 16..31
+ 32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47, // 32..47
+ 48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63, // 48..63
+ 64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79, // 64..79
+ 80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95, // 80..95
+ 96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111, // 96..111
+ 112,113,114,115,116,117,215,7,120,121,122,123,124,125,126,127, // 112..127
+ 128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143, // 128..143
+ 144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,182, // 144..159
+ 160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175, // 160..175
+ 176,177,178,179,180,181,182,183,184,185,186,198,199,189,190,191, // 176..191
+ 192,193,194,195,196,197,198,199,111,201,202,203,204,205,206,207, // 192..207
+ 208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223, // 208..223
+ 224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239, // 224..239
+ 240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255 // 240..255
+};
+
+unsigned char const RemapCiv9[256] = {
+ 0,1,2,3,4,5,6,7,8,9,10,11,12,13,7,15, // 0..15
+ 16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31, // 16..31
+ 32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47, // 32..47
+ 48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63, // 48..63
+ 64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79, // 64..79
+ 80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95, // 80..95
+ 96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111, // 96..111
+ 112,113,114,115,116,117,163,165,120,121,122,123,124,125,126,127, // 112..127
+ 128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143, // 128..143
+ 144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,200, // 144..159
+ 160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175, // 160..175
+ 176,177,178,179,180,181,182,183,184,185,186,111,13,189,190,191, // 176..191
+ 192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207, // 192..207
+ 208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223, // 208..223
+ 224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239, // 224..239
+ 240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255 // 240..255
+};
+
+unsigned char const RemapCiv10[256] = {
+ 0,1,2,3,4,5,6,137,8,9,10,11,12,13,15,15, // 0..15
+ 16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31, // 16..31
+ 32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47, // 32..47
+ 48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63, // 48..63
+ 64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79, // 64..79
+ 80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95, // 80..95
+ 96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111, // 96..111
+ 112,113,114,115,116,117,129,131,120,121,122,123,124,125,126,127, // 112..127
+ 128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143, // 128..143
+ 144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,137, // 144..159
+ 160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175, // 160..175
+ 176,177,178,179,180,181,182,183,184,185,186,163,165,189,190,191, // 176..191
+ 192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207, // 192..207
+ 208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223, // 208..223
+ 224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239, // 224..239
+ 240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255 // 240..255
+};
+
+unsigned char const RemapEmber[256] = {
+#define CEC CC_EMBER_COLOR
+ 0,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,BLACK,CEC,CEC,CEC,
+ CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,
+ CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,
+ CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,
+ CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,
+ CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,
+ CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,
+ CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,
+ CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,
+ CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,
+ CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,
+ CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,
+ CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,
+ CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,
+ CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,
+ CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC,CEC
+};
+
+
+//char const Keys[] =
+// "[PublicKey]\n"
+// "1=AgkCbXo9sKMHOBk=\n"
+//#ifdef CHEAT_KEYS
+// "[PrivateKey]\n"
+// "1=AggxFU55vc7LYQ==\n"
+//#endif
+// "\n";
+
+char const Keys[] =
+"[PublicKey]\n"
+"1=AihRvNoIbTn85FZRYNZRcT+i6KpU+maCsEqr3Q5q+LDB5tH7Tz2qQ38V\n"
+#ifdef CHEAT_KEYS
+"[PrivateKey]\n"
+"1=AigKVje8mROcR8QixnxUEF5b29Curkq01DNDWCdOG99XBqH79OaCiTCB\n"
+#endif
+"\n";
diff --git a/CODE/CONTROL.CPP b/CODE/CONTROL.CPP
new file mode 100644
index 0000000..6fa9224
--- /dev/null
+++ b/CODE/CONTROL.CPP
@@ -0,0 +1,226 @@
+/*
+** Command & Conquer Red Alert(tm)
+** Copyright 2025 Electronic Arts Inc.
+**
+** This program is free software: you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation, either version 3 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program. If not, see .
+*/
+
+/* $Header: /CounterStrike/CONTROL.CPP 1 3/03/97 10:24a Joe_bostic $ */
+/***********************************************************************************************
+ *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
+ ***********************************************************************************************
+ * *
+ * Project Name : Command & Conquer *
+ * *
+ * File Name : CONTROL.CPP *
+ * *
+ * Programmer : Joe L. Bostic *
+ * *
+ * Start Date : 01/15/95 *
+ * *
+ * Last Update : December 5, 1995 [JLB] *
+ * *
+ *---------------------------------------------------------------------------------------------*
+ * Functions: *
+ * ControlClass::Action -- Normal action for control gadget objects. *
+ * ControlClass::ControlClass -- Constructor for control class objects. *
+ * ControlClass::ControlClass -- Copy constructor for control gadget. *
+ * ControlClass::Draw_Me -- Draw logic for the control class object. *
+ * ControlClass::Get_ID -- Gets the ID number for this gadget. *
+ * ControlClass::Make_Peer -- Assigns a peer gadget to this gadget. *
+ * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+
+#include "function.h"
+
+
+/***********************************************************************************************
+ * ControlClass::ControlClass -- Constructor for control class objects. *
+ * *
+ * This is the normal constructor for control class objects. At this level, it only needs *
+ * to record the ID number assigned to this button. *
+ * *
+ * INPUT: id -- The ID number for this gadget. If the ID number specified is 0, then *
+ * this tells the system that no special ID code should be returned. *
+ * *
+ * x,y -- Pixel coordinate of upper left corner of gadget's region. *
+ * *
+ * w,h -- Pixel dimensions of the gadget's region. *
+ * *
+ * flags -- The input event flags that this gadget recognizes. *
+ * *
+ * sticky-- This this a "sticky" gadget? A sticky gadget is one that takes over the *
+ * gadget list while the mouse button is held down, if the mouse button was *
+ * initially clicked over its region. This is the behavior of "normal" *
+ * buttons in Windows. *
+ * *
+ * OUTPUT: none *
+ * *
+ * WARNINGS: none *
+ * *
+ * HISTORY: *
+ * 01/15/1995 JLB : Created. *
+ *=============================================================================================*/
+ControlClass::ControlClass(unsigned id, int x, int y, int w, int h, unsigned flags, int sticky) :
+ GadgetClass(x, y, w, h, flags, sticky),
+ ID(id),
+ Peer(0)
+{
+}
+
+
+/***********************************************************************************************
+ * ControlClass::ControlClass -- Copy constructor for control gadget. *
+ * *
+ * This copy constructor for a control gadget is used create a duplicate gadget that *
+ * is functionally similar. *
+ * *
+ * INPUT: control -- Reference to the gadget that is to be copied. *
+ * *
+ * OUTPUT: none *
+ * *
+ * WARNINGS: none *
+ * *
+ * HISTORY: *
+ * 12/05/1995 JLB : Created. *
+ *=============================================================================================*/
+ControlClass::ControlClass(ControlClass const & control) :
+ GadgetClass(control),
+ ID(control.ID),
+ Peer(control.Peer)
+{
+}
+
+/***********************************************************************************************
+ * ControlClass::Action -- Normal action for control gadget objects. *
+ * *
+ * This function gets called when the input event that this control gadget is looking for *
+ * occurs. In such a case, the return key code value is changed to the gadget's ID number *
+ * with the special button bit flag attached. *
+ * *
+ * INPUT: flags -- The event that triggered this function call. If this value is NULL, then *
+ * this is a forced (probably due to the sticky flag) call and the key code *
+ * is not altered. *
+ * *
+ * key -- Reference to the key code that will be returned by the controlling *
+ * Input() function. *
+ * *
+ * OUTPUT: bool; Should further list processing be aborted? *
+ * *
+ * WARNINGS: none *
+ * *
+ * HISTORY: *
+ * 01/15/1995 JLB : Created. *
+ *=============================================================================================*/
+int ControlClass::Action(unsigned flags, KeyNumType & key)
+{
+
+ /*
+ ** Only if the flags indicate that a recognized action has occurred, do the
+ ** normal processing of this gadget and set return value to the gadget ID.
+ */
+ if (flags) {
+ if (ID) {
+ key = (KeyNumType)(ID | KN_BUTTON);
+ } else {
+ key = KN_NONE;
+ }
+ }
+
+ /*
+ ** If there is a peer link established, inform that gadget of this
+ ** action call.
+ */
+ if (Peer) {
+ Peer->Peer_To_Peer(flags, key, *this);
+ }
+
+ return(GadgetClass::Action(flags, key));
+}
+
+
+/***********************************************************************************************
+ * ControlClass::Make_Peer -- Assigns a peer gadget to this gadget. *
+ * *
+ * This function will assign another gadget to this one. That other gadget will receive *
+ * notification of any Action() call to this gadget. Presumably, this is how one gadget *
+ * can automatically adapt to changes in another. Say for example, a slider bar can affect *
+ * the list box it is attached to. *
+ * *
+ * INPUT: gadget -- The gadget to inform when any Action() function is called. *
+ * *
+ * OUTPUT: none *
+ * *
+ * WARNINGS: none *
+ * *
+ * HISTORY: *
+ * 01/16/1995 JLB : Created. *
+ *=============================================================================================*/
+void ControlClass::Make_Peer(GadgetClass & gadget)
+{
+ Peer = &gadget;
+}
+
+
+/***********************************************************************************************
+ * ControlClass::Get_ID -- Gets the ID number for this gadget. *
+ * *
+ * This function will query and return with the ID number for this gadget. It is primarily *
+ * used by the Extract_Gadget() function. *
+ * *
+ * INPUT: none *
+ * *
+ * OUTPUT: Returns with the ID number for this gadget. If zero is returned, this means that *
+ * no ID was assigned to this gadget. This is a special case since a zero value will *
+ * never be returned as a pseudo-key as is done with non-zero values. *
+ * *
+ * WARNINGS: none *
+ * *
+ * HISTORY: *
+ * 01/16/1995 JLB : Created. *
+ *=============================================================================================*/
+unsigned ControlClass::Get_ID(void) const
+{
+ return(ID);
+}
+
+
+/***********************************************************************************************
+ * ControlClass::Draw_Me -- Draw logic for the control class object. *
+ * *
+ * This is called when the control object might need to be redrawn or when redrawing is *
+ * necessary. Since at this level of the class hierarchy, no actual drawing occurs, this *
+ * routine doesn't perform any rendering. It does, however, inform any peer attached *
+ * object that a Draw_Me function has been called. Presumably, the attached peer gadget *
+ * might very well need to be redrawn as a result of some action by this gadget. Since this *
+ * gadget might, more than likely, be of the "sticky" variety, a normal call to Draw_Me *
+ * for the other gadget will not occur. It must rely on the call by this routine in order *
+ * to update correctly. A typical example of this would be a slider that is attached to *
+ * a list box. As the slider is being drug around, the attached list box must be redrawn. *
+ * *
+ * INPUT: forced -- Should the redraw be forced regardless of the redraw flag? *
+ * *
+ * OUTPUT: bool; Was the gadget redrawn? *
+ * *
+ * WARNINGS: none *
+ * *
+ * HISTORY: *
+ * 01/16/1995 JLB : Created. *
+ *=============================================================================================*/
+int ControlClass::Draw_Me(int forced)
+{
+ if (Peer) {
+ Peer->Draw_Me();
+ }
+ return(GadgetClass::Draw_Me(forced));
+}
diff --git a/CODE/CONTROL.H b/CODE/CONTROL.H
new file mode 100644
index 0000000..078db39
--- /dev/null
+++ b/CODE/CONTROL.H
@@ -0,0 +1,90 @@
+/*
+** Command & Conquer Red Alert(tm)
+** Copyright 2025 Electronic Arts Inc.
+**
+** This program is free software: you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation, either version 3 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program. If not, see .
+*/
+
+/* $Header: /CounterStrike/CONTROL.H 1 3/03/97 10:24a Joe_bostic $ */
+/***********************************************************************************************
+ *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
+ ***********************************************************************************************
+ * *
+ * Project Name : Command & Conquer *
+ * *
+ * File Name : CONTROL.H *
+ * *
+ * Programmer : Joe L. Bostic *
+ * *
+ * Start Date : 01/15/95 *
+ * *
+ * Last Update : January 15, 1995 [JLB] *
+ * *
+ *---------------------------------------------------------------------------------------------*
+ * Functions: *
+ * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+
+#ifndef CONTROL_H
+#define CONTROL_H
+
+#include "gadget.h"
+
+/***************************************************************************
+ * ControlClass -- Region tracking class *
+ * *
+ * INPUT: int x -- x position of gadget *
+ * int y -- y position of gadget *
+ * int w -- width of gadget *
+ * int h -- height of gadget *
+ * UWORD flags -- see enumeration choices *
+ * *
+ * OUTPUT: 0 = new scenario created, -1 = not *
+ * WARNINGS: This class is Abstract (cannot make an instance of it) *
+ * *
+ * HISTORY: *
+ * 01/03/1995 MML : Created. *
+ *=========================================================================*/
+class ControlClass : public GadgetClass
+{
+ public:
+ ControlClass(NoInitClass const & x) : GadgetClass(x) {};
+ ControlClass(unsigned id, int x, int y, int w, int h, unsigned flags=LEFTPRESS|RIGHTPRESS, int sticky=false);
+ ControlClass(ControlClass const & control);
+
+ virtual void Make_Peer(GadgetClass & gadget);
+
+ /*
+ ** Render support function.
+ */
+ virtual int Draw_Me(int forced=false);
+
+ /*
+ ** This is the ID number for this control gadget. This number is used to generate
+ ** a special pseudo-key when the gadget detects valid input.
+ */
+ unsigned ID;
+
+ protected:
+ virtual unsigned Get_ID(void) const;
+ virtual int Action(unsigned flags, KeyNumType & key);
+
+ /*
+ ** This points to the peer button to inform when something happens to this
+ ** gadget.
+ */
+ GadgetClass * Peer;
+};
+
+#endif
+
diff --git a/CODE/COORD.CPP b/CODE/COORD.CPP
new file mode 100644
index 0000000..b33da6b
--- /dev/null
+++ b/CODE/COORD.CPP
@@ -0,0 +1,652 @@
+/*
+** Command & Conquer Red Alert(tm)
+** Copyright 2025 Electronic Arts Inc.
+**
+** This program is free software: you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation, either version 3 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program. If not, see .
+*/
+
+/* $Header: /CounterStrike/COORD.CPP 1 3/03/97 10:24a Joe_bostic $ */
+/***********************************************************************************************
+ *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
+ ***********************************************************************************************
+ * *
+ * Project Name : Command & Conquer *
+ * *
+ * File Name : COORD.CPP *
+ * *
+ * Programmer : Joe L. Bostic *
+ * *
+ * Start Date : September 10, 1993 *
+ * *
+ * Last Update : July 22, 1996 [JLB] *
+ * *
+ * Support code to handle the coordinate system is located in this module. *
+ * Routines here will be called QUITE frequently during play and must be *
+ * as efficient as possible. *
+ * *
+ *---------------------------------------------------------------------------------------------*
+ * Functions: *
+ * Cardinal_To_Fixed -- Converts cardinal numbers into a fixed point number. *
+ * Coord_Cell -- Convert a coordinate into a cell number. *
+ * Coord_Move -- Moves a coordinate an arbitrary direction for an arbitrary distance *
+ * Coord_Scatter -- Determines a random coordinate from an anchor point. *
+ * Coord_Spillage_List -- Calculate a spillage list for the dirty rectangle specified. *
+ * Coord_Spillage_List -- Determines the offset list for cell spillage/occupation. *
+ * Distance -- Determines the cell distance between two cells. *
+ * Distance -- Determines the lepton distance between two coordinates. *
+ * Distance -- Fetch distance between two target values. *
+ * Fixed_To_Cardinal -- Converts a fixed point number into a cardinal number. *
+ * Normal_Move_Point -- Moves point with tilt compensation. *
+ * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+
+#include "function.h"
+
+
+/***********************************************************************************************
+ * Coord_Cell -- Convert a coordinate into a cell number. *
+ * *
+ * This routine will convert the specified coordinate value into a cell number. This is *
+ * useful to determine the map index number into the cell array that corresponds to a *
+ * particular coordinate. *
+ * *
+ * INPUT: coord -- The coordinate to convert into a cell number. *
+ * *
+ * OUTPUT: Returns with the cell number that corresponds to the coordinate specified. *
+ * *
+ * WARNINGS: none *
+ * *
+ * HISTORY: *
+ * 06/17/1996 JLB : Created. *
+ *=============================================================================================*/
+CELL Coord_Cell(COORDINATE coord)
+{
+ CELL_COMPOSITE cell;
+ cell.Cell = 0;
+ cell.Sub.X = ((COORD_COMPOSITE &)coord).Sub.X.Sub.Cell;
+ cell.Sub.Y = ((COORD_COMPOSITE &)coord).Sub.Y.Sub.Cell;
+ return(cell.Cell);
+// return(XY_Cell(((COORD_COMPOSITE)coord).Sub.X, ((COORD_COMPOSITE)composite).Sub.Y));
+}
+
+
+/***********************************************************************************************
+ * Distance -- Fetch distance between two target values. *
+ * *
+ * This routine will determine the lepton distance between the two specified target *
+ * values. *
+ * *
+ * INPUT: target1 -- First target value. *
+ * *
+ * target2 -- Second target value. *
+ * *
+ * OUTPUT: Returns with the lepton distance between the two target values. *
+ * *
+ * WARNINGS: Be sure that the targets are legal before calling this routine. Otherwise, the *
+ * return value is meaningless. *
+ * *
+ * HISTORY: *
+ * 06/17/1996 JLB : Created. *
+ *=============================================================================================*/
+int Distance(TARGET target1, TARGET target2)
+{
+ return(Distance(As_Coord(target1), As_Coord(target2)));
+}
+
+
+/***********************************************************************************************
+ * Distance -- Determines the lepton distance between two coordinates. *
+ * *
+ * This routine is used to determine the distance between two coordinates. It uses the *
+ * Dragon Strike method of distance determination and thus it is very fast. *
+ * *
+ * INPUT: coord1 -- First coordinate. *
+ * *
+ * coord2 -- Second coordinate. *
+ * *
+ * OUTPUT: Returns the lepton distance between the two coordinates. *
+ * *
+ * WARNINGS: none *
+ * *
+ * HISTORY: *
+ * 05/27/1994 JLB : Created. *
+ *=============================================================================================*/
+int Distance(COORDINATE coord1, COORDINATE coord2)
+{
+ int diff1, diff2;
+
+ diff1 = Coord_Y(coord1) - Coord_Y(coord2);
+ if (diff1 < 0) diff1 = -diff1;
+ diff2 = Coord_X(coord1) - Coord_X(coord2);
+ if (diff2 < 0) diff2 = -diff2;
+ if (diff1 > diff2) {
+ return(diff1 + ((unsigned)diff2 / 2));
+ }
+ return(diff2 + ((unsigned)diff1 / 2));
+}
+
+
+/***********************************************************************************************
+ * Coord_Spillage_List -- Determines the offset list for cell spillage/occupation. *
+ * *
+ * This routine will take an arbitrary position and object size and return with a list of *
+ * cell offsets from the current cell for all cells that are overlapped by the object. The *
+ * first cell offset is always zero, so to just get the adjacent spill cell list, add one *
+ * to the return pointer. *
+ * *
+ * INPUT: coord -- The coordinate to examine. *
+ * *
+ * maxsize -- The maximum width/height of the object (pixels). *
+ * *
+ * OUTPUT: Returns with a pointer to a spillage list. *
+ * *
+ * WARNINGS: The algorithm is limited to working with a maxsize of 48 or less. Larger values *
+ * will generate an incomplete overlap list. *
+ * *
+ * HISTORY: *
+ * 11/06/1993 JLB : Created. *
+ * 03/25/1994 JLB : Added width optimization. *
+ * 04/29/1994 JLB : Converted to C. *
+ * 06/03/1994 JLB : Converted to general purpose spillage functionality. *
+ * 01/07/1995 JLB : Manually calculates spillage list for large objects. *
+ *=============================================================================================*/
+short const * Coord_Spillage_List(COORDINATE coord, int maxsize)
+{
+ static short const _MoveSpillage[(int)FACING_COUNT+1][5] = {
+ {0, -MAP_CELL_W, REFRESH_EOL, 0, 0}, // N
+ {0, -MAP_CELL_W, 1, -(MAP_CELL_W-1), REFRESH_EOL}, // NE
+ {0, 1, REFRESH_EOL, 0, 0}, // E
+ {0, 1, MAP_CELL_W, MAP_CELL_W+1, REFRESH_EOL}, // SE
+ {0, MAP_CELL_W, REFRESH_EOL, 0, 0}, // S
+ {0, -1, MAP_CELL_W, MAP_CELL_W-1, REFRESH_EOL}, // SW
+ {0, -1, REFRESH_EOL, 0, 0}, // W
+ {0, -1, -MAP_CELL_W, -(MAP_CELL_W+1), REFRESH_EOL}, // NW
+ {0, REFRESH_EOL, 0, 0, 0} // non-moving.
+ };
+ static short _manual[10];
+//; 00 = on axis
+//; 01 = below axis
+//; 10 = above axis
+//; 11 = undefined
+ static signed char const _SpillTable[16] = {8,6,2,-1,0,7,1,-1,4,5,3,-1,-1,-1,-1,-1};
+ int index=0;
+ int x,y;
+
+ /*
+ ** For mondo-enourmo-gigundo objects, use a prebuilt mammoth table
+ ** that covers a 5x5 square region.
+ */
+ if (maxsize > ICON_PIXEL_W * 2) {
+ static short const _gigundo[] = {
+ -((2*MAP_CELL_W)-2),-((2*MAP_CELL_W)-1),-((2*MAP_CELL_W)),-((2*MAP_CELL_W)+1),-((2*MAP_CELL_W)+2),
+ -((1*MAP_CELL_W)-2),-((1*MAP_CELL_W)-1),-((1*MAP_CELL_W)),-((1*MAP_CELL_W)+1),-((1*MAP_CELL_W)+2),
+ -((0*MAP_CELL_W)-2),-((0*MAP_CELL_W)-1),-((0*MAP_CELL_W)),-((0*MAP_CELL_W)+1),-((0*MAP_CELL_W)+2),
+ ((1*MAP_CELL_W)-2),((1*MAP_CELL_W)-1),((1*MAP_CELL_W)),((1*MAP_CELL_W)+1),((1*MAP_CELL_W)+2),
+ +((2*MAP_CELL_W)-2),+((2*MAP_CELL_W)-1),+((2*MAP_CELL_W)),+((2*MAP_CELL_W)+1),+((2*MAP_CELL_W)+2),
+ REFRESH_EOL
+ };
+ return(&_gigundo[0]);
+ }
+
+ /*
+ ** For very large objects, build the overlap list by hand. This is time consuming, but
+ ** not nearly as time consuming as drawing even a single cell unnecessarily.
+ */
+ if (maxsize > ICON_PIXEL_W) {
+ maxsize = min(maxsize, (ICON_PIXEL_W*2))/2;
+
+ x = (ICON_PIXEL_W * Coord_XLepton(coord)) / ICON_LEPTON_W;
+ y = (ICON_PIXEL_H * Coord_YLepton(coord)) / ICON_LEPTON_H;
+ int left = x-maxsize;
+ int right = x+maxsize;
+ int top = y-maxsize;
+ int bottom = y+maxsize;
+
+ _manual[index++] = 0;
+ if (left < 0) _manual[index++] = -1;
+ if (right >= ICON_PIXEL_W) _manual[index++] = 1;
+ if (top < 0) _manual[index++] = -MAP_CELL_W;
+ if (bottom >= ICON_PIXEL_H) _manual[index++] = MAP_CELL_W;
+ if (left < 0 && top < 0) _manual[index++] = -(MAP_CELL_W+1);
+ if (right >= ICON_PIXEL_W && bottom >= ICON_PIXEL_H) _manual[index++] = MAP_CELL_W+1;
+ if (left < 0 && bottom >= ICON_PIXEL_H) _manual[index++] = MAP_CELL_W-1;
+ if (right >= ICON_PIXEL_H && top < 0) _manual[index++] = -(MAP_CELL_W-1);
+ _manual[index] = REFRESH_EOL;
+ return(&_manual[0]);
+ }
+
+ /*
+ ** Determine the number of leptons "leeway" allowed this unit.
+ */
+ int posval = Pixel2Lepton[(ICON_PIXEL_W-maxsize)/2];
+
+ x = Coord_XLepton(coord) - 0x0080;
+ y = Coord_YLepton(coord) - 0x0080;
+ if (y > posval) index |= 0x08; // Spilling South.
+ if (y < -posval) index |= 0x04; // Spilling North.
+ if (x > posval) index |= 0x02; // Spilling East.
+ if (x < -posval) index |= 0x01; // Spilling West.
+
+ return(&_MoveSpillage[_SpillTable[index]][0]);
+}
+
+
+/***********************************************************************************************
+ * Coord_Spillage_List -- Calculate a spillage list for the dirty rectangle specified. *
+ * *
+ * Given a center coordinate and a dirty rectangle, calcuate a cell offset list for *
+ * determining such things as overlap and redraw logic. Optionally, the center cell *
+ * location will not be part of the list. *
+ * *
+ * INPUT: coord -- The center coordinate that the dirty rectangle is based off of. *
+ * *
+ * rect -- Reference to the dirty rectangle. *
+ * *
+ * nocenter -- If true, then the center cell offset will not be part of the spillage *
+ * list returned. This is handy when the center cell is known to be *
+ * processed by some other method and it can be safely and efficiently *
+ * ignored by the list generated. *
+ * *
+ * OUTPUT: Returns with a pointer to the spillage list that corresponds to the data *
+ * specified. This is a pointer to a static buffer and as such it will only be valid *
+ * until the next time that this routine is called. *
+ * *
+ * WARNINGS: none *
+ * *
+ * HISTORY: *
+ * 07/22/1996 JLB : Created. *
+ *=============================================================================================*/
+short const * Coord_Spillage_List(COORDINATE coord, Rect const & rect, bool nocenter)
+{
+ if (!rect.Is_Valid()) {
+ static short const _list[] = {REFRESH_EOL};
+ return(_list);
+ }
+
+ CELL coordcell = Coord_Cell(coord);
+ LEPTON x = Coord_X(coord);
+ LEPTON y = Coord_Y(coord);
+
+ /*
+ ** Add the rectangle values to the coordinate in order to normalize the start and end
+ ** corners of the rectangle. The values are now absolute to the real game world rather
+ ** than relative to the coordinate.
+ */
+ LEPTON_COMPOSITE startx;
+ LEPTON_COMPOSITE starty;
+ LEPTON_COMPOSITE endx;
+ LEPTON_COMPOSITE endy;
+ startx.Raw = (int)x + (short)Pixel_To_Lepton(rect.X);
+ starty.Raw = (int)y + (short)Pixel_To_Lepton(rect.Y);
+ endx.Raw = startx.Raw + Pixel_To_Lepton(rect.Width-1);
+ endy.Raw = starty.Raw + Pixel_To_Lepton(rect.Height-1);
+
+ /*
+ ** Determine the upper left and lower right cell indexes. This is a simple conversion from
+ ** their lepton counterpart. These cells values are used to form the bounding box for the
+ ** map offset list.
+ */
+ int cellx = startx.Sub.Cell;
+ int cellx2 = endx.Sub.Cell;
+ int celly = starty.Sub.Cell;
+ int celly2 = endy.Sub.Cell;
+
+ /*
+ ** Generate the spillage list by counting off the rows and colums of the cells
+ ** that are affected. This is easy since the upper left and lower right corner cells
+ ** are known.
+ */
+ int count = 0;
+ static short _spillagelist[128];
+ short * ptr = _spillagelist;
+ for (int yy = celly; yy <= celly2; yy++) {
+ for (int xx = cellx; xx <= cellx2; xx++) {
+ short offset = (XY_Cell(xx, yy) - coordcell);
+ if (!nocenter || offset != 0) {
+ *ptr++ = offset;
+ count++;
+ if (count+2 >= ARRAY_SIZE(_spillagelist)) break;
+ }
+ }
+ if (count+2 >= ARRAY_SIZE(_spillagelist)) break;
+ }
+
+ /*
+ ** Cap the list with the end of list marker and then return a pointer
+ ** to the completed list.
+ */
+ *ptr = REFRESH_EOL;
+ return(_spillagelist);
+}
+
+
+/***********************************************************************************************
+ * Coord_Move -- Moves a coordinate an arbitrary direction for an arbitrary distance *
+ * *
+ * This function will move a coordinate in a using SIN and COS arithmetic. *
+ * *
+ * INPUT: start -- The starting coordinate. *
+ * *
+ * dir -- The direction to move the coordinate. *
+ * *
+ * distance -- The distance to move the coordinate position (in leptons). *
+ * *
+ * OUTPUT: Returns the new coordinate position. *
+ * *
+ * WARNINGS: This routine uses multiplies -- use with caution. *
+ * *
+ * HISTORY: *
+ * 05/27/1994 JLB : Created. *
+ *=============================================================================================*/
+COORDINATE Coord_Move(COORDINATE start, register DirType dir, unsigned short distance)
+{
+#ifdef NEVER
+ short x = Coord_X(start);
+ short y = Coord_Y(start);
+
+ Move_Point(x, y, dir, distance);
+ return(XY_Coord(x,y));
+#endif
+
+ Move_Point(*(short *)&start, *(((short *)&start)+1), dir, distance);
+ return(start);
+}
+
+
+/***********************************************************************************************
+ * Coord_Scatter -- Determines a random coordinate from an anchor point. *
+ * *
+ * This routine will perform a scatter algorithm on the specified *
+ * anchor point in order to return with another coordinate that is *
+ * randomly nearby the original. Typical use of this would be for *
+ * missile targeting. *
+ * *
+ * INPUT: coord -- This is the anchor coordinate. *
+ * *
+ * distance -- This is the distance in pixels that the scatter *
+ * should fall within. *
+ * *
+ * lock -- bool; Convert the new coordinate into a center *
+ * cell based coordinate? *
+ * *
+ * OUTPUT: Returns with a new coordinate that is nearby the original. *
+ * *
+ * WARNINGS: Maximum pixel scatter distance is 255. *
+ * *
+ * HISTORY: *
+ * 02/01/1992 JLB : Created. *
+ * 05/13/1992 JLB : Only uses Random(). *
+ *=============================================================================================*/
+COORDINATE Coord_Scatter(COORDINATE coord, unsigned distance, bool lock)
+{
+ COORDINATE newcoord;
+
+ newcoord = Coord_Move(coord, Random_Pick(DIR_N, DIR_MAX), distance);
+
+ if (newcoord & HIGH_COORD_MASK) newcoord = coord;
+
+ if (lock) {
+ newcoord = Coord_Snap(newcoord);
+ }
+
+ return(newcoord);
+}
+
+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" \
+
+void Move_Point(short &x, short &y, register DirType dir, unsigned short distance)
+{
+ 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.
+
+#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
+ x += calcx(CosTable[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
+ y += calcy(SinTable[dir], distance);
+#endif
+// asm add [word ptr start+2],ax
+
+}
+
+
+/***********************************************************************************************
+ * Normal_Move_Point -- Moves point with tilt compensation. *
+ * *
+ * This routine will move the point in the direction and distance specified but it will *
+ * take into account the tilt of the playing field. Typical use of this routine is to *
+ * determine positioning as it relates to the playfield. Turrets are a good example of *
+ * this. *
+ * *
+ * INPUT: x,y -- References to the coordinates to adjust. *
+ * *
+ * dir -- The direction of the desired movement. *
+ * *
+ * distance -- The distance (in coordinate units) to move the point. *
+ * *
+ * OUTPUT: none *
+ * *
+ * WARNINGS: none *
+ * *
+ * HISTORY: *
+ * 12/19/1995 JLB : Created. *
+ *=============================================================================================*/
+// Loss of precision in initializations (8 bits to 7 bits) warning. Hmmm.. can this be fixed?
+//lint -e569
+void Normal_Move_Point(short &x, short &y, register DirType dir, unsigned short distance)
+{
+ static signed 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 signed 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.
+
+ x += calcx(CosTable[dir], distance);
+
+ y += calcy(SinTable[dir] / 2, distance);
+}
diff --git a/CODE/COORDA.ASM b/CODE/COORDA.ASM
new file mode 100644
index 0000000..f8e279f
--- /dev/null
+++ b/CODE/COORDA.ASM
@@ -0,0 +1,134 @@
+;
+; Command & Conquer Red Alert(tm)
+; Copyright 2025 Electronic Arts Inc.
+;
+; This program is free software: you can redistribute it and/or modify
+; it under the terms of the GNU General Public License as published by
+; the Free Software Foundation, either version 3 of the License, or
+; (at your option) any later version.
+;
+; This program is distributed in the hope that it will be useful,
+; but WITHOUT ANY WARRANTY; without even the implied warranty of
+; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+; GNU General Public License for more details.
+;
+; You should have received a copy of the GNU General Public License
+; along with this program. If not, see .
+;
+
+;***************************************************************************
+;** 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 Cardinal_To_Fixed :NEAR
+GLOBAL 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
diff --git a/CODE/CPUID.ASM b/CODE/CPUID.ASM
new file mode 100644
index 0000000..4f58f13
--- /dev/null
+++ b/CODE/CPUID.ASM
@@ -0,0 +1,185 @@
+;
+; Command & Conquer Red Alert(tm)
+; Copyright 2025 Electronic Arts Inc.
+;
+; This program is free software: you can redistribute it and/or modify
+; it under the terms of the GNU General Public License as published by
+; the Free Software Foundation, either version 3 of the License, or
+; (at your option) any later version.
+;
+; This program is distributed in the hope that it will be useful,
+; but WITHOUT ANY WARRANTY; without even the implied warranty of
+; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+; GNU General Public License for more details.
+;
+; You should have received a copy of the GNU General Public License
+; along with this program. If not, see .
+;
+
+; $Header: F:\projects\c&c0\vcs\code\cpuid.asv 5.0 11 Nov 1996 09:40:28 JOE_BOSTIC $
+;***************************************************************************
+;** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S I N C **
+;***************************************************************************
+;* *
+;* Project Name : Command & Conquer *
+;* *
+;* File Name : MMX.ASM *
+;* *
+;* Programmer : Steve Tall *
+;* *
+;* Start Date : May 19th, 1996 *
+;* *
+;* Last Update : May 19th 1996 [ST] *
+;* *
+;*-------------------------------------------------------------------------*
+;* Functions: *
+;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
+
+
+ .586
+ .model flat
+
+;
+; Variables externs
+;
+GLOBAL C CPUType:byte
+;externdef C CPUType:byte
+GLOBAL C VendorID:byte
+;externdef C VendorID:byte
+
+;
+; Function externs
+;
+GLOBAL C Detect_MMX_Availability:near
+;externdef C Detect_MMX_Availability:near
+
+
+ .code
+
+
+;*********************************************************************************************
+;* Detect_MMX_Availability -- Detect the presence of MMX technology. *
+;* *
+;* *
+;* INPUT: Nothing *
+;* *
+;* OUTPUT: True if MMX technology is available. *
+;* *
+;* Warnings: *
+;* *
+;* Note: Based in part on CPUID32.ASM by Intel *
+;* *
+;* HISTORY: *
+;* 05/19/96 ST : Created. *
+;*===========================================================================================*
+
+Detect_MMX_Availability proc C
+
+ local idflag:byte
+ local cputype:byte
+
+;assume processor is at least 386
+;
+;check whether AC bit in eflags can be toggled.
+;If not then processor is 386
+
+ mov [idflag],0
+
+ pushfd ;get Eflags in EAX
+ pop eax
+ mov ecx,eax ;save eflags
+ xor eax,40000h ;toggle AC bit in eflags
+ push eax ;new eflags on stack
+ popfd ;move new value into eflags
+ pushfd ;get new eflags back into eax
+ pop eax
+ xor eax,ecx ;if AC bit not toggled then CPU=386
+ mov [cputype],3
+ jz @@end_get_cpu ;cpu is 386
+
+ push ecx
+ popfd ;restore AC bit in eflags
+
+
+;processor is at least 486
+;
+;Check for ability to set/clear ID flag in EFLAGS
+;ID flag indicates ability of processor to execute the CPUID instruction.
+;486 not guaranteed to have CPUID inst?
+;
+ mov [cputype],4
+ mov eax,ecx ;original EFLAGS
+ xor eax,200000h ;toggle ID bit
+ push eax
+ popfd
+ pushfd
+ pop eax
+ xor eax,ecx ;check if still toggled
+ jz @@end_get_cpu
+
+
+; Execute CPUID instruction to determine vendor, family,
+; model and stepping.
+;
+
+ mov [idflag],1 ;flag ID is available
+
+ xor eax,eax
+ cpuid
+
+ mov dword ptr [VendorID],ebx
+ mov dword ptr [VendorID+4],edx
+ mov dword ptr [VendorID+8],ecx
+ mov dword ptr [VendorID+12]," "
+
+ cmp eax,1 ;check if 1 is valid
+ jl @@end_get_cpu ;inp for cpuid inst.
+
+ xor eax,eax
+ inc eax
+
+ cpuid ;get stepping, model and family
+
+ and ax,0f00H
+ shr ax,08H
+
+ mov [cputype],al
+
+@@end_get_cpu: mov al,[cputype]
+ mov [CPUType],al
+
+
+;
+; We have the CPU type in al now.
+; If we arent on at least a pentium then we can assume there is no MMX
+;
+ cmp al,5
+ jl @@no_mmx
+
+ mov eax,1
+ cpuid
+ test edx,00800000h
+ jz @@no_mmx
+
+;
+; MMX detected - return true
+;
+ mov eax,1
+ ret
+
+
+@@no_mmx: xor eax,eax
+ ret
+
+
+Detect_MMX_Availability endp
+
+
+ .data
+
+CPUType db 0
+VendorID db "Not available",0,0,0,0,0,0
+
+
+end
+
diff --git a/CODE/CRATE.CPP b/CODE/CRATE.CPP
new file mode 100644
index 0000000..bb17217
--- /dev/null
+++ b/CODE/CRATE.CPP
@@ -0,0 +1,185 @@
+/*
+** Command & Conquer Red Alert(tm)
+** Copyright 2025 Electronic Arts Inc.
+**
+** This program is free software: you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation, either version 3 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program. If not, see .
+*/
+
+/* $Header: /CounterStrike/CRATE.CPP 3 3/04/97 3:12p Joe_bostic $ */
+/***********************************************************************************************
+ *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
+ ***********************************************************************************************
+ * *
+ * Project Name : Command & Conquer *
+ * *
+ * File Name : CRATE.CPP *
+ * *
+ * Programmer : Joe L. Bostic *
+ * *
+ * Start Date : 08/26/96 *
+ * *
+ * Last Update : October 14, 1996 [JLB] *
+ * *
+ *---------------------------------------------------------------------------------------------*
+ * Functions: *
+ * CrateClass::Create_Crate -- Create a crate in the cell specified. *
+ * CrateClass::Get_Crate -- Pick up a crate from the cell specified. *
+ * CrateClass::Put_Crate -- Generates crate overlay at cell specified. *
+ * CrateClass::Remove_It -- Removes the crate from wherever it is. *
+ * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+
+#include "function.h"
+
+
+/***********************************************************************************************
+ * CrateClass::Remove_It -- Removes the crate from wherever it is. *
+ * *
+ * This routine will remove the crate from whereever it happens to be. *
+ * *
+ * INPUT: none *
+ * *
+ * OUTPUT: bool; Was the crate found and removed? *
+ * *
+ * WARNINGS: none *
+ * *
+ * HISTORY: *
+ * 08/26/1996 JLB : Created. *
+ *=============================================================================================*/
+bool CrateClass::Remove_It(void)
+{
+ if (Is_Valid()) {
+ Get_Crate(Cell);
+ Make_Invalid();
+ return(true);
+ }
+ return(false);
+}
+
+
+/***********************************************************************************************
+ * CrateClass::Create_Crate -- Create a crate in the cell specified. *
+ * *
+ * This will create a crate in the cell specified. If the crate could not be crated there *
+ * then 'false' will be returned. *
+ * *
+ * INPUT: cell -- The desired cell to place the crate in. *
+ * *
+ * OUTPUT: bool; Was the crate created and placed in the cell? *
+ * *
+ * WARNINGS: It is quite possible for the crate not to have been placed. Only the most clear *
+ * locations are valid for crate placement. *
+ * *
+ * HISTORY: *
+ * 08/26/1996 JLB : Created. *
+ *=============================================================================================*/
+bool CrateClass::Create_Crate(CELL cell)
+{
+ /*
+ ** Remove any existing crate that this crate class is tracking.
+ */
+ Remove_It();
+
+ /*
+ ** Try to place a new crate at the cell specified.
+ */
+ if (Put_Crate(cell)) {
+ Cell = cell;
+ Timer = Random_Pick(Rule.CrateTime * (TICKS_PER_MINUTE/2), Rule.CrateTime * (TICKS_PER_MINUTE*2));
+ Timer.Start();
+ return(true);
+ }
+ return(false);
+}
+
+
+/***********************************************************************************************
+ * CrateClass::Put_Crate -- Generates crate overlay at cell specified. *
+ * *
+ * This helpter routine will examine the cell and place the appropriate crate type into *
+ * the cell specified. If the overlay could not be generated, then 'false' is returned. *
+ * *
+ * INPUT: cell -- The cell to generate the crate overlay in. *
+ * *
+ * OUTPUT: bool; Was the crate overlay generated? *
+ * *
+ * WARNINGS: none *
+ * *
+ * HISTORY: *
+ * 08/26/1996 JLB : Created. *
+ * 10/14/1996 JLB : Takes reference to cell so that tracking can occur. *
+ *=============================================================================================*/
+bool CrateClass::Put_Crate(CELL & cell)
+{
+ int old = ScenarioInit;
+ ScenarioInit = 0;
+
+ if (Map.In_Radar(cell)) {
+ CellClass * cellptr = &Map[cell];
+
+ while (cellptr->Overlay != OVERLAY_NONE && !cellptr->Is_Clear_To_Build(SPEED_FLOAT) && !cellptr->Is_Clear_To_Build(SPEED_FOOT)) {
+ cell = Map.Pick_Random_Location();
+
+ if (Percent_Chance(100 * Rule.WaterCrateChance)) {
+ cell = Map.Nearby_Location(cell, SPEED_FLOAT);
+ } else {
+ cell = Map.Nearby_Location(cell, SPEED_TRACK);
+ }
+ cellptr = &Map[cell];
+ }
+
+ if (cellptr->Is_Clear_To_Build(SPEED_FLOAT)) {
+ new OverlayClass(OVERLAY_WATER_CRATE, cell);
+ } else {
+ new OverlayClass(OVERLAY_WOOD_CRATE, cell);
+ }
+ ScenarioInit = old;
+ return(true);
+ }
+
+ ScenarioInit = old;
+ return(false);
+}
+
+
+/***********************************************************************************************
+ * CrateClass::Get_Crate -- Pick up a crate from the cell specified. *
+ * *
+ * This will remove the crate from the cell specified. *
+ * *
+ * INPUT: cell -- The cell to examine and remove any crate overlays present. *
+ * *
+ * OUTPUT: bool; Was a crate overlay found and removed? *
+ * *
+ * WARNINGS: none *
+ * *
+ * HISTORY: *
+ * 08/26/1996 JLB : Created. *
+ *=============================================================================================*/
+bool CrateClass::Get_Crate(CELL cell)
+{
+ if (Map.In_Radar(cell)) {
+ CellClass * cellptr = &Map[cell];
+
+ if (cellptr->Overlay == OVERLAY_WOOD_CRATE ||
+ cellptr->Overlay == OVERLAY_STEEL_CRATE ||
+ cellptr->Overlay == OVERLAY_WATER_CRATE) {
+
+ cellptr->Overlay = OVERLAY_NONE;
+ cellptr->OverlayData = 0;
+ cellptr->Redraw_Objects();
+ return(true);
+ }
+ }
+ return(false);
+}
diff --git a/CODE/CRATE.H b/CODE/CRATE.H
new file mode 100644
index 0000000..97b55b6
--- /dev/null
+++ b/CODE/CRATE.H
@@ -0,0 +1,79 @@
+/*
+** Command & Conquer Red Alert(tm)
+** Copyright 2025 Electronic Arts Inc.
+**
+** This program is free software: you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation, either version 3 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program. If not, see .
+*/
+
+/* $Header: /CounterStrike/CRATE.H 1 3/03/97 10:24a Joe_bostic $ */
+/***********************************************************************************************
+ *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
+ ***********************************************************************************************
+ * *
+ * Project Name : Command & Conquer *
+ * *
+ * File Name : CRATE.H *
+ * *
+ * Programmer : Joe L. Bostic *
+ * *
+ * Start Date : 08/26/96 *
+ * *
+ * Last Update : August 26, 1996 [JLB] *
+ * *
+ *---------------------------------------------------------------------------------------------*
+ * Functions: *
+ * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+
+#ifndef CRATE_H
+#define CRATE_H
+
+#include "ftimer.h"
+#include "jshell.h"
+
+
+/*
+** The "bool" integral type was defined by the C++ comittee in
+** November of '94. Until the compiler supports this, use the following
+** definition.
+*/
+#ifndef __BORLANDC__
+#ifndef TRUE_FALSE_DEFINED
+#define TRUE_FALSE_DEFINED
+enum {false=0,true=1};
+typedef int bool;
+#endif
+#endif
+
+class CrateClass {
+ public:
+ CrateClass(void) : Timer(NoInitClass()), Cell(-1) {}
+ void Init(void) {Make_Invalid();}
+ bool Create_Crate(CELL cell);
+ bool Is_Here(CELL cell) const {return(Is_Valid() && cell == Cell);}
+ bool Remove_It(void);
+ bool Is_Expired(void) const {return(Is_Valid() && Timer == 0);}
+ bool Is_Valid(void) const {return(Cell != -1);}
+
+ private:
+ static bool Put_Crate(CELL & cell);
+ static bool Get_Crate(CELL cell);
+
+ void Make_Invalid(void) {Cell = -1;Timer.Stop();}
+
+ CDTimerClass Timer;
+ CELL Cell;
+};
+
+
+#endif
diff --git a/CODE/CRC.CPP b/CODE/CRC.CPP
new file mode 100644
index 0000000..9b4e448
--- /dev/null
+++ b/CODE/CRC.CPP
@@ -0,0 +1,136 @@
+/*
+** Command & Conquer Red Alert(tm)
+** Copyright 2025 Electronic Arts Inc.
+**
+** This program is free software: you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation, either version 3 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program. If not, see .
+*/
+
+/* $Header: /CounterStrike/CRC.CPP 1 3/03/97 10:24a Joe_bostic $ */
+/***********************************************************************************************
+ *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
+ ***********************************************************************************************
+ * *
+ * Project Name : Command & Conquer *
+ * *
+ * File Name : CRC.CPP *
+ * *
+ * Programmer : Joe L. Bostic *
+ * *
+ * Start Date : 03/02/96 *
+ * *
+ * Last Update : March 2, 1996 [JLB] *
+ * *
+ *---------------------------------------------------------------------------------------------*
+ * Functions: *
+ * CRCEngine::operator() -- Submits one byte of data to the CRC engine. *
+ * CRCEngine::operator() -- Submits an arbitrary data block to the CRC engine. *
+ * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+
+#include "crc.h"
+
+
+/***********************************************************************************************
+ * CRCEngine::operator() -- Submits one byte of data to the CRC engine. *
+ * *
+ * This routine will take the specified byte of data and submit it to the CRC engine *
+ * for processing. This routine is designed to be as fast as possible since the typical *
+ * use of this routine is to feed one of presumably many byte sized chunks of data to the *
+ * CRC engine. *
+ * *
+ * INPUT: datum -- One byte of data to submit to the CRC engine. *
+ * *
+ * OUTPUT: none *
+ * *
+ * WARNINGS: If possible, use the buffer/size operator to submit data rather than repeated *
+ * calls to this routine. *
+ * *
+ * HISTORY: *
+ * 03/02/1996 JLB : Created. *
+ *=============================================================================================*/
+void CRCEngine::operator() (char datum)
+{
+ StagingBuffer.Buffer[Index++] = datum;
+
+ if (Index == sizeof(long)) {
+ CRC = Value();
+ StagingBuffer.Composite = 0;
+ Index = 0;
+ }
+}
+
+
+/***********************************************************************************************
+ * CRCEngine::operator() -- Submits an arbitrary data block to the CRC engine. *
+ * *
+ * This routine will submit the specified block to the CRC engine. The block can be of *
+ * arbitrary length. *
+ * *
+ * INPUT: buffer -- Pointer to the buffer that contains the data. The buffer will not *
+ * be modified. *
+ * *
+ * length -- The length of the buffer (in bytes). *
+ * *
+ * OUTPUT: Returns with the current CRC value accumulated so far. *
+ * *
+ * WARNINGS: none *
+ * *
+ * HISTORY: *
+ * 03/02/1996 JLB : Created. *
+ *=============================================================================================*/
+long CRCEngine::operator() (void const * buffer, int length)
+{
+ if (buffer != NULL && length > 0) {
+ char const * dataptr = (char const *)buffer;
+ int bytes_left = length;
+
+ /*
+ ** If there are any leader bytes (needed to fill the staging buffer)
+ ** then process those by first using them to fill up the staging
+ ** buffer. The bulk of the data block will be processed by the high
+ ** speed longword processing loop.
+ */
+ while (bytes_left && Buffer_Needs_Data()) {
+ operator()(*dataptr);
+ dataptr++;
+ bytes_left--;
+ }
+
+ /*
+ ** Perform the fast 'bulk' processing by reading long word sized
+ ** data blocks.
+ */
+ long const * longptr = (long const *)dataptr;
+ int longcount = bytes_left / sizeof(long); // Whole 'long' elements remaining.
+ while (longcount--) {
+ CRC = _lrotl(CRC, 1) + *longptr++;
+ bytes_left -= sizeof(long);
+ }
+
+ /*
+ ** If there are remainder bytes, then process these by adding them
+ ** to the staging buffer.
+ */
+ dataptr = (char const *)longptr;
+ while (bytes_left) {
+ operator()(*dataptr);
+ dataptr++;
+ bytes_left--;
+ }
+ }
+
+ /*
+ ** Return the current CRC value.
+ */
+ return(Value());
+}
diff --git a/CODE/CRC.H b/CODE/CRC.H
new file mode 100644
index 0000000..7b758fb
--- /dev/null
+++ b/CODE/CRC.H
@@ -0,0 +1,121 @@
+/*
+** Command & Conquer Red Alert(tm)
+** Copyright 2025 Electronic Arts Inc.
+**
+** This program is free software: you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation, either version 3 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program. If not, see .
+*/
+
+/* $Header: /CounterStrike/CRC.H 1 3/03/97 10:24a Joe_bostic $ */
+/***********************************************************************************************
+ *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
+ ***********************************************************************************************
+ * *
+ * Project Name : Command & Conquer *
+ * *
+ * File Name : CRC.H *
+ * *
+ * Programmer : Joe L. Bostic *
+ * *
+ * Start Date : 03/02/96 *
+ * *
+ * Last Update : March 2, 1996 [JLB] *
+ * *
+ *---------------------------------------------------------------------------------------------*
+ * Functions: *
+ * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+
+
+#ifndef CRC_H
+#define CRC_H
+
+#include
+
+/*
+** The "bool" integral type was defined by the C++ comittee in
+** November of '94. Until the compiler supports this, use the following
+** definition.
+*/
+#ifndef __BORLANDC__
+#ifndef TRUE_FALSE_DEFINED
+#define TRUE_FALSE_DEFINED
+enum {false=0,true=1};
+typedef int bool;
+#endif
+#endif
+
+/*
+** This is a CRC engine class. It will process submitted data and generate a CRC from it.
+** Well, actually, the value returned is not a true CRC. However, it shares the same strength
+** characteristic and is faster to generate than the traditional CRC. This object is treated like
+** a method class. If it is called as a function (using the function operator), it will return
+** the CRC value. There are other function operators to submit data for processing.
+*/
+class CRCEngine {
+ public:
+
+ // Constructor for CRC engine (it can have an override initial CRC value).
+ CRCEngine(long initial=0) : CRC(initial), Index(0) {
+ StagingBuffer.Composite = 0;
+ };
+
+ // Fetches CRC value.
+ long operator() (void) const {return(Value());};
+
+ // Submits one byte sized datum to the CRC accumulator.
+ void operator() (char datum);
+
+ // Submits an arbitrary buffer to the CRC accumulator.
+ long operator() (void const * buffer, int length);
+
+ // Implicit conversion operator so this object appears like a 'long integer'.
+ operator long(void) const {return(Value());};
+
+ protected:
+
+ bool Buffer_Needs_Data(void) const {
+ return(Index != 0);
+ };
+
+ long Value(void) const {
+ if (Buffer_Needs_Data()) {
+ return(_lrotl(CRC, 1) + StagingBuffer.Composite);
+ }
+ return(CRC);
+ };
+
+ /*
+ ** Current accumulator of the CRC value. This value doesn't take into
+ ** consideration any pending data in the staging buffer.
+ */
+ long CRC;
+
+ /*
+ ** This is the sub index into the staging buffer used to keep track of
+ ** partial data blocks as they are submitted to the CRC engine.
+ */
+ int Index;
+
+ /*
+ ** This is the buffer that holds the incoming partial data. When the buffer
+ ** is filled, the value is transformed into the CRC and the buffer is flushed
+ ** in preparation for additional data.
+ */
+ union {
+ long Composite;
+ char Buffer[sizeof(long)];
+ } StagingBuffer;
+};
+
+#endif
+
diff --git a/CODE/CRCPIPE.CPP b/CODE/CRCPIPE.CPP
new file mode 100644
index 0000000..5b0c2fd
--- /dev/null
+++ b/CODE/CRCPIPE.CPP
@@ -0,0 +1,90 @@
+/*
+** Command & Conquer Red Alert(tm)
+** Copyright 2025 Electronic Arts Inc.
+**
+** This program is free software: you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation, either version 3 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program. If not, see .
+*/
+
+/* $Header: /CounterStrike/CRCPIPE.CPP 1 3/03/97 10:24a Joe_bostic $ */
+/***********************************************************************************************
+ *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
+ ***********************************************************************************************
+ * *
+ * Project Name : Command & Conquer *
+ * *
+ * File Name : CRCPIPE.CPP *
+ * *
+ * Programmer : Joe L. Bostic *
+ * *
+ * Start Date : 06/30/96 *
+ * *
+ * Last Update : July 3, 1996 [JLB] *
+ * *
+ *---------------------------------------------------------------------------------------------*
+ * Functions: *
+ * CRCPipe::Result -- Fetches the current CRC of the data. *
+ * CRCPipe::Put -- Retrieves the data bytes specified and calculates CRC on it. *
+ * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+
+
+#include "crcpipe.h"
+
+
+/***********************************************************************************************
+ * CRCPipe::Put -- Retrieves the data bytes specified and calculates CRC on it. *
+ * *
+ * This routine will fetch the number of bytes requested from the straw. The data is *
+ * not modified by this straw segment, but it is examined by the CRC engine in order to *
+ * keep an accurate CRC of the data that passes through this routine. *
+ * *
+ * INPUT: source -- Pointer to the buffer that will hold the data requested. *
+ * *
+ * length -- The number of bytes requested. *
+ * *
+ * OUTPUT: Returns with the actual number of bytes stored into the buffer. If this number is *
+ * less than the number requested, then this indicates that the data stream has been *
+ * exhausted. *
+ * *
+ * WARNINGS: none *
+ * *
+ * HISTORY: *
+ * 07/03/1996 JLB : Created. *
+ *=============================================================================================*/
+int CRCPipe::Put(void const * source, int slen)
+{
+ CRC(source, slen);
+ return(Pipe::Put(source, slen));
+}
+
+
+/***********************************************************************************************
+ * CRCPipe::Result -- Fetches the current CRC of the data. *
+ * *
+ * This routine will return the CRC of the data that has passed through the pipe up to *
+ * this time. *
+ * *
+ * INPUT: none *
+ * *
+ * OUTPUT: Returns with the CRC value. *
+ * *
+ * WARNINGS: none *
+ * *
+ * HISTORY: *
+ * 07/03/1996 JLB : Created. *
+ *=============================================================================================*/
+long CRCPipe::Result(void) const
+{
+ return(CRC());
+}
+
diff --git a/CODE/CRCPIPE.H b/CODE/CRCPIPE.H
new file mode 100644
index 0000000..d5c9b16
--- /dev/null
+++ b/CODE/CRCPIPE.H
@@ -0,0 +1,66 @@
+/*
+** Command & Conquer Red Alert(tm)
+** Copyright 2025 Electronic Arts Inc.
+**
+** This program is free software: you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation, either version 3 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program. If not, see .
+*/
+
+/* $Header: /CounterStrike/CRCPIPE.H 1 3/03/97 10:24a Joe_bostic $ */
+/***********************************************************************************************
+ *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
+ ***********************************************************************************************
+ * *
+ * Project Name : Command & Conquer *
+ * *
+ * File Name : CRCPIPE.H *
+ * *
+ * Programmer : Joe L. Bostic *
+ * *
+ * Start Date : 06/30/96 *
+ * *
+ * Last Update : June 30, 1996 [JLB] *
+ * *
+ *---------------------------------------------------------------------------------------------*
+ * Functions: *
+ * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+
+
+#ifndef CRCPIPE_H
+#define CRCPIPE_H
+
+#include "pipe.h"
+#include "crc.h"
+
+/*
+** This class doesn't modify the data being piped through, but it does examine it and build
+** a CRC value from the data.
+*/
+class CRCPipe : public Pipe
+{
+ public:
+ CRCPipe(void) {}
+ virtual int Put(void const * source, int slen);
+
+ // Fetch the CRC value.
+ long Result(void) const;
+
+ protected:
+ CRCEngine CRC;
+
+ private:
+ CRCPipe(CRCPipe & rvalue);
+ CRCPipe & operator = (CRCPipe const & pipe);
+};
+
+#endif
diff --git a/CODE/CRCSTRAW.CPP b/CODE/CRCSTRAW.CPP
new file mode 100644
index 0000000..04de153
--- /dev/null
+++ b/CODE/CRCSTRAW.CPP
@@ -0,0 +1,94 @@
+/*
+** Command & Conquer Red Alert(tm)
+** Copyright 2025 Electronic Arts Inc.
+**
+** This program is free software: you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation, either version 3 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program. If not, see .
+*/
+
+/* $Header: /CounterStrike/CRCSTRAW.CPP 1 3/03/97 10:24a Joe_bostic $ */
+/***********************************************************************************************
+ *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
+ ***********************************************************************************************
+ * *
+ * Project Name : Command & Conquer *
+ * *
+ * File Name : CRCSTRAW.CPP *
+ * *
+ * Programmer : Joe L. Bostic *
+ * *
+ * Start Date : 07/02/96 *
+ * *
+ * Last Update : July 3, 1996 [JLB] *
+ * *
+ *---------------------------------------------------------------------------------------------*
+ * Functions: *
+ * CRCStraw::Get -- Fetch the data requested and calculate CRC on it. *
+ * CRCStraw::Result -- Returns with the CRC of all data passed through the straw. *
+ * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+
+
+#include "crcstraw.h"
+
+
+/***********************************************************************************************
+ * CRCStraw::Get -- Fetch the data requested and calculate CRC on it. *
+ * *
+ * This routine will fetch the number of bytes requested. The data will not be modified *
+ * by this straw segment, but the CRC engine will examine the data so as to keep an *
+ * accurate CRC value. *
+ * *
+ * INPUT: source -- Pointer to the buffer to hold the data requested. *
+ * *
+ * length -- The number of bytes requested. *
+ * *
+ * OUTPUT: Returns with the actual number of bytes stored in the buffer. If this number is *
+ * less than that requested, then this indicates that the data stream has been *
+ * exhausted. *
+ * *
+ * WARNINGS: none *
+ * *
+ * HISTORY: *
+ * 07/03/1996 JLB : Created. *
+ *=============================================================================================*/
+int CRCStraw::Get(void * source, int slen)
+{
+ if (source == NULL || slen < 1) {
+ return(0);
+ }
+
+ int counter = Straw::Get(source, slen);
+ CRC(source, counter);
+ return(counter);
+}
+
+
+/***********************************************************************************************
+ * CRCStraw::Result -- Returns with the CRC of all data passed through the straw. *
+ * *
+ * This routine will return the CRC value of the data that has passed through this straw *
+ * segment. *
+ * *
+ * INPUT: none *
+ * *
+ * OUTPUT: Returns with the CRC value of the data this straw segment has seen. *
+ * *
+ * WARNINGS: none *
+ * *
+ * HISTORY: *
+ * 07/03/1996 JLB : Created. *
+ *=============================================================================================*/
+long CRCStraw::Result(void) const
+{
+ return(CRC());
+}
diff --git a/CODE/CRCSTRAW.H b/CODE/CRCSTRAW.H
new file mode 100644
index 0000000..da9fb9f
--- /dev/null
+++ b/CODE/CRCSTRAW.H
@@ -0,0 +1,67 @@
+/*
+** Command & Conquer Red Alert(tm)
+** Copyright 2025 Electronic Arts Inc.
+**
+** This program is free software: you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation, either version 3 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program. If not, see .
+*/
+
+/* $Header: /CounterStrike/CRCSTRAW.H 1 3/03/97 10:24a Joe_bostic $ */
+/***********************************************************************************************
+ *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
+ ***********************************************************************************************
+ * *
+ * Project Name : Command & Conquer *
+ * *
+ * File Name : CRCSTRAW.H *
+ * *
+ * Programmer : Joe L. Bostic *
+ * *
+ * Start Date : 07/02/96 *
+ * *
+ * Last Update : July 2, 1996 [JLB] *
+ * *
+ *---------------------------------------------------------------------------------------------*
+ * Functions: *
+ * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+
+
+#ifndef CRCSTRAW_H
+#define CRCSTRAW_H
+
+#include "straw.h"
+#include "crc.h"
+
+/*
+** This class will build a CRC value from the data stream that is drawn through this class.
+** The data is not modified, but it is examined as it passes through.
+*/
+class CRCStraw : public Straw
+{
+ public:
+ CRCStraw(void) {}
+ virtual int Get(void * source, int slen);
+
+ // Calculate and return the CRC value.
+ long Result(void) const;
+
+ protected:
+ CRCEngine CRC;
+
+ private:
+ CRCStraw(CRCStraw & rvalue);
+ CRCStraw & operator = (CRCStraw const & pipe);
+};
+
+
+#endif
diff --git a/CODE/CREDITS.CPP b/CODE/CREDITS.CPP
new file mode 100644
index 0000000..cd25f3f
--- /dev/null
+++ b/CODE/CREDITS.CPP
@@ -0,0 +1,245 @@
+/*
+** Command & Conquer Red Alert(tm)
+** Copyright 2025 Electronic Arts Inc.
+**
+** This program is free software: you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation, either version 3 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program. If not, see .
+*/
+
+/* $Header: /CounterStrike/CREDITS.CPP 1 3/03/97 10:24a Joe_bostic $ */
+/***********************************************************************************************
+ *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
+ ***********************************************************************************************
+ * *
+ * Project Name : Command & Conquer *
+ * *
+ * File Name : 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::CreditClass -- Default constructor for the credit class object. *
+ * CreditClass::Graphic_Logic -- Handles the credit redraw logic. *
+ * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+
+#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) :
+ Credits(0),
+ Current(0),
+ IsToRedraw(false),
+ IsUp(false),
+ IsAudible(false),
+ 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)
+{
+ if (forced || IsToRedraw) {
+ BStart(BENCH_TABS);
+
+ int xx = SeenBuff.Get_Width() - (120 * RESFACTOR);
+
+ /*
+ ** Adjust the credits display to be above the sidebar for 640x400
+ */
+#ifdef WIN32
+ xx += 80 * RESFACTOR;
+#endif
+
+ /*
+ ** Play a sound effect when the money display changes, but only if a sound
+ ** effect was requested.
+ */
+ if (IsAudible) {
+ if (IsUp) {
+ Sound_Effect(VOC_MONEY_UP, fixed(1, 2));
+ } else {
+ Sound_Effect(VOC_MONEY_DOWN, fixed(1, 2));
+ }
+ }
+
+ /*
+ ** Display the new current value.
+ */
+ TabClass::Draw_Credits_Tab();
+#ifdef WIN32
+ Fancy_Text_Print("%ld", xx, 0, &MetalScheme, TBLACK, TPF_METAL12 | TPF_CENTER | TPF_USE_GRAD_PAL, Current);
+#else
+ Fancy_Text_Print("%ld", xx, 0, &ColorRemaps[PCOLOR_GREY], TBLACK, TPF_NOSHADOW|TPF_6PT_GRAD|TPF_CENTER|TPF_BRIGHT_COLOR, Current);
+#endif //WIN32
+
+ if (Scen.MissionTimer.Is_Active()) {
+ long secs = Scen.MissionTimer / TICKS_PER_SECOND;
+ long mins = secs / 60;
+ long hours = mins / 60;
+ secs %= 60;
+ mins %= 60;
+
+ /*
+ ** Speak mission timer reminders.
+ */
+ VoxType vox = VOX_NONE;
+ if (Scen.MissionTimer == (1 * TICKS_PER_MINUTE)) vox = VOX_TIME_1;
+ if (Scen.MissionTimer == (2 * TICKS_PER_MINUTE)) vox = VOX_TIME_2;
+ if (Scen.MissionTimer == (3 * TICKS_PER_MINUTE)) vox = VOX_TIME_3;
+ if (Scen.MissionTimer == (4 * TICKS_PER_MINUTE)) vox = VOX_TIME_4;
+ if (Scen.MissionTimer == (5 * TICKS_PER_MINUTE)) vox = VOX_TIME_5;
+ if (Scen.MissionTimer == (10 * TICKS_PER_MINUTE)) vox = VOX_TIME_10;
+ if (Scen.MissionTimer == (20 * TICKS_PER_MINUTE)) vox = VOX_TIME_20;
+ if (Scen.MissionTimer == (30 * TICKS_PER_MINUTE)) vox = VOX_TIME_30;
+ if (Scen.MissionTimer == (40 * TICKS_PER_MINUTE)) vox = VOX_TIME_40;
+ if (vox != VOX_NONE) {
+ Speak(vox);
+ Map.FlasherTimer = 7;
+ }
+
+#ifdef WIN32
+ if (hours) {
+ Fancy_Text_Print(TXT_TIME_FORMAT_HOURS, 200 * RESFACTOR, 0, &MetalScheme, TBLACK, TPF_METAL12|TPF_CENTER|TPF_USE_GRAD_PAL, hours, mins, secs);
+ } else {
+ Fancy_Text_Print(TXT_TIME_FORMAT_NO_HOURS, 200 * RESFACTOR, 0, &MetalScheme, TBLACK, TPF_METAL12|TPF_CENTER|TPF_USE_GRAD_PAL, mins, secs);
+ }
+#else
+ if (hours) {
+ Fancy_Text_Print("%02d:%02d:%02d", 120 * RESFACTOR, 0, &ColorRemaps[PCOLOR_GREY], TBLACK, TPF_NOSHADOW|TPF_6PT_GRAD|TPF_CENTER|TPF_BRIGHT_COLOR, hours, mins, secs);
+ } else {
+ Fancy_Text_Print("%02d:%02d", 120 * RESFACTOR, 0, &ColorRemaps[PCOLOR_GREY], TBLACK, TPF_NOSHADOW|TPF_6PT_GRAD|TPF_CENTER|TPF_BRIGHT_COLOR, mins, secs);
+ }
+#endif //WIN32
+ }
+
+ IsToRedraw = false;
+ IsAudible = false;
+ BEnd(BENCH_TABS);
+ }
+}
+
+
+/***********************************************************************************************
+ * 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. *
+ * *
+ * OUTPUT: none *
+ * *
+ * WARNINGS: none *
+ * *
+ * HISTORY: *
+ * 03/13/1995 JLB : Created. *
+ *=============================================================================================*/
+void CreditClass::AI(bool forced)
+{
+ static int _last = 0;
+
+ if (!forced && Frame == _last) return;
+ _last = Frame;
+
+ Credits = PlayerPtr->Available_Money();
+
+ /*
+ ** Make sure that the credit counter doesn't drop below zero.
+ */
+ Credits = max(Credits, 0L);
+
+ if (Scen.MissionTimer.Is_Active() || Scen.MissionTimer) {
+ IsToRedraw = true;
+ Map.Flag_To_Redraw(false);
+ }
+
+ 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.
+ */
+ int adder = Credits - Current;
+
+ if (adder > 0) {
+ Countdown = 1;
+ } else {
+ Countdown = 3;
+ }
+
+ adder = ABS(adder);
+ adder >>= 3;
+// adder >>= 4;
+// adder >>= 5;
+ adder = Bound(adder, 1, 71+72);
+ if (Current > Credits) adder = -adder;
+ Current += adder;
+ if (Current-adder != Current) {
+ IsAudible = true;
+ IsUp = (adder > 0);
+ }
+ }
+ IsToRedraw = true;
+ Map.Flag_To_Redraw(false);
+}
diff --git a/CODE/CREDITS.H b/CODE/CREDITS.H
new file mode 100644
index 0000000..c79aa17
--- /dev/null
+++ b/CODE/CREDITS.H
@@ -0,0 +1,73 @@
+/*
+** Command & Conquer Red Alert(tm)
+** Copyright 2025 Electronic Arts Inc.
+**
+** This program is free software: you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation, either version 3 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program. If not, see .
+*/
+
+/* $Header: /CounterStrike/CREDITS.H 1 3/03/97 10:24a Joe_bostic $ */
+/***********************************************************************************************
+ *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
+ ***********************************************************************************************
+ * *
+ * Project Name : Command & Conquer *
+ * *
+ * File Name : CREDIT.H *
+ * *
+ * Programmer : Joe L. Bostic *
+ * *
+ * Start Date : April 19, 1994 *
+ * *
+ * Last Update : April 19, 1994 [JLB] *
+ * *
+ *---------------------------------------------------------------------------------------------*
+ * Functions: *
+ * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+
+#ifndef CREDITS_H
+#define CREDITS_H
+
+/****************************************************************************
+** 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);
+ CreditClass(NoInitClass const & ) {};
+
+ /*---------------------------------------------------------------------
+ ** Member function prototypes.
+ */
+ void Update(bool forced=false, bool redraw=false);
+
+ void Graphic_Logic(bool forced=false);
+ void AI(bool forced=false);
+
+ long Current; // Credit value currently displayed.
+
+ unsigned IsToRedraw:1;
+ unsigned IsUp:1;
+ unsigned IsAudible:1;
+
+ private:
+ int Countdown; // Delay between ticks.
+};
+
+#endif
+
diff --git a/CODE/CREW.CPP b/CODE/CREW.CPP
new file mode 100644
index 0000000..c9fe7e9
--- /dev/null
+++ b/CODE/CREW.CPP
@@ -0,0 +1,39 @@
+/*
+** Command & Conquer Red Alert(tm)
+** Copyright 2025 Electronic Arts Inc.
+**
+** This program is free software: you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation, either version 3 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program. If not, see .
+*/
+
+/* $Header: /CounterStrike/CREW.CPP 1 3/03/97 10:24a Joe_bostic $ */
+/***********************************************************************************************
+ *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
+ ***********************************************************************************************
+ * *
+ * Project Name : Command & Conquer *
+ * *
+ * File Name : CREW.CPP *
+ * *
+ * Programmer : Joe L. Bostic *
+ * *
+ * Start Date : April 23, 1994 *
+ * *
+ * Last Update : April 23, 1994 [JLB] *
+ * *
+ *---------------------------------------------------------------------------------------------*
+ * Functions: *
+ * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+
+#include "function.h"
+
diff --git a/CODE/CREW.H b/CODE/CREW.H
new file mode 100644
index 0000000..e8470fa
--- /dev/null
+++ b/CODE/CREW.H
@@ -0,0 +1,70 @@
+/*
+** Command & Conquer Red Alert(tm)
+** Copyright 2025 Electronic Arts Inc.
+**
+** This program is free software: you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation, either version 3 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program. If not, see .
+*/
+
+/* $Header: /CounterStrike/CREW.H 1 3/03/97 10:24a Joe_bostic $ */
+/***********************************************************************************************
+ *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
+ ***********************************************************************************************
+ * *
+ * Project Name : Command & Conquer *
+ * *
+ * File Name : 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) {};
+ CrewClass(NoInitClass const &) {};
+ ~CrewClass(void) {};
+
+ int Made_A_Kill(void) {
+ Kills++;
+ return(Kills);
+ };
+
+ private:
+};
+
+#endif
diff --git a/CODE/CSTRAW.CPP b/CODE/CSTRAW.CPP
new file mode 100644
index 0000000..250c188
--- /dev/null
+++ b/CODE/CSTRAW.CPP
@@ -0,0 +1,100 @@
+/*
+** Command & Conquer Red Alert(tm)
+** Copyright 2025 Electronic Arts Inc.
+**
+** This program is free software: you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation, either version 3 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program. If not, see .
+*/
+
+/* $Header: /CounterStrike/CSTRAW.CPP 1 3/03/97 10:24a Joe_bostic $ */
+/***********************************************************************************************
+ *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
+ ***********************************************************************************************
+ * *
+ * Project Name : Command & Conquer *
+ * *
+ * File Name : CSTRAW.CPP *
+ * *
+ * Programmer : Joe L. Bostic *
+ * *
+ * Start Date : 11/10/96 *
+ * *
+ * Last Update : November 10, 1996 [JLB] *
+ * *
+ *---------------------------------------------------------------------------------------------*
+ * Functions: *
+ * CacheStraw::Get -- Fetch data from the data source. *
+ * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+
+#include "cstraw.h"
+#include
+
+
+/***********************************************************************************************
+ * CacheStraw::Get -- Fetch data from the data source. *
+ * *
+ * This will supply the data quantity requested. It performs a regulating influence on the *
+ * data requests passed through it. The data is requested from the next straw in the *
+ * chain such that the data stream is requested in chunks. This serves to lessen the *
+ * impact of multiple small data requests. *
+ * *
+ * INPUT: source -- Pointer to the buffer to hold the data. *
+ * *
+ * slen -- The number of data bytes requested. *
+ * *
+ * OUTPUT: Returns with the number of data bytes stored into the buffer specified. If this *
+ * number is less than that requested, it indicates that the data source has been *
+ * exhausted. *
+ * *
+ * WARNINGS: none *
+ * *
+ * HISTORY: *
+ * 11/10/1996 JLB : Created. *
+ *=============================================================================================*/
+int CacheStraw::Get(void * source, int slen)
+{
+ int total = 0;
+
+ if (Is_Valid() && source != NULL && slen > 0) {
+
+ /*
+ ** Keep processing the data request until there is no more data to supply or the request
+ ** has been fulfilled.
+ */
+ while (slen > 0) {
+
+ /*
+ ** First try to fetch the data from data previously loaded into the buffer.
+ */
+ if (Length > 0) {
+ int tocopy = (Length < slen) ? Length : slen;
+ memmove(source, ((char *)BufferPtr.Get_Buffer()) + Index, tocopy);
+ slen -= tocopy;
+ Index += tocopy;
+ total += tocopy;
+ Length -= tocopy;
+ source = (char*)source + tocopy;
+ }
+ if (slen == 0) break;
+
+ /*
+ ** Since there is more to be fulfilled yet the holding buffer is empty,
+ ** refill the buffer with a fresh block of data from the source.
+ */
+ Length = Straw::Get(BufferPtr, BufferPtr.Get_Size());
+ Index = 0;
+ if (Length == 0) break;
+ }
+ }
+ return(total);
+}
diff --git a/CODE/CSTRAW.H b/CODE/CSTRAW.H
new file mode 100644
index 0000000..8d7c65b
--- /dev/null
+++ b/CODE/CSTRAW.H
@@ -0,0 +1,71 @@
+/*
+** Command & Conquer Red Alert(tm)
+** Copyright 2025 Electronic Arts Inc.
+**
+** This program is free software: you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation, either version 3 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program. If not, see .
+*/
+
+/* $Header: /CounterStrike/CSTRAW.H 1 3/03/97 10:24a Joe_bostic $ */
+/***********************************************************************************************
+ *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
+ ***********************************************************************************************
+ * *
+ * Project Name : Command & Conquer *
+ * *
+ * File Name : CSTRAW.H *
+ * *
+ * Programmer : Joe L. Bostic *
+ * *
+ * Start Date : 11/10/96 *
+ * *
+ * Last Update : November 10, 1996 [JLB] *
+ * *
+ *---------------------------------------------------------------------------------------------*
+ * Functions: *
+ * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+
+
+#ifndef CSTRAW_H
+#define CSTRAW_H
+
+#include "straw.h"
+#include "buff.h"
+
+/*
+** This class handles transfer of data by perform regulated requests for data from the next
+** class in the chain. It performs no translation on the data. By using this segment in a
+** straw chain, data throughput can be regulated. This can yield great performance increases
+** when dealing with a file source.
+*/
+class CacheStraw : public Straw
+{
+ public:
+ CacheStraw(Buffer const & buffer) : BufferPtr(buffer), Index(0), Length(0) {}
+ CacheStraw(int length=4096) : BufferPtr(length), Index(0), Length(0) {}
+ virtual int Get(void * source, int slen);
+
+ private:
+ Buffer BufferPtr;
+ int Index;
+ int Length;
+
+ bool Is_Valid(void) {return(BufferPtr.Is_Valid());}
+ CacheStraw(CacheStraw & rvalue);
+ CacheStraw & operator = (CacheStraw const & pipe);
+};
+
+
+
+#endif
+
diff --git a/CODE/CWSTUB.C b/CODE/CWSTUB.C
new file mode 100644
index 0000000..2af8ae0
--- /dev/null
+++ b/CODE/CWSTUB.C
@@ -0,0 +1,71 @@
+/*
+** Command & Conquer Red Alert(tm)
+** Copyright 2025 Electronic Arts Inc.
+**
+** This program is free software: you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation, either version 3 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program. If not, see .
+*/
+
+#include
+#include
+#include
+#include
+#include
+
+char *dos4g_path()
+{
+ static char *paths_to_check[] = {
+ "DOS4GPATH",
+ "PATH"
+ };
+ static char fullpath[80];
+ char *dos4gpath;
+ int i;
+
+ /* If DOS4GPATH points to an executable file name, don't bother
+ searching any paths for DOS4GW.EXE.
+ */
+ if (dos4gpath = getenv("DOS4GPATH")) {
+ strlwr(strcpy(fullpath, dos4gpath));
+ if (strstr(fullpath, ".exe")) {
+ return(fullpath);
+ }
+ }
+ for( i = 0; i < sizeof(paths_to_check) / sizeof(paths_to_check[0]); i++ ) {
+ _searchenv("dos4gw.exe", paths_to_check[i], fullpath);
+ if (fullpath[0]) {
+ return( &fullpath );
+ }
+ }
+ return("dos4gw.exe");
+}
+
+main( int argc, char *argv[] )
+{
+ char *av[4];
+ auto char cmdline[128];
+
+ av[0] = dos4g_path(); /* Locate the DOS/4GW loader */
+ av[1] = argv[0]; /* name of executable to run */
+ av[2] = getcmd(cmdline); /* command line */
+ av[3] = NULL; /* end of list */
+#ifdef VMM
+ putenv("DOS4GVM=MINMEM#2000 MAXMEM#16000 SWAPMIN#4096 SWAPINC#1024 VIRTUALSIZE#10000 SWAPFILE#CONQUER.SWP DELETESWAP @CONQUER.VMC");
+#endif
+#ifdef QUIET
+ putenv("DOS4G=QUIET"); /* disables DOS/4GW Copyright banner */
+#endif
+ execvp(av[0], av);
+ perror(av[0]);
+ exit(1); /* indicate error */
+}
diff --git a/CODE/DDE.CPP b/CODE/DDE.CPP
new file mode 100644
index 0000000..ec6d293
--- /dev/null
+++ b/CODE/DDE.CPP
@@ -0,0 +1,452 @@
+/*
+** Command & Conquer Red Alert(tm)
+** Copyright 2025 Electronic Arts Inc.
+**
+** This program is free software: you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation, either version 3 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program. If not, see .
+*/
+
+/***************************************************************************
+ ** 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 *
+ * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+
+#ifdef WIN32
+#include
+#include "dde.h"
+
+/***************************************************************************
+ * These are static members of Instance_Class
+ *=========================================================================*/
+
+static DWORD Instance_Class::id_inst; // instance identifier set by DdeInitialize
+static BOOL Instance_Class::process_pokes; // controls response to pokes
+static char Instance_Class::ascii_name[32]; // name of server
+
+static BOOL CALLBACK (*Instance_Class::callback) (
+ LPBYTE pointer, // pointer to received data
+ long length // length of received data or advisory flag
+ ) = NULL;
+
+/***************************************************************************
+ * 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 )
+{
+
+ 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
+
+}
+
+/***************************************************************************
+ * 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. *
+ *=========================================================================*/
+
+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 );
+ }
+}
+
+/***************************************************************************
+ * 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
+ )
+{
+
+
+ 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 //WIN32
diff --git a/CODE/DDE.H b/CODE/DDE.H
new file mode 100644
index 0000000..1554a9a
--- /dev/null
+++ b/CODE/DDE.H
@@ -0,0 +1,175 @@
+/*
+** Command & Conquer Red Alert(tm)
+** Copyright 2025 Electronic Arts Inc.
+**
+** This program is free software: you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation, either version 3 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program. If not, see .
+*/
+
+/***************************************************************************
+ ** 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
+
+#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));
+
+ /*.....................................................................
+ 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
+
+
\ No newline at end of file
diff --git a/CODE/DEBUG.CPP b/CODE/DEBUG.CPP
new file mode 100644
index 0000000..2631bf7
--- /dev/null
+++ b/CODE/DEBUG.CPP
@@ -0,0 +1,560 @@
+/*
+** Command & Conquer Red Alert(tm)
+** Copyright 2025 Electronic Arts Inc.
+**
+** This program is free software: you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation, either version 3 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program. If not, see .
+*/
+
+/* $Header: /CounterStrike/DEBUG.CPP 1 3/03/97 10:24a Joe_bostic $ */
+/***********************************************************************************************
+ *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
+ ***********************************************************************************************
+ * *
+ * Project Name : Command & Conquer *
+ * *
+ * File Name : DEBUG.CPP *
+ * *
+ * Programmer : Joe L. Bostic *
+ * *
+ * Start Date : September 10, 1993 *
+ * *
+ * Last Update : July 18, 1996 [JLB] *
+ * *
+ *---------------------------------------------------------------------------------------------*
+ * Functions: *
+ * Self_Regulate -- Regulates the logic timer to result in smooth animation. *
+ * Debug_Key -- Debug mode keyboard processing. *
+ * Bench_Time -- Convert benchmark timer into descriptive string. *
+ * Benchmarks -- Display the performance tracking benchmarks. *
+ * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+
+#include "function.h"
+#include "vortex.h"
+#include
+
+
+#ifdef CHEAT_KEYS
+
+
+static CDTimerClass DebugTimer;
+
+int VortexFrame = -1;
+
+/***********************************************************************************************
+ * 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_BACKSPACE:
+
+ if (ChronalVortex.Is_Active()) {
+ ChronalVortex.Disappear();
+ } else {
+ int xxxx = Get_Mouse_X() + Map.TacPixelX;
+ int yyyy = Get_Mouse_Y() + Map.TacPixelY;
+ CELL cell = Map.DisplayClass::Click_Cell_Calc(xxxx,yyyy);
+ ChronalVortex.Appear ( Cell_Coord (cell) );
+ }
+ break;
+
+#ifdef WIN32
+ case KN_J:
+ Debug_MotionCapture = true;
+ break;
+
+#ifdef OBSOLETE
+ case KN_K:
+ /*
+ ** time to create a screen shot using the PCX code (if it works)
+ */
+ if (!Debug_MotionCapture) {
+ GraphicBufferClass temp_page( SeenBuff.Get_Width(),
+ SeenBuff.Get_Height(),
+ NULL,
+ SeenBuff.Get_Width() * SeenBuff.Get_Height());
+ CDFileClass file;
+ char filename[30];
+
+ SeenBuff.Blit(temp_page);
+ for (int lp = 0; lp < 99; lp ++) {
+ sprintf(filename, "scrsht%02d.pcx", lp);
+ file.Set_Name(filename);
+ if (!file.Is_Available()) break;
+ }
+
+ file.Cache(200000);
+ Write_PCX_File(file, temp_page, & GamePalette);
+ Sound_Effect(VOC_BEEP);
+ }
+ break;
+#endif
+#endif
+
+ case KN_P:
+ {
+ for (SpecialWeaponType spc = SPC_FIRST; spc < SPC_COUNT; spc++) {
+ PlayerPtr->SuperWeapon[spc].Enable(true, true);
+ PlayerPtr->SuperWeapon[spc].Forced_Charge(true);
+ Map.Add(RTTI_SPECIAL, spc);
+ Map.Column[1].Flag_To_Redraw();
+ }
+ }
+ break;
+
+ case KN_I:
+ {
+ Map.Flash_Power();
+ Map.Flash_Money();
+ }
+ break;
+
+ case KN_O:
+ {
+ AircraftClass * air = new AircraftClass(AIRCRAFT_HIND, PlayerPtr->Class->House);
+ if (air) {
+ air->Height = 0;
+ air->Unlimbo(Map.Pixel_To_Coord(Get_Mouse_X(), Get_Mouse_Y()), DIR_N);
+ }
+ }
+ break;
+
+ case KN_B:
+ {
+ AircraftClass * air = new AircraftClass(AIRCRAFT_LONGBOW, PlayerPtr->Class->House);
+ if (air) {
+ air->Height = 0;
+ air->Unlimbo(Map.Pixel_To_Coord(Get_Mouse_X(), Get_Mouse_Y()), DIR_N);
+ }
+ }
+ break;
+
+ case KN_GRAVE:
+ {
+ WarheadType warhead = Random_Pick(WARHEAD_HE, WARHEAD_FIRE);
+ COORDINATE coord = Map.Pixel_To_Coord(Get_Mouse_X(), Get_Mouse_Y());
+ int damage = 1000;
+ new AnimClass(Combat_Anim(damage, warhead, Map[coord].Land_Type()), coord);
+ Explosion_Damage(coord, damage, NULL, warhead);
+ }
+ break;
+
+ case KN_C:
+ Debug_Cheat = (Debug_Cheat == false);
+ PlayerPtr->IsRecalcNeeded = true;
+
+ /*
+ ** 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 = MAP_CELL_W-2;
+ Map.MapCellHeight = MAP_CELL_H-2;
+ } 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;
+
+ 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_DELETE:
+ if (CurrentObject.Count()) {
+ Map.Recalc();
+ //CurrentObject[0]->Detach_All();
+ if (CurrentObject[0]->What_Am_I() == RTTI_BUILDING) {
+ ((BuildingClass *)CurrentObject[0])->Sell_Back(1);
+ } else {
+ ObjectClass * object = CurrentObject[0];
+ object->Unselect();
+ object->Limbo();
+ delete object;
+ }
+ }
+ 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;
+
+ case KN_LBRACKET:
+ case KN_F11:
+ if (MonoPage == DMONO_FIRST) {
+ MonoPage = DMonoType(DMONO_COUNT-1);
+ } else {
+ MonoPage = DMonoType(MonoPage - 1);
+ }
+ DebugTimer = 0;
+ break;
+
+ case KN_RBRACKET:
+ case KN_F12:
+ MonoPage = DMonoType(MonoPage + 1);
+ if (MonoPage == DMONO_COUNT) {
+ MonoPage = DMONO_FIRST;
+ }
+ DebugTimer = 0;
+ break;
+
+ case KN_V:
+ case KN_F3:
+ Debug_Icon = (Debug_Icon == false);
+ Map.Flag_To_Redraw(true);
+ break;
+
+ /*
+ ** Reveal entire map to player.
+ */
+// case KN_F4:
+// if (Session.Type == 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.PrimaryWeapon != NULL) weapon = ttype.PrimaryWeapon->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;
+
+ default:
+ break;
+ }
+ }
+}
+
+
+/***********************************************************************************************
+ * Bench_Time -- Convert benchmark timer into descriptive string. *
+ * *
+ * This routine will take the values of the benchmark timer specified and build a string *
+ * that displays the average time each event consumed as well as the ranking of how much *
+ * time that event took (total) during the tracking duration (one second?). *
+ * *
+ * INPUT: btype -- The benchmark to convert to a descriptive string. *
+ * *
+ * OUTPUT: Returns with a pointer to the descriptive string of the benchmark specified. *
+ * *
+ * WARNINGS: The value returned is a pointer to a static buffer. As such, it is only valid *
+ * until the next time that this routine is called. *
+ * *
+ * HISTORY: *
+ * 07/18/1996 JLB : Created. *
+ *=============================================================================================*/
+static char const * Bench_Time(BenchType btype)
+{
+ static char buffer[32];
+
+ int rootcount = Benches[BENCH_GAME_FRAME].Count();
+ if (rootcount == 0) rootcount = 1;
+ int roottime = Benches[BENCH_GAME_FRAME].Value();
+ int count = Benches[btype].Count();
+ int time = Benches[btype].Value();
+ if (count > 0 && count * time > roottime * rootcount) time = roottime / count;
+ int percent = 0;
+ if (roottime != 0 && rootcount != 0) {
+ percent = ((count * time) * 99) / (roottime * rootcount);
+ }
+ if (percent > 99) percent = 99;
+ sprintf(buffer, "%-2d%% %7d", percent, time);
+ return(buffer);
+}
+
+
+/***********************************************************************************************
+ * Benchmarks -- Display the performance tracking benchmarks. *
+ * *
+ * This will display the benchmarks for the various processes that are being tracked. The *
+ * display will indicate the fraction that each process is consuming out of the entire *
+ * process time as well as the time consumed by each individual event. The total fraction *
+ * is useful for determing what should be optimized. The individual time is useful for *
+ * guaging the effectiveness of optimization changes. *
+ * *
+ * INPUT: mono -- Pointer to the monochrome screen that the display will use. *
+ * *
+ * OUTPUT: none *
+ * *
+ * WARNINGS: none *
+ * *
+ * HISTORY: *
+ * 07/18/1996 JLB : Created. *
+ *=============================================================================================*/
+static void Benchmarks(MonoClass * mono)
+{
+ static bool _first = true;
+ if (_first) {
+ _first = false;
+ mono->Clear();
+ mono->Set_Cursor(0, 0);
+ mono->Print(Text_String(TXT_DEBUG_PERFORMANCE));
+ if (Benches == NULL) {
+ mono->Set_Cursor(20, 15);
+ mono->Printf(TXT_NO_PENTIUM);
+ }
+ }
+
+ if (Benches != NULL) {
+ mono->Set_Cursor(1, 2);mono->Printf("%s", Bench_Time(BENCH_FINDPATH));
+ mono->Set_Cursor(1, 4);mono->Printf("%s", Bench_Time(BENCH_GREATEST_THREAT));
+ mono->Set_Cursor(1, 6);mono->Printf("%s", Bench_Time(BENCH_AI));
+ mono->Set_Cursor(1, 8);mono->Printf("%s", Bench_Time(BENCH_PCP));
+ mono->Set_Cursor(1, 10);mono->Printf("%s", Bench_Time(BENCH_EVAL_OBJECT));
+ mono->Set_Cursor(1, 12);mono->Printf("%s", Bench_Time(BENCH_EVAL_CELL));
+ mono->Set_Cursor(1, 14);mono->Printf("%s", Bench_Time(BENCH_EVAL_WALL));
+ mono->Set_Cursor(1, 16);mono->Printf("%s", Bench_Time(BENCH_MISSION));
+
+ mono->Set_Cursor(14, 2);mono->Printf("%s", Bench_Time(BENCH_CELL));
+ mono->Set_Cursor(14, 4);mono->Printf("%s", Bench_Time(BENCH_OBJECTS));
+ mono->Set_Cursor(14, 6);mono->Printf("%s", Bench_Time(BENCH_ANIMS));
+
+ mono->Set_Cursor(27, 2);mono->Printf("%s", Bench_Time(BENCH_PALETTE));
+
+ mono->Set_Cursor(40, 2);mono->Printf("%s", Bench_Time(BENCH_GSCREEN_RENDER));
+ mono->Set_Cursor(40, 4);mono->Printf("%s", Bench_Time(BENCH_SIDEBAR));
+ mono->Set_Cursor(40, 6);mono->Printf("%s", Bench_Time(BENCH_RADAR));
+ mono->Set_Cursor(40, 8);mono->Printf("%s", Bench_Time(BENCH_TACTICAL));
+ mono->Set_Cursor(40, 10);mono->Printf("%s", Bench_Time(BENCH_POWER));
+ mono->Set_Cursor(40, 12);mono->Printf("%s", Bench_Time(BENCH_SHROUD));
+ mono->Set_Cursor(40, 14);mono->Printf("%s", Bench_Time(BENCH_TABS));
+ mono->Set_Cursor(40, 16);mono->Printf("%s", Bench_Time(BENCH_BLIT_DISPLAY));
+
+ mono->Set_Cursor(66, 2);mono->Printf("%7d", Benches[BENCH_RULES].Value());
+ mono->Set_Cursor(66, 4);mono->Printf("%7d", Benches[BENCH_SCENARIO].Value());
+
+ for (BenchType index = BENCH_FIRST; index < BENCH_COUNT; index++) {
+ if (index != BENCH_RULES && index != BENCH_SCENARIO) Benches[index].Reset();
+ }
+ }
+}
+
+
+/***********************************************************************************************
+ * 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 ObjectClass * _lastobject = 0;
+ static bool _first=true;
+
+ if (DebugTimer == 0) {
+ DebugTimer = UPDATE_INTERVAL;
+
+ if (MonoClass::Is_Enabled()) {
+ if (_first) {
+ _first = false;
+ for (DMonoType index = DMONO_FIRST; index < DMONO_COUNT; index++) {
+ MonoArray[index].Clear();
+ }
+ }
+
+ /*
+ ** Always update the stress tracking mono display even if it
+ ** currently isn't visible.
+ */
+ Logic.Debug_Dump(&MonoArray[DMONO_STRESS]);
+
+ MonoClass * mono = &MonoArray[MonoPage];
+ mono->Set_Default_Attribute(MonoClass::NORMAL);
+ mono->View();
+
+ switch (MonoPage) {
+ case DMONO_EVENTS:
+ Benchmarks(mono);
+ break;
+
+ case DMONO_OBJECT:
+ 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);
+ }
+ break;
+
+ case DMONO_STRESS:
+#ifdef OBSOLETE
+ 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)
+ );
+#endif
+ break;
+
+ case DMONO_HOUSE:
+ mono->Clear();
+
+ if (CurrentObject.Count()) {
+ _lastobject = CurrentObject[0];
+ }
+ if (_lastobject && !_lastobject->IsActive) {
+ _lastobject = 0;
+ }
+ if (_lastobject && _lastobject->Is_Techno()) {
+ ((TechnoClass *)_lastobject)->House->Debug_Dump(mono);
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ mono->Set_Cursor(0, 0);
+ }
+ }
+}
+#endif
diff --git a/CODE/DEBUG.H b/CODE/DEBUG.H
new file mode 100644
index 0000000..b18ada0
--- /dev/null
+++ b/CODE/DEBUG.H
@@ -0,0 +1,61 @@
+/*
+** Command & Conquer Red Alert(tm)
+** Copyright 2025 Electronic Arts Inc.
+**
+** This program is free software: you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation, either version 3 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program. If not, see .
+*/
+
+#define TXT_CLEAR_MAP 0x3e8 // Clear the map
+#define TXT_INHERIT_MAP 0x3e9 // Inherit previous map
+#define TXT_SPECIAL_OPTIONS 0x3ea // Select Special Options
+#define TXT_VISIBLE_TARGET 0x3eb // Targeting flash visible to
+#define TXT_TREE_TARGET 0x3ec // Allow targeting of trees.
+#define TXT_MCV_DEPLOY 0x3ed // Allow undeploy of
+#define TXT_SMART_DEFENCE 0x3ee // Employ smarter self defense
+#define TXT_SLOW_BUILD 0x3ef // Moderate production speed.
+#define TXT_THREE_POINT 0x3f0 // Use three point turn logic.
+#define TXT_TIBERIUM_GROWTH 0x3f1 // Ore will grow.
+#define TXT_TIBERIUM_SPREAD 0x3f2 // Ore will spread.
+#define TXT_ROAD_PIECES 0x3f3 // Disable building "bib"
+#define TXT_SCATTER 0x3f4 // Allow running from
+#define TXT_SHOW_NAMES 0x3f5 // Show true object names.
+#define TXT_DEFENDER_ADVANTAGE 0x3f6 // Defender has the advantage.
+#define TXT_SEPARATE_HELIPAD 0x3f7 // Allow separate helipad
+#define TXT_PASSWORD_CAPTION 0x3f8 // Password Request
+#define TXT_PASSWORD_MESSAGE 0x3f9 // Enter Red Alert access code
+#define TXT_PASSWORD_ERROR 0x3fa // Access code error detected.
+#define TXT_TRY_AGAIN 0x3fb // Try Again
+#define TXT_MINE_AWARE 0x3fc // Friendly units avoid
+#define TXT_TRIGGER_EDITOR 0x3fd // Trigger Editor
+#define TXT_TRIGGER_JUST_EVENT 0x3fe // Just This Event
+#define TXT_TRIGGER_AND 0x3ff // ... and ...
+#define TXT_TRIGGER_OR 0x400 // ... or ...
+#define TXT_TRIGGER_LINKED 0x401 // ... linked ...
+#define TXT_TRIGGER_JUST_ACTION 0x402 // Just This Action
+#define TXT_TEAM_EDIT 0x403 // Team Editor
+#define TXT_SELLABLE 0x404 // Sellable
+#define TXT_REBUILD 0x405 // Rebuild
+#define TXT_SPEED_BUILD 0x406 // Building constructin time
+#define TXT_SCENARIO_ERRORx 0x407 // Scenario authentication
+#define TXT_DEBUG_STRESS 0x408 // ÚFrames:ÄÂF/R:ÂCPU:ÄÄÂF/R:ÄÄ
+#define TXT_DEBUG_VEHICLE 0x409 // ÚFull
+#define TXT_DEBUG_INFANTRY 0x40a // ÚFull
+#define TXT_DEBUG_SHIP 0x40b // ÚFull
+#define TXT_DEBUG_BUILDING 0x40c // ÚFull
+#define TXT_DEBUG_PERFORMANCE 0x40d // Game Objects³ Drawing
+#define TXT_DEBUG_AIRCRAFT 0x40e // ÚFull
+#define TXT_DEBUG_HOUSE 0x40f // ÚFull Name:ÄÄÄÄÄÄÄÄÂAct
+#define TXT_NO_PENTIUM 0x410 // ****************************
+#define TXT_SIZE_MAP 0x411 // Size Map
+#define TXT_TRUCK_CRATE 0x412 // Trucks drop crate when
diff --git a/CODE/DEFINES.H b/CODE/DEFINES.H
new file mode 100644
index 0000000..de0009b
--- /dev/null
+++ b/CODE/DEFINES.H
@@ -0,0 +1,3555 @@
+/*
+** Command & Conquer Red Alert(tm)
+** Copyright 2025 Electronic Arts Inc.
+**
+** This program is free software: you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation, either version 3 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program. If not, see .
+*/
+
+/* $Header: /CounterStrike/DEFINES.H 4 3/07/97 9:55a 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 : DEFINES.H *
+ * *
+ * Programmer : Joe L. Bostic *
+ * *
+ * Start Date : September 10, 1993 *
+ * *
+ * Last Update : September 10, 1993 [JLB] *
+ * *
+ *---------------------------------------------------------------------------------------------*
+ * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+#ifndef DEFINES_H
+#define DEFINES_H
+
+/**********************************************************************
+** Language control: define the desired language for this build.
+*/
+//#define ENGLISH 1
+//#define FRENCH 1
+//#define GERMAN 1
+//#define SPAIN 1 (never used)
+// - Language define is now passed in from the makefile. -
+
+/**********************************************************************
+** Controls the nature of the game and its abilities. Only define
+** one of these values.
+**
+** Internal version -- complete with scenario editor.
+** Playtest version -- no editor but does have minimal cheat keys.
+** Release version -- no editor or cheat keys -- all debugging info removed.
+*/
+//#define INTERNAL_VERSION
+//#define PLAYTEST_VERSION
+#define RELEASE_VERSION
+
+/**********************************************************************
+** ColinM
+** Set this to enable dongle protection
+*/
+//#define DONGLE
+
+
+// Enable 640x400 VQ movie capability in WIN32 mode
+#define MOVIE640
+
+
+//#if (GERMAN | FRENCH)
+//#define BOGUSCD
+//#endif
+
+#define FIXIT_SCORE_CRASH // Fixes score screen crash
+#define FIXIT_MULTI_SAVE // Fixes multiplayer save/load
+#define FIXIT_NO_COMP_ALLY // Prevent ally with computer
+#define FIXIT_DESTNET // Fixes -destnet parameter in Win95
+#define FIXIT_RANDOM_GAME // Fixes random seed at start of multiplayer games
+#define FIXIT_FORCE_CD // Forces correct CD load after scenario #1
+#define FIXIT_IP_CRASH // Fixes crash if internet game aborts too quickly
+#define FIXIT_IP_STATS // Fixes so vessels show up in internet stat info
+#define FIXIT_NAME_OVERRIDE // Allows changing of unit names
+#define FIXIT_RADAR_JAMMED // Fixes unjamming by merely starting to build a radar facility
+#define FIXIT_CAPTURE_BIB // Fixes so that if fake is captured, you still can't build off of it.
+#define FIXIT_BASE_ANNOUNCE // Fixes so player controlled buildings count as base when attacked.
+#define FIXIT_APTIVA_MODEM // Fixes crash with Aptiva modem.
+#define FIXIT_FLAG_CHECK // Disable placing building over a flag.
+
+#define FIXIT_ANTS // Adds Ant Units
+
+#define FIXIT_CSII // Adds Aftermath CounterStrike II units
+// ajw 9/28/98 - Note about FIXIT_CSII. Changes seem to have been made for Aftermath ("Counterstrike II") that: a) were
+// bug fixes that should never be rolled back, b) change the nature of the game, at least in multi-player. This meant
+// that the "Red Alert" executable ( == Counterstrike executable ) could no longer be built. Apparently, at the time,
+// this was justified, as it was believed that no further patches to the RA executable would ever be necessary.
+// Given that Denzil's DVD changes and my WOLAPI integration are essentially a patch, we've got a problem.
+// We've decided to level the field and make sure every who gets or patches to the new version of Red Alert, CS, AM, (and
+// their DVD equivalent(s)) will have the same executable. So we're assuming that all of the FIXIT_CSII changes are
+// permanent (as, in fact, all prior FIXIT_'s are - makes me wonder why the old non-compiling code has to hang around
+// forever), and fixing the code so that the assumption "this is an Aftermath game" is no longer hard-coded, but can
+// change at runtime. (Which is what should have been done when Aftermath was created.)
+//
+#define FIXIT_CARRIER // Adds Aftermath aircraft carrier
+#define FIXIT_PHASETRANSPORT // Adds Aftermath cloaking APC
+// ajw - Discovered that engineer changing fields were specifically left out of aftrmath.ini, thus this has no effect.
+// Engineer changes (and other game rule changes) are in mplayer.ini, which was loaded before aftermath-only mplayer games.
+#define FIXIT_ENGINEER // Adds Engineer rules.ini overrides
+
+//#define FIXIT_FAST_LOAD // Enables faster INI loading
+
+// These fixes will cause the game to go out of sync.
+//#define FIXIT_ENGINEER_CAPTURE // If building not allied, will still capture if engineer not allied with building.
+//#define FIXIT_HELI_LANDING // Fixes so new helicopters land at free helipad
+//#define FIXIT_MINE_PASSABLE // Fixes units not driving onto mines
+
+/* Turn on these changes for the 1.08 patch */
+#define FIXIT_PATCH_108
+
+#ifdef FIXIT_PATCH_108
+#define STEVES_LOAD_OVERRIDE // Allows loading of CONQUER.ENG instead of from mix file.
+#define FIXIT_DIFFICULTY // Fixes no difficulty level for CStrike missions
+#define FIXIT_VERSION // Fixes version playability for 1.04, 1.07 & 1.08
+#define FIXIT_MODEM_LOAD_CRASH // Fixes crash after loading a modem game when names are the same
+#define FIXIT_PHONELIST_CRASH // Fixes crash when clicking on an empty phonelist
+#endif
+
+// Denotes changes made for version 3 - reunification of all existing versions and undoing of Aftermath divergence. - ajw
+#define FIXIT_VERSION_3
+#define DVD
+
+// Define DVD to turn on RADVD additions/changes - Denzil
+#ifdef DVD
+//#define INTERNET_OFF
+#define MPEGMOVIE
+//#define MCIMPEG
+#endif
+
+// Test to see if partial object drawing is any faster.
+#define PARTIAL
+//#define SORTDRAW
+
+/**********************************************************************
+** If the scenario editor to to be active in this build then uncomment
+** the following #define line.
+*/
+#ifdef INTERNAL_VERSION
+#define SCENARIO_EDITOR
+#endif
+
+
+/**********************************************************************
+** This define enables the full set of cheat keys and special
+** command line options.
+*/
+#if defined(INTERNAL_VERSION) || defined(PLAYTEST_VERSION)
+#define CHEAT_KEYS
+#endif
+
+
+/**********************************************************************
+** If this is defined, the special Virgin limited cheat keys
+** are enabled. This allows the "cheat" parameter and then only
+** allows the ALT-W to win the mission.
+*/
+#ifdef PLAYTEST_VERSION
+#define VIRGIN_CHEAT_KEYS
+#endif
+
+
+/**********************************************************************
+** If this is defined, then the network code will be enabled.
+*/
+#define NETWORK
+#define TIMING_FIX 1
+
+
+/**********************************************************************
+** Define this to 1 to enable MPath-specific code. Do not define
+** TEN at the same time.
+*/
+#define MPATH 0
+
+
+/**********************************************************************
+** Define this to 1 to enable TEN-specific code. Do not define
+** MPATH at the same time.
+*/
+#define TEN 0
+
+
+/**********************************************************************
+** If this is defined, the DoList is "mirrored", for memory trasher
+** detection.
+*/
+#ifdef CHEAT_KEYS
+//#define MIRROR_QUEUE
+#endif
+
+
+/**********************************************************************
+** This define tells the Version Number class to use the date/time-based
+** version numbering system. If this define is not set, the actual
+** major/minor version numbers will be used.
+*/
+//#define DEV_VERSION
+//#define DEV_VER_NAME
+
+
+/**********************************************************************
+** This define enables a special additional foreign-version-number
+** after the other version number, for display purposes only.
+*/
+#if !defined(ENGLISH)
+#define FOREIGN_VERSION
+#define FOREIGN_VERSION_NUMBER 7
+#endif
+
+
+/**********************************************************************
+** This is the multiplier factor to convert low resution coordinates
+** into their actual resolution counterparts.
+*/
+#ifdef WIN32
+#define RESFACTOR 2
+#else
+//#undef SCENARIO_EDITOR
+#define RESFACTOR 1
+#endif
+
+
+#define SIDEBAR_WID 80
+
+
+/**********************************************************************
+** Optional parameter control for special options.
+*/
+
+/*
+** Enable the set of limited cheat key options.
+*/
+#ifdef VIRGIN_CHEAT_KEYS
+#define PARM_PLAYTEST 0xF7DDC227 // "PLAYTEST"
+#endif
+
+/*
+** Enable the full set of cheat key options.
+*/
+#ifdef CHEAT_KEYS
+#ifndef PARM_PLAYTEST
+#define PARM_PLAYTEST 0xF7DDC227 // "PLAYTEST"
+#endif
+#endif
+
+
+#define PARM_INSTALL 0xD95C68A2 // "FROMINSTALL"
+
+
+//
+// Allow normal game play in the MPath version
+//
+#if(MPATH)
+#define PARM_ALLOW_SOLO 0xc901c9db // AllowSoloPlayOptions
+#endif
+
+//
+// Allow normal game play in the TEN version
+//
+#if(TEN)
+#define PARM_ALLOW_SOLO 0xc901c9db // AllowSoloPlayOptions
+#endif
+
+/**********************************************************************
+** Defines for verifying free disk space
+*/
+#define INIT_FREE_DISK_SPACE 8388608
+#define SAVE_GAME_DISK_SPACE (INIT_FREE_DISK_SPACE - (1024*4096))
+//#define SAVE_GAME_DISK_SPACE 100000
+
+
+/**********************************************************************
+** This is the complete list of VQs allowed to be played in the game.
+*/
+typedef enum VQType {
+ VQ_NONE=-1,
+ VQ_AAGUN,
+ VQ_MIG,
+ VQ_SFROZEN,
+ VQ_AIRFIELD,
+ VQ_BATTLE,
+ VQ_BMAP,
+ VQ_BOMBRUN,
+ VQ_DPTHCHRG,
+ VQ_GRVESTNE,
+ VQ_MONTPASS,
+ VQ_MTNKFACT,
+ VQ_CRONTEST,
+ VQ_OILDRUM,
+ VQ_ALLYEND,
+ VQ_RADRRAID,
+ VQ_SHIPYARD,
+ VQ_SHORBOMB,
+ VQ_SITDUCK,
+ VQ_SLNTSRVC,
+ VQ_SNOWBASE,
+ VQ_EXECUTE,
+ VQ_TITLE, // Low res.
+ VQ_NUKESTOK,
+ VQ_V2ROCKET,
+ VQ_SEARCH,
+ VQ_BINOC,
+ VQ_ELEVATOR,
+ VQ_FROZEN,
+ VQ_MCV,
+ VQ_SHIPSINK,
+ VQ_SOVMCV,
+ VQ_TRINITY,
+ VQ_ALLYMORF,
+ VQ_APCESCPE,
+ VQ_BRDGTILT,
+ VQ_CRONFAIL,
+ VQ_STRAFE,
+ VQ_DESTROYR,
+ VQ_DOUBLE,
+ VQ_FLARE,
+ VQ_SNSTRAFE,
+ VQ_LANDING,
+ VQ_ONTHPRWL,
+ VQ_OVERRUN,
+ VQ_SNOWBOMB,
+ VQ_SOVCEMET,
+ VQ_TAKE_OFF,
+ VQ_TESLA,
+ VQ_SOVIET8,
+ VQ_SPOTTER,
+ VQ_SCENE1,
+ VQ_SCENE2,
+ VQ_SCENE4,
+ VQ_SOVFINAL,
+ VQ_ASSESS,
+ VQ_SOVIET10,
+ VQ_DUD,
+ VQ_MCV_LAND,
+ VQ_MCVBRDGE,
+ VQ_PERISCOP,
+ VQ_SHORBOM1,
+ VQ_SHORBOM2,
+ VQ_SOVBATL,
+ VQ_SOVTSTAR,
+ VQ_AFTRMATH,
+ VQ_SOVIET11,
+ VQ_MASASSLT,
+ VQ_REDINTRO, // High res
+ VQ_SOVIET1,
+ VQ_SOVIET2,
+ VQ_SOVIET3,
+ VQ_SOVIET4,
+ VQ_SOVIET5,
+ VQ_SOVIET6,
+ VQ_SOVIET7,
+ VQ_INTRO_MOVIE,
+ VQ_AVERTED,
+ VQ_COUNTDWN,
+ VQ_MOVINGIN,
+ VQ_ALLIED10,
+ VQ_ALLIED12,
+ VQ_ALLIED5,
+ VQ_ALLIED6,
+ VQ_ALLIED8,
+ VQ_TANYA1,
+ VQ_TANYA2,
+ VQ_ALLY10B,
+ VQ_ALLY11,
+ VQ_ALLY14,
+ VQ_ALLY9,
+ VQ_SPY,
+ VQ_TOOFAR,
+ VQ_SOVIET12,
+ VQ_SOVIET13,
+ VQ_SOVIET9,
+ VQ_BEACHEAD,
+ VQ_SOVIET14,
+ VQ_SIZZLE,
+ VQ_SIZZLE2,
+ VQ_ANTEND,
+ VQ_ANTINTRO,
+
+ VQ_COUNT,
+ VQ_FIRST=0
+} VQType;
+
+
+/**********************************************************************
+** These enumerations are used to implement RTTI. The target system
+** uses these and thus there can be no more RTTI types than can fit
+** in the exponent of a target value.
+*/
+typedef enum RTTIType {
+ RTTI_NONE=0,
+ RTTI_AIRCRAFT,
+ RTTI_AIRCRAFTTYPE,
+ RTTI_ANIM,
+ RTTI_ANIMTYPE,
+ RTTI_BUILDING,
+ RTTI_BUILDINGTYPE,
+ RTTI_BULLET,
+ RTTI_BULLETTYPE,
+ RTTI_CELL,
+ RTTI_FACTORY,
+ RTTI_HOUSE,
+ RTTI_HOUSETYPE,
+ RTTI_INFANTRY,
+ RTTI_INFANTRYTYPE,
+ RTTI_OVERLAY,
+ RTTI_OVERLAYTYPE,
+ RTTI_SMUDGE,
+ RTTI_SMUDGETYPE,
+ RTTI_SPECIAL,
+ RTTI_TEAM,
+ RTTI_TEAMTYPE,
+ RTTI_TEMPLATE,
+ RTTI_TEMPLATETYPE,
+ RTTI_TERRAIN,
+ RTTI_TERRAINTYPE,
+ RTTI_TRIGGER,
+ RTTI_TRIGGERTYPE,
+ RTTI_UNIT,
+ RTTI_UNITTYPE,
+ RTTI_VESSEL,
+ RTTI_VESSELTYPE,
+
+ RTTI_COUNT
+} RTTIType;
+
+
+/**********************************************************************
+** These are the difficulty settings of the game.
+*/
+typedef enum DiffType {
+ DIFF_EASY,
+ DIFF_NORMAL,
+ DIFF_HARD,
+
+ DIFF_COUNT,
+ DIFF_FIRST=0
+} DiffType;
+
+
+/**********************************************************************
+** This is the size of the speech buffer. This value should be as large
+** as the largest speech sample, plus a few bytes for overhead
+** (16 bytes is sufficient).
+*/
+#define SPEECH_BUFFER_SIZE 50000L
+
+
+/**********************************************************************
+** The theater mixfiles are cached into a buffer of this size. Ensure
+** that the size specified is at least as large as the largest
+** theater mixfile data block.
+*/
+#define THEATER_BUFFER_SIZE 1100000L
+
+
+/**********************************************************************
+** This is the size of the shape buffer. This buffer is used as a staging
+** buffer for the shape drawing technology. It MUST be as big as the
+** largest shape (uncompressed) that will be drawn. If this value is
+** changed, be sure to update the makefile and rebuild all of the shape
+** data files.
+*/
+#define SHAPE_BUFFER_SIZE 65000L
+
+
+/**********************************************************************
+** Filenames of the data files it can create at run time.
+*/
+#define FAME_FILE_NAME "HALLFAME.DAT"
+#define NET_SAVE_FILE_NAME "SAVEGAME.NET"
+#define CONFIG_FILE_NAME "REDALERT.INI"
+
+
+/**********************************************************************
+** Map controls. The map is composed of square elements called 'cells'.
+** All larger elements are build upon these.
+*/
+
+#define HIGH_COORD_MASK 0x80008000L
+
+// Size of the map in cells.
+#define MAP_CELL_W 128
+#define MAP_CELL_H 128
+#define MAP_CELL_TOTAL (MAP_CELL_W*MAP_CELL_H)
+
+#define REFRESH_EOL 32767 // This number ends a refresh/occupy offset list.
+#define REFRESH_SIDEBAR 32766 // This number flags that sidebar needs refreshing.
+
+
+/****************************************************************************
+** These are custom C&C specific types. The CELL is used for map coordinate
+** with cell resolution. The COORDINATE type is used for map coordinates that
+** have a lepton resolution. CELL is more efficient when indexing into the map
+** and when size is critical. COORDINATE is more efficient when dealing with
+** accuracy and object movement.
+*/
+typedef unsigned short LEPTON;
+typedef union {
+ LEPTON Raw;
+ struct {
+#ifdef BIG_ENDIAN
+ unsigned char Cell;
+ unsigned char Lepton;
+#else
+ unsigned char Lepton;
+ unsigned char Cell;
+#endif
+ } Sub;
+} LEPTON_COMPOSITE;
+
+typedef unsigned long COORDINATE;
+typedef union {
+ COORDINATE Coord;
+ struct {
+#ifdef BIG_ENDIAN
+ LEPTON_COMPOSITE Y;
+ LEPTON_COMPOSITE X;
+#else
+ LEPTON_COMPOSITE X;
+ LEPTON_COMPOSITE Y;
+#endif
+ } Sub;
+} COORD_COMPOSITE;
+
+typedef signed short CELL;
+#define SLUFF_BITS (sizeof(CELL)*CHAR_BIT)-(14)
+typedef union {
+ CELL Cell;
+ struct {
+#ifdef BIG_ENDIAN
+#if SLUFF_BITS
+ /*
+ ** Unused upper bits will cause problems on a big-endian machine unless they
+ ** are deliberately accounted for.
+ */
+ unsigned sluff:SLUF_BITS;
+#endif
+ unsigned Y:7;
+ unsigned X:7;
+#else
+ unsigned X:7;
+ unsigned Y:7;
+#endif
+ } Sub;
+} CELL_COMPOSITE;
+
+typedef int WAYPOINT;
+
+
+/**********************************************************************
+** This is the target composit information. Notice that with an RTTI_NONE
+** and an index value of 0, the target value returned is identical with
+** TARGET_NONE. This is by design and is necessary.
+*/
+typedef long TARGET;
+
+#define TARGET_MANTISSA 24 // Bits of value precision.
+#define TARGET_EXPONENT 8
+typedef union {
+ TARGET Target;
+ struct {
+#ifdef BIG_ENDIAN
+ unsigned Exponent:TARGET_EXPONENT;
+ unsigned Mantissa:TARGET_MANTISSA;
+#else
+ unsigned Mantissa:TARGET_MANTISSA;
+ unsigned Exponent:TARGET_EXPONENT;
+#endif
+ } Sub;
+} TARGET_COMPOSITE;
+
+
+inline TARGET Build_Target(RTTIType kind, int value)
+{
+ TARGET_COMPOSITE target;
+
+ target.Target = 0;
+ target.Sub.Exponent = kind;
+ target.Sub.Mantissa = value;
+ return(target.Target);
+}
+
+
+#define TARGET_NONE ((TARGET)0)
+
+
+/*
+** The map is broken down into regions of this specified dimensions.
+*/
+#define REGION_WIDTH 4
+#define REGION_HEIGHT 4
+#define MAP_REGION_WIDTH (((MAP_CELL_W + (REGION_WIDTH -1)) / REGION_WIDTH)+2)
+#define MAP_REGION_HEIGHT (((MAP_CELL_H + (REGION_WIDTH -1)) / REGION_HEIGHT)+2)
+#define MAP_TOTAL_REGIONS (MAP_REGION_WIDTH * MAP_REGION_HEIGHT)
+
+
+/**********************************************************************
+** This enumerates the various known fear states for infantry units.
+** At these stages, certain events or recovery actions are performed.
+*/
+typedef enum FearType {
+ FEAR_NONE=0, // No fear at all (default state).
+ FEAR_ANXIOUS=10, // Something makes them scared.
+ FEAR_SCARED=100, // Scared enough to take cover.
+ FEAR_PANIC=200, // Run away! Run away!
+ FEAR_MAXIMUM=255 // Scared to death.
+} FearType;
+
+
+/**********************************************************************
+** When a moving object moves, the Per_Cell_Process function is called
+** at various times during the move. Certain operations must be
+** performed at different stages of the move. This enum specifies the
+** different conditions under which the Per_Cell_Process function is
+** called.
+*/
+typedef enum PCPType {
+ PCP_ROTATION, // When sitting in place and performing rotations.
+ PCP_DURING, // While moving between two cells.
+ PCP_END, // When the 'center' of a cell is reached during movement.
+} PCPType;
+
+
+/**********************************************************************
+** A base is broken up into several zones. This type enumerates the
+** various zones.
+*/
+typedef enum ZoneType {
+ ZONE_CORE, // Center of base.
+ ZONE_NORTH, // North section.
+ ZONE_EAST, // East section.
+ ZONE_SOUTH, // South section.
+ ZONE_WEST, // West section.
+
+ ZONE_COUNT,
+ ZONE_FIRST=0,
+ ZONE_NONE=-1
+} ZoneType;
+
+
+/**********************************************************************
+** The map is prescanned to mark of movement zones according to certain
+** movement characteristics. This enum specifies those characteristics
+** and movement zones kept track of.
+*/
+typedef enum MZoneType {
+ MZONE_NORMAL, // Normal terrestrial objects (can't crush walls).
+ MZONE_CRUSHER, // Can crush crushable wall types.
+ MZONE_DESTROYER, // Can destroy walls.
+ MZONE_WATER, // Water based objects.
+
+ MZONE_COUNT,
+ MZONE_FIRST=0
+} MZoneType;
+
+#define MZONEF_NORMAL (1<APC or vehicle->Repair facility.
+ ACTION_SELF, // Self select special case.
+ ACTION_ATTACK, // Can attack or fire upon it in some fashion.
+ ACTION_HARVEST, // Special harvest mode.
+ ACTION_SELECT, // Would change selection to specified object.
+ ACTION_TOGGLE_SELECT,// Toggles select state of the object.
+ ACTION_CAPTURE, // The unit will try to capture the object.
+ ACTION_REPAIR, // The target object should be repaired.
+ ACTION_SELL, // The target building should be sold back.
+ ACTION_SELL_UNIT, // The target unit should be sold back.
+ ACTION_NO_SELL, // No sell or no repair.
+ ACTION_NO_REPAIR, // No sell or no repair.
+ ACTION_SABOTAGE, // The unit will try to sabotage/destroy the object.
+ ACTION_PARA_BOMB, // Parachute bomb strike.
+ ACTION_PARA_INFANTRY,// Parachute infantry strike.
+ ACTION_PARA_SABOTEUR,// Parachute saboteur strike.
+ ACTION_NUKE_BOMB, // That target object should be blasted.
+ ACTION_AIR_STRIKE, // That target object should be blasted.
+ ACTION_CHRONOSPHERE, // That target object should be teleported.
+ ACTION_CHRONO2, // Teleport it to the given coordinates now.
+ ACTION_IRON_CURTAIN, // That target object should be invulnerable.
+ ACTION_SPY_MISSION, // Photo recon mission.
+ ACTION_GUARD_AREA, // Guard the area/object clicked on.
+ ACTION_HEAL, // Heal the infantryman clicked on.
+ ACTION_DAMAGE, // Enter and damage building.
+ ACTION_GREPAIR, // Enter and complete repair building.
+ ACTION_NO_DEPLOY,
+ ACTION_NO_ENTER,
+ ACTION_NO_GREPAIR,
+
+ ACTION_COUNT
+} ActionType;
+
+
+/**********************************************************************
+** When a unit gets damaged, the result of the damage is returned as
+** this type. It can range from no damage taken to complete destruction.
+*/
+typedef enum ResultType {
+ RESULT_NONE, // No damage was taken by the target.
+ RESULT_LIGHT, // Some damage was taken, but no state change occurred.
+ RESULT_HALF, // Damaged to below half strength (only returned on transition).
+ RESULT_MAJOR, // Damaged down to 1 hit point.
+ RESULT_DESTROYED // Damaged to complete destruction.
+} ResultType;
+
+
+#ifdef OBSOLETE
+/**********************************************************************
+** These are the special concrete control defines. They enumerate the
+** sequence order of the concrete icons in the concrete art file.
+*/
+// DEBUG === convert this to be zero based so that a nulled cell is the
+// default cell.
+enum ConcreteEnum {
+ C_NONE=-1,
+ C_LEFT=0,
+ C_RIGHT=1,
+ C_RIGHT_UPDOWN=2,
+ C_LEFT_UPDOWN=3,
+ C_UP_RIGHT=4,
+ C_UP_LEFT=5,
+ C_DOWN_RIGHT=6,
+ C_DOWN_LEFT=7,
+ C_RIGHT_DOWN=8,
+ C_LEFT_DOWN=9,
+ C_RIGHT_UP=10,
+ C_LEFT_UP=11,
+ C_UPDOWN_RIGHT=12,
+ C_UPDOWN_LEFT=13
+};
+#endif
+
+
+/**********************************************************************
+** Units that move can move at different speeds. These enumerate the
+** different speeds that a unit can move.
+*/
+typedef enum MPHType{
+ MPH_IMMOBILE=0,
+ MPH_VERY_SLOW=5, // 2
+ MPH_KINDA_SLOW=6, // 3
+ MPH_SLOW=8, // 4
+ MPH_SLOW_ISH=10, // 5
+ MPH_MEDIUM_SLOW=12, // 6
+ MPH_MEDIUM=18, // 9
+ MPH_MEDIUM_FAST=30, // 12
+ MPH_MEDIUM_FASTER=35, // 14
+ MPH_FAST=40, // 16
+ MPH_ROCKET=60, // 24
+ MPH_VERY_FAST=100, // 40
+ MPH_LIGHT_SPEED=255 // 100
+} MPHType;
+
+
+/**********************************************************************
+** The houses that can be played are listed here. Each has their own
+** personality and strengths.
+*/
+typedef enum HousesType {
+ HOUSE_NONE=-1,
+ HOUSE_SPAIN, // Gold (unremapped)
+ HOUSE_GREECE, // LtBlue
+ HOUSE_USSR, // Red
+ HOUSE_ENGLAND, // Green
+ HOUSE_UKRAINE, // Orange
+ HOUSE_GERMANY, // Grey
+ HOUSE_FRANCE, // Blue
+ HOUSE_TURKEY, // Brown
+ HOUSE_GOOD, // Global Defense Initiative
+ HOUSE_BAD, // Brotherhood of Nod
+ HOUSE_NEUTRAL, // Civilians
+ HOUSE_JP, // Disaster Containment Team
+ HOUSE_MULTI1, // Multi-Player house #1
+ HOUSE_MULTI2, // Multi-Player house #2
+ HOUSE_MULTI3, // Multi-Player house #3
+ HOUSE_MULTI4, // Multi-Player house #4
+ HOUSE_MULTI5, // Multi-Player house #5
+ HOUSE_MULTI6, // Multi-Player house #6
+ HOUSE_MULTI7, // Multi-Player house #7
+ HOUSE_MULTI8, // Multi-Player house #8
+ HOUSE_COUNT,
+ HOUSE_FIRST=0
+} HousesType;
+
+inline HousesType operator++(HousesType &, int);
+
+#define HOUSEF_ALLIES (HOUSEF_ENGLAND|HOUSEF_SPAIN|HOUSEF_GREECE|HOUSEF_GERMANY|HOUSEF_FRANCE|HOUSEF_TURKEY|HOUSEF_GOOD)
+#define HOUSEF_SOVIET (HOUSEF_USSR|HOUSEF_UKRAINE|HOUSEF_BAD)
+#define HOUSEF_OTHERS (HOUSEF_NEUTRAL|HOUSEF_JP|HOUSEF_MULTI1|HOUSEF_MULTI2|HOUSEF_MULTI3|HOUSEF_MULTI4|HOUSEF_MULTI5|HOUSEF_MULTI6|HOUSEF_MULTI7|HOUSEF_MULTI8)
+#define HOUSEF_NONE 0
+
+#define HOUSEF_ENGLAND (1L< 2 players.
+*/
+typedef enum ScenarioPlayerEnum
+{
+ SCEN_PLAYER_NONE = -1,
+ SCEN_PLAYER_SPAIN,
+ SCEN_PLAYER_GREECE,
+ SCEN_PLAYER_USSR,
+ SCEN_PLAYER_JP,
+ SCEN_PLAYER_2PLAYER,
+ SCEN_PLAYER_MPLAYER,
+ SCEN_PLAYER_COUNT,
+ SCEN_PLAYER_FIRST = 0
+} ScenarioPlayerType;
+
+inline ScenarioPlayerType operator++(ScenarioPlayerType &, int);
+
+
+/**********************************************************************
+** These are the directional parameters for a scenario.
+*/
+typedef enum ScenarioDirEnum
+{
+ SCEN_DIR_NONE = -1,
+ SCEN_DIR_EAST,
+ SCEN_DIR_WEST,
+ SCEN_DIR_COUNT,
+ SCEN_DIR_FIRST = 0
+} ScenarioDirType;
+
+inline ScenarioDirType operator++(ScenarioDirType &, int);
+
+
+/**********************************************************************
+** These are the random variations of a scenario.
+*/
+typedef enum ScenarioVarEnum
+{
+ SCEN_VAR_NONE = -1,
+ SCEN_VAR_A,
+ SCEN_VAR_B,
+ SCEN_VAR_C,
+ SCEN_VAR_D,
+ SCEN_VAR_COUNT, // comes before the Lose value!
+ SCEN_VAR_LOSE,
+ SCEN_VAR_FIRST = 0
+} ScenarioVarType;
+
+inline ScenarioVarType operator++(ScenarioVarType &, int);
+
+
+/**********************************************************************
+** The objects to be drawn on the map are grouped into layers. These
+** enumerated values specify those layers. The ground layer is sorted
+** from back to front.
+*/
+typedef enum LayerType {
+ LAYER_NONE=-1,
+ LAYER_SURFACE, // Flat on the ground (no sorting or apparent vertical height).
+ LAYER_GROUND, // Touching the ground type object (units & buildings).
+ LAYER_AIR, // Flying above the ground (explosions & flames).
+ LAYER_TOP, // Topmost layer (aircraft & bullets).
+
+ LAYER_COUNT,
+ LAYER_FIRST=0
+} LayerType;
+
+inline LayerType operator++(LayerType &, int);
+
+
+/**********************************************************************
+** This enumerates the various bullet types. These types specify bullet's
+** visual and explosive characteristics.
+*/
+typedef enum BulletType {
+ BULLET_NONE=-1,
+
+ BULLET_INVISIBLE,
+ BULLET_CANNON,
+ BULLET_ACK,
+ BULLET_TORPEDO,
+ BULLET_FROG,
+ BULLET_HEAT_SEEKER,
+ BULLET_LASER_GUIDED,
+ BULLET_LOBBED,
+ BULLET_BOMBLET,
+ BULLET_BALLISTIC,
+ BULLET_PARACHUTE,
+ BULLET_FIREBALL,
+ BULLET_DOG,
+ BULLET_CATAPULT,
+ BULLET_AAMISSILE,
+ BULLET_GPS_SATELLITE,
+ BULLET_NUKE_UP,
+ BULLET_NUKE_DOWN,
+
+ BULLET_COUNT,
+ BULLET_FIRST=0
+} BulletType;
+
+inline BulletType operator++(BulletType &, int);
+
+
+/**********************************************************************
+** All game buildings (structures) are enumerated here. This includes
+** civilian structures as well.
+*/
+typedef enum StructType {
+ STRUCT_NONE=-1,
+ STRUCT_ADVANCED_TECH,
+ STRUCT_IRON_CURTAIN,
+ STRUCT_WEAP,
+ STRUCT_CHRONOSPHERE,
+ STRUCT_PILLBOX,
+ STRUCT_CAMOPILLBOX,
+ STRUCT_RADAR,
+ STRUCT_GAP,
+ STRUCT_TURRET,
+ STRUCT_AAGUN,
+ STRUCT_FLAME_TURRET,
+ STRUCT_CONST,
+ STRUCT_REFINERY,
+ STRUCT_STORAGE,
+ STRUCT_HELIPAD,
+ STRUCT_SAM,
+ STRUCT_AIRSTRIP,
+ STRUCT_POWER,
+ STRUCT_ADVANCED_POWER,
+ STRUCT_SOVIET_TECH,
+ STRUCT_HOSPITAL,
+ STRUCT_BARRACKS,
+ STRUCT_TENT,
+ STRUCT_KENNEL,
+ STRUCT_REPAIR,
+ STRUCT_BIO_LAB,
+ STRUCT_MISSION,
+ STRUCT_SHIP_YARD,
+ STRUCT_SUB_PEN,
+ STRUCT_MSLO,
+ STRUCT_FORWARD_COM,
+ STRUCT_TESLA,
+
+ /*
+ ** All buildings that are never used as a prerequisite
+ ** for construction, follow this point. Typically, this is
+ ** limited to civilian structures. Also, the following
+ ** buildings are NEVER used in the availability bit field
+ ** record that each house maintains. i.e., STRUCTF_????
+ ** bit checking will never occur with the following
+ ** building types.
+ */
+ STRUCT_FAKEWEAP,
+ STRUCT_FAKECONST,
+ STRUCT_FAKE_YARD,
+ STRUCT_FAKE_PEN,
+ STRUCT_FAKE_RADAR,
+
+ STRUCT_SANDBAG_WALL,
+ STRUCT_CYCLONE_WALL,
+ STRUCT_BRICK_WALL,
+ STRUCT_BARBWIRE_WALL,
+ STRUCT_WOOD_WALL,
+ STRUCT_FENCE,
+
+ STRUCT_AVMINE,
+ STRUCT_APMINE,
+ STRUCT_V01,
+ STRUCT_V02,
+ STRUCT_V03,
+ STRUCT_V04,
+ STRUCT_V05,
+ STRUCT_V06,
+ STRUCT_V07,
+ STRUCT_V08,
+ STRUCT_V09,
+ STRUCT_V10,
+ STRUCT_V11,
+ STRUCT_V12,
+ STRUCT_V13,
+ STRUCT_V14,
+ STRUCT_V15,
+ STRUCT_V16,
+ STRUCT_V17,
+ STRUCT_V18,
+ STRUCT_PUMP,
+ STRUCT_V20,
+ STRUCT_V21,
+ STRUCT_V22,
+ STRUCT_V23,
+ STRUCT_V24,
+ STRUCT_V25,
+ STRUCT_V26,
+ STRUCT_V27,
+ STRUCT_V28,
+ STRUCT_V29,
+ STRUCT_V30,
+ STRUCT_V31,
+ STRUCT_V32,
+ STRUCT_V33,
+ STRUCT_V34,
+ STRUCT_V35,
+ STRUCT_V36,
+ STRUCT_V37,
+ STRUCT_BARREL,
+ STRUCT_BARREL3,
+
+#ifdef FIXIT_ANTS
+ STRUCT_QUEEN,
+ STRUCT_LARVA1,
+ STRUCT_LARVA2,
+#endif
+
+ STRUCT_COUNT,
+ STRUCT_FIRST=0
+} StructType;
+
+inline StructType operator++(StructType &, int);
+
+#define STRUCTF_NONE 0L
+#define STRUCTF_ADVANCED_TECH (1L << STRUCT_ADVANCED_TECH)
+#define STRUCTF_IRON_CURTAIN (1L << STRUCT_IRON_CURTAIN)
+#define STRUCTF_WEAP (1L << STRUCT_WEAP)
+#define STRUCTF_CHRONOSPHERE (1L << STRUCT_CHRONOSPHERE)
+#define STRUCTF_PILLBOX (1L << STRUCT_PILLBOX)
+#define STRUCTF_CAMOPILLBOX (1L << STRUCT_CAMOPILLBOX)
+#define STRUCTF_RADAR (1L << STRUCT_RADAR)
+#define STRUCTF_GAP (1L << STRUCT_GAP)
+#define STRUCTF_TURRET (1L << STRUCT_TURRET)
+#define STRUCTF_AAGUN (1L << STRUCT_AAGUN)
+#define STRUCTF_FLAME_TURRET (1L << STRUCT_FLAME_TURRET)
+#define STRUCTF_CONST (1L << STRUCT_CONST)
+#define STRUCTF_REFINERY (1L << STRUCT_REFINERY)
+#define STRUCTF_STORAGE (1L << STRUCT_STORAGE)
+#define STRUCTF_HELIPAD (1L << STRUCT_HELIPAD)
+#define STRUCTF_SAM (1L << STRUCT_SAM)
+#define STRUCTF_AIRSTRIP (1L << STRUCT_AIRSTRIP)
+#define STRUCTF_POWER (1L << STRUCT_POWER)
+#define STRUCTF_ADVANCED_POWER (1L << STRUCT_ADVANCED_POWER)
+#define STRUCTF_SOVIET_TECH (1L << STRUCT_SOVIET_TECH)
+#define STRUCTF_HOSPITAL (1L << STRUCT_HOSPITAL)
+#define STRUCTF_BARRACKS (1L << STRUCT_BARRACKS)
+#define STRUCTF_TENT (1L << STRUCT_TENT)
+#define STRUCTF_KENNEL (1L << STRUCT_KENNEL)
+#define STRUCTF_REPAIR (1L << STRUCT_REPAIR)
+#define STRUCTF_BIO_LAB (1L << STRUCT_BIO_LAB)
+#define STRUCTF_MISSION (1L << STRUCT_MISSION)
+#define STRUCTF_SHIP_YARD (1L << STRUCT_SHIP_YARD)
+#define STRUCTF_SUB_PEN (1L << STRUCT_SUB_PEN)
+#define STRUCTF_MSLO (1L << STRUCT_MSLO)
+#define STRUCTF_FAKECONST (1L << STRUCT_FAKECONST)
+#define STRUCTF_FAKEWEAP (1L << STRUCT_FAKEWEAP)
+
+
+/**********************************************************************
+** The overlays are enumerated here. An overlay functions similarly to
+** a transparent icon. It is placed over the terrain but usually falls
+** "under" buildings, trees, and units.
+*/
+typedef enum OverlayType {
+ OVERLAY_NONE=-1,
+ OVERLAY_SANDBAG_WALL, // Piled sandbags.
+ OVERLAY_CYCLONE_WALL, // Chain-link fence.
+ OVERLAY_BRICK_WALL, // Solid concrete wall.
+ OVERLAY_BARBWIRE_WALL, // Barbed-wire wall.
+ OVERLAY_WOOD_WALL, // Wooden fence.
+ OVERLAY_GOLD1,
+ OVERLAY_GOLD2,
+ OVERLAY_GOLD3,
+ OVERLAY_GOLD4,
+ OVERLAY_GEMS1,
+ OVERLAY_GEMS2,
+ OVERLAY_GEMS3,
+ OVERLAY_GEMS4,
+ OVERLAY_V12, // Haystacks
+ OVERLAY_V13, // Haystack
+ OVERLAY_V14, // Wheat field
+ OVERLAY_V15, // Fallow field
+ OVERLAY_V16, // Corn field
+ OVERLAY_V17, // Celery field
+ OVERLAY_V18, // Potato field
+ OVERLAY_FLAG_SPOT, // Flag start location.
+ OVERLAY_WOOD_CRATE, // Wooden goodie crate.
+ OVERLAY_STEEL_CRATE, // Steel goodie crate.
+ OVERLAY_FENCE, // New fangled fence.
+ OVERLAY_WATER_CRATE, // Water goodie crate.
+
+ OVERLAY_COUNT,
+ OVERLAY_FIRST=0
+} OverlayType;
+
+inline OverlayType operator++(OverlayType &, int);
+
+
+/**********************************************************************
+** This specifies the infantry in the game. The "E" designation is
+** similar to the army classification of enlisted soldiers.
+*/
+typedef enum InfantryType{
+ INFANTRY_NONE=-1,
+ INFANTRY_E1, // Mini-gun armed.
+ INFANTRY_E2, // Grenade thrower.
+ INFANTRY_E3, // Rocket launcher.
+ INFANTRY_E4, // Flame thrower equipped.
+ INFANTRY_RENOVATOR, // Engineer.
+ INFANTRY_TANYA, // Saboteur.
+ INFANTRY_SPY, // Spy.
+ INFANTRY_THIEF, // Thief.
+ INFANTRY_MEDIC, // Field Medic.
+ INFANTRY_GENERAL, // Field Marshal.
+ INFANTRY_DOG, // Soviet attack dog
+
+ INFANTRY_C1, // Civilian
+ INFANTRY_C2, // Civilian
+ INFANTRY_C3, // Civilian
+ INFANTRY_C4, // Civilian
+ INFANTRY_C5, // Civilian
+ INFANTRY_C6, // Civilian
+ INFANTRY_C7, // Civilian
+ INFANTRY_C8, // Civilian
+ INFANTRY_C9, // Civilian
+ INFANTRY_C10, // Nikumba
+ INFANTRY_EINSTEIN, // Einstein
+ INFANTRY_DELPHI, // Agent "Delphi"
+ INFANTRY_CHAN, // Dr. Chan
+
+#ifdef FIXIT_CSII // checked - ajw 9/28/98
+// CounterStrike II only!
+ INFANTRY_SHOCK, // Shock Trooper
+ INFANTRY_MECHANIC,
+#endif
+
+ INFANTRY_COUNT,
+ INFANTRY_FIRST=0
+#ifdef FIXIT_CSII // checked - ajw 9/28/98
+,
+ INFANTRY_RA_COUNT = INFANTRY_SHOCK
+#endif
+} InfantryType;
+
+#define INFANTRYF_DOG (1L << INFANTRY_DOG)
+
+inline InfantryType operator++(InfantryType &, int);
+
+
+/**********************************************************************
+** The game units are enumerated here. These include not only traditional
+** vehicles, but also hovercraft and gunboats.
+*/
+typedef enum UnitType{
+ UNIT_NONE=-1,
+ UNIT_HTANK, // Mammoth tank.
+ UNIT_MTANK, // Heavy tank.
+ UNIT_MTANK2, // Medium tank.
+ UNIT_LTANK, // Light tank ('Bradly').
+ UNIT_APC, // APC.
+ UNIT_MINELAYER, // Mine-laying vehicle.
+ UNIT_JEEP, // 4x4 jeep replacement.
+ UNIT_HARVESTER, // Resource gathering vehicle.
+ UNIT_ARTY, // Artillery unit.
+ UNIT_MRJ, // Mobile Radar Jammer.
+ UNIT_MGG, // Mobile Gap Generator
+ UNIT_MCV, // Mobile construction vehicle.
+ UNIT_V2_LAUNCHER, // V2 rocket launcher.
+ UNIT_TRUCK, // Convoy truck
+
+#ifdef FIXIT_ANTS
+ UNIT_ANT1, // Warrior ant.
+ UNIT_ANT2, // Warrior ant.
+ UNIT_ANT3, // Warrior ant.
+#endif
+
+#ifdef FIXIT_CSII // checked - ajw 9/28/98
+// CS II ONLY!
+ UNIT_CHRONOTANK, // Chrono-shifting tank
+ UNIT_TESLATANK, // Tesla-equipped tank
+ UNIT_MAD, // Timequake tank
+ UNIT_DEMOTRUCK, // Jihad truck
+#ifdef FIXIT_PHASETRANSPORT // checked - ajw 9/28/98
+ UNIT_PHASE, // cloaking APC for special missions
+#endif
+#endif
+
+ UNIT_COUNT,
+ UNIT_FIRST=0
+#ifdef FIXIT_CSII // checked - ajw 9/28/98
+,
+ UNIT_RA_COUNT = UNIT_CHRONOTANK
+#endif
+} UnitType;
+
+inline UnitType operator++(UnitType &, int);
+
+#define UNITF_HTANK (1L<id)
+
+
+#define MAX_LOG_LEVEL 10
+
+// Maximum number of multi players possible.
+#define MAX_PLAYERS 8 // max # of players we can have
+
+
+
+#endif
diff --git a/CODE/DESCDLG.CPP b/CODE/DESCDLG.CPP
new file mode 100644
index 0000000..3700a78
--- /dev/null
+++ b/CODE/DESCDLG.CPP
@@ -0,0 +1,163 @@
+/*
+** Command & Conquer Red Alert(tm)
+** Copyright 2025 Electronic Arts Inc.
+**
+** This program is free software: you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation, either version 3 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program. If not, see .
+*/
+
+/* $Header: /CounterStrike/DESCDLG.CPP 1 3/03/97 10:24a Joe_bostic $ */
+/***********************************************************************************************
+ *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
+ ***********************************************************************************************
+ * *
+ * Project Name : Command & Conquer *
+ * *
+ * File Name : 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_BUTTON, 0, BUTTON_Y);
+ TextButtonClass cancelbtn(BUTTON_CANCEL, TXT_CANCEL, TPF_BUTTON, 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, 320, 200, GadgetClass::LEFTPRESS|GadgetClass::RIGHTPRESS);
+ optionsbtn.Add_Tail(background);
+
+ /*
+ ** Main Processing Loop
+ */
+ bool display = true;
+ bool process = true;
+ while (process) {
+
+ /*
+ ** Invoke game callback
+ */
+ Call_Back();
+
+ /*
+ ** Refresh display if needed
+ */
+ if (display) {
+
+ Window_Hide_Mouse(WINDOW_EDITOR);
+
+ /*
+ ** Draw the background
+ */
+ Window_Box (WINDOW_EDITOR, BOXSTYLE_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 KeyNumType(BUTTON_OPTIONS|KN_BUTTON):
+ strtrim(string);
+ process = false;
+ break;
+
+ case KN_ESC:
+ case KeyNumType(BUTTON_CANCEL|KN_BUTTON):
+ string[0]= NULL;
+ strtrim(string);
+ process = false;
+ break;
+
+ case KeyNumType(BUTTON_EDIT|KN_BUTTON):
+ break;
+
+ default:
+ break;
+ }
+ }
+}
+
diff --git a/CODE/DESCDLG.H b/CODE/DESCDLG.H
new file mode 100644
index 0000000..484b4ce
--- /dev/null
+++ b/CODE/DESCDLG.H
@@ -0,0 +1,69 @@
+/*
+** Command & Conquer Red Alert(tm)
+** Copyright 2025 Electronic Arts Inc.
+**
+** This program is free software: you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation, either version 3 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program. If not, see .
+*/
+
+/* $Header: /CounterStrike/DESCDLG.H 1 3/03/97 10:24a Joe_bostic $ */
+/***********************************************************************************************
+ *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
+ ***********************************************************************************************
+ * *
+ * Project Name : Command & Conquer *
+ * *
+ * File Name : 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
+
+
diff --git a/CODE/DIAL8.CPP b/CODE/DIAL8.CPP
new file mode 100644
index 0000000..c201fc8
--- /dev/null
+++ b/CODE/DIAL8.CPP
@@ -0,0 +1,319 @@
+/*
+** Command & Conquer Red Alert(tm)
+** Copyright 2025 Electronic Arts Inc.
+**
+** This program is free software: you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation, either version 3 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program. If not, see .
+*/
+
+/* $Header: /CounterStrike/DIAL8.CPP 1 3/03/97 10:24a Joe_bostic $ */
+/***********************************************************************************************
+ *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
+ ***********************************************************************************************
+ * *
+ * Project Name : Command & Conquer *
+ * *
+ * File Name : DIAL8.CPP *
+ * *
+ * Programmer : Joe L. Bostic *
+ * *
+ * Start Date : 07/05/96 *
+ * *
+ * Last Update : July 5, 1996 [JLB] *
+ * *
+ *---------------------------------------------------------------------------------------------*
+ * 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 substitutes
+ ** '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)
+{
+ RemapControlType * scheme = GadgetClass::Get_Color_Scheme();
+
+ /*
+ ** 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_DOWN, true);
+ for (int i=0; i<8; i++) {
+ Draw_Box(FacePoint[i][0] - 1, FacePoint[i][1] -1, 3, 3, BOXSTYLE_RAISED, false);
+ }
+
+ /*
+ ** Draw the hand & its shadow.
+ */
+ LogicPage->Draw_Line(FaceX+1, FaceY+1, FaceLine[Facing][0]+1, FaceLine[Facing][1]+1, scheme->Shadow);
+ LogicPage->Draw_Line(FaceX, FaceY, FaceLine[Facing][0], FaceLine[Facing][1], scheme->Highlight);
+
+ /*
+ ** 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();
+}
diff --git a/CODE/DIAL8.H b/CODE/DIAL8.H
new file mode 100644
index 0000000..4fdb8c2
--- /dev/null
+++ b/CODE/DIAL8.H
@@ -0,0 +1,76 @@
+/*
+** Command & Conquer Red Alert(tm)
+** Copyright 2025 Electronic Arts Inc.
+**
+** This program is free software: you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation, either version 3 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program. If not, see .
+*/
+
+/* $Header: /CounterStrike/DIAL8.H 1 3/03/97 10:24a Joe_bostic $ */
+/***********************************************************************************************
+ *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
+ ***********************************************************************************************
+ * *
+ * Project Name : Command & Conquer *
+ * *
+ * File Name : 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
+
diff --git a/CODE/DIALOG.CPP b/CODE/DIALOG.CPP
new file mode 100644
index 0000000..1c5e93c
--- /dev/null
+++ b/CODE/DIALOG.CPP
@@ -0,0 +1,998 @@
+/*
+** Command & Conquer Red Alert(tm)
+** Copyright 2025 Electronic Arts Inc.
+**
+** This program is free software: you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation, either version 3 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program. If not, see .
+*/
+
+/* $Header: /CounterStrike/DIALOG.CPP 1 3/03/97 10:24a Joe_bostic $ */
+/***********************************************************************************************
+ *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
+ ***********************************************************************************************
+ * *
+ * Project Name : Command & Conquer *
+ * *
+ * File Name : DIALOG.CPP *
+ * *
+ * Programmer : Joe L. Bostic *
+ * *
+ * Start Date : September 10, 1993 *
+ * *
+ * Last Update : July 31, 1996 [JLB] *
+ * *
+ *---------------------------------------------------------------------------------------------*
+ * Functions: *
+ * Clip_Text_Print -- Prints text with clipping and 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. *
+ * Draw_Caption -- Draws a caption on a dialog box. *
+ * Fancy_Text_Print -- Prints text with a drop shadow. *
+ * Plain_Text_Print -- Prints text without using a color scheme *
+ * 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"
+
+#include "defines.h" //VG 10/17/96
+
+unsigned char * Font_Palette(int color);
+
+
+/***********************************************************************************************
+ * Dialog_Box -- draws a dialog background box *
+ * *
+ * INPUT: *
+ * x,y,w,h the usual *
+ * *
+ * OUTPUT: *
+ * none. *
+ * *
+ * WARNINGS: *
+ * none. *
+ * *
+ * HISTORY: *
+ * 01/26/1995 BR : Created. *
+ * 07/31/1996 JLB : Uses shapes to draw the box. *
+ *=============================================================================================*/
+void Dialog_Box(int x, int y, int w, int h)
+{
+// Try to expand the box a little taller and a little wider to make room for
+// the dialog box graphics in the DOS version.
+#ifndef WIN32
+ x = max(0, x-4);
+ y = max(0, y-4);
+ w = min(w+8, 320-x);
+ h = min(h+8, 200-y);
+#endif
+
+ WindowList[WINDOW_PARTIAL][WINDOWX] = x;
+ WindowList[WINDOW_PARTIAL][WINDOWY] = y;
+ WindowList[WINDOW_PARTIAL][WINDOWWIDTH] = w;
+ WindowList[WINDOW_PARTIAL][WINDOWHEIGHT] = h;
+
+ /*
+ ** Always draw to the hidpage and then blit forward.
+ */
+#ifdef WIN32
+ GraphicViewPortClass * oldpage = Set_Logic_Page(HidPage);
+#else
+ GraphicBufferClass * oldpage = Set_Logic_Page(HidPage);
+#endif
+
+ /*
+ ** Draw the background block.
+ */
+ int cx = w/2;
+ int cy = h/2;
+ void const * shapedata = MFCD::Retrieve("DD-BKGND.SHP");
+#ifdef WIN32
+ CC_Draw_Shape(shapedata, 0, cx-312, cy-192, WINDOW_PARTIAL, SHAPE_WIN_REL);
+ CC_Draw_Shape(shapedata, 1, cx, cy-192, WINDOW_PARTIAL, SHAPE_WIN_REL);
+ CC_Draw_Shape(shapedata, 2, cx-312, cy, WINDOW_PARTIAL, SHAPE_WIN_REL);
+ CC_Draw_Shape(shapedata, 3, cx, cy, WINDOW_PARTIAL, SHAPE_WIN_REL);
+#else
+ CC_Draw_Shape(shapedata, 0, cx-156, cy-96, WINDOW_PARTIAL, SHAPE_WIN_REL);
+#endif
+ /*
+ ** Draw the side strips.
+ */
+ shapedata = MFCD::Retrieve("DD-EDGE.SHP");
+ for (int yy = 0; yy < h; yy += 6) {
+ CC_Draw_Shape(shapedata, 0, 7*RESFACTOR, yy, WINDOW_PARTIAL, SHAPE_WIN_REL);
+ CC_Draw_Shape(shapedata, 1, w-((7+8)*RESFACTOR), yy, WINDOW_PARTIAL, SHAPE_WIN_REL);
+ }
+
+ /*
+ ** Draw the border bars.
+ */
+ shapedata = MFCD::Retrieve("DD-LEFT.SHP");
+ CC_Draw_Shape(shapedata, 0, 0, cy-100*RESFACTOR, WINDOW_PARTIAL, SHAPE_WIN_REL);
+ CC_Draw_Shape(shapedata, 0, 0, cy, WINDOW_PARTIAL, SHAPE_WIN_REL);
+
+ shapedata = MFCD::Retrieve("DD-RIGHT.SHP");
+ int rightx = w - (7*RESFACTOR);
+#ifndef WIN32
+ rightx--;
+#endif
+ CC_Draw_Shape(shapedata, 0, rightx, cy-100*RESFACTOR, WINDOW_PARTIAL, SHAPE_WIN_REL);
+ CC_Draw_Shape(shapedata, 0, rightx, cy, WINDOW_PARTIAL, SHAPE_WIN_REL);
+
+ shapedata = MFCD::Retrieve("DD-BOTM.SHP");
+ CC_Draw_Shape(shapedata, 0, cx-160*RESFACTOR, h-8*RESFACTOR, WINDOW_PARTIAL, SHAPE_WIN_REL);
+ CC_Draw_Shape(shapedata, 0, cx, h-8*RESFACTOR, WINDOW_PARTIAL, SHAPE_WIN_REL);
+
+ shapedata = MFCD::Retrieve("DD-TOP.SHP");
+ CC_Draw_Shape(shapedata, 0, cx-160*RESFACTOR, 0, WINDOW_PARTIAL, SHAPE_WIN_REL);
+ CC_Draw_Shape(shapedata, 0, cx, 0, WINDOW_PARTIAL, SHAPE_WIN_REL);
+
+ /*
+ ** Draw the corner caps.
+ */
+ shapedata = MFCD::Retrieve("DD-CRNR.SHP");
+ CC_Draw_Shape(shapedata, 0, 0, 0, WINDOW_PARTIAL, SHAPE_WIN_REL);
+ CC_Draw_Shape(shapedata, 1, w-(12*RESFACTOR-1), 0, WINDOW_PARTIAL, SHAPE_WIN_REL);
+ CC_Draw_Shape(shapedata, 2, 0, h-(12*RESFACTOR), WINDOW_PARTIAL, SHAPE_WIN_REL);
+ CC_Draw_Shape(shapedata, 3, w-(12*RESFACTOR-1), h-(12*RESFACTOR), WINDOW_PARTIAL, SHAPE_WIN_REL);
+
+#ifdef WIN32
+ WWMouse->Draw_Mouse(&HidPage);
+ HidPage.Blit(SeenBuff, x, y, x, y, w, h, false);
+ WWMouse->Erase_Mouse(&HidPage, FALSE);
+#else
+// Shadow_Blit(0, 0, 320, 200, HidPage, SeenPage, Map.ShadowPage->Get_Buffer());
+ Hide_Mouse();
+ HidPage.Blit(SeenBuff);
+ Show_Mouse();
+// Shadow_Blit(0, 0, 320, 200, HidPage, SeenPage, ((GraphicBufferClass*)Map.Shadow_Address())->Get_Buffer());
+#endif
+ Set_Logic_Page(oldpage);
+}
+
+
+/***********************************************************************************************
+ * 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. *
+ *=============================================================================================*/
+void Draw_Box(int x, int y, int w, int h, BoxStyleEnum up, bool filled)
+{
+ RemapControlType * scheme = GadgetClass::Get_Color_Scheme();
+
+ // Filler, Shadow, Hilite, Corner colors
+
+ BoxStyleType const ButtonColors[BOXSTYLE_COUNT] = {
+ { scheme->Background, scheme->Highlight, scheme->Shadow, scheme->Corners}, // Down
+ { scheme->Background, scheme->Shadow, scheme->Highlight, scheme->Corners}, // Raised
+ { DKGREY, WHITE, BLACK, DKGREY}, // Disabled down
+ { DKGREY, BLACK, LTGREY, DKGREY}, // Disabled up
+ { BLACK, scheme->Box, scheme->Box, BLACK}, // List box
+ { BLACK, scheme->Box, scheme->Box, BLACK}, // Dialog box
+ };
+
+ w--;
+ h--;
+ BoxStyleType const &style = ButtonColors[up];
+
+ if (filled) {
+ LogicPage->Fill_Rect( x, y, x+w, y+h, style.Filler);
+ }
+
+ switch (up) {
+ case (BOXSTYLE_BOX):
+ LogicPage->Draw_Rect(x, y, x+w, y+h, style.Highlight);
+ break;
+
+ case (BOXSTYLE_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. *
+ * 09/04/1996 BWG : Added '@' is treated as a carriage return for width calculations. *
+ *=============================================================================================*/
+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++;
+
+ /*
+ ** Look for special line break character and force a line break when it is
+ ** discovered.
+ */
+ if (*string == '@') {
+ *string = '\r';
+ }
+
+ // While the current line is less then the max length...
+ while (linelen < maxlinelen && *string != '\r' && *string != '\0' && *string != '@') {
+ 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' && *string != '@') {
+ 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 = WindowList[window][WINDOWX];
+ int y = WindowList[window][WINDOWY];
+ int w = WindowList[window][WINDOWWIDTH];
+ int 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);
+
+ /*
+ ** 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). *
+ * *
+ * The C&C gradient font colors are as follows: *
+ * 0 transparent (background) *
+ * 1 foreground color for mono-color fonts only *
+ * 2 shadow under characters ("drop shadow") *
+ * 3 shadow all around characters ("full shadow") *
+ * 4-10 unused *
+ * 11 top row *
+ * 12 next row *
+ * 13 next row *
+ * 14 next row *
+ * 15 bottom row *
+ * *
+ * 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, RemapControlType * 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.
+ int shadow; // Requested shadow value.
+ unsigned char fontpalette[16]; // Working font palette array.
+ int forecolor;
+
+ if (fore == NULL) {
+ fore = &ColorRemaps[PCOLOR_RED];
+ }
+
+ /*
+ ** Init the font palette to the given background color
+ */
+ memset(&fontpalette[0], back, 16);
+
+ forecolor = fore->Color;
+
+ /*
+ ** A gradient font always requires special fixups for the palette
+ */
+ int point = (flag & (TextPrintType)0x000F);
+ if (point == TPF_VCR || point == TPF_6PT_GRAD || point == TPF_METAL12 || point == TPF_EFNT || point == TPF_TYPE) {
+
+ /*
+ ** If a gradient palette is specified, copy the remap table directly, otherwise
+ ** use the foreground color as the entire font remap color.
+ */
+ if (flag & TPF_USE_GRAD_PAL) {
+ memcpy(fontpalette, fore->FontRemap, 16);
+ forecolor = fore->Color;
+ if (point == TPF_TYPE) {
+ forecolor = fontpalette[1];
+ }
+ } else {
+ memset(&fontpalette[4], fore->Color, 12);
+ forecolor = fore->Color;
+ }
+
+ /*
+ ** Medium color: set all font colors to a medium value. This flag
+ ** overrides any gradient effects.
+ */
+ if (flag & TPF_MEDIUM_COLOR) {
+ forecolor = fore->Color;
+ memset(&fontpalette[4], fore->Color, 12);
+ }
+
+ /*
+ ** Bright color: set all font colors to a bright value. This flag
+ ** overrides any gradient effects.
+ */
+ if (flag & TPF_BRIGHT_COLOR) {
+ forecolor = fore->Bright;
+ memset(&fontpalette[4], fore->BrightColor, 12);
+ }
+ }
+
+ /*
+ ** Change the current font if it differs from the font desired.
+ */
+#ifdef WIN32
+ xspace = 1;
+#else
+ xspace = 0;
+#endif
+ yspace = 0;
+
+ switch (point) {
+ case TPF_SCORE:
+ font = ScoreFontPtr;
+ break;
+
+ case TPF_METAL12:
+ font = Metal12FontPtr;
+ //xspace += 1;
+ break;
+
+ case TPF_MAP:
+ font = MapFontPtr;
+ xspace -= 1;
+ break;
+
+ case TPF_VCR:
+ font = VCRFontPtr;
+ break;
+
+ case TPF_6PT_GRAD:
+ font = GradFont6Ptr;
+ xspace -= 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;
+ break;
+
+ case TPF_EFNT:
+ font = EditorFont;
+#ifdef WIN32
+ yspace += 1;
+ xspace -= 1;
+#endif
+ xspace -= 1;
+ break;
+
+ case TPF_8POINT:
+ font = Font8Ptr;
+#ifdef WIN32
+ xspace -= 2;
+ yspace -= 4;
+#else
+ xspace -= 1;
+ yspace -= 2;
+#endif
+ break;
+
+ case TPF_LED:
+#ifdef WIN32
+ xspace -= 4;
+#else
+ xspace -= 2;
+#endif
+ font = FontLEDPtr;
+ break;
+
+ case TPF_TYPE:
+ font = TypeFontPtr;
+ xspace -= 1;
+
+#ifdef WOLAPI_INTEGRATION
+ xspace -= 2;
+ yspace += 2;
+#else // I am implicitly assuming that TPF_TYPE was no longer being used, before I came along, despite the following. ajw
+#ifdef GERMAN
+ yspace += 4; //VG 10/17/96
+#endif
+#endif
+
+ 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;
+#ifdef WIN32
+ yspace -= 2;
+#else
+ yspace -= 1;
+#endif
+ 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;
+ }
+ if (point != TPF_TYPE) {
+ fontpalette[0] = back;
+ fontpalette[1] = fore->Color;
+ }
+
+ /*
+ ** 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(text)>>1;
+ break;
+
+ case TPF_RIGHT:
+ x -= String_Pixel_Width(text);
+ break;
+
+ default:
+ break;
+ }
+
+ if ((unsigned)x < LogicPage->Get_Width() && (unsigned)y < LogicPage->Get_Height()) {
+ LogicPage->Print(text, x, y, forecolor, back);
+// LogicPage->Print(text, x, y, fore->Color, back);
+ }
+ }
+}
+
+
+/***********************************************************************************************
+ * 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, RemapControlType * 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, RemapControlType * 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 support. *
+ * *
+ * Use this routine to print text that that should be clipped at an arbitrary right margin *
+ * as well as possibly recognizing 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, RemapControlType * fore, unsigned back, TextPrintType flag, int 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 was the terminator for this text block, then advance
+ ** to the next tabstop.
+ */
+ if (ptr) {
+ if (tabs) {
+ while (offset > *tabs) {
+ tabs++;
+ }
+ offset = *tabs;
+ } else {
+ offset = ((offset+1 / 50) + 1) * 50;
+ }
+ source = ptr+1;
+ } else {
+ break;
+ }
+ }
+ }
+}
+
+/***************************************************************************
+ * Plain_Text_Print -- Prints text without using a color scheme *
+ * *
+ * INPUT: *
+ * text text to print *
+ * x,y coords to print at *
+ * fore desired foreground color *
+ * back desired background color *
+ * flag text print control flags *
+ * *
+ * OUTPUT: *
+ * none. *
+ * *
+ * WARNINGS: *
+ * Do not use the gradient control flag with this routine! For *
+ * a gradient appearance, use Fancy_Text_Print. *
+ * Despite this routine's name, it is actually faster to call *
+ * Fancy_Text_Print than this routine. *
+ * *
+ * HISTORY: *
+ * 01/05/1996 BRR : Created. *
+ *=========================================================================*/
+void Plain_Text_Print(int text, unsigned x, unsigned y, unsigned fore, unsigned back, TextPrintType flag, ...)
+{
+ RemapControlType scheme;
+
+ memset(&scheme, 0, sizeof(RemapControlType));
+ memset(&(scheme.FontRemap[4]), fore, 12);
+
+ scheme.BrightColor = fore;
+ scheme.Color = fore;
+ scheme.Shadow = fore;
+ scheme.Background = fore;
+ scheme.Corners = fore;
+ scheme.Highlight = fore;
+ scheme.Box = fore;
+ scheme.Bright = fore;
+ scheme.Underline = fore;
+ scheme.Bar = fore;
+
+ Fancy_Text_Print(text, x, y, &scheme, back, flag);
+}
+
+
+/***************************************************************************
+ * Plain_Text_Print -- Prints text without using a color scheme *
+ * *
+ * INPUT: *
+ * text text to print *
+ * x,y coords to print at *
+ * fore desired foreground color *
+ * back desired background color *
+ * flag text print control flags *
+ * *
+ * OUTPUT: *
+ * none. *
+ * *
+ * WARNINGS: *
+ * Do not use the gradient control flag with this routine! For *
+ * a gradient appearance, use Fancy_Text_Print. *
+ * Despite this routine's name, it is actually faster to call *
+ * Fancy_Text_Print than this routine. *
+ * *
+ * HISTORY: *
+ * 01/05/1996 BRR : Created. *
+ *=========================================================================*/
+void Plain_Text_Print(char const * text, unsigned x, unsigned y, unsigned fore, unsigned back, TextPrintType flag, ...)
+{
+ RemapControlType scheme;
+
+ memset(&scheme, 0, sizeof(RemapControlType));
+ memset(&(scheme.FontRemap[4]), fore, 12);
+
+ scheme.BrightColor = fore;
+ scheme.Color = fore;
+ scheme.Shadow = fore;
+ scheme.Background = fore;
+ scheme.Corners = fore;
+ scheme.Highlight = fore;
+ scheme.Box = fore;
+ scheme.Bright = fore;
+ scheme.Underline = fore;
+ scheme.Bar = fore;
+
+ Fancy_Text_Print(text, x, y, &scheme, back, flag);
+}
+
+
+
+unsigned char * Font_Palette(int color)
+{
+ static unsigned char _fpalette[16];
+
+ memset(_fpalette, '\0', sizeof(_fpalette));
+ memset(&_fpalette[11], color, 5);
+ return(_fpalette);
+}
+
+
+
+/***********************************************************************************************
+ * Draw_Caption -- Draws a caption on a dialog box. *
+ * *
+ * This routine draws the caption text and any fancy filigree that the dialog may require. *
+ * *
+ * INPUT: text -- The text of the caption. This is the text number. *
+ * *
+ * x,y -- The dialog box X and Y pixel coordinate of the upper left corner. *
+ * *
+ * w -- The width of the dialog box (in pixels). *
+ * *
+ * OUTPUT: none *
+ * *
+ * WARNINGS: none *
+ * *
+ * HISTORY: *
+ * 06/23/1995 JLB : Created. *
+ *=============================================================================================*/
+void Draw_Caption(int text, int x, int y, int w)
+{
+ Draw_Caption(Text_String(text), x, y, w);
+}
+
+
+void Draw_Caption(char const * text, int x, int y, int w)
+{
+ /*
+ ** Draw the caption.
+ */
+ if (text != NULL && *text != '\0') {
+ if (Debug_Map) {
+ Fancy_Text_Print(text, w/2 + x, (2 * RESFACTOR) + y, GadgetClass::Get_Color_Scheme(), TBLACK, TPF_CENTER|TPF_EFNT|TPF_USE_GRAD_PAL|TPF_NOSHADOW);
+ } else {
+ Fancy_Text_Print(text, w/2 + x, (8 * RESFACTOR) + y, GadgetClass::Get_Color_Scheme(), TBLACK, TPF_CENTER|TPF_TEXT);
+ int length = String_Pixel_Width(text);
+ LogicPage->Draw_Line((x+(w/2))-(length/2), y+FontHeight+FontYSpacing + (8 * RESFACTOR), (x+(w/2))+(length/2),
+ y+FontHeight+FontYSpacing + (8 * RESFACTOR), GadgetClass::Get_Color_Scheme()->Box);
+ }
+ }
+}
diff --git a/CODE/DIBAPI.H b/CODE/DIBAPI.H
new file mode 100644
index 0000000..59bb133
--- /dev/null
+++ b/CODE/DIBAPI.H
@@ -0,0 +1,153 @@
+/*
+** Command & Conquer Red Alert(tm)
+** Copyright 2025 Electronic Arts Inc.
+**
+** This program is free software: you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation, either version 3 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program. If not, see .
+*/
+
+#ifndef DIBAPI_H
+#define DIBAPI_H
+/*
+ * dibapi.h
+ *
+ * Copyright (c) 1991 Microsoft Corporation. All rights reserved
+ *
+ * Header file for Device-Independent Bitmap (DIB) API. Provides
+ * function prototypes and constants for the following functions:
+ *
+ * BitmapToDIB() - Creates a DIB from a bitmap
+ * ChangeBitmapFormat() - Changes a bitmap to a specified DIB format
+ * ChangeDIBFormat() - Changes a DIB's BPP and/or compression format
+ * CopyScreenToBitmap() - Copies entire screen to a standard Bitmap
+ * CopyScreenToDIB() - Copies entire screen to a DIB
+ * CopyWindowToBitmap() - Copies a window to a standard Bitmap
+ * CopyWindowToDIB() - Copies a window to a DIB
+ * CreateDIBPalette() - Creates a palette from a DIB
+ * CreateDIB() - Creates a new DIB
+ * DestroyDIB() - Deletes DIB when finished using it
+ * DIBError() - Displays message box with error message
+ * DIBHeight() - Gets the DIB height
+ * DIBNumColors() - Calculates number of colors in the DIB's color table
+ * DIBToBitmap() - Creates a bitmap from a DIB
+ * DIBWidth() - Gets the DIB width
+ * FindDIBBits() - Sets pointer to the DIB bits
+ * GetSystemPalette() - Gets the current palette
+ * LoadDIB() - Loads a DIB from a file
+ * PaintBitmap() - Displays standard bitmap in the specified DC
+ * PaintDIB() - Displays DIB in the specified DC
+ * PalEntriesOnDevice() - Gets the number of palette entries
+ * PaletteSize() - Calculates the buffer size required by a palette
+ * PrintDIB() - Prints the specified DIB
+ * PrintScreen() - Prints the entire screen
+ * PrintWindow() - Prints all or part of a window
+ * SaveDIB() - Saves the specified dib in a file
+ *
+ * See the file DIBAPI.TXT for more information about these functions.
+ *
+ * ajw added
+ * LoadDIB_FromMemory() - Loads a DIB from BMP file data located at a location in memory.
+ *
+ */
+
+
+/* Handle to a DIB */
+#define HDIB HANDLE
+
+
+/* Print Area selection */
+#define PW_WINDOW 1
+#define PW_CLIENT 2
+
+
+/* Print Options selection */
+#define PW_BESTFIT 1
+#define PW_STRETCHTOPAGE 2
+#define PW_SCALE 3
+
+/* DIB Macros*/
+
+// WIDTHBYTES performs DWORD-aligning of DIB scanlines. The "bits"
+// parameter is the bit count for the scanline (biWidth * biBitCount),
+// and this macro returns the number of DWORD-aligned bytes needed
+// to hold those bits.
+
+#define WIDTHBYTES(bits) (((bits) + 31) / 32 * 4)
+
+/* Error constants */
+enum {
+ ERR_MIN = 0, // All error #s >= this value
+ ERR_NOT_DIB = 0, // Tried to load a file, NOT a DIB!
+ ERR_MEMORY, // Not enough memory!
+ ERR_READ, // Error reading file!
+ ERR_LOCK, // Error on a GlobalLock()!
+ ERR_OPEN, // Error opening a file!
+ ERR_CREATEPAL, // Error creating palette.
+ ERR_GETDC, // Couldn't get a DC.
+ ERR_CREATEDDB, // Error create a DDB.
+ ERR_STRETCHBLT, // StretchBlt() returned failure.
+ ERR_STRETCHDIBITS, // StretchDIBits() returned failure.
+ ERR_SETDIBITSTODEVICE, // SetDIBitsToDevice() failed.
+ ERR_STARTDOC, // Error calling StartDoc().
+ ERR_NOGDIMODULE, // Couldn't find GDI module in memory.
+ ERR_SETABORTPROC, // Error calling SetAbortProc().
+ ERR_STARTPAGE, // Error calling StartPage().
+ ERR_NEWFRAME, // Error calling NEWFRAME escape.
+ ERR_ENDPAGE, // Error calling EndPage().
+ ERR_ENDDOC, // Error calling EndDoc().
+ ERR_SETDIBITS, // Error calling SetDIBits().
+ ERR_FILENOTFOUND, // Error opening file in GetDib()
+ ERR_INVALIDHANDLE, // Invalid Handle
+ ERR_DIBFUNCTION, // Error on call to DIB function
+ ERR_MAX // All error #s < this value
+ };
+
+
+
+/* Function prototypes */
+
+HDIB FAR BitmapToDIB (HBITMAP hBitmap, HPALETTE hPal);
+HDIB FAR ChangeBitmapFormat (HBITMAP hBitmap,
+ WORD wBitCount,
+ DWORD dwCompression,
+ HPALETTE hPal);
+HDIB FAR ChangeDIBFormat (HDIB hDIB, WORD wBitCount,
+ DWORD dwCompression);
+HBITMAP FAR CopyScreenToBitmap (LPRECT);
+HDIB FAR CopyScreenToDIB (LPRECT);
+HBITMAP FAR CopyWindowToBitmap (HWND, WORD);
+HDIB FAR CopyWindowToDIB (HWND, WORD);
+HPALETTE FAR CreateDIBPalette (HDIB hDIB);
+HDIB FAR CreateDIB(DWORD, DWORD, WORD);
+WORD FAR DestroyDIB (HDIB);
+void FAR DIBError (int ErrNo);
+DWORD FAR DIBHeight (LPCSTR lpDIB);
+WORD FAR DIBNumColors (LPCSTR lpDIB);
+HBITMAP FAR DIBToBitmap (HDIB hDIB, HPALETTE hPal);
+DWORD FAR DIBWidth (LPCSTR lpDIB);
+LPSTR FAR FindDIBBits (LPCSTR lpDIB);
+HPALETTE FAR GetSystemPalette (void);
+HDIB FAR LoadDIB (LPSTR);
+BOOL FAR PaintBitmap (HDC, LPRECT, HBITMAP, LPRECT, HPALETTE);
+BOOL FAR PaintDIB (HDC, LPRECT, HDIB, LPRECT, HPALETTE);
+int FAR PalEntriesOnDevice (HDC hDC);
+WORD FAR PaletteSize (LPCSTR lpDIB);
+WORD FAR PrintDIB (HDIB, WORD, WORD, WORD, LPSTR);
+WORD FAR PrintScreen (LPRECT, WORD, WORD, WORD, LPSTR);
+WORD FAR PrintWindow (HWND, WORD, WORD, WORD, WORD, LPSTR);
+WORD FAR SaveDIB (HDIB, LPSTR);
+
+// ajw added
+HDIB LoadDIB_FromMemory( const unsigned char* pData, DWORD dwBitsSize );
+
+#endif
diff --git a/CODE/DIBFILE.CPP b/CODE/DIBFILE.CPP
new file mode 100644
index 0000000..ddd1f49
--- /dev/null
+++ b/CODE/DIBFILE.CPP
@@ -0,0 +1,703 @@
+/*
+** Command & Conquer Red Alert(tm)
+** Copyright 2025 Electronic Arts Inc.
+**
+** This program is free software: you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation, either version 3 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program. If not, see .
+*/
+
+//*******************************************************************
+//
+// file.c
+//
+// Source file for Device-Independent Bitmap (DIB) API. Provides
+// the following functions:
+//
+// SaveDIB() - Saves the specified dib in a file
+// LoadDIB() - Loads a DIB from a file
+// DestroyDIB() - Deletes DIB when finished using it
+//
+// Development Team: Mark Bader
+// Patrick Schreiber
+// Garrett McAuliffe
+// Eric Flo
+// Tony Claflin
+//
+// Written by Microsoft Product Support Services, Developer Support.
+// COPYRIGHT:
+//
+// (C) Copyright Microsoft Corp. 1993. All rights reserved.
+//
+// You have a royalty-free right to use, modify, reproduce and
+// distribute the Sample Files (and/or any modified version) in
+// any way you find useful, provided that you agree that
+// Microsoft has no warranty obligations or liability for any
+// Sample Application Files which are modified.
+//
+//*******************************************************************
+
+#include
+#include
+#include
+#include